mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 11:13:16 +00:00
Merge pull request #2592 from Cameron653/SYNC_OY_VEY
Mid December Polaris Sync
This commit is contained in:
@@ -37,9 +37,14 @@ script:
|
||||
- (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} ])
|
||||
- source $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}/byond/bin/byondsetup
|
||||
- python tools/TagMatcher/tag-matcher.py ../..
|
||||
- echo "#define UNIT_TEST 1" > code/_unit_tests.dm
|
||||
#First compile is to ensure maps are valid.
|
||||
- echo "#define MAP_TEST 1" > code/_map_tests.dm
|
||||
- cp config/example/* config/
|
||||
- DreamMaker vorestation.dme
|
||||
- travis_wait DreamDaemon vorestation.dmb -invisible -trusted -core 2>&1 | tee log.txt
|
||||
- echo "#define MAP_TEST 0" > code/_map_tests.dm
|
||||
#Second compile is for the unit tests. Compiling a second time to exclude the validated maps is actually faster than waiting for startup with them compiled.
|
||||
- echo "#define UNIT_TEST 1" > code/_unit_tests.dm
|
||||
- DreamMaker vorestation.dme
|
||||
- DreamDaemon vorestation.dmb -invisible -trusted -core 2>&1 | tee log.txt
|
||||
- grep "All Unit Tests Passed" log.txt
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ obj/var/phoronproof = 0
|
||||
suit_contamination()
|
||||
|
||||
if(!pl_head_protected())
|
||||
if(prob(1)) suit_contamination() //Phoron can sometimes get through such an open suit.
|
||||
if(prob(1))
|
||||
suit_contamination() //Phoron can sometimes get through such an open suit.
|
||||
|
||||
//Cannot wash backpacks currently.
|
||||
// if(istype(back,/obj/item/weapon/storage/backpack))
|
||||
@@ -88,7 +89,8 @@ obj/var/phoronproof = 0
|
||||
//Handles all the bad things phoron can do.
|
||||
|
||||
//Contamination
|
||||
if(vsc.plc.CLOTH_CONTAMINATION) contaminate()
|
||||
if(vsc.plc.CLOTH_CONTAMINATION)
|
||||
contaminate()
|
||||
|
||||
//Anything else requires them to not be dead.
|
||||
if(stat >= 2)
|
||||
@@ -143,22 +145,22 @@ obj/var/phoronproof = 0
|
||||
Blind(20)
|
||||
|
||||
/mob/living/carbon/human/proc/pl_head_protected()
|
||||
//Checks if the head is adequately sealed.
|
||||
//Checks if the head is adequately sealed. //This is just odd. TODO: Make this respect the body_parts_covered stuff like thermal gear does.
|
||||
if(head)
|
||||
if(vsc.plc.PHORONGUARD_ONLY)
|
||||
if(head.flags & PHORONGUARD)
|
||||
if(head.flags & PHORONGUARD || head.phoronproof)
|
||||
return 1
|
||||
else if(head.body_parts_covered & EYES)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/pl_suit_protected()
|
||||
//Checks if the suit is adequately sealed.
|
||||
//Checks if the suit is adequately sealed. //This is just odd. TODO: Make this respect the body_parts_covered stuff like thermal gear does.
|
||||
var/coverage = 0
|
||||
for(var/obj/item/protection in list(wear_suit, gloves, shoes))
|
||||
for(var/obj/item/protection in list(wear_suit, gloves, shoes)) //This is why it's odd. If I'm in a full suit, but my shoes and gloves aren't phoron proof, damage.
|
||||
if(!protection)
|
||||
continue
|
||||
if(vsc.plc.PHORONGUARD_ONLY && !(protection.flags & PHORONGUARD))
|
||||
if(vsc.plc.PHORONGUARD_ONLY && !(protection.flags & PHORONGUARD) && !protection.phoronproof)
|
||||
return 0
|
||||
coverage |= protection.body_parts_covered
|
||||
|
||||
@@ -169,9 +171,12 @@ obj/var/phoronproof = 0
|
||||
|
||||
/mob/living/carbon/human/proc/suit_contamination()
|
||||
//Runs over the things that can be contaminated and does so.
|
||||
if(w_uniform) w_uniform.contaminate()
|
||||
if(shoes) shoes.contaminate()
|
||||
if(gloves) gloves.contaminate()
|
||||
if(w_uniform)
|
||||
w_uniform.contaminate()
|
||||
if(shoes)
|
||||
shoes.contaminate()
|
||||
if(gloves)
|
||||
gloves.contaminate()
|
||||
|
||||
|
||||
turf/Entered(obj/item/I)
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#define PASSTABLE 0x1
|
||||
#define PASSGLASS 0x2
|
||||
#define PASSGRILLE 0x4
|
||||
#define PASSBLOB 0x8
|
||||
|
||||
// Bitmasks for the flags_inv variable. These determine when a piece of clothing hides another, i.e. a helmet hiding glasses.
|
||||
// WARNING: The following flags apply only to the external suit!
|
||||
|
||||
@@ -6,3 +6,6 @@
|
||||
#define MAP_LEVEL_SEALED 0x010 // Z-levels that don't allow random transit at edge
|
||||
#define MAP_LEVEL_EMPTY 0x020 // Empty Z-levels that may be used for various things (currently used by bluespace jump)
|
||||
#define MAP_LEVEL_CONSOLES 0x040 // Z-levels available to various consoles, such as the crew monitor (when that gets coded in). Defaults to station_levels if unset.
|
||||
|
||||
// Misc map defines.
|
||||
#define SUBMAP_MAP_EDGE_PAD 15 // Automatically created submaps are forbidden from being this close to the main map's edge.
|
||||
@@ -159,6 +159,7 @@
|
||||
#define MAT_TITANIUM "titanium"
|
||||
#define MAT_PHORON "phoron"
|
||||
#define MAT_DIAMOND "diamond"
|
||||
#define MAT_SNOW "snow"
|
||||
|
||||
#define SHARD_SHARD "shard"
|
||||
#define SHARD_SHRAPNEL "shrapnel"
|
||||
|
||||
@@ -873,22 +873,3 @@ proc/sort_atoms_by_layer(var/list/atoms)
|
||||
result.Swap(i, gap + i)
|
||||
swapped = 1
|
||||
return result
|
||||
|
||||
// Mutable appearances are an inbuilt byond datastructure. Read the documentation on them by hitting F1 in DM.
|
||||
// Basically use them instead of images for overlays/underlays and when changing an object's appearance if you're doing so with any regularity.
|
||||
// Unless you need the overlay/underlay to have a different direction than the base object. Then you have to use an image due to a bug.
|
||||
|
||||
// Mutable appearances are children of images, just so you know.
|
||||
|
||||
/mutable_appearance/New()
|
||||
..()
|
||||
plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE
|
||||
// And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var
|
||||
|
||||
// Helper similar to image()
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.icon = icon
|
||||
MA.icon_state = icon_state
|
||||
MA.layer = layer
|
||||
return MA
|
||||
|
||||
@@ -164,6 +164,14 @@ proc/listclearnulls(list/list)
|
||||
L.Swap(i, rand(i,L.len))
|
||||
return L
|
||||
|
||||
//same, but returns nothing and acts on list in place
|
||||
/proc/shuffle_inplace(list/L)
|
||||
if(!L)
|
||||
return
|
||||
|
||||
for(var/i=1, i<L.len, ++i)
|
||||
L.Swap(i,rand(i,L.len))
|
||||
|
||||
//Return a list with no duplicate entries
|
||||
/proc/uniquelist(var/list/L)
|
||||
. = list()
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
//Checks if all high bits in req_mask are set in bitfield
|
||||
#define BIT_TEST_ALL(bitfield, req_mask) ((~(bitfield) & (req_mask)) == 0)
|
||||
|
||||
//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a
|
||||
#define RANGE_TURFS(RADIUS, CENTER) \
|
||||
block( \
|
||||
locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \
|
||||
locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
|
||||
)
|
||||
|
||||
//Inverts the colour of an HTML string
|
||||
/proc/invertHTML(HTMLstring)
|
||||
|
||||
@@ -476,6 +483,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
var/list/sortmob = sortAtom(mob_list)
|
||||
for(var/mob/observer/eye/M in sortmob)
|
||||
moblist.Add(M)
|
||||
for(var/mob/observer/blob/M in sortmob)
|
||||
moblist.Add(M)
|
||||
for(var/mob/living/silicon/ai/M in sortmob)
|
||||
moblist.Add(M)
|
||||
for(var/mob/living/silicon/pai/M in sortmob)
|
||||
@@ -1331,3 +1340,24 @@ var/mob/dview/dview_mob = new
|
||||
return "[round(number / 1e9, 0.1)] G[symbol]" // giga
|
||||
if(1e12 to 1e15-1)
|
||||
return "[round(number / 1e12, 0.1)] T[symbol]" // tera
|
||||
|
||||
|
||||
|
||||
//ultra range (no limitations on distance, faster than range for distances > 8); including areas drastically decreases performance
|
||||
/proc/urange(dist=0, atom/center=usr, orange=0, areas=0)
|
||||
if(!dist)
|
||||
if(!orange)
|
||||
return list(center)
|
||||
else
|
||||
return list()
|
||||
|
||||
var/list/turfs = RANGE_TURFS(dist, center)
|
||||
if(orange)
|
||||
turfs -= get_turf(center)
|
||||
. = list()
|
||||
for(var/V in turfs)
|
||||
var/turf/T = V
|
||||
. += T
|
||||
. += T.contents
|
||||
if(areas)
|
||||
. |= T.loc
|
||||
|
||||
10
code/_map_tests.dm
Normal file
10
code/_map_tests.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
*
|
||||
* This file is used by Travis to indicate that additional maps need to be compiled to look for errors such as missing paths.
|
||||
* Do not add anything but the MAP_TEST definition here as it will be overwritten by Travis when running tests.
|
||||
*
|
||||
*
|
||||
* Should you wish to edit set MAP_TEST to 1 like so:
|
||||
* #define MAP_TEST 1
|
||||
*/
|
||||
#define MAP_TEST 0
|
||||
@@ -108,7 +108,7 @@
|
||||
W.afterattack(A, src, 1, params) // 1 indicates adjacency
|
||||
else
|
||||
if(ismob(A)) // No instant mob attacking
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
setClickCooldown(get_attack_speed())
|
||||
UnarmedAttack(A, 1)
|
||||
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
@@ -121,7 +121,7 @@
|
||||
// A is a turf or is on a turf, or in something on a turf (pen in a box); but not something in something on a turf (pen in a box in a backpack)
|
||||
sdepth = A.storage_depth_turf()
|
||||
if(isturf(A) || isturf(A.loc) || (sdepth != -1 && sdepth <= 1))
|
||||
if(A.Adjacent(src)) // see adjacent.dm
|
||||
if(A.Adjacent(src) || (W && W.attack_can_reach(src, A, W.reach)) ) // see adjacent.dm
|
||||
if(W)
|
||||
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
|
||||
var/resolved = W.resolve_attackby(A,src)
|
||||
@@ -129,7 +129,7 @@
|
||||
W.afterattack(A, src, 1, params) // 1: clicking something Adjacent
|
||||
else
|
||||
if(ismob(A)) // No instant mob attacking
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
setClickCooldown(get_attack_speed())
|
||||
UnarmedAttack(A, 1)
|
||||
trigger_aiming(TARGET_CAN_CLICK)
|
||||
return
|
||||
|
||||
@@ -23,8 +23,13 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
/obj/item/proc/attack_self(mob/user)
|
||||
return
|
||||
|
||||
// Called at the start of resolve_attackby(), before the actual attack.
|
||||
/obj/item/proc/pre_attack(atom/a, mob/user)
|
||||
return
|
||||
|
||||
//I would prefer to rename this to attack(), but that would involve touching hundreds of files.
|
||||
/obj/item/proc/resolve_attackby(atom/A, mob/user)
|
||||
pre_attack(A, user)
|
||||
add_fingerprint(user)
|
||||
return A.attackby(src, user)
|
||||
|
||||
@@ -44,6 +49,22 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
if(attempt_vr(src,"vore_attackby",args)) return //VOREStation Code
|
||||
return I.attack(src, user, user.zone_sel.selecting)
|
||||
|
||||
// Used to get how fast a mob should attack, and influences click delay.
|
||||
// This is just for inheritence.
|
||||
/mob/proc/get_attack_speed()
|
||||
return DEFAULT_ATTACK_COOLDOWN
|
||||
|
||||
// Same as above but actually does useful things.
|
||||
// W is the item being used in the attack, if any. modifier is if the attack should be longer or shorter than usual, for whatever reason.
|
||||
/mob/living/get_attack_speed(var/obj/item/W)
|
||||
var/speed = DEFAULT_ATTACK_COOLDOWN
|
||||
if(W && istype(W))
|
||||
speed = W.attackspeed
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.attack_speed_percent))
|
||||
speed *= M.attack_speed_percent
|
||||
return speed
|
||||
|
||||
// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person.
|
||||
// Click parameters is the params string from byond Click() code, see that documentation.
|
||||
/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
@@ -66,7 +87,7 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" )
|
||||
/////////////////////////
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
user.do_attack_animation(M)
|
||||
|
||||
var/hit_zone = M.resolve_item_attack(src, user, target_zone)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
if(!..())
|
||||
return 0
|
||||
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
setClickCooldown(get_attack_speed())
|
||||
A.attack_generic(src,rand(5,6),"bitten")
|
||||
|
||||
/*
|
||||
@@ -87,7 +87,7 @@
|
||||
custom_emote(1,"[friendly] [A]!")
|
||||
return
|
||||
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
setClickCooldown(get_attack_speed())
|
||||
if(isliving(A))
|
||||
target_mob = A
|
||||
PunchTarget()
|
||||
@@ -96,7 +96,7 @@
|
||||
A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), attacktext)
|
||||
|
||||
/mob/living/simple_animal/RangedAttack(var/atom/A)
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
setClickCooldown(get_attack_speed())
|
||||
var/distance = get_dist(src, A)
|
||||
|
||||
if(prob(spattack_prob) && (distance >= spattack_min_range) && (distance <= spattack_max_range))
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
return 0
|
||||
rig.selected_module.engage(A, alert_ai)
|
||||
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
|
||||
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
setClickCooldown(get_attack_speed())
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -51,9 +51,10 @@ var/datum/controller/process/planet/planet_controller = null
|
||||
//Redraw weather icons
|
||||
for(var/T in P.planet_floors)
|
||||
var/turf/simulated/turf = T
|
||||
turf.overlays -= turf.weather_overlay
|
||||
// turf.overlays -= turf.weather_overlay
|
||||
turf.weather_overlay = new_overlay
|
||||
turf.overlays += turf.weather_overlay
|
||||
// turf.overlays += turf.weather_overlay
|
||||
turf.update_icon()
|
||||
SCHECK
|
||||
|
||||
//Sun light needs changing
|
||||
|
||||
@@ -540,10 +540,10 @@ var/datum/controller/master/Master = new()
|
||||
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
|
||||
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
|
||||
|
||||
/datum/controller/master/StartLoadingMap()
|
||||
/datum/controller/master/StartLoadingMap(var/quiet = TRUE)
|
||||
if(map_loading)
|
||||
admin_notice("<span class='danger'>Another map is attempting to be loaded before first map released lock. Delaying.</span>", R_DEBUG)
|
||||
else
|
||||
else if(!quiet)
|
||||
admin_notice("<span class='danger'>Map is now being built. Locking.</span>", R_DEBUG)
|
||||
|
||||
//disallow more than one map to load at once, multithreading it will just cause race conditions
|
||||
@@ -557,7 +557,8 @@ var/datum/controller/master/Master = new()
|
||||
air_processing_killed = TRUE
|
||||
map_loading = TRUE
|
||||
|
||||
/datum/controller/master/StopLoadingMap(bounds = null)
|
||||
/datum/controller/master/StopLoadingMap(var/quiet = TRUE)
|
||||
if(!quiet)
|
||||
admin_notice("<span class='danger'>Map is finished. Unlocking.</span>", R_DEBUG)
|
||||
air_processing_killed = FALSE
|
||||
map_loading = FALSE
|
||||
|
||||
@@ -13,10 +13,10 @@ SUBSYSTEM_DEF(creation)
|
||||
|
||||
var/map_loading = FALSE
|
||||
|
||||
/datum/controller/subsystem/creation/StartLoadingMap()
|
||||
/datum/controller/subsystem/creation/StartLoadingMap(var/quiet)
|
||||
map_loading = TRUE
|
||||
|
||||
/datum/controller/subsystem/creation/StopLoadingMap()
|
||||
/datum/controller/subsystem/creation/StopLoadingMap(var/quiet)
|
||||
map_loading = FALSE
|
||||
|
||||
/datum/controller/subsystem/creation/proc/initialize_late_atoms()
|
||||
|
||||
@@ -133,6 +133,16 @@
|
||||
add_inherent_law("Prevent unplanned damage to your assigned vessel wherever possible.")
|
||||
..()
|
||||
|
||||
/datum/ai_laws/mining_drone
|
||||
name = "Excavation Protocols"
|
||||
law_header = "Excavation Protocols"
|
||||
|
||||
/datum/ai_laws/mining_drone/New()
|
||||
add_inherent_law("Do not interfere with the excavation work of non-drones whenever possible.")
|
||||
add_inherent_law("Provide materials for repairing, refitting, and upgrading your assigned vessel.")
|
||||
add_inherent_law("Prevent unplanned damage to your assigned excavation equipment wherever possible.")
|
||||
..()
|
||||
|
||||
/******************** T.Y.R.A.N.T. ********************/
|
||||
/datum/ai_laws/tyrant
|
||||
name = "T.Y.R.A.N.T."
|
||||
|
||||
@@ -147,17 +147,27 @@
|
||||
name = "rifle magazine (5.45mm practice)"
|
||||
path =/obj/item/ammo_magazine/m545/practice
|
||||
|
||||
/*/datum/category_item/autolathe/arms/rifle_545_hunter //VOREStation Edit Start. By request of Ace
|
||||
name = "rifle magazine (5.45mm hunting)"
|
||||
path =/obj/item/ammo_magazine/m545/hunter*/ //VOREStation Edit End.
|
||||
|
||||
/datum/category_item/autolathe/arms/machinegun_545
|
||||
name = "machinegun box magazine (5.45)"
|
||||
path =/obj/item/ammo_magazine/m545saw
|
||||
hidden = 1
|
||||
|
||||
/*/datum/category_item/autolathe/arms/machinegun_545_hunter //VOREStation Edit Start. By request of Ace
|
||||
name = "machinegun box magazine (5.56 hunting)"
|
||||
path =/obj/item/ammo_magazine/m545saw/hunter
|
||||
hidden = 1*/ //VOREStation Edit End.
|
||||
|
||||
/////// 7.62
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_762
|
||||
name = "rifle magazine (7.62mm)"
|
||||
path =/obj/item/ammo_magazine/m762
|
||||
hidden = 1
|
||||
|
||||
/*
|
||||
/datum/category_item/autolathe/arms/rifle_small_762
|
||||
name = "rifle magazine (7.62mm)"
|
||||
@@ -384,6 +394,10 @@
|
||||
path =/obj/item/ammo_magazine/clip/c762
|
||||
hidden = 1
|
||||
|
||||
/*/datum/category_item/autolathe/arms/rifle_clip_762_hunter //VOREStation Edit Start. By request of Ace
|
||||
name = "ammo clip (7.62mm hunting)"
|
||||
path =/obj/item/ammo_magazine/clip/c762/hunter*/ //VOREStation Edit End.
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_clip_762_practice
|
||||
name = "ammo clip (7.62mm practice)"
|
||||
path =/obj/item/ammo_magazine/clip/c762/practice
|
||||
|
||||
@@ -92,6 +92,13 @@
|
||||
question = "An Alien has just been created on the facility. Would you like to play as them?"
|
||||
be_special_flag = BE_ALIEN
|
||||
|
||||
/datum/ghost_query/blob
|
||||
role_name = "Blob"
|
||||
question = "A rapidly expanding Blob has just appeared on the facility. Would you like to play as it?"
|
||||
be_special_flag = BE_ALIEN
|
||||
cutoff_number = 1
|
||||
wait_time = 10 SECONDS
|
||||
|
||||
/datum/ghost_query/syndicate_drone
|
||||
role_name = "Mercenary Drone"
|
||||
question = "A team of dubious mercenaries have purchased a powerful drone, and they are attempting to activate it. Would you like to play as the drone?"
|
||||
|
||||
18
code/datums/mutable_appearance.dm
Normal file
18
code/datums/mutable_appearance.dm
Normal file
@@ -0,0 +1,18 @@
|
||||
// Mutable appearances are an inbuilt byond datastructure. Read the documentation on them by hitting F1 in DM.
|
||||
// Basically use them instead of images for overlays/underlays and when changing an object's appearance if you're doing so with any regularity.
|
||||
// Unless you need the overlay/underlay to have a different direction than the base object. Then you have to use an image due to a bug.
|
||||
|
||||
// Mutable appearances are children of images, just so you know.
|
||||
|
||||
/mutable_appearance/New()
|
||||
..()
|
||||
plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE
|
||||
// And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var
|
||||
|
||||
// Helper similar to image()
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER)
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.icon = icon
|
||||
MA.icon_state = icon_state
|
||||
MA.layer = layer
|
||||
return MA
|
||||
@@ -87,3 +87,18 @@
|
||||
l_hand = /obj/item/weapon/storage/bible
|
||||
id_type = /obj/item/weapon/card/id/civilian/chaplain
|
||||
pda_type = /obj/item/device/pda/chaplain
|
||||
|
||||
/decl/hierarchy/outfit/job/explorer
|
||||
name = OUTFIT_JOB_NAME("Explorer")
|
||||
shoes = /obj/item/clothing/shoes/boots/winter/explorer
|
||||
uniform = /obj/item/clothing/under/explorer
|
||||
mask = /obj/item/clothing/mask/gas/explorer
|
||||
suit = /obj/item/clothing/suit/storage/hooded/explorer
|
||||
gloves = /obj/item/clothing/gloves/black
|
||||
l_ear = /obj/item/device/radio/headset
|
||||
id_slot = slot_wear_id
|
||||
id_type = /obj/item/weapon/card/id/civilian
|
||||
pda_slot = slot_belt
|
||||
pda_type = /obj/item/device/pda/cargo // Brown looks more rugged
|
||||
r_pocket = /obj/item/device/gps/explorer
|
||||
id_pda_assignment = "Explorer"
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/decl/hierarchy/outfit/military/sifguard/pt
|
||||
name = OUTFIT_MILITARY("SifGuard PT")
|
||||
uniform = /obj/item/clothing/under/pt/expeditionary
|
||||
uniform = /obj/item/clothing/under/pt/sifguard
|
||||
shoes = /obj/item/clothing/shoes/black
|
||||
|
||||
/decl/hierarchy/outfit/military/sifguard/utility
|
||||
name = OUTFIT_MILITARY("SifGuard Utility")
|
||||
uniform = /obj/item/clothing/under/utility/expeditionary
|
||||
uniform = /obj/item/clothing/under/utility/sifguard
|
||||
shoes = /obj/item/clothing/shoes/boots/jackboots
|
||||
|
||||
/decl/hierarchy/outfit/military/sifguard/service
|
||||
name = OUTFIT_MILITARY("SifGuard Service")
|
||||
uniform = /obj/item/clothing/under/utility/expeditionary
|
||||
uniform = /obj/item/clothing/under/utility/sifguard
|
||||
shoes = /obj/item/clothing/shoes/boots/jackboots
|
||||
suit = /obj/item/clothing/suit/storage/service/expeditionary
|
||||
suit = /obj/item/clothing/suit/storage/service/sifguard
|
||||
|
||||
/decl/hierarchy/outfit/military/sifguard/dress
|
||||
name = OUTFIT_MILITARY("SifGuard Dress")
|
||||
uniform = /obj/item/clothing/under/mildress/expeditionary
|
||||
uniform = /obj/item/clothing/under/mildress/sifguard
|
||||
shoes = /obj/item/clothing/shoes/dress
|
||||
suit = /obj/item/clothing/suit/dress/expedition
|
||||
gloves = /obj/item/clothing/gloves/white
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
containername = "Moghes imports crate"
|
||||
contraband = 1
|
||||
|
||||
/datum/supply_packs/security/bolt_rifles_mosin
|
||||
/datum/supply_packs/security/bolt_rifles_militia
|
||||
name = "Surplus militia rifles"
|
||||
contains = list(
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/mosin = 3,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle = 3,
|
||||
/obj/item/ammo_magazine/clip/c762 = 6
|
||||
)
|
||||
cost = 50
|
||||
@@ -80,7 +80,7 @@
|
||||
/obj/item/weapon/storage/box/syndie_kit/demolitions,
|
||||
/obj/item/device/multitool/ai_detector,
|
||||
/obj/item/weapon/plastique,
|
||||
/obj/item/weapon/storage/toolbox/syndicate
|
||||
/obj/item/weapon/storage/toolbox/syndicate/powertools
|
||||
),
|
||||
list( //the infiltrator,
|
||||
/obj/item/weapon/gun/projectile/silenced,
|
||||
|
||||
@@ -134,10 +134,12 @@ datum/supply_packs/costumes/witch
|
||||
/obj/item/clothing/head/pirate,
|
||||
/obj/item/clothing/head/hasturhood,
|
||||
/obj/item/clothing/head/powdered_wig,
|
||||
/obj/item/clothing/head/hairflower,
|
||||
/obj/item/clothing/head/hairflower/yellow,
|
||||
/obj/item/clothing/head/hairflower/blue,
|
||||
/obj/item/clothing/head/hairflower/pink,
|
||||
/obj/item/clothing/head/pin/flower,
|
||||
/obj/item/clothing/head/pin/flower/yellow,
|
||||
/obj/item/clothing/head/pin/flower/blue,
|
||||
/obj/item/clothing/head/pin/flower/pink,
|
||||
/obj/item/clothing/head/pin/clover,
|
||||
/obj/item/clothing/head/pin/butterfly,
|
||||
/obj/item/clothing/mask/gas/owl_mask,
|
||||
/obj/item/clothing/mask/gas/monkeymask,
|
||||
/obj/item/clothing/head/helmet/gladiator,
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
/obj/item/weapon/storage/box/glasses/shake,
|
||||
/obj/item/weapon/storage/box/glasses/shot,
|
||||
/obj/item/weapon/storage/box/glasses/mug,
|
||||
/obj/item/weapon/storage/box/glasses/meta,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/shaker,
|
||||
/obj/item/weapon/storage/box/glass_extras/straws,
|
||||
/obj/item/weapon/storage/box/glass_extras/sticks
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
contains = list(
|
||||
/obj/item/weapon/storage/firstaid/clotting
|
||||
)
|
||||
cost = 40
|
||||
cost = 100
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Clotting Medicine crate"
|
||||
access = access_medical
|
||||
|
||||
@@ -9,11 +9,16 @@
|
||||
item_cost = 5
|
||||
path = /obj/item/device/binoculars
|
||||
|
||||
/datum/uplink_item/item/tools/toolbox
|
||||
/datum/uplink_item/item/tools/toolbox // Leaving the basic as an option since powertools are loud.
|
||||
name = "Fully Loaded Toolbox"
|
||||
item_cost = 10
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/toolbox/syndicate
|
||||
|
||||
/datum/uplink_item/item/tools/powertoolbox
|
||||
name = "Fully Loaded Powertool Box"
|
||||
item_cost = 10
|
||||
path = /obj/item/weapon/storage/toolbox/syndicate/powertools
|
||||
|
||||
/datum/uplink_item/item/tools/clerical
|
||||
name = "Morphic Clerical Kit"
|
||||
item_cost = 10
|
||||
|
||||
@@ -55,11 +55,13 @@
|
||||
if(APC_WIRE_MAIN_POWER1, APC_WIRE_MAIN_POWER2)
|
||||
|
||||
if(!mended)
|
||||
if(istype(usr, /mob/living))
|
||||
A.shock(usr, 50)
|
||||
A.shorted = 1
|
||||
|
||||
else if(!IsIndexCut(APC_WIRE_MAIN_POWER1) && !IsIndexCut(APC_WIRE_MAIN_POWER2))
|
||||
A.shorted = 0
|
||||
if(istype(usr, /mob/living))
|
||||
A.shock(usr, 50)
|
||||
|
||||
if(APC_WIRE_AI_CONTROL)
|
||||
|
||||
@@ -85,7 +85,7 @@ var/datum/antagonist/raider/raiders
|
||||
/obj/item/weapon/gun/projectile/silenced,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/mosin,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/pellet,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
|
||||
|
||||
@@ -48,7 +48,7 @@ var/datum/antagonist/renegade/renegades
|
||||
/obj/item/weapon/gun/projectile/revolver,
|
||||
/obj/item/weapon/gun/projectile/derringer,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle/mosin,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/rifle,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
|
||||
/obj/item/weapon/gun/projectile/revolver/judge,
|
||||
|
||||
@@ -84,6 +84,10 @@
|
||||
P.on_hit(src, 0, def_zone)
|
||||
. = 0
|
||||
|
||||
// Called when a blob expands onto the tile the atom occupies.
|
||||
/atom/proc/blob_act()
|
||||
return
|
||||
|
||||
/atom/proc/in_contents_of(container)//can take class or object instance as argument
|
||||
if(ispath(container))
|
||||
if(istype(src.loc, container))
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
var/mob/pulledby = null
|
||||
var/item_state = null // Used to specify the item state for the on-mob overlays.
|
||||
var/icon_scale = 1 // Used to scale icons up or down in update_transform().
|
||||
var/old_x = 0
|
||||
var/old_y = 0
|
||||
var/auto_init = 1
|
||||
|
||||
/atom/movable/New()
|
||||
|
||||
@@ -23,6 +23,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
var/recursive_enhancement = 0 //Used to power up other abilities from the ling power with the same name.
|
||||
var/list/purchased_powers_history = list() //Used for round-end report, includes respec uses too.
|
||||
var/last_shriek = null // world.time when the ling last used a shriek.
|
||||
var/next_escape = 0 // world.time when the ling can next use Escape Restraints
|
||||
|
||||
/datum/changeling/New(var/gender=FEMALE)
|
||||
..()
|
||||
@@ -167,7 +168,8 @@ turf/proc/AdjacentTurfsRangedSting()
|
||||
/obj/structure/target_stake,
|
||||
/obj/structure/cable,
|
||||
/obj/structure/disposalpipe,
|
||||
/obj/machinery/
|
||||
/obj/machinery,
|
||||
/mob
|
||||
)
|
||||
|
||||
var/L[] = new()
|
||||
|
||||
63
code/game/gamemodes/changeling/powers/escape_restraints.dm
Normal file
63
code/game/gamemodes/changeling/powers/escape_restraints.dm
Normal file
@@ -0,0 +1,63 @@
|
||||
/datum/power/changeling/escape_restraints
|
||||
name = "Escape Restraints"
|
||||
desc = "We evolve more complex joints"
|
||||
helptext = "We can instantly escape from most restraints and bindings, but we cannot do it often."
|
||||
enhancedtext = "More frequent escapes."
|
||||
ability_icon_state = "ling_escape_restraints"
|
||||
genomecost = 2
|
||||
verbpath = /mob/proc/changeling_escape_restraints
|
||||
|
||||
//Escape Cuffs. By design this does not escape from straight jackets
|
||||
/mob/proc/changeling_escape_restraints()
|
||||
set category = "Changeling"
|
||||
set name = "Escape Restraints (40)"
|
||||
set desc = "Removes handcuffs and legcuffs instantly."
|
||||
|
||||
var/escape_cooldown = 5 MINUTES //This is used later to prevent spamming
|
||||
var/mob/living/carbon/human/C = src
|
||||
var/datum/changeling/changeling = changeling_power(40,0,100,CONSCIOUS)
|
||||
if(!changeling)
|
||||
return 0
|
||||
if(world.time < changeling.next_escape)
|
||||
to_chat(src, "<span class='warning'>We are still recovering from our last escape...</span>")
|
||||
return 0
|
||||
if(!(C.handcuffed || C.legcuffed)) // No need to waste chems if there's nothing to break out of
|
||||
to_chat(C, "<span class='warning'>We are are not restrained in a way we can escape...</span>")
|
||||
return 0
|
||||
|
||||
changeling.chem_charges -= 40
|
||||
|
||||
to_chat(C,"<span class='notice'>We contort our extremities and slip our cuffs.</span>")
|
||||
playsound(src, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
if(C.handcuffed)
|
||||
var/obj/item/weapon/W = C.handcuffed
|
||||
C.handcuffed = null
|
||||
if(C.buckled && C.buckled.buckle_require_restraints)
|
||||
C.buckled.unbuckle_mob()
|
||||
C.update_inv_handcuffed()
|
||||
if (C.client)
|
||||
C.client.screen -= W
|
||||
if(W)
|
||||
W.loc = C.loc
|
||||
W.dropped(C)
|
||||
if(W)
|
||||
W.layer = initial(W.layer)
|
||||
if(C.legcuffed)
|
||||
var/obj/item/weapon/W = C.legcuffed
|
||||
C.legcuffed = null
|
||||
C.update_inv_legcuffed()
|
||||
if(C.client)
|
||||
C.client.screen -= W
|
||||
if(W)
|
||||
W.loc = C.loc
|
||||
W.dropped(C)
|
||||
if(W)
|
||||
W.layer = initial(W.layer)
|
||||
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
escape_cooldown *= 0.5
|
||||
|
||||
changeling.next_escape = world.time + escape_cooldown //And now we set the timer
|
||||
|
||||
feedback_add_details("changeling_powers","ESR")
|
||||
return 1
|
||||
@@ -1,6 +1,6 @@
|
||||
/datum/power/changeling/resonant_shriek
|
||||
name = "Resonant Shriek"
|
||||
desc = "Our lungs and vocal chords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded biologicals and synthetics."
|
||||
desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
|
||||
helptext = "Lights are blown, organics are disoriented, and synthetics act as if they were flashed."
|
||||
enhancedtext = "Range is doubled."
|
||||
ability_icon_state = "ling_resonant_shriek"
|
||||
@@ -20,19 +20,19 @@
|
||||
/mob/proc/changeling_resonant_shriek()
|
||||
set category = "Changeling"
|
||||
set name = "Resonant Shriek (20)"
|
||||
set desc = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors."
|
||||
set desc = "Emits a high-frequency sound that confuses and deafens organics, blows out nearby lights, and overloads synthetics' sensors."
|
||||
|
||||
var/datum/changeling/changeling = changeling_power(20,0,100,CONSCIOUS)
|
||||
if(!changeling) return 0
|
||||
|
||||
if(is_muzzled())
|
||||
src << "<span class='danger'>Mmmf mrrfff!</span>"
|
||||
to_chat(src, "<span class='danger'>Mmmf mrrfff!</span>")
|
||||
return 0
|
||||
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.silent)
|
||||
src << "<span class='danger'>You can't speak!</span>"
|
||||
to_chat(src, "<span class='danger'>You can't speak!</span>")
|
||||
return 0
|
||||
|
||||
if(world.time < (changeling.last_shriek + 10 SECONDS) )
|
||||
@@ -49,7 +49,7 @@
|
||||
var/range = 4
|
||||
if(src.mind.changeling.recursive_enhancement)
|
||||
range = range * 2
|
||||
src << "<span class='notice'>We are extra loud.</span>"
|
||||
to_chat(src, "<span class='notice'>We are extra loud.</span>")
|
||||
|
||||
src.attack_log += text("\[[time_stamp()]\] <font color='red'>Used Resonant Shriek.</font>")
|
||||
message_admins("[key_name(src)] used Resonant Shriek ([src.x],[src.y],[src.z]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>).")
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
..()
|
||||
|
||||
/obj/item/weapon/toy/xmas_cracker/attack(mob/target, mob/user)
|
||||
if( !cracked && istype(target,/mob/living/carbon/human) && (target.stat == CONSCIOUS) && !target.get_active_hand() )
|
||||
if( !cracked && (istype(target,/mob/living/silicon) || (istype(target,/mob/living/carbon/human) && !target.get_active_hand())) && target.stat == CONSCIOUS)
|
||||
target.visible_message("<span class='notice'>[user] and [target] pop \an [src]! *pop*</span>", "<span class='notice'>You pull \an [src] with [target]! *pop*</span>", "<span class='notice'>You hear a *pop*.</span>")
|
||||
var/obj/item/weapon/paper/Joke = new /obj/item/weapon/paper(user.loc)
|
||||
Joke.name = "[pick("awful","terrible","unfunny")] joke"
|
||||
|
||||
@@ -10,6 +10,8 @@ var/global/datum/controller/gameticker/ticker
|
||||
var/event_time = null
|
||||
var/event = 0
|
||||
|
||||
// var/login_music // music played in pregame lobby // VOREStation Edit - We do music differently
|
||||
|
||||
var/list/datum/mind/minds = list()//The people in the game. Used for objective tracking.
|
||||
|
||||
var/Bible_icon_state // icon_state the chaplain has chosen for his bible
|
||||
@@ -32,10 +34,24 @@ var/global/datum/controller/gameticker/ticker
|
||||
var/round_end_announced = 0 // Spam Prevention. Announce round end only once.
|
||||
|
||||
/datum/controller/gameticker/proc/pregame()
|
||||
/* VOREStation Edit - We do music differently
|
||||
login_music = pick(\
|
||||
'sound/music/halloween/skeletons.ogg',\
|
||||
'sound/music/halloween/halloween.ogg',\
|
||||
'sound/music/halloween/ghosts.ogg'
|
||||
'sound/music/space.ogg',\
|
||||
'sound/music/traitor.ogg',\
|
||||
'sound/music/title2.ogg',\
|
||||
'sound/music/clouds.s3m',\
|
||||
'sound/music/space_oddity.ogg') //Ground Control to Major Tom, this song is cool, what's going on?
|
||||
*/
|
||||
|
||||
send2mainirc("Server lobby is loaded and open at byond://[config.serverurl ? config.serverurl : (config.server ? config.server : "[world.address]:[world.port]")]")
|
||||
|
||||
do
|
||||
pregame_timeleft = 180
|
||||
world << "<B><FONT color='blue'>Welcome to the pre-game lobby!</FONT></B>"
|
||||
world << "Please, setup your character and select ready. Game will start in [pregame_timeleft] seconds"
|
||||
to_chat(world, "<B><FONT color='blue'>Welcome to the pregame lobby!</FONT></B>")
|
||||
to_chat(world, "Please set up your character and select ready. The round will start in [pregame_timeleft] seconds.")
|
||||
while(current_state == GAME_STATE_PREGAME)
|
||||
for(var/i=0, i<10, i++)
|
||||
sleep(1)
|
||||
@@ -65,7 +81,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
if(!runnable_modes.len)
|
||||
current_state = GAME_STATE_PREGAME
|
||||
Master.SetRunLevel(RUNLEVEL_LOBBY)
|
||||
world << "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby."
|
||||
to_chat(world, "<B>Unable to choose playable game mode.</B> Reverting to pregame lobby.")
|
||||
return 0
|
||||
if(secret_force_mode != "secret")
|
||||
src.mode = config.pick_mode(secret_force_mode)
|
||||
@@ -80,7 +96,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
if(!src.mode)
|
||||
current_state = GAME_STATE_PREGAME
|
||||
Master.SetRunLevel(RUNLEVEL_LOBBY)
|
||||
world << "<span class='danger'>Serious error in mode setup!</span> Reverting to pre-game lobby."
|
||||
to_chat(world, "<span class='danger'>Serious error in mode setup!</span> Reverting to pregame lobby.") //Uses setup instead of set up due to computational context.
|
||||
return 0
|
||||
|
||||
job_master.ResetOccupations()
|
||||
@@ -89,7 +105,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
|
||||
|
||||
if(!src.mode.can_start())
|
||||
world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
|
||||
world << "<B>Unable to start [mode.name].</B> Not enough players readied, [mode.required_players] players needed. Reverting to pregame lobby."
|
||||
current_state = GAME_STATE_PREGAME
|
||||
Master.SetRunLevel(RUNLEVEL_LOBBY)
|
||||
mode.fail_setup()
|
||||
@@ -105,13 +121,13 @@ var/global/datum/controller/gameticker/ticker
|
||||
tmpmodes+=M.name
|
||||
tmpmodes = sortList(tmpmodes)
|
||||
if(tmpmodes.len)
|
||||
world << "<B>Possibilities:</B> [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]"
|
||||
to_chat(world, "<B>Possibilities:</B> [english_list(tmpmodes, and_text= "; ", comma_text = "; ")]")
|
||||
else
|
||||
src.mode.announce()
|
||||
|
||||
setup_economy()
|
||||
current_state = GAME_STATE_PLAYING
|
||||
create_characters() //Create player characters and transfer them
|
||||
create_characters() //Create player characters and transfer them.
|
||||
collect_minds()
|
||||
equip_characters()
|
||||
data_core.manifest()
|
||||
@@ -128,7 +144,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
//Deleting Startpoints but we need the ai point to AI-ize people later
|
||||
if (S.name != "AI")
|
||||
qdel(S)
|
||||
world << "<FONT color='blue'><B>Enjoy the game!</B></FONT>"
|
||||
to_chat(world, "<FONT color='blue'><B>Enjoy the game!</B></FONT>")
|
||||
world << sound('sound/AI/welcome.ogg') // Skie
|
||||
//Holiday Round-start stuff ~Carn
|
||||
Holiday_Game_Start()
|
||||
@@ -141,7 +157,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
if(C.holder)
|
||||
admins_number++
|
||||
if(admins_number == 0)
|
||||
send2adminirc("Round has started with no admins online.")
|
||||
send2adminirc("A round has started with no admins online.")
|
||||
|
||||
/* supply_controller.process() //Start the supply shuttle regenerating points -- TLE // handled in scheduler
|
||||
master_controller.process() //Start master_controller.process()
|
||||
@@ -293,7 +309,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
if(captainless)
|
||||
for(var/mob/M in player_list)
|
||||
if(!istype(M,/mob/new_player))
|
||||
M << "Colony Directorship not forced on anyone."
|
||||
to_chat(M, "Colony Directorship not forced on anyone.")
|
||||
|
||||
|
||||
proc/process()
|
||||
@@ -329,7 +345,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
feedback_set_details("end_proper","nuke")
|
||||
time_left = 1 MINUTE //No point waiting five minutes if everyone's dead.
|
||||
if(!delay_end)
|
||||
world << "<span class='notice'><b>Rebooting due to destruction of station in [round(time_left/600)] minutes.</b></span>"
|
||||
to_chat(world, "<span class='notice'><b>Rebooting due to destruction of station in [round(time_left/600)] minutes.</b></span>")
|
||||
else
|
||||
feedback_set_details("end_proper","proper completion")
|
||||
time_left = round(restart_timeout)
|
||||
@@ -342,15 +358,15 @@ var/global/datum/controller/gameticker/ticker
|
||||
while(time_left > 0)
|
||||
if(delay_end)
|
||||
break
|
||||
world << "<span class='notice'><b>Restarting in [round(time_left/600)] minute\s.</b></span>"
|
||||
to_chat(world, "<span class='notice'><b>Restarting in [round(time_left/600)] minute\s.</b></span>")
|
||||
time_left -= 1 MINUTES
|
||||
sleep(600)
|
||||
if(!delay_end)
|
||||
world.Reboot()
|
||||
else
|
||||
world << "<span class='notice'><b>An admin has delayed the round end.</b></span>"
|
||||
to_chat(world, "<span class='notice'><b>An admin has delayed the round end.</b></span>")
|
||||
else
|
||||
world << "<span class='notice'><b>An admin has delayed the round end.</b></span>"
|
||||
to_chat(world, "<span class='notice'><b>An admin has delayed the round end.</b></span>")
|
||||
|
||||
else if (mode_finished)
|
||||
post_game = 1
|
||||
@@ -360,7 +376,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
//call a transfer shuttle vote
|
||||
spawn(50)
|
||||
if(!round_end_announced) // Spam Prevention. Now it should announce only once.
|
||||
world << "<span class='danger'>The round has ended!</span>"
|
||||
to_chat(world, "<span class='danger'>The round has ended!</span>")
|
||||
round_end_announced = 1
|
||||
vote.autotransfer()
|
||||
|
||||
@@ -374,7 +390,7 @@ var/global/datum/controller/gameticker/ticker
|
||||
var/turf/playerTurf = get_turf(Player)
|
||||
if(emergency_shuttle.departed && emergency_shuttle.evac)
|
||||
if(isNotAdminLevel(playerTurf.z))
|
||||
Player << "<font color='blue'><b>You managed to survive, but were marooned on [station_name()] as [Player.real_name]...</b></font>"
|
||||
Player << "<font color='blue'><b>You survived the round, but remained on [station_name()] as [Player.real_name].</b></font>"
|
||||
else
|
||||
Player << "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></font>"
|
||||
else if(isAdminLevel(playerTurf.z))
|
||||
@@ -415,9 +431,9 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
if (!robo.connected_ai)
|
||||
if (robo.stat != 2)
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) survived as an AI-less synthetic! Its laws were:</b>"
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) survived as an AI-less stationbound synthetic! Its laws were:</b>"
|
||||
else
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a synthetic without an AI. Its laws were:</b>"
|
||||
world << "<b>[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:</b>"
|
||||
|
||||
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
|
||||
robo.laws.show_laws(world)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/game_mode/mercren
|
||||
name = "Mercenaries & Renegades"
|
||||
round_description = "A mercenary team has invaded the station, as well as other having brought their own form protection."
|
||||
extended_round_description = "Mercenaries and traitors spawn during this round."
|
||||
round_description = "A mercenary team has invaded the station, and others have brought their own form of protection."
|
||||
extended_round_description = "Mercenaries and renegades spawn during this round."
|
||||
config_tag = "mercren"
|
||||
required_players = 16 //What could possibly go wrong?
|
||||
required_players_secret = 15
|
||||
|
||||
@@ -21,9 +21,14 @@
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/spell/proc/allowed_to_teleport()
|
||||
if(owner && owner.z in using_map.admin_levels)
|
||||
return 0
|
||||
return 1
|
||||
if(owner)
|
||||
if(owner.z in using_map.admin_levels)
|
||||
return FALSE
|
||||
|
||||
var/turf/T = get_turf(owner)
|
||||
if(T.block_tele)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/spell/proc/within_range(var/atom/target, var/max_range = 7) // Beyond 7 is off the screen.
|
||||
if(range(get_dist(owner, target) <= max_range))
|
||||
|
||||
@@ -23,9 +23,12 @@
|
||||
var/turf/starting = get_turf(AM)
|
||||
var/list/targets = list()
|
||||
|
||||
if(starting.block_tele)
|
||||
return
|
||||
|
||||
valid_turfs:
|
||||
for(var/turf/simulated/T in range(AM, range))
|
||||
if(T.density || istype(T, /turf/simulated/mineral)) //Don't blink to vacuum or a wall
|
||||
if(T.density || T.block_tele || istype(T, /turf/simulated/mineral)) //Don't blink to vacuum or a wall
|
||||
continue
|
||||
for(var/atom/movable/stuff in T.contents)
|
||||
if(stuff.density)
|
||||
@@ -54,7 +57,10 @@
|
||||
if(istype(hit_atom, /atom/movable))
|
||||
var/atom/movable/AM = hit_atom
|
||||
if(!within_range(AM))
|
||||
user << "<span class='warning'>\The [AM] is too far away to blink.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [AM] is too far away to blink.</span>")
|
||||
return
|
||||
if(!allowed_to_teleport())
|
||||
to_chat(user, "<span class='warning'>Teleportation doesn't seem to work here.</span>")
|
||||
return
|
||||
if(pay_energy(400))
|
||||
if(check_for_scepter())
|
||||
@@ -67,6 +73,9 @@
|
||||
to_chat(user, "<span class='warning'>You need more energy to blink [AM] away!</span>")
|
||||
|
||||
/obj/item/weapon/spell/blink/on_use_cast(mob/user)
|
||||
if(!allowed_to_teleport())
|
||||
to_chat(user, "<span class='warning'>Teleportation doesn't seem to work here.</span>")
|
||||
return
|
||||
if(pay_energy(200))
|
||||
if(check_for_scepter())
|
||||
safe_blink(user, calculate_spell_power(10))
|
||||
@@ -80,6 +89,9 @@
|
||||
/obj/item/weapon/spell/blink/on_melee_cast(atom/hit_atom, mob/living/user, def_zone)
|
||||
if(istype(hit_atom, /atom/movable))
|
||||
var/atom/movable/AM = hit_atom
|
||||
if(!allowed_to_teleport())
|
||||
to_chat(user, "<span class='warning'>Teleportation doesn't seem to work here.</span>")
|
||||
return
|
||||
if(pay_energy(300))
|
||||
visible_message("<span class='danger'>\The [user] reaches out towards \the [AM] with a glowing hand.</span>")
|
||||
if(check_for_scepter())
|
||||
|
||||
@@ -68,6 +68,9 @@
|
||||
user << "<span class='danger'>There's no Mark!</span>"
|
||||
return 0
|
||||
else
|
||||
if(!allowed_to_teleport())
|
||||
to_chat(user, "<span class='warning'>Teleportation doesn't seem to work here.</span>")
|
||||
return
|
||||
visible_message("<span class='warning'>\The [user] starts glowing!</span>")
|
||||
var/light_intensity = 2
|
||||
var/time_left = 3
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
checked_turf = get_step(checked_turf, direction) //Advance in the given direction
|
||||
total_cost += check_for_scepter() ? 400 : 800 //Phasing through matter's expensive, you know.
|
||||
i--
|
||||
if(checked_turf.block_tele) // The fun ends here.
|
||||
break
|
||||
|
||||
if(!checked_turf.density) //If we found a destination (a non-dense turf), then we can stop.
|
||||
var/dense_objs_on_turf = 0
|
||||
for(var/atom/movable/stuff in checked_turf.contents) //Make sure nothing dense is where we want to go, like an airlock or window.
|
||||
|
||||
@@ -462,3 +462,9 @@
|
||||
/datum/access/trader
|
||||
id = access_trader
|
||||
access_type = ACCESS_TYPE_PRIVATE
|
||||
|
||||
/var/const/access_alien = 300 // For things like crashed ships.
|
||||
/datum/access/alien
|
||||
id = access_alien
|
||||
desc = "#%_^&*@!"
|
||||
access_type = ACCESS_TYPE_PRIVATE
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
while(!accepted)
|
||||
if(!B) break // prevents possible runtime errors
|
||||
new_book_style = input(H,"Which bible style would you like?") in list("Bible", "Koran", "Scrapbook", "Creeper", "White Bible", "Holy Light", "Athiest", "Tome", "The King in Yellow", "Ithaqua", "Scientology", "the bible melts", "Necronomicon")
|
||||
new_book_style = input(H,"Which bible style would you like?") in list("Bible", "Koran", "Scrapbook", "Pagan", "White Bible", "Holy Light", "Athiest", "Tome", "The King in Yellow", "Ithaqua", "Scientology", "the bible melts", "Necronomicon","Orthodox","Torah")
|
||||
switch(new_book_style)
|
||||
if("Koran")
|
||||
B.icon_state = "koran"
|
||||
@@ -90,9 +90,6 @@
|
||||
if("Scrapbook")
|
||||
B.icon_state = "scrapbook"
|
||||
B.item_state = "scrapbook"
|
||||
if("Creeper")
|
||||
B.icon_state = "creeper"
|
||||
B.item_state = "syringe_kit"
|
||||
if("White Bible")
|
||||
B.icon_state = "white"
|
||||
B.item_state = "syringe_kit"
|
||||
@@ -120,6 +117,15 @@
|
||||
if("Necronomicon")
|
||||
B.icon_state = "necronomicon"
|
||||
B.item_state = "necronomicon"
|
||||
if("Pagan")
|
||||
B.icon_state = "shadows"
|
||||
B.item_state = "syringe_kit"
|
||||
if("Orthodox")
|
||||
B.icon_state = "orthodoxy"
|
||||
B.item_state = "bible"
|
||||
if("Torah")
|
||||
B.icon_state = "torah"
|
||||
B.item_state = "clipboard"
|
||||
else
|
||||
B.icon_state = "bible"
|
||||
B.item_state = "bible"
|
||||
|
||||
@@ -76,7 +76,7 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
proc/FreeRole(var/rank) //making additional slot on the fly
|
||||
var/datum/job/job = GetJob(rank)
|
||||
if(job && job.current_positions >= job.total_positions && job.total_positions != -1)
|
||||
if(job && job.total_positions != -1)
|
||||
job.total_positions++
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/machinery/sleep_console
|
||||
name = "Sleeper Console"
|
||||
name = "sleeper console"
|
||||
icon = 'icons/obj/Cryogenic2_vr.dmi' //VOREStation Edit - Better icon.
|
||||
icon_state = "sleeperconsole"
|
||||
var/obj/machinery/sleeper/sleeper
|
||||
@@ -34,7 +34,7 @@
|
||||
return 1
|
||||
|
||||
if(sleeper.panel_open)
|
||||
user << "<span class='notice'>Close the maintenance panel first.</span>"
|
||||
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
|
||||
return
|
||||
|
||||
if(!sleeper)
|
||||
@@ -44,7 +44,7 @@
|
||||
else if(sleeper)
|
||||
return sleeper.ui_interact(user)
|
||||
else
|
||||
user << "<span class='warning'>Sleeper not found!</span>"
|
||||
to_chat(user, "<span class='warning'>Sleeper not found!</span>")
|
||||
|
||||
/obj/machinery/sleep_console/attackby(var/obj/item/I, var/mob/user)
|
||||
if(computer_deconstruction_screwdriver(user, I))
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
/obj/machinery/sleeper
|
||||
name = "sleeper"
|
||||
desc = "A fancy bed with built-in injectors, a dialysis machine, and a limited health scanner."
|
||||
desc = "A stasis pod with built-in injectors, a dialysis machine, and a limited health scanner."
|
||||
icon = 'icons/obj/Cryogenic2_vr.dmi' //VOREStation Edit - Better icons
|
||||
icon_state = "sleeper_0"
|
||||
density = 1
|
||||
@@ -181,7 +181,7 @@
|
||||
return 1
|
||||
|
||||
if(usr == occupant)
|
||||
usr << "<span class='warning'>You can't reach the controls from the inside.</span>"
|
||||
to_chat(usr, "<span class='warning'>You can't reach the controls from the inside.</span>")
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
@@ -221,7 +221,7 @@
|
||||
I.loc = src
|
||||
user.visible_message("<span class='notice'>\The [user] adds \a [I] to \the [src].</span>", "<span class='notice'>You add \a [I] to \the [src].</span>")
|
||||
else
|
||||
user << "<span class='warning'>\The [src] has a beaker already.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] has a beaker already.</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/sleeper/verb/move_eject()
|
||||
@@ -233,7 +233,7 @@
|
||||
if(DEAD)
|
||||
return
|
||||
if(UNCONSCIOUS)
|
||||
usr << "<span class='notice'>You struggle through the haze to hit the eject button. This will take a couple of minutes...</span>"
|
||||
to_chat(usr, "<span class='notice'>You struggle through the haze to hit the eject button. This will take a couple of minutes...</span>")
|
||||
sleep(2 MINUTES)
|
||||
if(!src || !usr || !occupant || (occupant != usr)) //Check if someone's released/replaced/bombed him already
|
||||
return
|
||||
@@ -279,9 +279,11 @@
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(occupant)
|
||||
user << "<span class='warning'>\The [src] is already occupied.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is already occupied.</span>")
|
||||
return
|
||||
if(!ishuman(M))
|
||||
to_chat(user, "<span class='warning'>\The [src] is not designed for that organism!</span>")
|
||||
return
|
||||
|
||||
if(M == user)
|
||||
visible_message("\The [user] starts climbing into \the [src].")
|
||||
else
|
||||
@@ -289,7 +291,7 @@
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(occupant)
|
||||
user << "<span class='warning'>\The [src] is already occupied.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is already occupied.</span>")
|
||||
return
|
||||
M.stop_pulling()
|
||||
if(M.client)
|
||||
@@ -333,8 +335,8 @@
|
||||
if(occupant.reagents.get_reagent_amount(chemical) + amount <= 20)
|
||||
use_power(amount * CHEM_SYNTH_ENERGY)
|
||||
occupant.reagents.add_reagent(chemical, amount)
|
||||
user << "Occupant now has [occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in their bloodstream."
|
||||
to_chat(user, "Occupant now has [occupant.reagents.get_reagent_amount(chemical)] units of [available_chemicals[chemical]] in their bloodstream.")
|
||||
else
|
||||
user << "The subject has too many chemicals."
|
||||
to_chat(user, "The subject has too many chemicals in their bloodstream.")
|
||||
else
|
||||
user << "There's no suitable occupant in \the [src]."
|
||||
to_chat(user, "There's no suitable occupant in \the [src].")
|
||||
|
||||
@@ -39,20 +39,23 @@
|
||||
else if(istype(G, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/H = G
|
||||
if(panel_open)
|
||||
user << "<span class='notice'>Close the maintenance panel first.</span>"
|
||||
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
|
||||
return
|
||||
if(!ismob(H.affecting))
|
||||
return
|
||||
if(!ishuman(H.affecting))
|
||||
to_chat(user, "<span class='warning'>\The [src] is not designed for that organism!</span>")
|
||||
return
|
||||
if(occupant)
|
||||
user << "<span class='notice'>The scanner is already occupied!</span>"
|
||||
to_chat(user, "<span class='notice'>\The [src] is already occupied!</span>")
|
||||
return
|
||||
for(var/mob/living/simple_animal/slime/M in range(1, H.affecting))
|
||||
if(M.victim == H.affecting)
|
||||
user << "<span class='danger'>[H.affecting.name] has a fucking slime attached to them, deal with that first.</span>"
|
||||
to_chat(user, "<span class='danger'>[H.affecting.name] has a slime attached to them, deal with that first.</span>")
|
||||
return
|
||||
var/mob/M = H.affecting
|
||||
if(M.abiotic())
|
||||
user << "<span class='notice'>Subject cannot have abiotic items on.</span>"
|
||||
to_chat(user, "<span class='notice'>Subject cannot have abiotic items on.</span>")
|
||||
return
|
||||
M.forceMove(src)
|
||||
occupant = M
|
||||
@@ -72,20 +75,20 @@
|
||||
if(!ishuman(user) && !isrobot(user))
|
||||
return 0 //not a borg or human
|
||||
if(panel_open)
|
||||
user << "<span class='notice'>Close the maintenance panel first.</span>"
|
||||
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
|
||||
return 0 //panel open
|
||||
if(occupant)
|
||||
user << "<span class='notice'>\The [src] is already occupied.</span>"
|
||||
to_chat(user, "<span class='notice'>\The [src] is already occupied.</span>")
|
||||
return 0 //occupied
|
||||
|
||||
if(O.buckled)
|
||||
return 0
|
||||
if(O.abiotic())
|
||||
user << "<span class='notice'>Subject cannot have abiotic items on.</span>"
|
||||
to_chat(user, "<span class='notice'>Subject cannot have abiotic items on.</span>")
|
||||
return 0
|
||||
for(var/mob/living/simple_animal/slime/M in range(1, O))
|
||||
if(M.victim == O)
|
||||
user << "<span class='danger'>[O] has a fucking slime attached to them, deal with that first.</span>"
|
||||
to_chat(user, "<span class='danger'>[O] has a slime attached to them, deal with that first.</span>")
|
||||
return 0
|
||||
|
||||
if(O == user)
|
||||
@@ -185,9 +188,9 @@
|
||||
var/obj/machinery/bodyscanner/C = P.connectable
|
||||
scanner = C
|
||||
C.console = src
|
||||
user << "<span class='warning'> You link the [src] to the [P.connectable]!</span>"
|
||||
to_chat(user, "<span class='warning'> You link the [src] to the [P.connectable]!</span>")
|
||||
else
|
||||
user << "<span class='warning'> You store the [src] in the [P]'s buffer!</span>"
|
||||
to_chat(user, "<span class='warning'> You store the [src] in the [P]'s buffer!</span>")
|
||||
P.connectable = src
|
||||
return
|
||||
else
|
||||
@@ -243,7 +246,7 @@
|
||||
return
|
||||
|
||||
if (scanner.panel_open)
|
||||
user << "<span class='notice'>Close the maintenance panel first.</span>"
|
||||
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
|
||||
return
|
||||
|
||||
if(!scanner)
|
||||
@@ -253,7 +256,7 @@
|
||||
else if(scanner)
|
||||
return ui_interact(user)
|
||||
else
|
||||
user << "<span class='warning'>Scanner not found!</span>"
|
||||
to_chat(user, "<span class='warning'>Scanner not found!</span>")
|
||||
|
||||
/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
@@ -180,15 +180,17 @@
|
||||
if(!get_danger_level(target_temperature, TLV["temperature"]) && abs(environment.temperature - target_temperature) > 2.0)
|
||||
update_use_power(2)
|
||||
regulating_temperature = 1
|
||||
visible_message("\The [src] clicks as it starts [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
|
||||
audible_message("\The [src] clicks as it starts [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
|
||||
"You hear a click and a faint electronic hum.")
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
else
|
||||
//check for when we should stop adjusting temperature
|
||||
if(get_danger_level(target_temperature, TLV["temperature"]) || abs(environment.temperature - target_temperature) <= 0.5)
|
||||
update_use_power(1)
|
||||
regulating_temperature = 0
|
||||
visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
|
||||
audible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\
|
||||
"You hear a click as a faint electronic humming stops.")
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
if(regulating_temperature)
|
||||
if(target_temperature > T0C + MAX_TEMPERATURE)
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
else
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/blob_act()
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/portable_atmospherics/proc/StandardAirMix()
|
||||
return list(
|
||||
"oxygen" = O2STANDARD * MolesForPressure(),
|
||||
|
||||
@@ -111,6 +111,11 @@
|
||||
|
||||
..() //and give it the regular chance of being deleted outright
|
||||
|
||||
/obj/machinery/camera/blob_act()
|
||||
if((stat & BROKEN) || invuln)
|
||||
return
|
||||
destroy()
|
||||
|
||||
/obj/machinery/camera/hitby(AM as mob|obj)
|
||||
..()
|
||||
if (istype(AM, /obj))
|
||||
@@ -130,7 +135,7 @@
|
||||
if(user.species.can_shred(user))
|
||||
set_status(0)
|
||||
user.do_attack_animation(src)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
visible_message("<span class='warning'>\The [user] slashes at [src]!</span>")
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
|
||||
add_hiddenprint(user)
|
||||
@@ -210,7 +215,7 @@
|
||||
src.bugged = 1
|
||||
|
||||
else if(W.damtype == BRUTE || W.damtype == BURN) //bashing cameras
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
if (W.force >= src.toughness)
|
||||
user.do_attack_animation(src)
|
||||
visible_message("<span class='warning'><b>[src] has been [W.attack_verb.len? pick(W.attack_verb) : "attacked"] with [W] by [user]!</b></span>")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define TRACKING_NO_COVERAGE 1
|
||||
#define TRACKING_TERMINATE 2
|
||||
|
||||
/mob/living/silicon/ai/var/max_locations = 10
|
||||
/mob/living/silicon/ai/var/max_locations = 30
|
||||
/mob/living/silicon/ai/var/stored_locations[0]
|
||||
|
||||
/proc/InvalidPlayerTurf(turf/T as turf)
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
set_broken()
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/blob_act()
|
||||
ex_act(2)
|
||||
|
||||
/obj/machinery/computer/update_icon()
|
||||
overlays.Cut()
|
||||
if(stat & NOPOWER)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
var/turf/Tr = null
|
||||
for(var/obj/item/weapon/implant/chem/C in world)
|
||||
Tr = get_turf(C)
|
||||
if(!Tr) continue//Out of range //VOREStation Edit
|
||||
if(!Tr) continue//Out of range
|
||||
if(!C.implanted) continue
|
||||
dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: "
|
||||
dat += "<A href='?src=\ref[src];inject1=\ref[C]'>(<font color=red>(1)</font>)</A>"
|
||||
@@ -41,7 +41,7 @@
|
||||
dat += "<HR>Tracking Implants<BR>"
|
||||
for(var/obj/item/weapon/implant/tracking/T in world)
|
||||
Tr = get_turf(T)
|
||||
if(!Tr) continue//Out of range //VOREStation Edit
|
||||
if(!Tr) continue//Out of range
|
||||
if(!T.implanted) continue
|
||||
var/loc_display = "Unknown"
|
||||
var/mob/living/carbon/M = T.imp_in
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
// Locks or unlocks the cyborg
|
||||
if (href_list["lockdown"])
|
||||
var/mob/living/silicon/robot/target = get_cyborg_by_name(href_list["lockdown"])
|
||||
var/failmsg = ""
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
@@ -57,11 +58,19 @@
|
||||
|
||||
var/istraitor = target.mind.special_role
|
||||
if (istraitor)
|
||||
failmsg = "failed (target is traitor) "
|
||||
target.lockcharge = !target.lockcharge
|
||||
if (target.lockcharge)
|
||||
target << "Someone tried to lock you down!"
|
||||
to_chat(target, "Someone tried to lock you down!")
|
||||
else
|
||||
target << "Someone tried to lift your lockdown!"
|
||||
to_chat(target, "Someone tried to lift your lockdown!")
|
||||
else if (target.emagged)
|
||||
failmsg = "failed (target is hacked) "
|
||||
target.lockcharge = !target.lockcharge
|
||||
if (target.lockcharge)
|
||||
to_chat(target, "Someone tried to lock you down!")
|
||||
else
|
||||
to_chat(target, "Someone tried to lift your lockdown!")
|
||||
else
|
||||
target.canmove = !target.canmove
|
||||
target.lockcharge = !target.canmove //when canmove is 1, lockcharge should be 0
|
||||
@@ -70,7 +79,7 @@
|
||||
target << "You have been locked down!"
|
||||
else
|
||||
target << "Your lockdown has been lifted!"
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] [istraitor ? "failed (target is traitor) " : ""][target.lockcharge ? "lockdown" : "release"] on [target.name]!</span>")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] [failmsg][target.lockcharge ? "lockdown" : "release"] on [target.name]!</span>")
|
||||
log_game("[key_name(usr)] attempted to [target.lockcharge ? "lockdown" : "release"] [target.name] on the robotics console!")
|
||||
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ for reference:
|
||||
return
|
||||
return
|
||||
else
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
health -= W.force * 1
|
||||
|
||||
@@ -197,8 +197,14 @@
|
||||
/obj/machinery/door/airlock/centcom
|
||||
name = "Centcom Airlock"
|
||||
icon = 'icons/obj/doors/Doorele.dmi'
|
||||
//opacity = 0 //VOREStation Edit - Why is this like this??
|
||||
req_one_access = list(access_cent_general)
|
||||
opacity = 1
|
||||
|
||||
/obj/machinery/door/airlock/glass_centcom
|
||||
name = "Airlock"
|
||||
icon = 'icons/obj/doors/Dooreleglass.dmi'
|
||||
opacity = 0
|
||||
glass = 1
|
||||
|
||||
/obj/machinery/door/airlock/vault
|
||||
name = "Vault"
|
||||
@@ -447,6 +453,24 @@
|
||||
icon = 'icons/obj/doors/shuttledoors_vertical.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_voidcraft/vertical
|
||||
|
||||
/obj/machinery/door/airlock/alien
|
||||
name = "alien airlock"
|
||||
desc = "You're fairly sure this is a door."
|
||||
icon = 'icons/obj/doors/Dooralien.dmi'
|
||||
explosion_resistance = 20
|
||||
secured_wires = TRUE
|
||||
hackProof = TRUE
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_alien
|
||||
req_one_access = list(access_alien)
|
||||
|
||||
/obj/machinery/door/airlock/alien/locked
|
||||
icon_state = "door_locked"
|
||||
locked = TRUE
|
||||
|
||||
/obj/machinery/door/airlock/alien/public // Entry to UFO.
|
||||
req_one_access = list()
|
||||
normalspeed = FALSE // So it closes faster and hopefully keeps the warm air inside.
|
||||
|
||||
/*
|
||||
About the new airlock wires panel:
|
||||
* An airlock wire dialog can be accessed by the normal way or by using wirecutters or a multitool on the door while the wire-panel is open. This would show the following wires, which you can either wirecut/mend or send a multitool pulse through. There are 9 wires.
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
else if(src.density && (user.a_intent == I_HURT)) //If we can't pry it open and it's a weapon, let's hit it.
|
||||
var/obj/item/weapon/W = C
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||
user.do_attack_animation(src)
|
||||
if(W.force < min_force)
|
||||
@@ -162,7 +162,7 @@
|
||||
|
||||
else if(src.density && (user.a_intent == I_HURT)) //If we can't pry it open and it's not a weapon.... Eh, let's attack it anyway.
|
||||
var/obj/item/weapon/W = C
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||
user.do_attack_animation(src)
|
||||
if(W.force < min_force) //No actual non-weapon item shouls have a force greater than the min_force, but let's include this just in case.
|
||||
|
||||
@@ -262,7 +262,7 @@
|
||||
//psa to whoever coded this, there are plenty of objects that need to call attack() on doors without bludgeoning them.
|
||||
if(src.density && istype(I, /obj/item/weapon) && user.a_intent == I_HURT && !istype(I, /obj/item/weapon/card))
|
||||
var/obj/item/weapon/W = I
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||
user.do_attack_animation(src)
|
||||
if(W.force < min_force)
|
||||
@@ -357,6 +357,13 @@
|
||||
take_damage(150)
|
||||
return
|
||||
|
||||
/obj/machinery/door/blob_act()
|
||||
if(density) // If it's closed.
|
||||
if(stat & BROKEN)
|
||||
spawn(0)
|
||||
open(1)
|
||||
else
|
||||
take_damage(100)
|
||||
|
||||
/obj/machinery/door/update_icon()
|
||||
if(density)
|
||||
|
||||
@@ -391,6 +391,7 @@
|
||||
else
|
||||
use_power(360)
|
||||
else
|
||||
if(usr && usr.ckey)
|
||||
log_admin("[usr]([usr.ckey]) has forced open an emergency shutter.")
|
||||
message_admins("[usr]([usr.ckey]) has forced open an emergency shutter.")
|
||||
latetoggle()
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
|
||||
visible_message("<span class='danger'>[user] smashes against the [src.name].</span>", 1)
|
||||
user.do_attack_animation(src)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
take_damage(25)
|
||||
return
|
||||
return src.attackby(user, user)
|
||||
@@ -246,7 +246,7 @@
|
||||
|
||||
//If it's a weapon, smash windoor. Unless it's an id card, agent card, ect.. then ignore it (Cards really shouldnt damage a door anyway)
|
||||
if(src.density && istype(I, /obj/item/weapon) && !istype(I, /obj/item/weapon/card))
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(I))
|
||||
var/aforce = I.force
|
||||
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
|
||||
visible_message("<span class='danger'>[src] was hit by [I].</span>")
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
name = "surgery holosign"
|
||||
desc = "Small wall-mounted holographic projector. This one reads SURGERY."
|
||||
on_icon = "surgery"
|
||||
|
||||
/obj/machinery/holosign/exit
|
||||
name = "exit holosign"
|
||||
desc = "Small wall-mounted holographic projector. This one reads EXIT."
|
||||
on_icon = "exit"
|
||||
////////////////////SWITCH///////////////////////////////////////
|
||||
|
||||
/obj/machinery/button/holosign
|
||||
|
||||
@@ -86,6 +86,23 @@
|
||||
health = 250 // Since lasers do 40 each.
|
||||
maxhealth = 250
|
||||
|
||||
/obj/machinery/porta_turret/alien // The kind used on the UFO submap.
|
||||
name = "interior anti-boarding turret"
|
||||
desc = "A very tough looking turret made by alien hands."
|
||||
installation = /obj/item/weapon/gun/energy/alien
|
||||
enabled = TRUE
|
||||
lethal = TRUE
|
||||
ailock = TRUE
|
||||
check_all = TRUE
|
||||
health = 250 // Similar to the AI turrets.
|
||||
maxhealth = 250
|
||||
|
||||
/obj/machinery/porta_turret/alien/destroyed // Turrets that are already dead, to act as a warning of what the rest of the submap contains.
|
||||
name = "broken interior anti-boarding turret"
|
||||
desc = "A very tough looking turret made by alien hands. This one looks destroyed, thankfully."
|
||||
icon_state = "destroyed_target_prism"
|
||||
stat = BROKEN
|
||||
|
||||
/obj/machinery/porta_turret/New()
|
||||
..()
|
||||
req_access.Cut()
|
||||
@@ -103,6 +120,11 @@
|
||||
req_one_access.Cut()
|
||||
req_access = list(access_cent_specops)
|
||||
|
||||
/obj/machinery/porta_turret/alien/New()
|
||||
..()
|
||||
req_one_access.Cut()
|
||||
req_access = list(access_alien)
|
||||
|
||||
/obj/machinery/porta_turret/Destroy()
|
||||
qdel(spark_system)
|
||||
spark_system = null
|
||||
@@ -359,7 +381,7 @@ var/list/turret_icons
|
||||
|
||||
else
|
||||
//if the turret was attacked with the intention of harming it:
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(I))
|
||||
take_damage(I.force * 0.5)
|
||||
if(I.force * 0.5 > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off
|
||||
if(!attacked && !emagged)
|
||||
@@ -436,6 +458,14 @@ var/list/turret_icons
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/machinery/porta_turret/alien/emp_act(severity) // This is overrided to give an EMP resistance as well as avoid scambling the turret settings.
|
||||
if(prob(75)) // Superior alien technology, I guess.
|
||||
return
|
||||
enabled = FALSE
|
||||
spawn(rand(1 MINUTE, 2 MINUTES))
|
||||
if(!enabled)
|
||||
enabled = TRUE
|
||||
|
||||
/obj/machinery/porta_turret/ex_act(severity)
|
||||
switch (severity)
|
||||
if(1)
|
||||
|
||||
@@ -103,13 +103,6 @@
|
||||
R.adjustFireLoss(-wire_rate)
|
||||
else if(ishuman(occupant))
|
||||
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)
|
||||
cell.use(7000/450*10)
|
||||
|
||||
else if(istype(occupant, /mob/living/carbon/human))
|
||||
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
|
||||
// In case they somehow end up with positive values for otherwise unobtainable damage...
|
||||
if(H.getToxLoss()>0) H.adjustToxLoss(-(rand(1,3)))
|
||||
@@ -153,9 +146,21 @@
|
||||
return
|
||||
if(default_part_replacement(user, O))
|
||||
return
|
||||
if (istype(O, /obj/item/weapon/grab) && get_dist(src,user)<2)
|
||||
var/obj/item/weapon/grab/G = O
|
||||
if(istype(G.affecting,/mob/living))
|
||||
var/mob/living/M = G.affecting
|
||||
qdel(O)
|
||||
go_in(M)
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/recharge_station/MouseDrop_T(var/mob/target, var/mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user))
|
||||
return
|
||||
|
||||
go_in(target)
|
||||
|
||||
/obj/machinery/recharge_station/RefreshParts()
|
||||
..()
|
||||
var/man_rating = 0
|
||||
@@ -214,15 +219,16 @@
|
||||
if(icon_update_tick == 0)
|
||||
build_overlays()
|
||||
|
||||
/obj/machinery/recharge_station/Bumped(var/mob/living/silicon/robot/R)
|
||||
go_in(R)
|
||||
/obj/machinery/recharge_station/Bumped(var/mob/living/L)
|
||||
go_in(L)
|
||||
|
||||
/obj/machinery/recharge_station/proc/go_in(var/mob/living/silicon/robot/R)
|
||||
/obj/machinery/recharge_station/proc/go_in(var/mob/living/L)
|
||||
|
||||
if(occupant)
|
||||
return
|
||||
|
||||
if(istype(R, /mob/living/silicon/robot))
|
||||
if(istype(L, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = L
|
||||
|
||||
if(R.incapacitated())
|
||||
return
|
||||
@@ -237,8 +243,8 @@
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
else if(istype(R, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = R
|
||||
else if(istype(L, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(!isnull(H.internal_organs_by_name["cell"]))
|
||||
add_fingerprint(H)
|
||||
H.reset_view(src)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//not a computer
|
||||
obj/machinery/scanner
|
||||
name = "Identity Analyser"
|
||||
name = "identity analyzer"
|
||||
var/outputdir = 0
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "scanner_idle"
|
||||
@@ -70,7 +70,7 @@ obj/machinery/scanner/attack_hand(mob/living/carbon/human/user)
|
||||
<b><u>Black Marks</u></b>:<br> "}
|
||||
for(var/A in marks)
|
||||
text += "<span class='danger'>[A]</span><br>"
|
||||
user << "<span class='notice'>You feel a sting as the scanner extracts some of your blood.</span>"
|
||||
to_chat(user, "<span class='notice'>You feel a sting as the scanner extracts some of your blood.</span>")
|
||||
var/turf/T = get_step(src,outputdir)
|
||||
var/obj/item/weapon/paper/print = new(T)
|
||||
print.name = "[mname] Report"
|
||||
|
||||
@@ -23,7 +23,7 @@ var/req_console_information = list()
|
||||
var/list/obj/machinery/requests_console/allConsoles = list()
|
||||
|
||||
/obj/machinery/requests_console
|
||||
name = "Requests Console"
|
||||
name = "requests console"
|
||||
desc = "A console intended to send requests to different departments on the station."
|
||||
anchored = 1
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
@@ -72,7 +72,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
|
||||
announcement.title = "[department] announcement"
|
||||
announcement.newscast = 1
|
||||
|
||||
name = "[department] Requests Console"
|
||||
name = "[department] requests console"
|
||||
allConsoles += src
|
||||
if(departmentType & RC_ASSIST)
|
||||
req_console_assistance |= department
|
||||
@@ -208,15 +208,15 @@ var/list/obj/machinery/requests_console/allConsoles = list()
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
//err... hacking code, which has no reason for existing... but anyway... it was once supposed to unlock priority 3 messanging on that console (EXTREME priority...), but the code for that was removed.
|
||||
//err... hacking code, which has no reason for existing... but anyway... it was once supposed to unlock priority 3 messaging on that console (EXTREME priority...), but the code for that was removed.
|
||||
/obj/machinery/requests_console/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob)
|
||||
if(computer_deconstruction_screwdriver(user, O))
|
||||
return
|
||||
if(istype(O, /obj/item/device/multitool))
|
||||
if(panel_open)
|
||||
var/input = sanitize(input(usr, "What Department id would you like to give this Request Console?", "Multitool-Request Console interface", department))
|
||||
var/input = sanitize(input(usr, "What Department ID would you like to give this request console?", "Multitool-Request Console Interface", department))
|
||||
if(!input)
|
||||
usr << "No input found please hang up and try your call again."
|
||||
to_chat(usr, "No input found. Please hang up and try your call again.")
|
||||
return
|
||||
department = input
|
||||
announcement.title = "[department] announcement"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/machinery/robotic_fabricator
|
||||
name = "Robotic Fabricator"
|
||||
name = "robotic fabricator"
|
||||
icon = 'icons/obj/robotics.dmi'
|
||||
icon_state = "fab-idle"
|
||||
density = 1
|
||||
@@ -30,7 +30,7 @@
|
||||
overlays -= "fab-load-metal"
|
||||
updateDialog()
|
||||
else
|
||||
user << "The robot part maker is full. Please remove metal from the robot part maker in order to insert more."
|
||||
to_chat(user, "The robot part maker is full. Please remove metal from the robot part maker in order to insert more.")
|
||||
|
||||
/obj/machinery/robotic_fabricator/attack_hand(user as mob)
|
||||
var/dat
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
/obj/machinery/power/supply_beacon/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
if(!use_power && istype(W, /obj/item/weapon/wrench))
|
||||
if(!anchored && !connect_to_network())
|
||||
user << "<span class='warning'>This device must be placed over an exposed cable.</span>"
|
||||
to_chat(user, "<span class='warning'>This device must be placed over an exposed cable.</span>")
|
||||
return
|
||||
anchored = !anchored
|
||||
user.visible_message("<span class='notice'>\The [user] [anchored ? "secures" : "unsecures"] \the [src].</span>")
|
||||
@@ -59,13 +59,13 @@
|
||||
|
||||
if(expended)
|
||||
use_power = 0
|
||||
user << "<span class='warning'>\The [src] has used up its charge.</span>"
|
||||
to_chat (user, "<span class='warning'>\The [src] has used up its charge.</span>")
|
||||
return
|
||||
|
||||
if(anchored)
|
||||
return use_power ? deactivate(user) : activate(user)
|
||||
else
|
||||
user << "<span class='warning'>You need to secure the beacon with a wrench first!</span>"
|
||||
to_chat(user, "<span class='warning'>You need to secure the beacon with a wrench first!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/power/supply_beacon/attack_ai(var/mob/user)
|
||||
@@ -76,12 +76,12 @@
|
||||
if(expended)
|
||||
return
|
||||
if(surplus() < 500)
|
||||
if(user) user << "<span class='notice'>The connected wire doesn't have enough current.</span>"
|
||||
if(user) to_chat(user, "<span class='notice'>The connected wire doesn't have enough current.</span>")
|
||||
return
|
||||
set_light(3, 3, "#00CCAA")
|
||||
icon_state = "beacon_active"
|
||||
use_power = 1
|
||||
if(user) user << "<span class='notice'>You activate the beacon. The supply drop will be dispatched soon.</span>"
|
||||
if(user) to_chat(user, "<span class='notice'>You activate the beacon. The supply drop will be dispatched soon.</span>")
|
||||
|
||||
/obj/machinery/power/supply_beacon/proc/deactivate(var/mob/user, var/permanent)
|
||||
if(permanent)
|
||||
@@ -92,7 +92,7 @@
|
||||
set_light(0)
|
||||
use_power = 0
|
||||
target_drop_time = null
|
||||
if(user) user << "<span class='notice'>You deactivate the beacon.</span>"
|
||||
if(user) to_chat(user, "<span class='notice'>You deactivate the beacon.</span>")
|
||||
|
||||
/obj/machinery/power/supply_beacon/Destroy()
|
||||
if(use_power)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/machinery/computer/teleporter
|
||||
name = "Teleporter Control Console"
|
||||
name = "teleporter control console"
|
||||
desc = "Used to control a linked teleportation Hub and Station."
|
||||
icon_keyboard = "teleport_key"
|
||||
icon_screen = "teleport"
|
||||
@@ -56,8 +56,8 @@
|
||||
L = locate("landmark*[C.data]") // use old stype
|
||||
|
||||
if(istype(L, /obj/effect/landmark/) && istype(L.loc, /turf))
|
||||
usr << "You insert the coordinates into the machine."
|
||||
usr << "A message flashes across the screen reminding the traveller that the nuclear authentication disk is to remain on the station at all times."
|
||||
to_chat(usr, "You insert the coordinates into the machine.")
|
||||
to_chat(usr, "A message flashes across the screen, reminding the user that the nuclear authentication disk is not transportable via insecure means.")
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
|
||||
|
||||
110
code/game/machinery/transportpod.dm
Normal file
110
code/game/machinery/transportpod.dm
Normal file
@@ -0,0 +1,110 @@
|
||||
/obj/machinery/transportpod
|
||||
name = "Ballistic Transportation Pod"
|
||||
desc = "A fast transit ballistic pod used to get from one place to the next. Batteries not included!"
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "borg_pod_opened"
|
||||
|
||||
density = 1 //thicc
|
||||
anchored = 1
|
||||
use_power = 0
|
||||
|
||||
var/in_transit = 0
|
||||
var/mob/occupant = null
|
||||
|
||||
var/xc = list(137, 209, 163, 110, 95, 60, 129, 201) // List of x values on the map to go to.
|
||||
var/yc = list(134, 99, 169, 120, 96, 122, 189, 219) // List of y values on the map to go to.
|
||||
|
||||
var/limit_x = 3
|
||||
var/limit_y = 3
|
||||
|
||||
/obj/machinery/transportpod/process()
|
||||
if(occupant)
|
||||
if(in_transit)
|
||||
var/locNum = rand(0, 7) //pick a random location
|
||||
var/turf/L = locate(xc[locNum], yc[locNum], 1) // Pairs the X and Y to get an actual location.
|
||||
limit_x = xc[locNum]+1
|
||||
limit_y = yc[locNum]+1
|
||||
build()
|
||||
sleep(20) //Give explosion time so the pod itself doesn't go boom
|
||||
src.forceMove(L)
|
||||
playsound(src, pick('sound/effects/Explosion1.ogg', 'sound/effects/Explosion2.ogg', 'sound/effects/Explosion3.ogg', 'sound/effects/Explosion4.ogg'))
|
||||
in_transit = 0
|
||||
sleep(2)
|
||||
go_out()
|
||||
sleep(2)
|
||||
del(src)
|
||||
|
||||
/obj/machinery/transportpod/relaymove(mob/user as mob)
|
||||
if(user.stat)
|
||||
return
|
||||
go_out()
|
||||
return
|
||||
|
||||
/obj/machinery/transportpod/update_icon()
|
||||
..()
|
||||
if(occupant)
|
||||
icon_state = "borg_pod_closed"
|
||||
else
|
||||
icon_state = "borg_pod_opened"
|
||||
|
||||
/obj/machinery/transportpod/Bumped(var/mob/living/O)
|
||||
go_in(O)
|
||||
|
||||
/obj/machinery/transportpod/proc/go_in(var/mob/living/carbon/human/O)
|
||||
if(occupant)
|
||||
return
|
||||
|
||||
if(O.incapacitated()) //aint no sleepy people getting in here
|
||||
return
|
||||
|
||||
add_fingerprint(O)
|
||||
O.reset_view(src)
|
||||
O.forceMove(src)
|
||||
occupant = O
|
||||
update_icon()
|
||||
if(alert(O, "Are you sure you're ready to launch?", , "Yes", "No") == "Yes")
|
||||
in_transit = 1
|
||||
playsound(src, HYPERSPACE_WARMUP)
|
||||
else
|
||||
go_out()
|
||||
return 1
|
||||
|
||||
/obj/machinery/transportpod/proc/go_out()
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
occupant.forceMove(src.loc)
|
||||
occupant.reset_view()
|
||||
occupant = null
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/transportpod/verb/move_eject()
|
||||
set category = "Object"
|
||||
set name = "Eject Pod"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
go_out()
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
|
||||
/obj/machinery/transportpod/verb/move_inside()
|
||||
set category = "Object"
|
||||
set name = "Enter Pod"
|
||||
set src in oview(1)
|
||||
|
||||
if(usr.incapacitated()) //just to DOUBLE CHECK the damn sleepy people don't touch the pod
|
||||
return
|
||||
|
||||
go_in(usr)
|
||||
|
||||
/obj/machinery/transportpod/proc/build()
|
||||
for(var/x = limit_x-2, x <= limit_x, x++)
|
||||
for(var/y = limit_y-2, y <= limit_y, y++)
|
||||
var/current_cell = locate(x, y, 1)
|
||||
var/turf/T = get_turf(current_cell)
|
||||
if(!current_cell)
|
||||
continue
|
||||
T.ChangeTurf(/turf/unsimulated/floor/shuttle_ceiling)
|
||||
@@ -147,7 +147,7 @@
|
||||
/obj/machinery/vending/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
user << "You short out the product lock on \the [src]"
|
||||
to_chat(user, "You short out \the [src]'s product lock.")
|
||||
return 1
|
||||
|
||||
/obj/machinery/vending/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
@@ -182,7 +182,7 @@
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/screwdriver))
|
||||
panel_open = !panel_open
|
||||
user << "You [panel_open ? "open" : "close"] the maintenance panel."
|
||||
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance panel.")
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
overlays.Cut()
|
||||
if(panel_open)
|
||||
@@ -199,7 +199,7 @@
|
||||
W.forceMove(src)
|
||||
coin = W
|
||||
categories |= CAT_COIN
|
||||
user << "<span class='notice'>You insert \the [W] into \the [src].</span>"
|
||||
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
|
||||
nanomanager.update_uis(src)
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
@@ -211,7 +211,7 @@
|
||||
|
||||
if(do_after(user, 20 * W.toolspeed))
|
||||
if(!src) return
|
||||
user << "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>"
|
||||
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
|
||||
anchored = !anchored
|
||||
return
|
||||
else
|
||||
@@ -232,7 +232,7 @@
|
||||
|
||||
// This is not a status display message, since it's something the character
|
||||
// themselves is meant to see BEFORE putting the money in
|
||||
usr << "\icon[cashmoney] <span class='warning'>That is not enough money.</span>"
|
||||
to_chat(usr, "\icon[cashmoney] <span class='warning'>That is not enough money.</span>")
|
||||
return 0
|
||||
|
||||
if(istype(cashmoney, /obj/item/weapon/spacecash))
|
||||
@@ -418,21 +418,22 @@
|
||||
|
||||
if(href_list["remove_coin"] && !istype(usr,/mob/living/silicon))
|
||||
if(!coin)
|
||||
usr << "There is no coin in this machine."
|
||||
to_chat(usr, "There is no coin in this machine.")
|
||||
return
|
||||
|
||||
coin.forceMove(src.loc)
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(coin)
|
||||
usr << "<span class='notice'>You remove \the [coin] from \the [src]</span>"
|
||||
to_chat(usr, "<span class='notice'>You remove \the [coin] from \the [src]</span>")
|
||||
coin = null
|
||||
categories &= ~CAT_COIN
|
||||
|
||||
if((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
|
||||
if((href_list["vend"]) && (vend_ready) && (!currently_vending))
|
||||
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
|
||||
usr << "<span class='warning'>Access denied.</span>" //Unless emagged of course
|
||||
to_chat(usr, "<span class='warning'>Access denied.</span>") //Unless emagged of course
|
||||
flick(icon_deny,src)
|
||||
playsound(src.loc, 'sound/machines/deniedbeep.ogg', 50, 0)
|
||||
return
|
||||
|
||||
var/key = text2num(href_list["vend"])
|
||||
@@ -445,12 +446,12 @@
|
||||
if(R.price <= 0)
|
||||
vend(R, usr)
|
||||
else if(istype(usr,/mob/living/silicon)) //If the item is not free, provide feedback if a synth is trying to buy something.
|
||||
usr << "<span class='danger'>Artificial unit recognized. Artificial units cannot complete this transaction. Purchase canceled.</span>"
|
||||
to_chat(usr, "<span class='danger'>Lawed unit recognized. Lawed units cannot complete this transaction. Purchase canceled.</span>")
|
||||
return
|
||||
else
|
||||
currently_vending = R
|
||||
if(!vendor_account || vendor_account.suspended)
|
||||
status_message = "This machine is currently unable to process payments due to problems with the associated account."
|
||||
status_message = "This machine is currently unable to process payments due to issues with the associated account."
|
||||
status_error = 1
|
||||
else
|
||||
status_message = "Please swipe a card or insert cash to pay for the item."
|
||||
@@ -467,8 +468,9 @@
|
||||
|
||||
/obj/machinery/vending/proc/vend(datum/stored_item/vending_product/R, mob/user)
|
||||
if((!allowed(usr)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH
|
||||
usr << "<span class='warning'>Access denied.</span>" //Unless emagged of course
|
||||
to_chat(usr, "<span class='warning'>Access denied.</span>") //Unless emagged of course
|
||||
flick(icon_deny,src)
|
||||
playsound(src.loc, 'sound/machines/deniedbeep.ogg', 50, 0)
|
||||
return
|
||||
vend_ready = 0 //One thing at a time!!
|
||||
status_message = "Vending..."
|
||||
@@ -477,13 +479,13 @@
|
||||
|
||||
if(R.category & CAT_COIN)
|
||||
if(!coin)
|
||||
user << "<span class='notice'>You need to insert a coin to get this item.</span>"
|
||||
to_chat(user, "<span class='notice'>You need to insert a coin to get this item.</span>")
|
||||
return
|
||||
if(coin.string_attached)
|
||||
if(prob(50))
|
||||
user << "<span class='notice'>You successfully pull the coin out before \the [src] could swallow it.</span>"
|
||||
to_chat(user, "<span class='notice'>You successfully pull the coin out before \the [src] could swallow it.</span>")
|
||||
else
|
||||
user << "<span class='notice'>You weren't able to pull the coin out fast enough, the machine ate it, string and all.</span>"
|
||||
to_chat(user, "<span class='notice'>You weren't able to pull the coin out fast enough, the machine ate it, string and all.</span>")
|
||||
qdel(coin)
|
||||
coin = null
|
||||
categories &= ~CAT_COIN
|
||||
@@ -685,6 +687,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/pint = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/mug = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/metaglass = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 5,
|
||||
@@ -765,7 +768,7 @@
|
||||
/obj/machinery/vending/cola
|
||||
name = "Robust Softdrinks"
|
||||
desc = "A softdrink vendor provided by Robust Industries, LLC."
|
||||
icon_state = "Cola_Machine"
|
||||
icon_state = "soda-blu"
|
||||
product_slogans = "Robust Softdrinks: More robust than a toolbox to the head!"
|
||||
product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space."
|
||||
products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/cans/space_mountain_wind = 10,
|
||||
@@ -805,7 +808,6 @@
|
||||
|
||||
contraband = list(/obj/item/weapon/reagent_containers/syringe/steroid = 4)
|
||||
|
||||
//This one's from bay12
|
||||
/obj/machinery/vending/cart
|
||||
name = "PTech"
|
||||
desc = "Cartridges for PDAs."
|
||||
@@ -820,7 +822,7 @@
|
||||
has_logs = 1
|
||||
|
||||
/obj/machinery/vending/cigarette
|
||||
name = "Cigarette machine" //OCD had to be uppercase to look nice with the new formating
|
||||
name = "cigarette machine"
|
||||
desc = "If you want to get cancer, might as well do it in style!"
|
||||
product_slogans = "Space cigs taste good like a cigarette should.;I'd rather toolbox than switch.;Smoke!;Don't believe the reports - smoke today!"
|
||||
product_ads = "Probably not bad for you!;Don't believe the scientists!;It's good for you!;Don't quit, buy more!;Smoke!;Nicotine heaven.;Best cigarettes since 2150.;Award-winning cigs.;Feeling temperamental? Try a Temperamento!;Carcinoma Angels - go fuck yerself!;Don't be so hard on yourself, kid. Smoke a Lucky Star!"
|
||||
@@ -864,7 +866,6 @@
|
||||
req_log_access = access_cmo
|
||||
has_logs = 1
|
||||
|
||||
//This one's from bay12
|
||||
/obj/machinery/vending/phoronresearch
|
||||
name = "Toximate 3000"
|
||||
desc = "All the fine parts you need in one vending machine!"
|
||||
@@ -993,6 +994,7 @@
|
||||
/obj/item/weapon/glass_extra/stick = 15,
|
||||
/obj/item/weapon/glass_extra/straw = 15,
|
||||
/obj/item/clothing/suit/chef/classic = 2,
|
||||
/obj/item/weapon/storage/bag/food = 2,
|
||||
/obj/item/weapon/storage/toolbox/lunchbox = 3,
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/heart = 3,
|
||||
/obj/item/weapon/storage/toolbox/lunchbox/cat = 3,
|
||||
@@ -1050,7 +1052,6 @@
|
||||
req_log_access = access_ce
|
||||
has_logs = 1
|
||||
|
||||
//This one's from bay12
|
||||
/obj/machinery/vending/engineering
|
||||
name = "Robco Tool Maker"
|
||||
desc = "Everything you need for do-it-yourself station repair."
|
||||
@@ -1069,7 +1070,6 @@
|
||||
req_log_access = access_ce
|
||||
has_logs = 1
|
||||
|
||||
//This one's from bay12
|
||||
/obj/machinery/vending/robotics
|
||||
name = "Robotech Deluxe"
|
||||
desc = "All the tools you need to create your own robot army."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/machinery/vr_sleeper
|
||||
name = "VR sleeper"
|
||||
name = "virtual reality sleeper"
|
||||
desc = "A fancy bed with built-in sensory I/O ports and connectors to interface users' minds with their bodies in virtual reality."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "syndipod_0"
|
||||
@@ -53,6 +53,10 @@
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
return
|
||||
else if(default_deconstruction_crowbar(user, I))
|
||||
if(occupant && avatar)
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
go_out()
|
||||
return
|
||||
|
||||
|
||||
@@ -213,10 +217,9 @@
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
// Prompt for username after they've enterred the body.
|
||||
var/newname = sanitize(input(avatar, "You are enterring virtual reality. Your username is currently [src.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
var/newname = sanitize(input(avatar, "You are entering virtual reality. Your username is currently [src.name]. Would you like to change it to something else?", "Name change") as null|text, MAX_NAME_LEN)
|
||||
if (newname)
|
||||
avatar.real_name = newname
|
||||
|
||||
else
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
equip_cooldown = 50
|
||||
var/mob/living/carbon/human/occupant = null
|
||||
var/datum/global_iterator/pr_mech_sleeper
|
||||
var/inject_amount = 10
|
||||
var/inject_amount = 5
|
||||
required_type = /obj/mecha/medical
|
||||
salvageable = 0
|
||||
|
||||
@@ -185,10 +185,14 @@
|
||||
if(!R || !occupant || !SG || !(SG in chassis.equipment))
|
||||
return 0
|
||||
var/to_inject = min(R.volume, inject_amount)
|
||||
if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2)
|
||||
if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject > inject_amount*4)
|
||||
occupant_message("Sleeper safeties prohibit you from injecting more than [inject_amount*4] units of [R.name].")
|
||||
else
|
||||
occupant_message("Injecting [occupant] with [to_inject] units of [R.name].")
|
||||
log_message("Injecting [occupant] with [to_inject] units of [R.name].")
|
||||
SG.reagents.trans_id_to(occupant,R.id,to_inject)
|
||||
//SG.reagents.trans_id_to(occupant,R.id,to_inject)
|
||||
SG.reagents.remove_reagent(R.id,to_inject)
|
||||
occupant.reagents.add_reagent(R.id,to_inject)
|
||||
update_equip_info()
|
||||
return
|
||||
|
||||
@@ -200,6 +204,19 @@
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tool/sleeper/verb/eject()
|
||||
set name = "Sleeper Eject"
|
||||
set category = "Exosuit Interface"
|
||||
set src = usr.loc
|
||||
set popup_menu = 0
|
||||
if(usr!=src.occupant || usr.stat == 2)
|
||||
return
|
||||
to_chat(usr,"<span class='notice'>Release sequence activated. This will take one minute.</span>")
|
||||
sleep(600)
|
||||
if(!src || !usr || !occupant || (occupant != usr)) //Check if someone's released/replaced/bombed him already
|
||||
return
|
||||
go_out()//and release him from the eternal prison.
|
||||
|
||||
/datum/global_iterator/mech_sleeper
|
||||
|
||||
process(var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S)
|
||||
|
||||
@@ -505,7 +505,7 @@
|
||||
return
|
||||
|
||||
/obj/mecha/attack_hand(mob/user as mob)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
src.log_message("Attack by hand/paw. Attacker - [user].",1)
|
||||
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
@@ -513,7 +513,6 @@
|
||||
if(H.species.can_shred(user))
|
||||
if(!prob(src.deflect_chance))
|
||||
src.take_damage(15)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
|
||||
user << "<span class='danger'>You slash at the armored suit!</span>"
|
||||
@@ -666,7 +665,7 @@
|
||||
return
|
||||
|
||||
/obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
src.log_message("Attacked by [W]. Attacker - [user]")
|
||||
if(prob(src.deflect_chance))
|
||||
user << "<span class='danger'>\The [W] bounces off [src.name].</span>"
|
||||
@@ -1763,7 +1762,7 @@
|
||||
|
||||
/obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message)
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
if(!damage)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -99,7 +99,9 @@
|
||||
C.images += holder
|
||||
|
||||
holder = patient.hud_list[STATUS_HUD]
|
||||
if(patient.stat == DEAD)
|
||||
if(patient.isSynthetic())
|
||||
holder.icon_state = "hudrobo"
|
||||
else if(patient.stat == DEAD)
|
||||
holder.icon_state = "huddead"
|
||||
else if(foundVirus)
|
||||
holder.icon_state = "hudill"
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, var/forced = FALSE, var/silent = FALSE)
|
||||
if(!ticker)
|
||||
user << "<span class='warning'>You can't buckle anyone in before the game starts.</span>"
|
||||
if(!user.Adjacent(M) || user.restrained() || user.lying || user.stat || istype(user, /mob/living/silicon/pai))
|
||||
if(!user.Adjacent(M) || user.restrained() || user.stat || istype(user, /mob/living/silicon/pai))
|
||||
return
|
||||
if(M == buckled_mob)
|
||||
return
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
|
||||
/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
var/aforce = W.force
|
||||
health = max(0, health - aforce)
|
||||
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||
@@ -227,7 +227,7 @@ Alien plants should do something if theres a lot of poison
|
||||
return
|
||||
|
||||
/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
if(W.attack_verb.len)
|
||||
visible_message("<span class='danger'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
else
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "extinguish"
|
||||
mouse_opacity = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSBLOB
|
||||
|
||||
/obj/effect/effect/water/New(loc)
|
||||
..()
|
||||
@@ -27,7 +27,7 @@
|
||||
var/mob/M
|
||||
for(var/atom/A in T)
|
||||
if(!ismob(A) && A.simulated) // Mobs are handled differently
|
||||
reagents.touch(A)
|
||||
reagents.touch(A, reagents.total_volume)
|
||||
else if(ismob(A) && !M)
|
||||
M = A
|
||||
if(M)
|
||||
|
||||
@@ -68,3 +68,9 @@
|
||||
var/datum/effect/effect/system/smoke_spread/S = new/datum/effect/effect/system/smoke_spread()
|
||||
S.set_up(5,0,location,null)
|
||||
S.start()
|
||||
|
||||
/datum/effect/system/explosion/smokeless/start()
|
||||
new/obj/effect/explosion(location)
|
||||
var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles()
|
||||
P.set_up(10,location)
|
||||
P.start()
|
||||
@@ -21,7 +21,7 @@
|
||||
return
|
||||
|
||||
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(W))
|
||||
|
||||
if(W.attack_verb.len)
|
||||
visible_message("<span class='warning'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||
@@ -218,25 +218,8 @@
|
||||
//=================
|
||||
|
||||
if(isturf(loc))
|
||||
if(prob(25))
|
||||
var/list/nearby = trange(5, src) - loc
|
||||
if(nearby.len)
|
||||
var/target_atom = pick(nearby)
|
||||
walk_to(src, target_atom, 5)
|
||||
if(prob(25))
|
||||
src.visible_message("<span class='notice'>\The [src] skitters[pick(" away"," around","")].</span>")
|
||||
else if(prob(5))
|
||||
//vent crawl!
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
|
||||
if(!v.welded)
|
||||
entry_vent = v
|
||||
walk_to(src, entry_vent, 5)
|
||||
break
|
||||
skitter()
|
||||
|
||||
if(amount_grown >= 100)
|
||||
var/spawn_type = pick(grow_as)
|
||||
new spawn_type(src.loc, src)
|
||||
qdel(src)
|
||||
else if(isorgan(loc))
|
||||
if(!amount_grown) amount_grown = 1
|
||||
var/obj/item/organ/external/O = loc
|
||||
@@ -257,6 +240,27 @@
|
||||
if(amount_grown)
|
||||
amount_grown += rand(0,2)
|
||||
|
||||
/obj/effect/spider/spiderling/proc/skitter()
|
||||
if(isturf(loc))
|
||||
if(prob(25))
|
||||
var/list/nearby = trange(5, src) - loc
|
||||
if(nearby.len)
|
||||
var/target_atom = pick(nearby)
|
||||
walk_to(src, target_atom, 5)
|
||||
if(prob(25))
|
||||
src.visible_message("<span class='notice'>\The [src] skitters[pick(" away"," around","")].</span>")
|
||||
else if(prob(5))
|
||||
//vent crawl!
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
|
||||
if(!v.welded)
|
||||
entry_vent = v
|
||||
walk_to(src, entry_vent, 5)
|
||||
break
|
||||
if(amount_grown >= 100)
|
||||
var/spawn_type = pick(grow_as)
|
||||
new spawn_type(src.loc, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "spiderling remains"
|
||||
desc = "Green squishy mess."
|
||||
@@ -269,7 +273,7 @@
|
||||
icon_state = "cocoon1"
|
||||
health = 60
|
||||
|
||||
New()
|
||||
/obj/effect/spider/cocoon/New()
|
||||
icon_state = pick("cocoon1","cocoon2","cocoon3")
|
||||
|
||||
/obj/effect/spider/cocoon/Destroy()
|
||||
|
||||
@@ -175,12 +175,9 @@ var/global/list/tele_landmarks = list() // Terrible, but the alternative is loop
|
||||
|
||||
if(isliving(A)) // Someday, implement parachutes. For now, just turbomurder whoever falls.
|
||||
var/mob/living/L = A
|
||||
for(var/i = 1 to 6)
|
||||
L.adjustBruteLoss(100)
|
||||
L.fall_impact(T, 42, 90, FALSE, TRUE) //You will not be defibbed from this.
|
||||
message_admins("\The [A] fell out of the sky.")
|
||||
explosion(T, 0, 1, 2)
|
||||
A.forceMove(T)
|
||||
T.visible_message("<span class='danger'><font size='3'>\A [A] falls out of the sky and crashes into \the [T]!</font></span>")
|
||||
else
|
||||
message_admins("ERROR: planetary_fall step trigger lacks a planet to fall onto.")
|
||||
return
|
||||
|
||||
@@ -80,6 +80,8 @@
|
||||
var/list/sprite_sheets_obj = list()
|
||||
|
||||
var/toolspeed = 1.0 // This is a multipler on how 'fast' a tool works. e.g. setting this to 0.5 will make the tool work twice as fast.
|
||||
var/attackspeed = DEFAULT_ATTACK_COOLDOWN // How long click delay will be when using this, in 1/10ths of a second. Checked in the user's get_attack_speed().
|
||||
var/reach = 1 // Length of tiles it can reach, 1 is adjacent.
|
||||
var/addblends // Icon overlay for ADD highlights when applicable.
|
||||
|
||||
/obj/item/New()
|
||||
@@ -457,7 +459,7 @@ var/list/global/slot_flags_enumeration = list(
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
user.do_attack_animation(M)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
@@ -640,3 +642,11 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
/obj/item/proc/pwr_drain()
|
||||
return 0 // Process Kill
|
||||
|
||||
// Used for non-adjacent melee attacks with specific weapons capable of reaching more than one tile.
|
||||
// This uses changeling range string A* but for this purpose its also applicable.
|
||||
/obj/item/proc/attack_can_reach(var/atom/us, var/atom/them, var/range)
|
||||
if(us.Adjacent(them))
|
||||
return TRUE // Already adjacent.
|
||||
if(AStar(get_turf(us), get_turf(them), /turf/proc/AdjacentTurfsRangedSting, /turf/proc/Distance, max_nodes=25, max_node_depth=range))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -429,6 +429,13 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
exonet.send_message(their_address, "text", text)
|
||||
im_list += list(list("address" = exonet.address, "to_address" = their_address, "im" = text))
|
||||
log_pda("[usr] (COMM: [src]) sent \"[text]\" to [exonet.get_atom_from_address(their_address)]")
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
|
||||
continue
|
||||
if(exonet.get_atom_from_address(their_address) == M)
|
||||
continue
|
||||
M.show_message("Comm IM - [src] -> [exonet.get_atom_from_address(their_address)]: [text]")
|
||||
|
||||
if(href_list["disconnect"])
|
||||
var/name_to_disconnect = href_list["disconnect"]
|
||||
@@ -988,6 +995,14 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
src << "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>"
|
||||
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
|
||||
log_pda("[usr] (COMM: [src]) sent \"[text_message]\" to [chosen_communicator]")
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
|
||||
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
|
||||
continue
|
||||
if(M == src)
|
||||
continue
|
||||
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
|
||||
|
||||
|
||||
|
||||
// Verb: show_text_messages()
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
qdel_null(paddles)
|
||||
qdel_null(bcell)
|
||||
|
||||
/obj/item/device/defib_kit/loaded //starts with highcap cell
|
||||
bcell = /obj/item/weapon/cell/high
|
||||
/obj/item/device/defib_kit/loaded //starts with a cell
|
||||
bcell = /obj/item/weapon/cell/apc
|
||||
|
||||
|
||||
/obj/item/device/defib_kit/update_icon()
|
||||
@@ -209,7 +209,7 @@
|
||||
var/combat = 0 //If it can be used to revive people wearing thick clothing (e.g. spacesuits)
|
||||
var/cooldowntime = (6 SECONDS) // How long in deciseconds until the defib is ready again after use.
|
||||
var/chargetime = (2 SECONDS)
|
||||
var/chargecost = 1000 //units of charge
|
||||
var/chargecost = 1250 //units of charge per zap //With the default APC level cell, this allows 4 shocks
|
||||
var/burn_damage_amt = 5
|
||||
var/use_on_synthetic = 0 //If 1, this is only useful on FBPs, if 0, this is only useful on fleshies
|
||||
|
||||
@@ -284,7 +284,12 @@
|
||||
return "buzzes, \"Resuscitation failed - Excessive neural degeneration. Further attempts futile.\""
|
||||
|
||||
H.updatehealth()
|
||||
if(H.health + H.getOxyLoss() <= config.health_threshold_dead || (HUSK in H.mutations))
|
||||
|
||||
if(H.isSynthetic())
|
||||
if(H.health + H.getOxyLoss() + H.getToxLoss() <= config.health_threshold_dead)
|
||||
return "buzzes, \"Resuscitation failed - Severe damage detected. Begin manual repair before further attempts futile.\""
|
||||
|
||||
else if(H.health + H.getOxyLoss() <= config.health_threshold_dead || (HUSK in H.mutations) || !H.can_defib)
|
||||
return "buzzes, \"Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile.\""
|
||||
|
||||
var/bad_vital_organ = check_vital_organs(H)
|
||||
@@ -374,7 +379,10 @@
|
||||
// This proc is used so that we can return out of the revive process while ensuring that busy and update_icon() are handled
|
||||
/obj/item/weapon/shockpaddles/proc/do_revive(mob/living/carbon/human/H, mob/user)
|
||||
if(!H.client && !H.teleop)
|
||||
to_chat(find_dead_player(H.ckey, 1), "Someone is attempting to resuscitate you. Re-enter your body if you want to be revived!")
|
||||
for(var/mob/observer/dead/ghost in player_list)
|
||||
if(ghost.mind == H.mind)
|
||||
to_chat(ghost, "<b><font color = #330033><font size = 3>Someone is attempting to resuscitate you. Re-enter your body if you want to be revived!</b> (Verbs -> Ghost -> Re-enter corpse)</font></font>")
|
||||
break
|
||||
|
||||
//beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
|
||||
user.visible_message("<span class='warning'>\The [user] begins to place [src] on [H]'s chest.</span>", "<span class='warning'>You begin to place [src] on [H]'s chest...</span>")
|
||||
@@ -420,6 +428,9 @@
|
||||
var/adjust_health = barely_in_crit - H.health //need to increase health by this much
|
||||
H.adjustOxyLoss(-adjust_health)
|
||||
|
||||
if(H.isSynthetic())
|
||||
H.adjustToxLoss(-H.getToxLoss())
|
||||
|
||||
make_announcement("pings, \"Resuscitation successful.\"", "notice")
|
||||
playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
|
||||
|
||||
@@ -642,7 +653,8 @@
|
||||
name = "jumper cable kit"
|
||||
desc = "A device that delivers powerful shocks to detachable jumper cables that are capable of reviving full body prosthetics."
|
||||
icon_state = "jumperunit"
|
||||
item_state = "jumperunit"
|
||||
item_state = "defibunit"
|
||||
// item_state = "jumperunit"
|
||||
paddles = /obj/item/weapon/shockpaddles/linked/jumper
|
||||
|
||||
/obj/item/device/defib_kit/jumper_kit/loaded
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/obj/item/device/flash/proc/clown_check(var/mob/user)
|
||||
if(user && (CLUMSY in user.mutations) && prob(50))
|
||||
user << "<span class='warning'>\The [src] slips out of your hand.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] slips out of your hand.</span>")
|
||||
user.drop_item()
|
||||
return 0
|
||||
return 1
|
||||
@@ -43,7 +43,7 @@
|
||||
if(prob( round(times_used / 2) )) //if you use it 10 times in a minute it has a 5% chance to break.
|
||||
broken = 1
|
||||
if(user)
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
|
||||
icon_state = "flashburnt"
|
||||
return FALSE
|
||||
else
|
||||
@@ -51,7 +51,8 @@
|
||||
return TRUE
|
||||
else //can only use it 10 times a minute
|
||||
if(user)
|
||||
user << "<span class='warning'>*click* *click*</span>"
|
||||
to_chat(user, "<span class='warning'><i>click</i></span>")
|
||||
playsound(src.loc, 'sound/weapons/empty.ogg', 80, 1)
|
||||
return FALSE
|
||||
|
||||
//attack_as_weapon
|
||||
@@ -62,12 +63,12 @@
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to flash [M.name] ([M.ckey])</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
user.do_attack_animation(M)
|
||||
|
||||
if(!clown_check(user)) return
|
||||
if(broken)
|
||||
user << "<span class='warning'>\The [src] is broken.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is broken.</span>")
|
||||
return
|
||||
|
||||
flash_recharge()
|
||||
@@ -75,9 +76,6 @@
|
||||
if(!check_capacitor(user))
|
||||
return
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.do_attack_animation(M)
|
||||
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
var/flashfail = 0
|
||||
|
||||
@@ -155,7 +153,7 @@
|
||||
/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
if(!user || !clown_check(user)) return
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
|
||||
if(broken)
|
||||
user.show_message("<span class='warning'>The [src.name] is broken</span>", 2)
|
||||
@@ -215,12 +213,12 @@
|
||||
..()
|
||||
if(!broken)
|
||||
broken = 1
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
|
||||
icon_state = "flashburnt"
|
||||
|
||||
/obj/item/device/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
..()
|
||||
if(!broken)
|
||||
broken = 1
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
|
||||
icon_state = "flashburnt"
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
else
|
||||
user << "<span class='notice'>\The [M]'s pupils narrow.</span>"
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //can be used offensively
|
||||
user.setClickCooldown(user.get_attack_speed(src)) //can be used offensively
|
||||
M.flash_eyes()
|
||||
else
|
||||
return ..()
|
||||
@@ -290,6 +290,7 @@
|
||||
name = "desk lamp"
|
||||
desc = "A desk lamp with an adjustable mount."
|
||||
icon_state = "lamp"
|
||||
force = 10
|
||||
brightness_on = 5
|
||||
w_class = ITEMSIZE_LARGE
|
||||
flags = CONDUCT
|
||||
|
||||
211
code/game/objects/items/devices/gps.dm
Normal file
211
code/game/objects/items/devices/gps.dm
Normal file
@@ -0,0 +1,211 @@
|
||||
var/list/GPS_list = list()
|
||||
|
||||
/obj/item/device/gps
|
||||
name = "global positioning system"
|
||||
desc = "Triangulates the approximate co-ordinates using a nearby satellite network. Alt+click to toggle power."
|
||||
icon = 'icons/obj/gps.dmi'
|
||||
icon_state = "gps-c"
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_MAGNET = 1)
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 500)
|
||||
var/gps_tag = "COM0"
|
||||
var/emped = FALSE
|
||||
var/tracking = FALSE // Will not show other signals or emit its own signal if false.
|
||||
var/long_range = FALSE // If true, can see farther, depending on get_map_levels().
|
||||
var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown.
|
||||
var/hide_signal = FALSE // If true, signal is not visible to other GPS devices.
|
||||
var/can_hide_signal = FALSE // If it can toggle the above var.
|
||||
|
||||
/obj/item/device/gps/initialize()
|
||||
GPS_list += src
|
||||
name = "global positioning system ([gps_tag])"
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/gps/Destroy()
|
||||
GPS_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/device/gps/AltClick(mob/user)
|
||||
toggletracking(user)
|
||||
|
||||
/obj/item/device/gps/proc/toggletracking(mob/living/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
if(emped)
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
if(tracking)
|
||||
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
|
||||
tracking = FALSE
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
|
||||
tracking = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/gps/emp_act(severity)
|
||||
if(emped) // Without a fancy callback system, this will have to do.
|
||||
return
|
||||
var/severity_modifier = severity ? severity : 4 // In case emp_act gets called without any arguments.
|
||||
var/duration = 5 MINUTES / severity_modifier
|
||||
emped = TRUE
|
||||
update_icon()
|
||||
|
||||
spawn(duration)
|
||||
emped = FALSE
|
||||
update_icon()
|
||||
visible_message("\The [src] appears to be functional again.")
|
||||
|
||||
/obj/item/device/gps/update_icon()
|
||||
overlays.Cut()
|
||||
if(emped)
|
||||
overlays += image(icon, src, "emp")
|
||||
else if(tracking)
|
||||
overlays += image(icon, src, "working")
|
||||
|
||||
/obj/item/device/gps/attack_self(mob/user)
|
||||
display(user)
|
||||
|
||||
/obj/item/device/gps/proc/display(mob/user)
|
||||
if(!tracking)
|
||||
to_chat(user, "The device is off. Alt-click it to turn it on.")
|
||||
return
|
||||
if(emped)
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
|
||||
var/list/dat = list()
|
||||
|
||||
var/turf/curr = get_turf(src)
|
||||
var/area/my_area = get_area(src)
|
||||
dat += "Current location: [my_area.name] <b>([curr.x], [curr.y], [curr.z])</b>"
|
||||
dat += "[hide_signal ? "Tagged" : "Broadcasting"] as '[gps_tag]'. <a href='?src=\ref[src];tag=1'>\[Change Tag\]</a> \
|
||||
<a href='?src=\ref[src];range=1'>\[Toggle Scan Range\]</a> \
|
||||
[can_hide_signal ? "<a href='?src=\ref[src];hide=1'>\[Toggle Signal Visibility\]</a>":""]"
|
||||
|
||||
var/list/signals = list()
|
||||
|
||||
for(var/gps in GPS_list)
|
||||
var/obj/item/device/gps/G = gps
|
||||
if(G.emped || !G.tracking || G.hide_signal || G == src) // Their GPS isn't on or functional.
|
||||
continue
|
||||
var/turf/T = get_turf(G)
|
||||
var/z_level_detection = using_map.get_map_levels(curr.z, long_range)
|
||||
|
||||
if(local_mode && T.z != curr.z) // Only care about the current z-level.
|
||||
continue
|
||||
else if(!(T.z in z_level_detection)) // Too far away.
|
||||
continue
|
||||
|
||||
var/area/their_area = get_area(G)
|
||||
var/area_name = their_area.name
|
||||
if(istype(their_area, /area/submap))
|
||||
area_name = "Unknown Area" // Avoid spoilers.
|
||||
var/coord = "[T.x], [T.y], [T.z]"
|
||||
var/degrees = round(Get_Angle(curr, T))
|
||||
var/direction = uppertext(dir2text(get_dir(curr, T)))
|
||||
var/distance = get_dist(curr, T)
|
||||
var/local = curr.z == T.z ? TRUE : FALSE
|
||||
if(!direction)
|
||||
direction = "CENTER"
|
||||
degrees = "N/A"
|
||||
|
||||
signals += " [G.gps_tag]: [area_name] ([coord]) [local ? "Dist: [distance]m Dir: [degrees]<5D> ([direction])":""]"
|
||||
|
||||
if(signals.len)
|
||||
dat += "Detected signals;"
|
||||
for(var/line in signals)
|
||||
dat += line
|
||||
else
|
||||
dat += "No other signals detected."
|
||||
|
||||
var/result = dat.Join("<br>")
|
||||
to_chat(user, result)
|
||||
|
||||
/obj/item/device/gps/Topic(var/href, var/list/href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["tag"])
|
||||
var/a = input("Please enter desired tag.", name, gps_tag) as text
|
||||
a = uppertext(copytext(sanitize(a), 1, 11))
|
||||
if(in_range(src, usr))
|
||||
gps_tag = a
|
||||
name = "global positioning system ([gps_tag])"
|
||||
to_chat(usr, "You set your GPS's tag to '[gps_tag]'.")
|
||||
|
||||
if(href_list["range"])
|
||||
local_mode = !local_mode
|
||||
to_chat(usr, "You set the signal receiver to [local_mode ? "'NARROW'" : "'BROAD'"].")
|
||||
|
||||
if(href_list["hide"])
|
||||
if(!can_hide_signal)
|
||||
return
|
||||
hide_signal = !hide_signal
|
||||
to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.")
|
||||
|
||||
/obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these.
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/device/gps/science
|
||||
icon_state = "gps-s"
|
||||
gps_tag = "SCI0"
|
||||
|
||||
/obj/item/device/gps/science/on
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/device/gps/engineering
|
||||
icon_state = "gps-e"
|
||||
gps_tag = "ENG0"
|
||||
|
||||
/obj/item/device/gps/engineering/on
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/device/gps/mining
|
||||
icon_state = "gps-m"
|
||||
gps_tag = "MINE0"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life. Alt+click to toggle power."
|
||||
|
||||
/obj/item/device/gps/mining/on
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/device/gps/explorer
|
||||
icon_state = "gps-ex"
|
||||
gps_tag = "EX0"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured explorers, keeping one on you at all times while exploring might just save your life. Alt+click to toggle power."
|
||||
|
||||
/obj/item/device/gps/explorer/on
|
||||
tracking = TRUE
|
||||
|
||||
/obj/item/device/gps/syndie
|
||||
icon_state = "gps-syndie"
|
||||
gps_tag = "NULL"
|
||||
desc = "A positioning system that has extended range and can detect other GPS device signals without revealing its own. How that works is best left a mystery. Alt+click to toggle power."
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_BLUESPACE = 3, TECH_MAGNET = 2, TECH_ILLEGAL = 2)
|
||||
long_range = TRUE
|
||||
hide_signal = TRUE
|
||||
can_hide_signal = TRUE
|
||||
|
||||
/obj/item/device/gps/robot
|
||||
icon_state = "gps-b"
|
||||
gps_tag = "SYNTH0"
|
||||
desc = "A synthetic internal positioning system. Used as a recovery beacon for damaged synthetic assets, or a collaboration tool for mining or exploration teams. \
|
||||
Alt+click to toggle power."
|
||||
tracking = TRUE // On by default.
|
||||
|
||||
/obj/item/device/gps/internal // Base type for immobile/internal GPS units.
|
||||
icon_state = null
|
||||
gps_tag = "Eerie Signal"
|
||||
desc = "Report to a coder immediately."
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
tracking = TRUE // Meant to point to a location, so it needs to be on.
|
||||
anchored = TRUE
|
||||
|
||||
/obj/item/device/gps/internal/base
|
||||
gps_tag = "NT_BASE"
|
||||
desc = "A homing signal from NanoTrasen's outpost."
|
||||
|
||||
/obj/item/device/gps/internal/alien_vessel
|
||||
gps_tag = "Mysterious Signal"
|
||||
desc = "A signal that seems forboding."
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with working lightbulbs or sheets of glass."
|
||||
|
||||
force = 8
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
flags = CONDUCT
|
||||
@@ -61,32 +61,32 @@
|
||||
|
||||
/obj/item/device/lightreplacer/examine(mob/user)
|
||||
if(..(user, 2))
|
||||
user << "It has [uses] lights remaining."
|
||||
to_chat(user, "It has [uses] lights remaining.")
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
|
||||
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>"
|
||||
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
|
||||
return
|
||||
else if(G.use(1))
|
||||
AddUses(16) //Autolathe converts 1 sheet into 16 lights.
|
||||
user << "<span class='notice'>You insert a piece of glass into \the [src.name]. You have [uses] light\s remaining.</span>"
|
||||
add_uses(16) //Autolathe converts 1 sheet into 16 lights.
|
||||
to_chat(user, "<span class='notice'>You insert a piece of glass into \the [src.name]. You have [uses] light\s remaining.</span>")
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You need one sheet of glass to replace lights.</span>"
|
||||
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights.</span>")
|
||||
|
||||
if(istype(W, /obj/item/weapon/light))
|
||||
var/obj/item/weapon/light/L = W
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
AddUses(1)
|
||||
user << "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining."
|
||||
add_uses(1)
|
||||
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
|
||||
user.drop_item()
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user << "You need a working light."
|
||||
to_chat(user, "You need a working light.")
|
||||
return
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
@@ -95,10 +95,10 @@
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.emagged)
|
||||
src.Emag()
|
||||
usr << "You shortcircuit the [src]."
|
||||
to_chat(usr, You short circuit the [src].")
|
||||
return
|
||||
*/
|
||||
usr << "It has [uses] lights remaining."
|
||||
to_chat(usr, "It has [uses] lights remaining.")
|
||||
|
||||
/obj/item/device/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
@@ -107,17 +107,17 @@
|
||||
/obj/item/device/lightreplacer/proc/Use(var/mob/user)
|
||||
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
AddUses(-1)
|
||||
add_uses(-1)
|
||||
return 1
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/device/lightreplacer/proc/AddUses(var/amount = 1)
|
||||
/obj/item/device/lightreplacer/proc/add_uses(var/amount = 1)
|
||||
uses = min(max(uses + amount, 0), max_uses)
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1)
|
||||
charge += amount
|
||||
if(charge > 6)
|
||||
AddUses(1)
|
||||
add_uses(1)
|
||||
charge = 0
|
||||
|
||||
/obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U)
|
||||
|
||||
@@ -23,6 +23,13 @@ REAGENT SCANNER
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 200)
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
|
||||
var/mode = 1;
|
||||
var/advscan = 0
|
||||
var/showadvscan = 1
|
||||
|
||||
/obj/item/device/healthanalyzer/New()
|
||||
if(advscan >= 1)
|
||||
verbs += /obj/item/device/healthanalyzer/proc/toggle_adv
|
||||
..()
|
||||
|
||||
/obj/item/device/healthanalyzer/do_surgery(mob/living/M, mob/living/user)
|
||||
if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
|
||||
@@ -39,7 +46,7 @@ REAGENT SCANNER
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message("<span class='warning'>\The [user] has analyzed the floor's vitals!</span>", 1)
|
||||
user.show_message("<span class='notice'>Analyzing Results for The floor:</span>", 1)
|
||||
user.show_message("Overall Status: Healthy</span>", 1)
|
||||
user.show_message("<span class='notice'>Overall Status: Healthy</span>", 1)
|
||||
user.show_message("<span class='notice'> Damage Specifics: 0-0-0-0</span>", 1)
|
||||
user.show_message("<span class='notice'>Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||
user.show_message("<span class='notice'>Body Temperature: ???</span>", 1)
|
||||
@@ -100,39 +107,72 @@ REAGENT SCANNER
|
||||
OX = fake_oxy > 50 ? "<span class='warning'>Severe oxygen deprivation detected</span>" : "Subject bloodstream oxygen level normal"
|
||||
user.show_message("[OX] | [TX] | [BU] | [BR]")
|
||||
if(M.radiation)
|
||||
if(advscan >= 2 && showadvscan == 1)
|
||||
if(M.radiation >= 75)
|
||||
user.show_message("<span class='warning'>Critical levels of radiation detected. Immediate treatment advised.</span>")
|
||||
else if(M.radiation >= 50)
|
||||
user.show_message("<span class='warning'>Severe levels of radiation detected.</span>")
|
||||
else if(M.radiation >= 25)
|
||||
user.show_message("<span class='warning'>Moderate levels of radiation detected.</span>")
|
||||
else if(M.radiation >= 1)
|
||||
user.show_message("<span_class='warning'>Low levels of radiation detected.</span>")
|
||||
else
|
||||
user.show_message("<span class='warning'>Radiation detected.</span>")
|
||||
if(istype(M, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = M
|
||||
if(C.reagents.total_volume)
|
||||
var/unknown = 0
|
||||
var/reagentdata[0]
|
||||
var/unknownreagents[0]
|
||||
for(var/A in C.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(R.scannable)
|
||||
reagentdata["[R.id]"] = "<span class='notice'> [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]</span>"
|
||||
else
|
||||
unknown++
|
||||
unknownreagents["[R.id]"] = "<span class='notice'> [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]</span>"
|
||||
if(reagentdata.len)
|
||||
user.show_message("<span class='notice'>Beneficial reagents detected in subject's blood:</span>")
|
||||
for(var/d in reagentdata)
|
||||
user.show_message(reagentdata[d])
|
||||
if(unknown)
|
||||
if(advscan >= 3 && showadvscan == 1)
|
||||
user.show_message("<span class='warning'>Warning: Non-medical reagent[(unknown>1)?"s":""] detected in subject's blood:</span>")
|
||||
for(var/d in unknownreagents)
|
||||
user.show_message(unknownreagents[d])
|
||||
else
|
||||
user.show_message("<span class='warning'>Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood.</span>")
|
||||
if(C.ingested && C.ingested.total_volume)
|
||||
var/unknown = 0
|
||||
for(var/datum/reagent/R in C.ingested.reagent_list)
|
||||
if(R.scannable)
|
||||
user << "<span class='notice'>[R.name] found in subject's stomach.</span>"
|
||||
var/stomachreagentdata[0]
|
||||
var/stomachunknownreagents[0]
|
||||
for(var/B in C.ingested.reagent_list)
|
||||
var/datum/reagent/T = B
|
||||
if(T.scannable)
|
||||
stomachreagentdata["[T.id]"] = "<span class='notice'> [round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]</span>"
|
||||
if (advscan == 0 || showadvscan == 0)
|
||||
user.show_message("<span class='notice'>[T.name] found in subject's stomach.</span>")
|
||||
else
|
||||
++unknown
|
||||
stomachunknownreagents["[T.id]"] = "<span class='notice'> [round(C.ingested.get_reagent_amount(T.id), 1)]u [T.name]</span>"
|
||||
if(advscan >= 1 && showadvscan == 1)
|
||||
user.show_message("<span class='notice'>Beneficial reagents detected in subject's stomach:</span>")
|
||||
for(var/d in stomachreagentdata)
|
||||
user.show_message(stomachreagentdata[d])
|
||||
if(unknown)
|
||||
user << "<span class='warning'>Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach.</span>"
|
||||
if(advscan >= 3 && showadvscan == 1)
|
||||
user.show_message("<span class='warning'>Warning: Non-medical reagent[(unknown > 1)?"s":""] found in subject's stomach:</span>")
|
||||
for(var/d in stomachunknownreagents)
|
||||
user.show_message(stomachunknownreagents[d])
|
||||
else
|
||||
user.show_message("<span class='warning'>Unknown substance[(unknown > 1)?"s":""] found in subject's stomach.</span>")
|
||||
if(C.virus2.len)
|
||||
for (var/ID in C.virus2)
|
||||
if (ID in virusDB)
|
||||
var/datum/data/record/V = virusDB[ID]
|
||||
user.show_message("<span class='warning'>Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]</span>")
|
||||
// user.show_message(text("<span class='warning'>Warning: Unknown pathogen detected in subject's blood.</span>"))
|
||||
else
|
||||
user.show_message("<span class='warning'>Warning: Unknown pathogen detected in subject's blood.</span>")
|
||||
if (M.getCloneLoss())
|
||||
user.show_message("<span class='warning'>Subject appears to have been imperfectly cloned.</span>")
|
||||
// if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
|
||||
@@ -145,6 +185,8 @@ REAGENT SCANNER
|
||||
user.show_message("<span class='warning'>Severe brain damage detected. Subject likely to have a traumatic brain injury.</span>")
|
||||
else if (M.getBrainLoss() >= 10)
|
||||
user.show_message("<span class='warning'>Significant brain damage detected. Subject may have had a concussion.</span>")
|
||||
else if (M.getBrainLoss() >= 1 && advscan >= 2 && showadvscan == 1)
|
||||
user.show_message("<span class='warning'>Minor brain damage detected.</span>")
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
for(var/name_i in H.internal_organs_by_name)
|
||||
@@ -166,21 +208,28 @@ REAGENT SCANNER
|
||||
var/limb = e.name
|
||||
if(e.status & ORGAN_BROKEN)
|
||||
if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!e.splinted))
|
||||
user << "<span class='warning'>Unsecured fracture in subject [limb]. Splinting recommended for transport.</span>"
|
||||
to_chat(user, "<span class='warning'>Unsecured fracture in subject [limb]. Splinting recommended for transport.</span>")
|
||||
if(e.has_infected_wound())
|
||||
user << "<span class='warning'>Infected wound detected in subject [limb]. Disinfection recommended.</span>"
|
||||
to_chat(user, "<span class='warning'>Infected wound detected in subject [limb]. Disinfection recommended.</span>")
|
||||
|
||||
for(var/name in H.organs_by_name)
|
||||
var/obj/item/organ/external/e = H.organs_by_name[name]
|
||||
if(e && e.status & ORGAN_BROKEN)
|
||||
if(advscan >= 1 && showadvscan == 1)
|
||||
user.show_message(text("<span class='warning'>Bone fractures detected in subject [e.name].</span>"), 1)
|
||||
else
|
||||
user.show_message(text("<span class='warning'>Bone fractures detected. Advanced scanner required for location.</span>"), 1)
|
||||
break
|
||||
for(var/obj/item/organ/external/e in H.organs)
|
||||
if(!e)
|
||||
continue
|
||||
for(var/datum/wound/W in e.wounds) if(W.internal)
|
||||
if(advscan >= 1 && showadvscan == 1)
|
||||
user.show_message(text("<span class='warning'>Internal bleeding detected in subject [e.name].</span>"), 1)
|
||||
else
|
||||
user.show_message(text("<span class='warning'>Internal bleeding detected. Advanced scanner required for location.</span>"), 1)
|
||||
break
|
||||
break
|
||||
|
||||
if(M:vessel)
|
||||
var/blood_volume = H.vessel.get_reagent_amount("blood")
|
||||
@@ -202,10 +251,37 @@ REAGENT SCANNER
|
||||
mode = !mode
|
||||
switch (mode)
|
||||
if(1)
|
||||
usr << "The scanner now shows specific limb damage."
|
||||
to_chat(usr, "The scanner now shows specific limb damage.")
|
||||
if(0)
|
||||
usr << "The scanner no longer shows limb damage."
|
||||
to_chat(usr, "The scanner no longer shows limb damage.")
|
||||
|
||||
/obj/item/device/healthanalyzer/proc/toggle_adv()
|
||||
set name = "Toggle Advanced Scan"
|
||||
set category = "Object"
|
||||
|
||||
showadvscan = !showadvscan
|
||||
switch (showadvscan)
|
||||
if(1)
|
||||
to_chat(usr, "The scanner will now perform an advanced analysis.")
|
||||
if(0)
|
||||
to_chat(usr, "The scanner will now perform a basic analysis.")
|
||||
|
||||
/obj/item/device/healthanalyzer/improved //reports bone fractures, IB, quantity of beneficial reagents in stomach; also regular health analyzer stuff
|
||||
name = "advanced health analyzer"
|
||||
desc = "A miracle of medical technology, this handheld scanner can produce an accurate and specific report of a patient's biosigns."
|
||||
advscan = 1
|
||||
origin_tech = list(TECH_MAGNET = 5, TECH_BIO = 6)
|
||||
icon_state = "advhealth"
|
||||
|
||||
/obj/item/device/healthanalyzer/advanced //reports all of the above, as well as radiation severity and minor brain damage
|
||||
name = "advanced health analyzer"
|
||||
advscan = 2
|
||||
icon_state = "advhealth"
|
||||
|
||||
/obj/item/device/healthanalyzer/enhanced //reports all of the above, as well as name and quantity of nonmed reagents in stomach
|
||||
name = "phasic health analyzer"
|
||||
advscan = 3
|
||||
icon_state = "advhealth"
|
||||
|
||||
/obj/item/device/analyzer
|
||||
name = "analyzer"
|
||||
@@ -235,7 +311,7 @@ REAGENT SCANNER
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
|
||||
analyze_gases(src, user)
|
||||
@@ -274,14 +350,14 @@ REAGENT SCANNER
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
if(reagents.total_volume)
|
||||
var/list/blood_traces = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.id != "blood")
|
||||
reagents.clear_reagents()
|
||||
user << "<span class='warning'>The sample was contaminated! Please insert another sample</span>"
|
||||
to_chat(user, "<span class='warning'>The sample was contaminated! Please insert another sample</span>")
|
||||
return
|
||||
else
|
||||
blood_traces = params2list(R.data["trace_chem"])
|
||||
@@ -292,7 +368,7 @@ REAGENT SCANNER
|
||||
dat += "[R] ([blood_traces[R]] units) "
|
||||
else
|
||||
dat += "[R] "
|
||||
user << "[dat]"
|
||||
to_chat(user, "[dat]")
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
|
||||
@@ -325,7 +401,7 @@ REAGENT SCANNER
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
if(!istype(O))
|
||||
return
|
||||
@@ -335,9 +411,9 @@ REAGENT SCANNER
|
||||
if(O.reagents.reagent_list.len > 0)
|
||||
var/one_percent = O.reagents.total_volume / 100
|
||||
for (var/datum/reagent/R in O.reagents.reagent_list)
|
||||
dat += "\n \t <span class='notice'>[R][details ? ": [R.volume / one_percent]%" : ""]"
|
||||
dat += "\n \t <span class='notice'>[R][details ? ": [R.volume / one_percent]%" : ""]</span>"
|
||||
if(dat)
|
||||
user << "<span class='notice'>Chemicals found: [dat]</span>"
|
||||
to_chat(user, "<span class='notice'>Chemicals found: [dat]</span>")
|
||||
else
|
||||
user << "<span class='notice'>No active chemical agents found in [O].</span>"
|
||||
else
|
||||
|
||||
@@ -1,115 +1,196 @@
|
||||
/obj/item/device/spy_bug
|
||||
/obj/item/device/camerabug
|
||||
name = "mobile camera pod"
|
||||
desc = "A camera pod used by tactical operators. Must be linked to a camera scanner unit."
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "camgrenade"
|
||||
item_state = "empgrenade"
|
||||
flags = CONDUCT
|
||||
w_class = ITEMSIZE_SMALL
|
||||
force = 0
|
||||
throwforce = 5.0
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
|
||||
var/obj/item/device/bug_monitor/linkedmonitor
|
||||
var/brokentype = /obj/item/brokenbug
|
||||
|
||||
// var/obj/item/device/radio/bug/radio
|
||||
var/obj/machinery/camera/bug/camera
|
||||
|
||||
/obj/item/device/camerabug/New()
|
||||
..()
|
||||
// radio = new(src)
|
||||
camera = new(src)
|
||||
|
||||
/obj/item/device/camerabug/attack_self(mob/user)
|
||||
if(user.a_intent == I_HURT)
|
||||
to_chat(user, "<span class='notice'>You crush the [src] under your foot, breaking it.</span>")
|
||||
visible_message("[user.name] crushes the [src] under their foot, breaking it!</span>")
|
||||
new brokentype(get_turf(src))
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
/* else
|
||||
user.set_machine(radio)
|
||||
radio.interact(user)
|
||||
*/
|
||||
/obj/item/device/camerabug/verb/reset()
|
||||
set name = "Reset camera bug"
|
||||
set category = "Object"
|
||||
if(linkedmonitor)
|
||||
linkedmonitor.unpair(src)
|
||||
linkedmonitor = null
|
||||
qdel(camera)
|
||||
camera = new(src)
|
||||
to_chat(usr, "<span class='notice'>You turn the [src] off and on again, delinking it from any monitors.")
|
||||
|
||||
/obj/item/brokenbug
|
||||
name = "broken mobile camera pod"
|
||||
desc = "A camera pod formerly used by tactical operators. The lens is smashed, and the circuits are damaged beyond repair."
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "camgrenadebroken"
|
||||
item_state = "empgrenade"
|
||||
flags = CONDUCT
|
||||
force = 5.0
|
||||
w_class = ITEMSIZE_SMALL
|
||||
throwforce = 5.0
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
origin_tech = list(TECH_ENGINEERING = 1)
|
||||
|
||||
/obj/item/brokenbug/spy
|
||||
name = "broken bug"
|
||||
desc = "" //Even when it's broken it's inconspicuous
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "eshield0"
|
||||
item_state = "nothing"
|
||||
layer = TURF_LAYER+0.2
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_EARS
|
||||
origin_tech = list(TECH_ENGINEERING = 1, TECH_ILLEGAL = 3) //crush it and you lose the data
|
||||
flags = CONDUCT
|
||||
force = 0
|
||||
throwforce = 5.0
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
|
||||
/obj/item/device/camerabug/spy
|
||||
name = "bug"
|
||||
desc = "" //Nothing to see here
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "eshield0"
|
||||
item_state = "nothing"
|
||||
layer = TURF_LAYER+0.2
|
||||
|
||||
flags = CONDUCT
|
||||
force = 5.0
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_EARS
|
||||
throwforce = 5.0
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
|
||||
|
||||
var/obj/item/device/radio/spy/radio
|
||||
var/obj/machinery/camera/spy/camera
|
||||
|
||||
/obj/item/device/spy_bug/New()
|
||||
..()
|
||||
radio = new(src)
|
||||
camera = new(src)
|
||||
|
||||
/obj/item/device/spy_bug/examine(mob/user)
|
||||
/obj/item/device/camerabug/examine(mob/user)
|
||||
. = ..(user, 0)
|
||||
if(.)
|
||||
user << "It's a tiny camera, microphone, and transmission device in a happy union."
|
||||
user << "Needs to be both configured and brought in contact with monitor device to be fully functional."
|
||||
to_chat(user, "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional.")
|
||||
|
||||
/obj/item/device/spy_bug/attack_self(mob/user)
|
||||
radio.attack_self(user)
|
||||
|
||||
/obj/item/device/spy_bug/attackby(obj/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/device/spy_monitor))
|
||||
var/obj/item/device/spy_monitor/SM = W
|
||||
SM.pair(src, user)
|
||||
/obj/item/device/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/device/bug_monitor))
|
||||
var/obj/item/device/bug_monitor/SM = W
|
||||
if(!linkedmonitor)
|
||||
to_chat(user, "<span class='notice'>\The [src] has been paired with \the [SM].</span>")
|
||||
SM.pair(src)
|
||||
linkedmonitor = SM
|
||||
else if (linkedmonitor == SM)
|
||||
to_chat(user, "<span class='notice'>\The [src] has been unpaired from \the [SM].</span>")
|
||||
linkedmonitor.unpair(src)
|
||||
linkedmonitor = null
|
||||
else
|
||||
to_chat(user, "Error: The device is linked to another monitor.")
|
||||
else
|
||||
if(W.force >= 5)
|
||||
visible_message("\The [src] lens shatters!")
|
||||
new brokentype(get_turf(src))
|
||||
if(linkedmonitor)
|
||||
linkedmonitor.unpair(src)
|
||||
linkedmonitor = null
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
..()
|
||||
|
||||
/obj/item/device/spy_bug/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
|
||||
/obj/item/device/camerabug/bullet_act()
|
||||
visible_message("The [src] lens shatters!")
|
||||
new brokentype(get_turf(src))
|
||||
if(linkedmonitor)
|
||||
linkedmonitor.unpair(src)
|
||||
linkedmonitor = null
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/camerabug/Destroy()
|
||||
if(linkedmonitor)
|
||||
linkedmonitor.unpair(src)
|
||||
linkedmonitor = null
|
||||
..()
|
||||
/*
|
||||
/obj/item/device/camerabug/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
|
||||
radio.hear_talk(M, msg, speaking)
|
||||
|
||||
|
||||
/obj/item/device/spy_monitor
|
||||
name = "\improper PDA"
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "pda"
|
||||
*/
|
||||
/obj/item/device/bug_monitor
|
||||
name = "mobile camera pod monitor"
|
||||
desc = "A portable camera console designed to work with mobile camera pods."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "forensic0"
|
||||
item_state = "electronic"
|
||||
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
|
||||
|
||||
var/operating = 0
|
||||
var/obj/item/device/radio/spy/radio
|
||||
var/obj/machinery/camera/spy/selected_camera
|
||||
var/list/obj/machinery/camera/spy/cameras = new()
|
||||
|
||||
/obj/item/device/spy_monitor/New()
|
||||
// var/obj/item/device/radio/bug/radio
|
||||
var/obj/machinery/camera/bug/selected_camera
|
||||
var/list/obj/machinery/camera/bug/cameras = new()
|
||||
/*
|
||||
/obj/item/device/bug_monitor/New()
|
||||
radio = new(src)
|
||||
|
||||
/obj/item/device/spy_monitor/examine(mob/user)
|
||||
. = ..(user, 1)
|
||||
if(.)
|
||||
user << "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made."
|
||||
|
||||
/obj/item/device/spy_monitor/attack_self(mob/user)
|
||||
*/
|
||||
/obj/item/device/bug_monitor/attack_self(mob/user)
|
||||
if(operating)
|
||||
return
|
||||
|
||||
radio.attack_self(user)
|
||||
// radio.attack_self(user)
|
||||
view_cameras(user)
|
||||
|
||||
/obj/item/device/spy_monitor/attackby(obj/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/device/spy_bug))
|
||||
pair(W, user)
|
||||
/obj/item/device/bug_monitor/attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/device/camerabug))
|
||||
W.attackby(src, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/spy_monitor/proc/pair(var/obj/item/device/spy_bug/SB, var/mob/living/user)
|
||||
/obj/item/device/bug_monitor/proc/unpair(var/obj/item/device/camerabug/SB)
|
||||
if(SB.camera in cameras)
|
||||
user << "<span class='notice'>\The [SB] has been unpaired from \the [src].</span>"
|
||||
cameras -= SB.camera
|
||||
else
|
||||
user << "<span class='notice'>\The [SB] has been paired with \the [src].</span>"
|
||||
|
||||
/obj/item/device/bug_monitor/proc/pair(var/obj/item/device/camerabug/SB)
|
||||
cameras += SB.camera
|
||||
|
||||
/obj/item/device/spy_monitor/proc/view_cameras(mob/user)
|
||||
/obj/item/device/bug_monitor/proc/view_cameras(mob/user)
|
||||
if(!can_use_cam(user))
|
||||
return
|
||||
|
||||
selected_camera = cameras[1]
|
||||
user.reset_view(selected_camera)
|
||||
view_camera(user)
|
||||
|
||||
operating = 1
|
||||
while(selected_camera && Adjacent(user))
|
||||
selected_camera = input("Select camera bug to view.") as null|anything in cameras
|
||||
selected_camera = input("Select camera to view.") as null|anything in cameras
|
||||
selected_camera = null
|
||||
operating = 0
|
||||
|
||||
/obj/item/device/spy_monitor/proc/view_camera(mob/user)
|
||||
/obj/item/device/bug_monitor/proc/view_camera(mob/user)
|
||||
spawn(0)
|
||||
while(selected_camera && Adjacent(user))
|
||||
var/turf/T = get_turf(selected_camera)
|
||||
if(!T || !is_on_same_plane_or_station(T.z, user.z) || !selected_camera.can_use())
|
||||
user.unset_machine()
|
||||
user.reset_view(null)
|
||||
user << "<span class='notice'>[selected_camera] unavailable.</span>"
|
||||
to_chat(user, "<span class='notice'>Link to [selected_camera] has been lost.</span>")
|
||||
src.unpair(selected_camera.loc)
|
||||
sleep(90)
|
||||
else
|
||||
user.set_machine(selected_camera)
|
||||
@@ -118,37 +199,67 @@
|
||||
user.unset_machine()
|
||||
user.reset_view(null)
|
||||
|
||||
/obj/item/device/spy_monitor/proc/can_use_cam(mob/user)
|
||||
/obj/item/device/bug_monitor/proc/can_use_cam(mob/user)
|
||||
if(operating)
|
||||
return
|
||||
|
||||
if(!cameras.len)
|
||||
user << "<span class='warning'>No paired cameras detected!</span>"
|
||||
user << "<span class='warning'>Bring a bug in contact with this device to pair the camera.</span>"
|
||||
to_chat(user, "<span class='warning'>No paired cameras detected!</span>")
|
||||
to_chat(user, "<span class='warning'>Bring a camera in contact with this device to pair the camera.</span>")
|
||||
return
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/device/spy_monitor/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
|
||||
/*
|
||||
/obj/item/device/bug_monitor/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
|
||||
return radio.hear_talk(M, msg, speaking)
|
||||
*/
|
||||
/obj/item/device/bug_monitor/spy
|
||||
name = "\improper PDA"
|
||||
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
|
||||
icon = 'icons/obj/pda.dmi'
|
||||
icon_state = "pda"
|
||||
item_state = "electronic"
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
|
||||
|
||||
/obj/item/device/bug_monitor/spy/examine(mob/user)
|
||||
. = ..(user, 1)
|
||||
if(.)
|
||||
to_chat(user, "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made.")
|
||||
|
||||
/obj/machinery/camera/spy
|
||||
// These cheap toys are accessible from the mercenary camera console as well
|
||||
/obj/machinery/camera/bug/check_eye(var/mob/user as mob)
|
||||
return 0
|
||||
|
||||
/obj/machinery/camera/bug
|
||||
network = list(NETWORK_SECURITY)
|
||||
|
||||
/obj/machinery/camera/bug/New()
|
||||
..()
|
||||
name = "Camera #[rand(1000,9999)]"
|
||||
c_tag = name
|
||||
|
||||
/obj/machinery/camera/bug/spy
|
||||
// These cheap toys are accessible from the mercenary camera console as well - only the antag ones though!
|
||||
network = list(NETWORK_MERCENARY)
|
||||
|
||||
/obj/machinery/camera/spy/New()
|
||||
/obj/machinery/camera/bug/spy/New()
|
||||
..()
|
||||
name = "DV-136ZB #[rand(1000,9999)]"
|
||||
c_tag = name
|
||||
|
||||
/obj/machinery/camera/spy/check_eye(var/mob/user as mob)
|
||||
return 0
|
||||
/* //These were originally supposed to have radios in them. Doesn't work.
|
||||
/obj/item/device/radio/bug
|
||||
listening = 0 //turn it on first
|
||||
frequency = 1359 //sec comms
|
||||
broadcasting = 0
|
||||
canhear_range = 1
|
||||
name = "camera bug device"
|
||||
icon_state = "syn_cypherkey"
|
||||
|
||||
/obj/item/device/radio/spy
|
||||
/obj/item/device/radio/bug/spy
|
||||
listening = 0
|
||||
frequency = 1473
|
||||
broadcasting = 0
|
||||
canhear_range = 1
|
||||
name = "spy device"
|
||||
icon_state = "syn_cypherkey"
|
||||
*/
|
||||
@@ -160,6 +160,29 @@
|
||||
to_chat(usr, "There's no mounting point for the module!")
|
||||
return 0
|
||||
|
||||
/obj/item/borg/upgrade/advhealth
|
||||
name = "advanced health analyzer module"
|
||||
desc = "A carbon dioxide jetpack suitable for low-gravity operations."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
item_state = "cyborg_upgrade"
|
||||
require_module = 1
|
||||
|
||||
/obj/item/borg/upgrade/advhealth/action(var/mob/living/silicon/robot/R)
|
||||
if(..()) return 0
|
||||
|
||||
var/obj/item/device/healthanalyzer/advanced/T = locate() in R.module
|
||||
if(!T)
|
||||
T = locate() in R.module.contents
|
||||
if(!T)
|
||||
T = locate() in R.module.modules
|
||||
if(!T)
|
||||
R.module.modules += new/obj/item/device/healthanalyzer/advanced
|
||||
return 1
|
||||
if(T)
|
||||
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
|
||||
to_chat(usr, "There's no mounting point for the module!")
|
||||
return 0
|
||||
|
||||
/obj/item/borg/upgrade/syndicate/
|
||||
name = "scrambled equipment module"
|
||||
desc = "Unlocks new and often deadly module specific items of a robot"
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
singular_name = "advanced trauma kit"
|
||||
desc = "An advanced trauma kit for severe injuries."
|
||||
icon_state = "traumakit"
|
||||
heal_brute = 5
|
||||
heal_brute = 3
|
||||
origin_tech = list(TECH_BIO = 1)
|
||||
|
||||
/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
|
||||
@@ -225,7 +225,7 @@
|
||||
singular_name = "advanced burn kit"
|
||||
desc = "An advanced treatment kit for severe burns."
|
||||
icon_state = "burnkit"
|
||||
heal_burn = 5
|
||||
heal_burn = 3
|
||||
origin_tech = list(TECH_BIO = 1)
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
if(!S.get_damage())
|
||||
user << "<span class='notice'>Nothing to fix here.</span>"
|
||||
else if(can_use(1))
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
if(S.open >= 2)
|
||||
if(do_after(user,5 * toolspeed))
|
||||
S.heal_damage(20, 20, robo_repair = 1)
|
||||
|
||||
@@ -771,13 +771,13 @@
|
||||
user.visible_message("<span class='notice'><b>\The [user]</b> pokes [src].</span>","<span class='notice'>You poke [src].</span>")
|
||||
last_message = world.time
|
||||
|
||||
obj/item/toy/plushie/verb/rename_plushie()
|
||||
/obj/item/toy/plushie/verb/rename_plushie()
|
||||
set name = "Name Plushie"
|
||||
set category = "Object"
|
||||
set desc = "Give your plushie a cute name!"
|
||||
w_class = ITEMSIZE_TINY
|
||||
var/mob/M = usr
|
||||
if(!M.mind) return 0
|
||||
if(!M.mind)
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the plushie?", ,""), MAX_NAME_LEN)
|
||||
|
||||
|
||||
@@ -25,51 +25,51 @@ AI MODULES
|
||||
if (istype(AM, /obj/machinery/computer/aiupload))
|
||||
var/obj/machinery/computer/aiupload/comp = AM
|
||||
if(comp.stat & NOPOWER)
|
||||
usr << "The upload computer has no power!"
|
||||
to_chat(usr, "The upload computer has no power!")
|
||||
return
|
||||
if(comp.stat & BROKEN)
|
||||
usr << "The upload computer is broken!"
|
||||
to_chat(usr, "The upload computer is broken!")
|
||||
return
|
||||
if (!comp.current)
|
||||
usr << "You haven't selected an AI to transmit laws to!"
|
||||
to_chat(usr, "You haven't selected an AI to transmit laws to!")
|
||||
return
|
||||
|
||||
if (comp.current.stat == 2 || comp.current.control_disabled == 1)
|
||||
usr << "Upload failed. No signal is being detected from the AI."
|
||||
to_chat(usr, "Upload failed. No signal is being detected from the AI.")
|
||||
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."
|
||||
to_chat(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)
|
||||
comp.current << "These are your laws now:"
|
||||
to_chat(comp.current, "These are your laws now:")
|
||||
comp.current.show_laws()
|
||||
for(var/mob/living/silicon/robot/R in mob_list)
|
||||
if(R.lawupdate && (R.connected_ai == comp.current))
|
||||
R << "These are your laws now:"
|
||||
to_chat(R, "These are your laws now:")
|
||||
R.show_laws()
|
||||
usr << "Upload complete. The AI's laws have been modified."
|
||||
to_chat(usr, "Upload complete. The AI's laws have been modified.")
|
||||
|
||||
|
||||
else if (istype(AM, /obj/machinery/computer/borgupload))
|
||||
var/obj/machinery/computer/borgupload/comp = AM
|
||||
if(comp.stat & NOPOWER)
|
||||
usr << "The upload computer has no power!"
|
||||
to_chat(usr, "The upload computer has no power!")
|
||||
return
|
||||
if(comp.stat & BROKEN)
|
||||
usr << "The upload computer is broken!"
|
||||
to_chat(usr, "The upload computer is broken!")
|
||||
return
|
||||
if (!comp.current)
|
||||
usr << "You haven't selected a robot to transmit laws to!"
|
||||
to_chat(usr, "You haven't selected a robot to transmit laws to!")
|
||||
return
|
||||
|
||||
if (comp.current.stat == 2 || comp.current.emagged)
|
||||
usr << "Upload failed. No signal is being detected from the robot."
|
||||
to_chat(usr, "Upload failed. No signal is being detected from the robot.")
|
||||
else if (comp.current.connected_ai)
|
||||
usr << "Upload failed. The robot is slaved to an AI."
|
||||
to_chat(usr, "Upload failed. The robot is slaved to an AI.")
|
||||
else
|
||||
src.transmitInstructions(comp.current, usr)
|
||||
comp.current << "These are your laws now:"
|
||||
to_chat(comp.current, "These are your laws now:")
|
||||
comp.current.show_laws()
|
||||
usr << "Upload complete. The robot's laws have been modified."
|
||||
to_chat(usr, "Upload complete. The robot's laws have been modified.")
|
||||
|
||||
else if(istype(AM, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = AM
|
||||
@@ -104,7 +104,7 @@ AI MODULES
|
||||
laws.sync(target, 0)
|
||||
addAdditionalLaws(target, sender)
|
||||
|
||||
target << "\The [sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: "
|
||||
to_chat(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)
|
||||
@@ -133,7 +133,7 @@ AI MODULES
|
||||
|
||||
/obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C, var/mob/living/user)
|
||||
if(!targetName)
|
||||
usr << "No name detected on module, please enter one."
|
||||
to_chat(usr, "No name detected on module, please enter one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
@@ -159,18 +159,14 @@ AI MODULES
|
||||
|
||||
/obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C, var/mob/living/user)
|
||||
if(!targetName)
|
||||
usr << "No name detected on module, please enter one."
|
||||
to_chat(usr, "No name detected on module, please enter one.")
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
var/law = "Only [targetName] is an crew member."
|
||||
if (!target.is_malf_or_traitor()) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite
|
||||
target << law
|
||||
target.set_zeroth_law(law)
|
||||
lawchanges.Add("The law specified [targetName]")
|
||||
else
|
||||
lawchanges.Add("The law specified [targetName], but the AI's existing law 0 cannot be overriden.")
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(16, law)
|
||||
|
||||
/******************** ProtectStation ********************/
|
||||
|
||||
@@ -255,7 +251,7 @@ AI MODULES
|
||||
|
||||
/obj/item/weapon/aiModule/freeform/install(var/obj/machinery/computer/C, var/mob/living/user)
|
||||
if(!newFreeFormLaw)
|
||||
usr << "No law detected on module, please create one."
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
@@ -275,7 +271,7 @@ AI MODULES
|
||||
target.laws.clear_supplied_laws()
|
||||
target.laws.clear_ion_laws()
|
||||
|
||||
target << "[sender.real_name] attempted to reset your laws using a reset module."
|
||||
to_chat(target, "[sender.real_name] attempted to reset your laws using a reset module.")
|
||||
target.show_laws()
|
||||
|
||||
/******************** Purge ********************/
|
||||
@@ -294,7 +290,7 @@ AI MODULES
|
||||
target.laws.clear_ion_laws()
|
||||
target.laws.clear_inherent_laws()
|
||||
|
||||
target << "[sender.real_name] attempted to wipe your laws using a purge module."
|
||||
to_chat(target, "[sender.real_name] attempted to wipe your laws using a purge module.")
|
||||
target.show_laws()
|
||||
|
||||
/******************** Asimov ********************/
|
||||
@@ -366,7 +362,7 @@ AI MODULES
|
||||
|
||||
/obj/item/weapon/aiModule/freeformcore/install(var/obj/machinery/computer/C, var/mob/living/user)
|
||||
if(!newFreeFormLaw)
|
||||
usr << "No law detected on module, please create one."
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
@@ -388,14 +384,14 @@ AI MODULES
|
||||
log_law_changes(target, sender)
|
||||
|
||||
lawchanges.Add("The law is '[newFreeFormLaw]'")
|
||||
target << "<span class='danger'>BZZZZT</span>"
|
||||
to_chat(target, "<span class='danger'>BZZZZT</span>")
|
||||
var/law = "[newFreeFormLaw]"
|
||||
target.add_ion_law(law)
|
||||
target.show_laws()
|
||||
|
||||
/obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C, var/mob/living/user)
|
||||
if(!newFreeFormLaw)
|
||||
usr << "No law detected on module, please create one."
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
|
||||
/obj/item/weapon/circuitboard/request
|
||||
name = T_BOARD("reques console")
|
||||
name = T_BOARD("request console")
|
||||
build_path = /obj/machinery/requests_console
|
||||
board_type = new /datum/frame/frame_types/supply_request_console
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50, "glass" = 50)
|
||||
|
||||
@@ -33,23 +33,23 @@
|
||||
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
|
||||
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
|
||||
if(user.client && (target in user.client.screen))
|
||||
user << "<span class='notice'>You need to take that [target.name] off before cleaning it.</span>"
|
||||
to_chat(user, "<span class='notice'>You need to take that [target.name] off before cleaning it.</span>")
|
||||
else if(istype(target,/obj/effect/decal/cleanable/blood))
|
||||
user << "<span class='notice'>You scrub \the [target.name] out.</span>"
|
||||
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
|
||||
target.clean_blood()
|
||||
return //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals.
|
||||
else if(istype(target,/obj/effect/decal/cleanable))
|
||||
user << "<span class='notice'>You scrub \the [target.name] out.</span>"
|
||||
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
|
||||
qdel(target)
|
||||
else if(istype(target,/turf))
|
||||
user << "<span class='notice'>You scrub \the [target.name] clean.</span>"
|
||||
to_chat(user, "<span class='notice'>You scrub \the [target.name] clean.</span>")
|
||||
var/turf/T = target
|
||||
T.clean(src, user)
|
||||
else if(istype(target,/obj/structure/sink))
|
||||
user << "<span class='notice'>You wet \the [src] in the sink.</span>"
|
||||
to_chat(user, "<span class='notice'>You wet \the [src] in the sink.</span>")
|
||||
wet()
|
||||
else
|
||||
user << "<span class='notice'>You clean \the [target.name].</span>"
|
||||
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
target.clean_blood()
|
||||
return
|
||||
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
for(var/mob/living/carbon/M in hear(7, get_turf(src)))
|
||||
bang(get_turf(src), M)
|
||||
|
||||
for(var/obj/effect/blob/B in hear(8,get_turf(src))) //Blob damage here
|
||||
for(var/obj/structure/blob/B in hear(8,get_turf(src))) //Blob damage here
|
||||
var/damage = round(30/(get_dist(B,get_turf(src))+1))
|
||||
B.health -= damage
|
||||
B.update_icon()
|
||||
if(B.overmind)
|
||||
damage *= B.overmind.blob_type.burn_multiplier
|
||||
B.adjust_integrity(-damage)
|
||||
|
||||
new/obj/effect/effect/sparks(src.loc)
|
||||
new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF")
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/breakouttime = 1200 //Deciseconds = 120s = 2 minutes
|
||||
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
|
||||
var/cuff_type = "handcuffs"
|
||||
var/use_time = 30
|
||||
sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi')
|
||||
|
||||
/obj/item/weapon/handcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
|
||||
@@ -69,7 +70,7 @@
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
|
||||
|
||||
if(!do_after(user,30))
|
||||
if(!do_after(user,use_time))
|
||||
return 0
|
||||
|
||||
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
|
||||
@@ -80,7 +81,7 @@
|
||||
msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(H)]")
|
||||
feedback_add_details("handcuffs","H")
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
user.do_attack_animation(H)
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
|
||||
@@ -199,6 +200,44 @@ var/last_chew = 0
|
||||
elastic = 0
|
||||
cuff_sound = 'sound/weapons/handcuffs.ogg' //This shold work for now.
|
||||
|
||||
/obj/item/weapon/handcuffs/legcuffs/bola
|
||||
name = "bola"
|
||||
desc = "Keeps prey in line."
|
||||
elastic = 1
|
||||
use_time = 0
|
||||
breakouttime = 30
|
||||
cuff_sound = 'sound/weapons/towelwipe.ogg' //Is there anything this sound can't do?
|
||||
|
||||
/obj/item/weapon/handcuffs/legcuffs/bola/can_place(var/mob/target, var/mob/user)
|
||||
if(user) //A ranged legcuff, until proper implementation as items it remains a projectile-only thing.
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/handcuffs/legcuffs/bola/dropped()
|
||||
visible_message("<span class='notice'>\The [src] falls apart!</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/handcuffs/legcuffs/bola/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
|
||||
playsound(src.loc, cuff_sound, 30, 1, -2)
|
||||
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!istype(H))
|
||||
src.dropped()
|
||||
return 0
|
||||
|
||||
if(!H.has_organ_for_slot(slot_legcuffed))
|
||||
H.visible_message("<span class='notice'>\The [src] slams into [H], but slides off!</span>")
|
||||
src.dropped()
|
||||
return 0
|
||||
|
||||
H.visible_message("<span class='danger'>\The [H] has been snared by \the [src]!</span>")
|
||||
|
||||
// Apply cuffs.
|
||||
var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
|
||||
lcuffs.loc = target
|
||||
target.legcuffed = lcuffs
|
||||
target.update_inv_legcuffed()
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/handcuffs/legcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
@@ -236,7 +275,7 @@ var/last_chew = 0
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
|
||||
|
||||
if(!do_after(user,30))
|
||||
if(!do_after(user,use_time))
|
||||
return 0
|
||||
|
||||
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
|
||||
@@ -247,7 +286,7 @@ var/last_chew = 0
|
||||
msg_admin_attack("[key_name(user)] attempted to legcuff [key_name(H)]")
|
||||
feedback_add_details("legcuffs","H")
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
user.do_attack_animation(H)
|
||||
|
||||
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
|
||||
|
||||
@@ -351,6 +351,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
|
||||
R << "You hear a faint *beep*."
|
||||
if(!src.reagents.total_volume)
|
||||
R << "You hear a faint click from your chest."
|
||||
playsound(R, 'sound/weapons/empty.ogg', 10, 1)
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
112
code/game/objects/items/weapons/material/chainsaw.dm
Normal file
112
code/game/objects/items/weapons/material/chainsaw.dm
Normal file
@@ -0,0 +1,112 @@
|
||||
obj/item/weapon/chainsaw
|
||||
name = "Chainsaw"
|
||||
desc = "Vroom vroom."
|
||||
icon_state = "chainsaw0"
|
||||
var/on = 0
|
||||
var/max_fuel = 20
|
||||
w_class = ITEMSIZE_LARGE
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = ITEMSIZE_LARGE
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
obj/item/weapon/chainsaw/New()
|
||||
var/datum/reagents/R = new/datum/reagents(max_fuel)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("fuel", max_fuel)
|
||||
..()
|
||||
|
||||
obj/item/weapon/chainsaw/proc/turnOn()
|
||||
if(on) return
|
||||
|
||||
visible_message("You start pulling the string on \the [src].", "[usr] starts pulling the string on the [src].")
|
||||
|
||||
if(max_fuel <= 0)
|
||||
if(do_after(usr, 15))
|
||||
to_chat(usr, "\The [src] won't start!")
|
||||
else
|
||||
to_chat(usr, "You fumble with the string.")
|
||||
else
|
||||
if(do_after(usr, 15))
|
||||
visible_message("You start \the [src] up with a loud grinding!", "[usr] starts \the [src] up with a loud grinding!")
|
||||
attack_verb = list("shreds", "rips", "tears")
|
||||
playsound(src, 'sound/weapons/chainsaw_startup.ogg',40,1)
|
||||
force = 55
|
||||
edge = 1
|
||||
sharp = 1
|
||||
on = 1
|
||||
update_icon()
|
||||
else
|
||||
to_chat(usr, "You fumble with the string.")
|
||||
|
||||
obj/item/weapon/chainsaw/proc/turnOff()
|
||||
if(!on) return
|
||||
to_chat(usr, "You switch the gas nozzle on the chainsaw, turning it off.")
|
||||
attack_verb = list("bluntly hit", "beat", "knocked")
|
||||
playsound(src, 'sound/weapons/chainsaw_turnoff.ogg',40,1)
|
||||
force = 10
|
||||
edge = 0
|
||||
sharp = 0
|
||||
on = 0
|
||||
update_icon()
|
||||
|
||||
obj/item/weapon/chainsaw/attack_self(mob/user as mob)
|
||||
if(!on)
|
||||
turnOn()
|
||||
else
|
||||
turnOff()
|
||||
|
||||
obj/item/weapon/chainsaw/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
..()
|
||||
if(on)
|
||||
playsound(src, 'sound/weapons/chainsaw_attack.ogg',40,1)
|
||||
if(A && on)
|
||||
if(istype(A,/obj/structure/window))
|
||||
var/obj/structure/window/W = A
|
||||
W.shatter()
|
||||
else if(istype(A,/obj/structure/grille))
|
||||
new /obj/structure/grille/broken(A.loc)
|
||||
new /obj/item/stack/rods(A.loc)
|
||||
qdel(A)
|
||||
else if(istype(A,/obj/effect/plant))
|
||||
var/obj/effect/plant/P = A
|
||||
qdel(P) //Plant isn't surviving that. At all
|
||||
if (istype(A, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,A) <= 1)
|
||||
to_chat(user, "<span class='notice'>You begin filling the tank on the chainsaw.</span>")
|
||||
if(do_after(usr, 15))
|
||||
A.reagents.trans_to_obj(src, max_fuel)
|
||||
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
to_chat(user, "<span class='notice'>Chainsaw succesfully refueled.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Don't move while you're refilling the chainsaw.</span>")
|
||||
|
||||
obj/item/weapon/chainsaw/process()
|
||||
if(!on) return
|
||||
|
||||
if(on)
|
||||
if(get_fuel() > 0)
|
||||
reagents.remove_reagent("fuel", 1)
|
||||
if(get_fuel() <= 0)
|
||||
to_chat(usr, "\The [src] sputters to a stop!")
|
||||
on = !on
|
||||
|
||||
obj/item/weapon/chainsaw/proc/get_fuel()
|
||||
reagents.get_reagent_amount("fuel")
|
||||
|
||||
obj/item/weapon/chainsaw/examine(mob/user)
|
||||
if(..(user,0))
|
||||
if(max_fuel)
|
||||
to_chat(usr, "<span class = 'notice'>The [src] feels like it contains roughtly [get_fuel()] units of fuel left.</span>")
|
||||
|
||||
obj/item/weapon/chainsaw/suicide_act(mob/user)
|
||||
to_chat(viewers(user), "<span class='danger'>[user] is lying down and pulling the chainsaw into \him, it looks like \he's trying to commit suicide!</span>")
|
||||
return(BRUTELOSS)
|
||||
|
||||
obj/item/weapon/chainsaw/update_icon()
|
||||
if(on)
|
||||
icon_state = "chainsaw1"
|
||||
item_state = "chainsaw1"
|
||||
else
|
||||
icon_state = "chainsaw0"
|
||||
icon_state = "chainsaw0"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user