mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 02:34:00 +00:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into 10/28/2017_new_blob
# Conflicts: # code/game/atoms_movable.dm
This commit is contained in:
@@ -36,9 +36,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 polaris.dme
|
||||
- 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 polaris.dme
|
||||
- DreamDaemon polaris.dmb -invisible -trusted -core 2>&1 | tee log.txt
|
||||
- grep "All Unit Tests Passed" log.txt
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ client/proc/ZoneTick()
|
||||
|
||||
var/result = air_master.Tick()
|
||||
if(result)
|
||||
src << "Sucessfully Processed."
|
||||
src << "Successfully Processed."
|
||||
|
||||
else
|
||||
src << "Failed to process! ([air_master.tick_progress])"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define OXY "oxy"
|
||||
#define CLONE "clone"
|
||||
#define HALLOSS "halloss"
|
||||
#define ELECTROCUTE "electrocute"
|
||||
|
||||
#define CUT "cut"
|
||||
#define BRUISE "bruise"
|
||||
@@ -56,3 +57,4 @@
|
||||
#define INFECTION_LEVEL_ONE 100
|
||||
#define INFECTION_LEVEL_TWO 500
|
||||
#define INFECTION_LEVEL_THREE 1000
|
||||
#define INFECTION_LEVEL_MAX 1500
|
||||
@@ -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.
|
||||
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)
|
||||
@@ -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
|
||||
|
||||
@@ -51,6 +51,22 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
return 0
|
||||
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)
|
||||
@@ -73,7 +89,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()
|
||||
|
||||
@@ -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
|
||||
name = "rifle magazine (5.45mm hunting)"
|
||||
path =/obj/item/ammo_magazine/m545/hunter
|
||||
|
||||
/datum/category_item/autolathe/arms/machinegun_545
|
||||
name = "machinegun box magazine (5.56)"
|
||||
path =/obj/item/ammo_magazine/m545saw
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/machinegun_545_hunter
|
||||
name = "machinegun box magazine (5.56 hunting)"
|
||||
path =/obj/item/ammo_magazine/m545saw/hunter
|
||||
hidden = 1
|
||||
|
||||
/////// 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)"
|
||||
@@ -298,6 +308,15 @@
|
||||
name = "speedloader (.38 rubber)"
|
||||
path =/obj/item/ammo_magazine/s38/rubber
|
||||
|
||||
/datum/category_item/autolathe/arms/speedloader_45
|
||||
name = "speedloader (.45)"
|
||||
path = /obj/item/ammo_magazine/s45
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/speedloader_45r
|
||||
name = "speedloader (.45 rubber)"
|
||||
path = /obj/item/ammo_magazine/s45/rubber
|
||||
|
||||
// Commented out until metal exploits with autolathe is fixed.
|
||||
/*/datum/category_item/autolathe/arms/pistol_clip_45
|
||||
name = "ammo clip (.45)"
|
||||
@@ -375,6 +394,10 @@
|
||||
path =/obj/item/ammo_magazine/clip/c762
|
||||
hidden = 1
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_clip_762_hunter
|
||||
name = "ammo clip (7.62mm hunting)"
|
||||
path =/obj/item/ammo_magazine/clip/c762/hunter
|
||||
|
||||
/datum/category_item/autolathe/arms/rifle_clip_762_practice
|
||||
name = "ammo clip (7.62mm practice)"
|
||||
path =/obj/item/ammo_magazine/clip/c762/practice
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
belt = /obj/item/weapon/storage/belt/utility/full
|
||||
l_ear = /obj/item/device/radio/headset/headset_eng
|
||||
shoes = /obj/item/clothing/shoes/boots/workboots
|
||||
r_pocket = /obj/item/device/t_scanner
|
||||
backpack = /obj/item/weapon/storage/backpack/industrial
|
||||
satchel_one = /obj/item/weapon/storage/backpack/satchel/eng
|
||||
messenger_bag = /obj/item/weapon/storage/backpack/messenger/engi
|
||||
@@ -22,7 +23,6 @@
|
||||
name = OUTFIT_JOB_NAME("Engineer")
|
||||
head = /obj/item/clothing/head/hardhat
|
||||
uniform = /obj/item/clothing/under/rank/engineer
|
||||
r_pocket = /obj/item/device/t_scanner
|
||||
id_type = /obj/item/weapon/card/id/engineering/engineer
|
||||
pda_type = /obj/item/device/pda/engineering
|
||||
|
||||
|
||||
@@ -103,3 +103,4 @@
|
||||
/decl/hierarchy/outfit/job/medical/paramedic/emt
|
||||
name = OUTFIT_JOB_NAME("Emergency Medical Technician")
|
||||
uniform = /obj/item/clothing/under/rank/medical/paramedic
|
||||
suit = /obj/item/clothing/suit/storage/toggle/labcoat/emt
|
||||
|
||||
@@ -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
|
||||
@@ -63,11 +63,13 @@
|
||||
/obj/item/clothing/suit/storage/vest/heavy/merc,
|
||||
/obj/item/clothing/glasses/night,
|
||||
/obj/item/weapon/storage/box/anti_photons,
|
||||
/obj/item/ammo_magazine/clip/c12g/pellet, /obj/item/ammo_magazine/clip/c12g
|
||||
/obj/item/ammo_magazine/clip/c12g/pellet,
|
||||
/obj/item/ammo_magazine/clip/c12g
|
||||
),
|
||||
list( //the doc,
|
||||
/obj/item/weapon/storage/firstaid/combat,
|
||||
/obj/item/weapon/gun/projectile/dartgun, /obj/item/weapon/reagent_containers/hypospray,
|
||||
/obj/item/weapon/gun/projectile/dartgun,
|
||||
/obj/item/weapon/reagent_containers/hypospray,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/cyanide,
|
||||
/obj/item/ammo_magazine/chemdart
|
||||
@@ -78,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,
|
||||
|
||||
@@ -21,6 +21,48 @@
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "Superconducting Magnetic Coil crate"
|
||||
|
||||
/datum/supply_packs/eng/shield_capacitor
|
||||
name = "Shield Capacitor"
|
||||
contains = list(/obj/machinery/shield_capacitor)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "shield capacitor crate"
|
||||
|
||||
/datum/supply_packs/eng/shield_capacitor/advanced
|
||||
name = "Advanced Shield Capacitor"
|
||||
contains = list(/obj/machinery/shield_capacitor/advanced)
|
||||
cost = 30
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "advanced shield capacitor crate"
|
||||
|
||||
/datum/supply_packs/eng/bubble_shield
|
||||
name = "Bubble Shield Generator"
|
||||
contains = list(/obj/machinery/shield_gen)
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "shield bubble generator crate"
|
||||
|
||||
/datum/supply_packs/eng/bubble_shield/advanced
|
||||
name = "Advanced Bubble Shield Generator"
|
||||
contains = list(/obj/machinery/shield_gen/advanced)
|
||||
cost = 60
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "advanced bubble shield generator crate"
|
||||
|
||||
/datum/supply_packs/eng/hull_shield
|
||||
name = "Hull Shield Generator"
|
||||
contains = list(/obj/machinery/shield_gen/external)
|
||||
cost = 80
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "shield hull generator crate"
|
||||
|
||||
/datum/supply_packs/eng/hull_shield/advanced
|
||||
name = "Advanced Hull Shield Generator"
|
||||
contains = list(/obj/machinery/shield_gen/external/advanced)
|
||||
cost = 120
|
||||
containertype = /obj/structure/closet/crate/engineering
|
||||
containername = "advanced hull shield generator crate"
|
||||
|
||||
/datum/supply_packs/eng/electrical
|
||||
name = "Electrical maintenance crate"
|
||||
contains = list(
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
/obj/item/weapon/storage/belt/medical,
|
||||
/obj/item/device/radio/headset/heads/cmo,
|
||||
/obj/item/clothing/under/rank/chief_medical_officer,
|
||||
/obj/item/weapon/reagent_containers/hypospray,
|
||||
/obj/item/weapon/reagent_containers/hypospray/vial,
|
||||
/obj/item/clothing/accessory/stethoscope,
|
||||
/obj/item/clothing/glasses/hud/health,
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat/cmo,
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
/obj/item/clothing/shoes/magboots = 2,
|
||||
/obj/item/weapon/tank/oxygen = 2
|
||||
)
|
||||
cost = 50
|
||||
cost = 60
|
||||
containertype = "/obj/structure/closet/crate/secure"
|
||||
containername = "Vey-Med Medical voidsuit crate"
|
||||
access = access_medical_equip
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
name = "Pistol Magazine (.45 AP)"
|
||||
path = /obj/item/ammo_magazine/m45/ap
|
||||
|
||||
/datum/uplink_item/item/ammo/s45m
|
||||
name = "Speedloader (.45)"
|
||||
path = /obj/item/ammo_magazine/s45
|
||||
|
||||
/datum/uplink_item/item/ammo/s45map
|
||||
name = "Speedloader (.45 AP)"
|
||||
path = /obj/item/ammo_magazine/s45/ap
|
||||
|
||||
/datum/uplink_item/item/ammo/tommymag
|
||||
name = "Tommygun Magazine (.45)"
|
||||
path = /obj/item/ammo_magazine/m45tommy
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
/obj/item/weapon/cane
|
||||
name = "cane"
|
||||
desc = "A cane used by a true gentlemen. Or a clown."
|
||||
desc = "A cane used by a true gentleman."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "cane"
|
||||
item_icons = list(
|
||||
@@ -88,7 +88,7 @@
|
||||
flags = CONDUCT
|
||||
force = 5.0
|
||||
throwforce = 7.0
|
||||
w_class = ITEMSIZE_SMALL
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50)
|
||||
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
|
||||
/obj/item/weapon/SWF_uplink
|
||||
name = "station-bounced radio"
|
||||
desc = "used to comunicate it appears."
|
||||
desc = "Used to communicate, it appears."
|
||||
icon = 'icons/obj/radio.dmi'
|
||||
icon_state = "radio"
|
||||
var/temp = null
|
||||
@@ -607,7 +607,7 @@
|
||||
|
||||
/obj/item/weapon/ectoplasm
|
||||
name = "ectoplasm"
|
||||
desc = "spooky"
|
||||
desc = "Spooky!"
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "ectoplasm"
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -13,5 +13,5 @@ var/datum/antagonist/thug/thugs
|
||||
Try to make sure other players have <i>fun</i>! If you are confused or at a loss, always adminhelp, \
|
||||
and before taking extreme actions, please try to also contact the administration! \
|
||||
Think through your actions and make the roleplay immersive! <b>Please remember all \
|
||||
rules aside from those without explicit exceptions apply to antagonists.</b>"
|
||||
rules aside from those with explicit exceptions apply to antagonists.</b>"
|
||||
flags = ANTAG_SUSPICIOUS | ANTAG_IMPLANT_IMMUNE | ANTAG_RANDSPAWN | ANTAG_VOTABLE
|
||||
@@ -1,6 +1,6 @@
|
||||
/atom/movable
|
||||
layer = 3
|
||||
appearance_flags = TILE_BOUND
|
||||
appearance_flags = TILE_BOUND|PIXEL_SCALE
|
||||
var/last_move = null
|
||||
var/anchored = 0
|
||||
// var/elevation = 2 - not used anywhere
|
||||
@@ -15,6 +15,7 @@
|
||||
var/moved_recently = 0
|
||||
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
|
||||
@@ -297,3 +298,12 @@
|
||||
return null
|
||||
return text2num(pickweight(candidates))
|
||||
|
||||
/atom/movable/proc/update_transform()
|
||||
var/matrix/M = matrix()
|
||||
M.Scale(icon_scale)
|
||||
src.transform = M
|
||||
|
||||
// Use this to set the object's scale.
|
||||
/atom/movable/proc/adjust_scale(new_scale)
|
||||
icon_scale = new_scale
|
||||
update_transform()
|
||||
|
||||
@@ -4,6 +4,7 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
var/list/datum/absorbed_dna/absorbed_dna = list()
|
||||
var/list/absorbed_languages = list() // Necessary because of set_species stuff
|
||||
var/absorbedcount = 0
|
||||
var/lingabsorbedcount = 1 //Starts at one, because that's us
|
||||
var/chem_charges = 20
|
||||
var/chem_recharge_rate = 0.5
|
||||
var/chem_storage = 50
|
||||
@@ -11,8 +12,8 @@ var/global/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","E
|
||||
var/changelingID = "Changeling"
|
||||
var/geneticdamage = 0
|
||||
var/isabsorbing = 0
|
||||
var/geneticpoints = 5
|
||||
var/max_geneticpoints = 5
|
||||
var/geneticpoints = 7
|
||||
var/max_geneticpoints = 7
|
||||
var/readapts = 1
|
||||
var/max_readapts = 2
|
||||
var/list/purchased_powers = list()
|
||||
@@ -22,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)
|
||||
..()
|
||||
@@ -219,7 +221,11 @@ turf/proc/AdjacentTurfsRangedSting()
|
||||
victims += C
|
||||
var/mob/living/carbon/T = input(src, "Who will we sting?") as null|anything in victims
|
||||
|
||||
if(!T) return
|
||||
if(!T)
|
||||
return
|
||||
if(T.isSynthetic())
|
||||
src << "<span class='notice'>We are unable to pierce the outer shell of [T].</span>"
|
||||
return
|
||||
if(!(T in view(changeling.sting_range))) return
|
||||
if(!sting_can_reach(T, changeling.sting_range)) return
|
||||
if(!changeling_power(required_chems)) return
|
||||
|
||||
@@ -90,16 +90,23 @@
|
||||
continue
|
||||
absorbDNA(dna_data)
|
||||
changeling.absorbedcount++
|
||||
|
||||
T.mind.changeling.absorbed_dna.len = 1
|
||||
|
||||
changeling.geneticpoints += 5
|
||||
changeling.max_geneticpoints += 5
|
||||
// This is where lings get boosts from eating eachother
|
||||
if(T.mind.changeling.lingabsorbedcount)
|
||||
for(var/a = 1 to T.mind.changeling.lingabsorbedcount)
|
||||
changeling.lingabsorbedcount++
|
||||
changeling.geneticpoints += 4
|
||||
changeling.max_geneticpoints += 4
|
||||
|
||||
src << "<span class='notice'>We absorbed another changeling, and we grow stronger. Our genomes increase.</span>"
|
||||
|
||||
T.mind.changeling.chem_charges = 0
|
||||
T.mind.changeling.geneticpoints = -1
|
||||
T.mind.changeling.max_geneticpoints = -1 //To prevent revival.
|
||||
T.mind.changeling.absorbedcount = 0
|
||||
T.mind.changeling.lingabsorbedcount = 0
|
||||
|
||||
changeling.absorbedcount++
|
||||
changeling.isabsorbing = 0
|
||||
|
||||
@@ -135,3 +135,4 @@
|
||||
name = "hand greatclaw"
|
||||
force = 20
|
||||
armor_penetration = 20
|
||||
pry = 1
|
||||
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
|
||||
@@ -123,7 +123,7 @@ var/global/list/rnwords = list("ire","ego","nahlizet","certum","veri","jatkaa","
|
||||
if(word1 == cultwords["hell"] && word2 == cultwords["join"] && word3 == cultwords["self"])
|
||||
return tearreality()
|
||||
if(word1 == cultwords["destroy"] && word2 == cultwords["see"] && word3 == cultwords["technology"])
|
||||
return emp(src.loc,3)
|
||||
return emp(src.loc,5)
|
||||
if(word1 == cultwords["travel"] && word2 == cultwords["blood"] && word3 == cultwords["self"])
|
||||
return drain()
|
||||
if(word1 == cultwords["see"] && word2 == cultwords["hell"] && word3 == cultwords["join"])
|
||||
|
||||
@@ -43,10 +43,13 @@ var/global/datum/controller/gameticker/ticker
|
||||
'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)
|
||||
@@ -76,7 +79,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)
|
||||
@@ -91,7 +94,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()
|
||||
@@ -100,7 +103,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()
|
||||
@@ -116,13 +119,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()
|
||||
@@ -139,7 +142,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()
|
||||
@@ -152,7 +155,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()
|
||||
@@ -304,7 +307,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()
|
||||
@@ -340,7 +343,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)
|
||||
@@ -353,15 +356,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
|
||||
@@ -371,7 +374,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()
|
||||
|
||||
@@ -385,7 +388,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))
|
||||
@@ -426,9 +429,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)
|
||||
|
||||
@@ -7,8 +7,8 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
|
||||
/datum/game_mode/heist
|
||||
name = "Heist"
|
||||
config_tag = "heist"
|
||||
required_players = 9
|
||||
required_players_secret = 9
|
||||
required_players = 12
|
||||
required_players_secret = 12
|
||||
required_enemies = 3
|
||||
round_description = "An unidentified bluespace signature is approaching the station!"
|
||||
extended_round_description = "The Company's majority control of phoron in the system has marked the \
|
||||
|
||||
@@ -12,8 +12,8 @@ var/list/nuke_disks = list()
|
||||
colony of sizable population and considerable wealth causes it to often be the target of various \
|
||||
attempts of robbery, fraud and other malicious actions."
|
||||
config_tag = "mercenary"
|
||||
required_players = 9
|
||||
required_players_secret = 9
|
||||
required_players = 12
|
||||
required_players_secret = 12
|
||||
required_enemies = 3
|
||||
end_on_antag_death = 0
|
||||
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
|
||||
|
||||
@@ -440,7 +440,7 @@ datum/objective/steal
|
||||
"a chief medical officer's jumpsuit" = /obj/item/clothing/under/rank/chief_medical_officer,
|
||||
"a head of security's jumpsuit" = /obj/item/clothing/under/rank/head_of_security,
|
||||
"a head of personnel's jumpsuit" = /obj/item/clothing/under/rank/head_of_personnel,
|
||||
"the hypospray" = /obj/item/weapon/reagent_containers/hypospray,
|
||||
"the hypospray" = /obj/item/weapon/reagent_containers/hypospray/vial,
|
||||
"the colony director's pinpointer" = /obj/item/weapon/pinpointer,
|
||||
"an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof,
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -74,7 +74,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
|
||||
|
||||
@@ -55,31 +55,31 @@
|
||||
|
||||
if(shocked)
|
||||
shock(user, 50)
|
||||
|
||||
var/dat = "<center><h1>Autolathe Control Panel</h1><hr/>"
|
||||
var/list/dat = list()
|
||||
dat += "<center><h1>Autolathe Control Panel</h1><hr/>"
|
||||
|
||||
if(!disabled)
|
||||
dat += "<table width = '100%'>"
|
||||
var/material_top = "<tr>"
|
||||
var/material_bottom = "<tr>"
|
||||
var/list/material_top = list("<tr>")
|
||||
var/list/material_bottom = list("<tr>")
|
||||
|
||||
for(var/material in stored_material)
|
||||
material_top += "<td width = '25%' align = center><b>[material]</b></td>"
|
||||
material_bottom += "<td width = '25%' align = center>[stored_material[material]]<b>/[storage_capacity[material]]</b></td>"
|
||||
|
||||
dat += "[material_top]</tr>[material_bottom]</tr></table><hr>"
|
||||
dat += "[material_top.Join()]</tr>[material_bottom.Join()]</tr></table><hr>"
|
||||
dat += "<h2>Printable Designs</h2><h3>Showing: <a href='?src=\ref[src];change_category=1'>[current_category]</a>.</h3></center><table width = '100%'>"
|
||||
|
||||
for(var/datum/category_item/autolathe/R in current_category.items)
|
||||
if(R.hidden && !hacked)
|
||||
continue
|
||||
var/can_make = 1
|
||||
var/material_string = ""
|
||||
var/multiplier_string = ""
|
||||
var/list/material_string = list()
|
||||
var/list/multiplier_string = list()
|
||||
var/max_sheets
|
||||
var/comma
|
||||
if(!R.resources || !R.resources.len)
|
||||
material_string = "No resources required.</td>"
|
||||
material_string += "No resources required.</td>"
|
||||
else
|
||||
//Make sure it's buildable and list requires resources.
|
||||
for(var/material in R.resources)
|
||||
@@ -103,7 +103,7 @@
|
||||
multiplier_string += "<a href='?src=\ref[src];make=\ref[R];multiplier=[i]'>\[x[i]\]</a>"
|
||||
multiplier_string += "<a href='?src=\ref[src];make=\ref[R];multiplier=[max_sheets]'>\[x[max_sheets]\]</a>"
|
||||
|
||||
dat += "<tr><td width = 180>[R.hidden ? "<font color = 'red'>*</font>" : ""]<b>[can_make ? "<a href='?src=\ref[src];make=\ref[R];multiplier=1'>" : ""][R.name][can_make ? "</a>" : ""]</b>[R.hidden ? "<font color = 'red'>*</font>" : ""][multiplier_string]</td><td align = right>[material_string]</tr>"
|
||||
dat += "<tr><td width = 180>[R.hidden ? "<font color = 'red'>*</font>" : ""]<b>[can_make ? "<a href='?src=\ref[src];make=\ref[R];multiplier=1'>" : ""][R.name][can_make ? "</a>" : ""]</b>[R.hidden ? "<font color = 'red'>*</font>" : ""][multiplier_string.Join()]</td><td align = right>[material_string.Join()]</tr>"
|
||||
|
||||
dat += "</table><hr>"
|
||||
//Hacking.
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
dat += "<hr>"
|
||||
|
||||
user << browse(dat, "window=autolathe")
|
||||
user << browse(dat.Join(), "window=autolathe")
|
||||
onclose(user, "autolathe")
|
||||
|
||||
/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
|
||||
@@ -130,7 +130,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 +210,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -127,6 +127,36 @@
|
||||
icon = 'icons/obj/doors/Doormaint.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/door_assembly_mai
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/cargo
|
||||
icon = 'icons/obj/doors/Doormaint_cargo.dmi'
|
||||
req_one_access = list(access_cargo)
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/command
|
||||
icon = 'icons/obj/doors/Doormaint_command.dmi'
|
||||
req_one_access = list(access_heads)
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/common
|
||||
icon = 'icons/obj/doors/Doormaint_common.dmi'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/engi
|
||||
icon = 'icons/obj/doors/Doormaint_engi.dmi'
|
||||
req_one_access = list(access_engine)
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/int
|
||||
icon = 'icons/obj/doors/Doormaint_int.dmi'
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/medical
|
||||
icon = 'icons/obj/doors/Doormaint_med.dmi'
|
||||
req_one_access = list(access_medical)
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/rnd
|
||||
icon = 'icons/obj/doors/Doormaint_rnd.dmi'
|
||||
req_one_access = list(access_research)
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/sec
|
||||
icon = 'icons/obj/doors/Doormaint_sec.dmi'
|
||||
req_one_access = list(access_security)
|
||||
|
||||
/obj/machinery/door/airlock/external
|
||||
name = "External Airlock"
|
||||
icon = 'icons/obj/doors/Doorext.dmi'
|
||||
@@ -386,6 +416,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.
|
||||
|
||||
@@ -260,7 +260,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)
|
||||
|
||||
@@ -2,15 +2,44 @@
|
||||
/obj/machinery/door/airlock/multi_tile
|
||||
width = 2
|
||||
appearance_flags = 0
|
||||
var/obj/machinery/filler_object/filler1
|
||||
var/obj/machinery/filler_object/filler2
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/New()
|
||||
..()
|
||||
SetBounds()
|
||||
if(opacity)
|
||||
create_fillers()
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/Destroy()
|
||||
qdel_null(filler1)
|
||||
qdel_null(filler2)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/Move()
|
||||
. = ..()
|
||||
SetBounds()
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/open()
|
||||
. = ..()
|
||||
|
||||
if(filler1)
|
||||
filler1.set_opacity(opacity)
|
||||
if(filler2)
|
||||
filler2.set_opacity(opacity)
|
||||
|
||||
return .
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/close()
|
||||
. = ..()
|
||||
|
||||
if(filler1)
|
||||
filler1.set_opacity(opacity)
|
||||
if(filler2)
|
||||
filler2.set_opacity(opacity)
|
||||
|
||||
return .
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/proc/SetBounds()
|
||||
if(dir in list(EAST, WEST))
|
||||
bound_width = width * world.icon_size
|
||||
@@ -19,9 +48,35 @@
|
||||
bound_width = world.icon_size
|
||||
bound_height = width * world.icon_size
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/proc/create_fillers()
|
||||
if(src.dir > 3)
|
||||
filler1 = new/obj/machinery/filler_object (src.loc)
|
||||
filler2 = new/obj/machinery/filler_object (get_step(src,EAST))
|
||||
else
|
||||
filler1 = new/obj/machinery/filler_object (src.loc)
|
||||
filler2 = new/obj/machinery/filler_object (get_step(src,NORTH))
|
||||
filler1.density = 0
|
||||
filler2.density = 0
|
||||
filler1.set_opacity(opacity)
|
||||
filler2.set_opacity(opacity)
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/glass
|
||||
name = "Glass Airlock"
|
||||
icon = 'icons/obj/doors/Door2x1glass.dmi'
|
||||
opacity = 0
|
||||
glass = 1
|
||||
assembly_type = /obj/structure/door_assembly/multi_tile
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/metal
|
||||
name = "Airlock"
|
||||
icon = 'icons/obj/doors/Door2x1metal.dmi'
|
||||
assembly_type = /obj/structure/door_assembly/multi_tile
|
||||
|
||||
/obj/machinery/filler_object
|
||||
name = ""
|
||||
icon = 'icons/obj/doors/rapid_pdoor.dmi'
|
||||
icon_state = ""
|
||||
density = 0
|
||||
|
||||
/obj/machinery/door/airlock/multi_tile/metal/mait
|
||||
icon = 'icons/obj/doors/Door2x1_Maint.dmi'
|
||||
|
||||
@@ -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)
|
||||
@@ -289,3 +295,27 @@
|
||||
if(!usr.incapacitated())
|
||||
return
|
||||
go_in(usr)
|
||||
|
||||
/obj/machinery/recharge_station/ghost_pod_recharger
|
||||
name = "drone pod"
|
||||
desc = "This is a pod which used to contain a drone... Or maybe it still does?"
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
|
||||
/obj/machinery/recharge_station/ghost_pod_recharger/update_icon()
|
||||
..()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "borg_pod_closed"
|
||||
desc = "It appears broken..."
|
||||
return
|
||||
|
||||
if(occupant)
|
||||
if((stat & NOPOWER) && !has_cell_power())
|
||||
icon_state = "borg_pod_closed"
|
||||
desc = "It appears to be unpowered..."
|
||||
else
|
||||
icon_state = "borg_pod_closed"
|
||||
else
|
||||
icon_state = "borg_pod_opened"
|
||||
|
||||
if(icon_update_tick == 0)
|
||||
build_overlays()
|
||||
@@ -640,7 +640,7 @@
|
||||
name = "Nonstandard suit cycler"
|
||||
model_text = "Nonstandard"
|
||||
req_access = list(access_syndicate)
|
||||
departments = list("Mercenary")
|
||||
departments = list("Mercenary", "Charring")
|
||||
can_repair = 1
|
||||
|
||||
/obj/machinery/suit_cycler/attack_ai(mob/user as mob)
|
||||
@@ -752,7 +752,7 @@
|
||||
|
||||
//Clear the access reqs, disable the safeties, and open up all paintjobs.
|
||||
user << "<span class='danger'>You run the sequencer across the interface, corrupting the operating protocols.</span>"
|
||||
departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Crowd Control","Emergency Medical Response","^%###^%$")
|
||||
departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","Crowd Control","Emergency Medical Response","^%###^%$", "Charring")
|
||||
species = list("Human","Tajara","Skrell","Unathi", "Teshari")
|
||||
|
||||
emagged = 1
|
||||
@@ -1073,6 +1073,15 @@
|
||||
suit.name = "blood-red voidsuit"
|
||||
suit.item_state = "syndie_voidsuit"
|
||||
suit.icon_state = "rig-syndie"
|
||||
if("Charring")
|
||||
if(helmet)
|
||||
helmet.name = "soot-covered voidsuit helmet"
|
||||
helmet.icon_state = "rig0-firebug"
|
||||
helmet.item_state = "rig0-firebug"
|
||||
if(suit)
|
||||
suit.name = "soot-covered voidsuit"
|
||||
suit.item_state = "rig-firebug"
|
||||
suit.icon_state = "rig-firebug"
|
||||
|
||||
if(helmet) helmet.name = "refitted [helmet.name]"
|
||||
if(suit) suit.name = "refitted [suit.name]"
|
||||
|
||||
@@ -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)
|
||||
|
||||
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
|
||||
@@ -806,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."
|
||||
@@ -821,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!"
|
||||
@@ -865,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!"
|
||||
@@ -1051,7 +1051,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."
|
||||
@@ -1070,7 +1069,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."
|
||||
|
||||
226
code/game/machinery/vr_console.dm
Normal file
226
code/game/machinery/vr_console.dm
Normal file
@@ -0,0 +1,226 @@
|
||||
/obj/machinery/vr_sleeper
|
||||
name = "VR 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"
|
||||
density = 1
|
||||
anchored = 1
|
||||
circuit = /obj/item/weapon/circuitboard/vr_sleeper
|
||||
var/mob/living/carbon/human/occupant = null
|
||||
var/mob/living/carbon/human/avatar = null
|
||||
var/datum/mind/vr_mind = null
|
||||
|
||||
use_power = 1
|
||||
idle_power_usage = 15
|
||||
active_power_usage = 200
|
||||
light_color = "#FF0000"
|
||||
|
||||
/obj/machinery/vr_sleeper/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
|
||||
|
||||
RefreshParts()
|
||||
|
||||
/obj/machinery/vr_sleeper/initialize()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
/obj/machinery/vr_sleeper/update_icon()
|
||||
icon_state = "syndipod_[occupant ? "1" : "0"]"
|
||||
|
||||
/obj/machinery/vr_sleeper/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(usr == occupant)
|
||||
to_chat(usr, "<span class='warning'>You can't reach the controls from the inside.</span>")
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["eject"])
|
||||
go_out()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/vr_sleeper/attackby(var/obj/item/I, var/mob/user)
|
||||
add_fingerprint(user)
|
||||
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
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/MouseDrop_T(var/mob/target, var/mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user)|| !isliving(target))
|
||||
return
|
||||
go_in(target, user)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/sleeper/relaymove(var/mob/user)
|
||||
..()
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
go_out()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/vr_sleeper/emp_act(var/severity)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
|
||||
if(occupant)
|
||||
// This will eject the user from VR
|
||||
// ### Fry the brain?
|
||||
go_out()
|
||||
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/vr_sleeper/verb/eject()
|
||||
set src in oview(1)
|
||||
set category = "Object"
|
||||
set name = "Eject VR Capsule"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
if(usr != occupant && avatar && alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
// The player in VR is fine with leaving, kick them out and reset avatar
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
go_out()
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/verb/climb_in()
|
||||
set src in oview(1)
|
||||
set category = "Object"
|
||||
set name = "Enter VR Capsule"
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
go_in(usr, usr)
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/machinery/vr_sleeper/relaymove(mob/user as mob)
|
||||
if(user.incapacitated())
|
||||
return 0 //maybe they should be able to get out with cuffs, but whatever
|
||||
go_out()
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/go_in(var/mob/M, var/mob/user)
|
||||
if(!M)
|
||||
return
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(!ishuman(M))
|
||||
user << "<span class='warning'>\The [src] rejects [M] with a sharp beep.</span>"
|
||||
if(occupant)
|
||||
user << "<span class='warning'>\The [src] is already occupied.</span>"
|
||||
return
|
||||
|
||||
if(M == user)
|
||||
visible_message("\The [user] starts climbing into \the [src].")
|
||||
else
|
||||
visible_message("\The [user] starts putting [M] into \the [src].")
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(occupant)
|
||||
to_chat(user, "<span class='warning'>\The [src] is already occupied.</span>")
|
||||
return
|
||||
M.stop_pulling()
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.loc = src
|
||||
update_use_power(2)
|
||||
occupant = M
|
||||
|
||||
update_icon()
|
||||
|
||||
enter_vr()
|
||||
return
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/go_out()
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
if(occupant.client)
|
||||
occupant.client.eye = occupant.client.mob
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
occupant.loc = src.loc
|
||||
occupant = null
|
||||
for(var/atom/movable/A in src) // In case an object was dropped inside or something
|
||||
if(A == circuit)
|
||||
continue
|
||||
if(A in component_parts)
|
||||
continue
|
||||
A.loc = src.loc
|
||||
update_use_power(1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/vr_sleeper/proc/enter_vr()
|
||||
|
||||
// No mob to transfer a mind from
|
||||
if(!occupant)
|
||||
return
|
||||
|
||||
// No mind to transfer
|
||||
if(!occupant.mind)
|
||||
return
|
||||
|
||||
// Mob doesn't have an active consciousness to send/receive from
|
||||
if(occupant.stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
avatar = occupant.vr_link
|
||||
// If they've already enterred VR, and are reconnecting, prompt if they want a new body
|
||||
if(avatar && alert(occupant, "You already have a Virtual Reality avatar. Would you like to use it?", "New avatar", "Yes", "No") == "No")
|
||||
// Delink the mob
|
||||
occupant.vr_link = null
|
||||
avatar = null
|
||||
|
||||
if(!avatar)
|
||||
// Get the desired spawn location to put the body
|
||||
var/S = null
|
||||
var/list/vr_landmarks = list()
|
||||
for(var/obj/effect/landmark/virtual_reality/sloc in landmarks_list)
|
||||
vr_landmarks += sloc.name
|
||||
|
||||
S = input(occupant, "Please select a location to spawn your avatar at:", "Spawn location") as null|anything in vr_landmarks
|
||||
if(!S)
|
||||
return 0
|
||||
|
||||
for(var/obj/effect/landmark/virtual_reality/i in landmarks_list)
|
||||
if(i.name == S)
|
||||
S = i
|
||||
break
|
||||
|
||||
avatar = new(S, "Virtual Reality Avatar")
|
||||
// If the user has a non-default (Human) bodyshape, make it match theirs.
|
||||
if(occupant.species.name != "Promethean" && occupant.species.name != "Human")
|
||||
avatar.shapeshifter_change_shape(occupant.species.name)
|
||||
avatar.forceMove(get_turf(S)) // Put the mob on the landmark, instead of inside it
|
||||
avatar.Sleeping(1)
|
||||
|
||||
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)
|
||||
if (newname)
|
||||
avatar.real_name = newname
|
||||
|
||||
else
|
||||
occupant.enter_vr(avatar)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -107,6 +107,18 @@
|
||||
|
||||
return 1
|
||||
|
||||
/obj/effect/landmark/virtual_reality
|
||||
name = "virtual_reality"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "x"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effect/landmark/virtual_reality/New()
|
||||
..()
|
||||
tag = "virtual_reality*[name]"
|
||||
invisibility = 101
|
||||
return 1
|
||||
|
||||
//Costume spawner landmarks
|
||||
/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears
|
||||
|
||||
|
||||
@@ -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>")
|
||||
@@ -210,25 +210,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
|
||||
@@ -249,6 +232,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."
|
||||
@@ -261,7 +265,7 @@
|
||||
icon_state = "cocoon1"
|
||||
health = 60
|
||||
|
||||
New()
|
||||
/obj/effect/spider/cocoon/New()
|
||||
icon_state = pick("cocoon1","cocoon2","cocoon3")
|
||||
|
||||
/obj/effect/spider/cocoon/Destroy()
|
||||
|
||||
@@ -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/addblends // Icon overlay for ADD highlights when applicable.
|
||||
|
||||
/obj/item/New()
|
||||
..()
|
||||
@@ -456,7 +458,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)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
//..() //Doesn't need to run the parent. Since when can fucking bodybags be welded shut? -Agouri
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/wirecutters))
|
||||
user << "You cut the tag off the bodybag"
|
||||
to_chat(user, "You cut the tag off the bodybag")
|
||||
src.name = "body bag"
|
||||
src.overlays.Cut()
|
||||
return
|
||||
@@ -160,7 +160,7 @@
|
||||
O.name = "used stasis bag"
|
||||
O.icon = src.icon
|
||||
O.icon_state = "bodybag_used"
|
||||
O.desc = "Pretty useless now.."
|
||||
O.desc = "Pretty useless now..."
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/body_bag/cryobag/MouseDrop(over_object, src_location, over_location)
|
||||
@@ -211,9 +211,9 @@
|
||||
/obj/structure/closet/body_bag/cryobag/examine(mob/user)
|
||||
..()
|
||||
if(Adjacent(user)) //The bag's rather thick and opaque from a distance.
|
||||
user << "<span class='info'>You peer into \the [src].</span>"
|
||||
to_chat(user, "<span class='info'>You peer into \the [src].</span>")
|
||||
if(syringe)
|
||||
user << "<span class='info'>It has a syringe added to it.</span>"
|
||||
to_chat(user, "<span class='info'>It has a syringe added to it.</span>")
|
||||
for(var/mob/living/L in contents)
|
||||
L.examine(user)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
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
|
||||
@@ -75,9 +75,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
|
||||
|
||||
@@ -147,7 +144,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define RAD_LEVEL_LOW 5 //10 // Around the level at which radiation starts to become harmful
|
||||
#define RAD_LEVEL_MODERATE 15 //15
|
||||
#define RAD_LEVEL_HIGH 50 //50
|
||||
#define RAD_LEVEL_VERY_HIGH 100 //100
|
||||
#define RAD_LEVEL_LOW 0.01 // Around the level at which radiation starts to become harmful
|
||||
#define RAD_LEVEL_MODERATE 10
|
||||
#define RAD_LEVEL_HIGH 25
|
||||
#define RAD_LEVEL_VERY_HIGH 50
|
||||
|
||||
//Geiger counter
|
||||
//Rewritten version of TG's geiger counter
|
||||
@@ -19,7 +19,14 @@
|
||||
/obj/item/device/geiger/New()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/device/geiger/Destroy()
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/device/geiger/process()
|
||||
get_radiation()
|
||||
|
||||
/obj/item/device/geiger/proc/get_radiation()
|
||||
if(!scanning)
|
||||
return
|
||||
radiation_count = radiation_repository.get_rads_at_turf(get_turf(src))
|
||||
@@ -27,12 +34,29 @@
|
||||
|
||||
/obj/item/device/geiger/examine(mob/user)
|
||||
..(user)
|
||||
to_chat(user, "<span class='warning'>[scanning ? "ambient" : "stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq.</span>")
|
||||
get_radiation()
|
||||
to_chat(user, "<span class='warning'>[scanning ? "Ambient" : "Stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq.</span>")
|
||||
|
||||
/obj/item/device/geiger/rad_act(amount)
|
||||
if(!amount || !scanning)
|
||||
return FALSE
|
||||
|
||||
if(amount > radiation_count)
|
||||
radiation_count = amount
|
||||
|
||||
var/sound = "geiger"
|
||||
if(amount < 5)
|
||||
sound = "geiger_weak"
|
||||
playsound(src, sound, between(10, 10 + (radiation_count * 4), 100), 0)
|
||||
if(sound == "geiger_weak") // A weak geiger sound every two seconds sounds too infrequent.
|
||||
spawn(1 SECOND)
|
||||
playsound(src, sound, between(10, 10 + (radiation_count * 4), 100), 0)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/geiger/attack_self(var/mob/user)
|
||||
scanning = !scanning
|
||||
update_icon()
|
||||
to_chat(user, "<span class='notice'>\icon[src] You switch [scanning ? "on" : "off"] [src].</span>")
|
||||
to_chat(user, "<span class='notice'>\icon[src] You switch [scanning ? "on" : "off"] \the [src].</span>")
|
||||
|
||||
/obj/item/device/geiger/update_icon()
|
||||
if(!scanning)
|
||||
@@ -40,12 +64,18 @@
|
||||
return 1
|
||||
|
||||
switch(radiation_count)
|
||||
if(null) icon_state = "geiger_on_1"
|
||||
if(-INFINITY to RAD_LEVEL_LOW) icon_state = "geiger_on_1"
|
||||
if(RAD_LEVEL_LOW + 1 to RAD_LEVEL_MODERATE) icon_state = "geiger_on_2"
|
||||
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) icon_state = "geiger_on_3"
|
||||
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) icon_state = "geiger_on_4"
|
||||
if(RAD_LEVEL_VERY_HIGH + 1 to INFINITY) icon_state = "geiger_on_5"
|
||||
if(null)
|
||||
icon_state = "geiger_on_1"
|
||||
if(-INFINITY to RAD_LEVEL_LOW)
|
||||
icon_state = "geiger_on_1"
|
||||
if(RAD_LEVEL_LOW to RAD_LEVEL_MODERATE)
|
||||
icon_state = "geiger_on_2"
|
||||
if(RAD_LEVEL_MODERATE to RAD_LEVEL_HIGH)
|
||||
icon_state = "geiger_on_3"
|
||||
if(RAD_LEVEL_HIGH to RAD_LEVEL_VERY_HIGH)
|
||||
icon_state = "geiger_on_4"
|
||||
if(RAD_LEVEL_VERY_HIGH to INFINITY)
|
||||
icon_state = "geiger_on_5"
|
||||
|
||||
#undef RAD_LEVEL_LOW
|
||||
#undef RAD_LEVEL_MODERATE
|
||||
|
||||
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_MATERIALS = 2, TECH_BLUESPACE = 2, TECH_MAGNETS = 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_MATERIALS = 2, TECH_BLUESPACE = 3, TECH_MAGNETS = 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)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/spamcheck = 0
|
||||
var/emagged = 0
|
||||
var/insults = 0
|
||||
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TATER!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!")
|
||||
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TERRORIST!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "GLORY TO ALMACH!")
|
||||
|
||||
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
|
||||
if (user.client)
|
||||
|
||||
19
code/game/objects/items/gunbox.dm
Normal file
19
code/game/objects/items/gunbox.dm
Normal file
@@ -0,0 +1,19 @@
|
||||
/obj/item/gunbox
|
||||
name = "detective's gun box"
|
||||
desc = "A secure box containing a Detective's sidearm."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "gunbox"
|
||||
w_class = ITEMSIZE_HUGE
|
||||
|
||||
/obj/item/gunbox/attack_self(mob/living/user)
|
||||
var/list/options = list()
|
||||
options[".45 Pistol"] = list(/obj/item/weapon/gun/projectile/colt/detective, /obj/item/ammo_magazine/m45/rubber, /obj/item/ammo_magazine/m45/rubber)
|
||||
options[".45 Revolver"] = list(/obj/item/weapon/gun/projectile/revolver/detective45, /obj/item/ammo_magazine/s45/rubber, /obj/item/ammo_magazine/s45/rubber)
|
||||
var/choice = input(user,"Would you prefer a pistol or a revolver?") as null|anything in options
|
||||
if(src && choice)
|
||||
var/list/things_to_spawn = options[choice]
|
||||
for(var/new_type in things_to_spawn) // Spawn all the things, the gun and the ammo.
|
||||
var/atom/movable/AM = new new_type(get_turf(src))
|
||||
if(istype(AM, /obj/item/weapon/gun))
|
||||
to_chat(user, "You have chosen \the [AM]. Say hello to your new friend.")
|
||||
qdel(src)
|
||||
@@ -173,3 +173,23 @@
|
||||
|
||||
R.emag_items = 1
|
||||
return 1
|
||||
|
||||
/obj/item/borg/upgrade/language
|
||||
name = "language module"
|
||||
desc = "Used to let cyborgs other than clerical or service speak a variety of languages."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
item_state = "cyborg_upgrade"
|
||||
|
||||
/obj/item/borg/upgrade/language/action(var/mob/living/silicon/robot/R)
|
||||
if(..()) return 0
|
||||
|
||||
R.add_language(LANGUAGE_SOL_COMMON, 1)
|
||||
R.add_language(LANGUAGE_TRADEBAND, 1)
|
||||
R.add_language(LANGUAGE_UNATHI, 1)
|
||||
R.add_language(LANGUAGE_SIIK, 1)
|
||||
R.add_language(LANGUAGE_SKRELLIAN, 1)
|
||||
R.add_language(LANGUAGE_GUTTER, 1)
|
||||
R.add_language(LANGUAGE_SCHECHI, 1)
|
||||
R.add_language(LANGUAGE_ROOTLOCAL, 1)
|
||||
|
||||
return 1
|
||||
@@ -75,11 +75,11 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(affecting.open)
|
||||
user << "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>"
|
||||
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
|
||||
return
|
||||
|
||||
if(affecting.is_bandaged())
|
||||
user << "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>"
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] starts treating [M]'s [affecting.name].</span>", \
|
||||
@@ -93,9 +93,13 @@
|
||||
if(used == amount)
|
||||
break
|
||||
if(!do_mob(user, M, W.damage/5))
|
||||
user << "<span class='notice'>You must stand still to bandage wounds.</span>"
|
||||
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
|
||||
break
|
||||
|
||||
if(affecting.is_bandaged()) // We do a second check after the delay, in case it was bandaged after the first check.
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
|
||||
return 1
|
||||
|
||||
if (W.current_stage <= W.max_bleeding_stage)
|
||||
user.visible_message("<span class='notice'>\The [user] bandages \a [W.desc] on [M]'s [affecting.name].</span>", \
|
||||
"<span class='notice'>You bandage \a [W.desc] on [M]'s [affecting.name].</span>" )
|
||||
@@ -111,9 +115,9 @@
|
||||
affecting.update_damages()
|
||||
if(used == amount)
|
||||
if(affecting.is_bandaged())
|
||||
user << "<span class='warning'>\The [src] is used up.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
|
||||
else
|
||||
user << "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
|
||||
use(used)
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
@@ -135,17 +139,20 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(affecting.open)
|
||||
user << "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>"
|
||||
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
|
||||
return
|
||||
|
||||
if(affecting.is_salved())
|
||||
user << "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>"
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] starts salving wounds on [M]'s [affecting.name].</span>", \
|
||||
"<span class='notice'>You start salving the wounds on [M]'s [affecting.name].</span>" )
|
||||
if(!do_mob(user, M, 10))
|
||||
user << "<span class='notice'>You must stand still to salve wounds.</span>"
|
||||
to_chat(user, "<span class='notice'>You must stand still to salve wounds.</span>")
|
||||
return 1
|
||||
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
|
||||
return 1
|
||||
user.visible_message("<span class='notice'>[user] salved wounds on [M]'s [affecting.name].</span>", \
|
||||
"<span class='notice'>You salved wounds on [M]'s [affecting.name].</span>" )
|
||||
@@ -169,11 +176,11 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(affecting.open)
|
||||
user << "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>"
|
||||
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
|
||||
return
|
||||
|
||||
if(affecting.is_bandaged() && affecting.is_disinfected())
|
||||
user << "<span class='warning'>The wounds on [M]'s [affecting.name] have already been treated.</span>"
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been treated.</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] starts treating [M]'s [affecting.name].</span>", \
|
||||
@@ -187,8 +194,11 @@
|
||||
if(used == amount)
|
||||
break
|
||||
if(!do_mob(user, M, W.damage/5))
|
||||
user << "<span class='notice'>You must stand still to bandage wounds.</span>"
|
||||
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
|
||||
break
|
||||
if(affecting.is_bandaged() && affecting.is_disinfected()) // We do a second check after the delay, in case it was bandaged after the first check.
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
|
||||
return 1
|
||||
if (W.current_stage <= W.max_bleeding_stage)
|
||||
user.visible_message("<span class='notice'>\The [user] cleans \a [W.desc] on [M]'s [affecting.name] and seals the edges with bioglue.</span>", \
|
||||
"<span class='notice'>You clean and seal \a [W.desc] on [M]'s [affecting.name].</span>" )
|
||||
@@ -205,9 +215,9 @@
|
||||
affecting.update_damages()
|
||||
if(used == amount)
|
||||
if(affecting.is_bandaged())
|
||||
user << "<span class='warning'>\The [src] is used up.</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
|
||||
else
|
||||
user << "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>"
|
||||
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
|
||||
use(used)
|
||||
|
||||
/obj/item/stack/medical/advanced/ointment
|
||||
@@ -228,16 +238,19 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(affecting.open)
|
||||
user << "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>"
|
||||
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
|
||||
|
||||
if(affecting.is_salved())
|
||||
user << "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>"
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
|
||||
return 1
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [user] starts salving wounds on [M]'s [affecting.name].</span>", \
|
||||
"<span class='notice'>You start salving the wounds on [M]'s [affecting.name].</span>" )
|
||||
if(!do_mob(user, M, 10))
|
||||
user << "<span class='notice'>You must stand still to salve wounds.</span>"
|
||||
to_chat(user, "<span class='notice'>You must stand still to salve wounds.</span>")
|
||||
return 1
|
||||
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
|
||||
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
|
||||
return 1
|
||||
user.visible_message( "<span class='notice'>[user] covers wounds on [M]'s [affecting.name] with regenerative membrane.</span>", \
|
||||
"<span class='notice'>You cover wounds on [M]'s [affecting.name] with regenerative membrane.</span>" )
|
||||
@@ -264,20 +277,23 @@
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
var/limb = affecting.name
|
||||
if(!(affecting.organ_tag in splintable_organs))
|
||||
user << "<span class='danger'>You can't use \the [src] to apply a splint there!</span>"
|
||||
to_chat(user, "<span class='danger'>You can't use \the [src] to apply a splint there!</span>")
|
||||
return
|
||||
if(affecting.splinted)
|
||||
user << "<span class='danger'>[M]'s [limb] is already splinted!</span>"
|
||||
to_chat(user, "<span class='danger'>[M]'s [limb] is already splinted!</span>")
|
||||
return
|
||||
if (M != user)
|
||||
user.visible_message("<span class='danger'>[user] starts to apply \the [src] to [M]'s [limb].</span>", "<span class='danger'>You start to apply \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
|
||||
else
|
||||
if(( !user.hand && (affecting.organ_tag in list(BP_R_ARM, BP_R_HAND)) || \
|
||||
user.hand && (affecting.organ_tag in list(BP_L_ARM, BP_L_HAND)) ))
|
||||
user << "<span class='danger'>You can't apply a splint to the arm you're using!</span>"
|
||||
to_chat(user, "<span class='danger'>You can't apply a splint to the arm you're using!</span>")
|
||||
return
|
||||
user.visible_message("<span class='danger'>[user] starts to apply \the [src] to their [limb].</span>", "<span class='danger'>You start to apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
|
||||
if(do_after(user, 50, M))
|
||||
if(affecting.splinted)
|
||||
to_chat(user, "<span class='danger'>[M]'s [limb] is already splinted!</span>")
|
||||
return
|
||||
if(M == user && prob(75))
|
||||
user.visible_message("<span class='danger'>\The [user] fumbles [src].</span>", "<span class='danger'>You fumble [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
|
||||
return
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon_state = "nanopaste"
|
||||
origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3)
|
||||
amount = 10
|
||||
toolspeed = 0.75 //Used in surgery, shouldn't be the same speed as a normal screwdriver on mechanical organ repair.
|
||||
w_class = ITEMSIZE_SMALL
|
||||
no_variants = FALSE
|
||||
|
||||
@@ -15,6 +16,7 @@
|
||||
if (istype(M,/mob/living/silicon/robot)) //Repairing cyborgs
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if (R.getBruteLoss() || R.getFireLoss())
|
||||
if(do_after(user,7 * toolspeed))
|
||||
R.adjustBruteLoss(-15)
|
||||
R.adjustFireLoss(-15)
|
||||
R.updatehealth()
|
||||
@@ -28,13 +30,16 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(S.open >= 2)
|
||||
if (S && (S.robotic >= ORGAN_ROBOT))
|
||||
if(!S.get_damage())
|
||||
user << "<span class='notice'>Nothing to fix here.</span>"
|
||||
else if(can_use(1))
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
S.heal_damage(15, 15, robo_repair = 1)
|
||||
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)
|
||||
else if(do_after(user,5 * toolspeed))
|
||||
S.heal_damage(10,10, robo_repair =1)
|
||||
H.updatehealth()
|
||||
use(1)
|
||||
user.visible_message("<span class='notice'>\The [user] applies some nanite paste on [user != M ? "[M]'s [S.name]" : "[S]"] with [src].</span>",\
|
||||
|
||||
@@ -699,54 +699,6 @@
|
||||
desc = "A \"Space Life\" brand Emergency Response Team Commander action figure."
|
||||
icon_state = "ert"
|
||||
|
||||
/obj/item/toy/therapy_red
|
||||
name = "red therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is red."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyred"
|
||||
item_state = "egg4" // It's the red egg in items_left/righthand
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/toy/therapy_purple
|
||||
name = "purple therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is purple."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapypurple"
|
||||
item_state = "egg1" // It's the magenta egg in items_left/righthand
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/toy/therapy_blue
|
||||
name = "blue therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is blue."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyblue"
|
||||
item_state = "egg2" // It's the blue egg in items_left/righthand
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/toy/therapy_yellow
|
||||
name = "yellow therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is yellow."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyyellow"
|
||||
item_state = "egg5" // It's the yellow egg in items_left/righthand
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/toy/therapy_orange
|
||||
name = "orange therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is orange."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyorange"
|
||||
item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/toy/therapy_green
|
||||
name = "green therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is green."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapygreen"
|
||||
item_state = "egg3" // It's the green egg in items_left/righthand
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/*
|
||||
* Plushies
|
||||
*/
|
||||
@@ -800,9 +752,10 @@
|
||||
//Small plushies.
|
||||
/obj/item/toy/plushie
|
||||
name = "generic small plush"
|
||||
desc = "A very generic small plushie. It seems to not want to exist."
|
||||
desc = "A small toy plushie. It's very cute."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "nymphplushie"
|
||||
w_class = ITEMSIZE_TINY
|
||||
var/last_message = 0
|
||||
|
||||
/obj/item/toy/plushie/attack_self(mob/user as mob)
|
||||
@@ -815,9 +768,24 @@
|
||||
else if (user.a_intent == I_GRAB)
|
||||
user.visible_message("<span class='warning'><b>\The [user]</b> attempts to strangle [src]!</span>","<span class='warning'>You attempt to strangle [src]!</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'><b>\The [user]</b> pokes the [src].</span>","<span class='notice'>You poke the [src].</span>")
|
||||
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()
|
||||
set name = "Name Plushie"
|
||||
set category = "Object"
|
||||
set desc = "Give your plushie a cute name!"
|
||||
var/mob/M = usr
|
||||
if(!M.mind)
|
||||
return 0
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the plushie?", ,""), MAX_NAME_LEN)
|
||||
|
||||
if(src && input && !M.stat && in_range(M,src))
|
||||
name = input
|
||||
to_chat(M, "You name the plushie [input], giving it a hug for good luck.")
|
||||
return 1
|
||||
|
||||
/obj/item/toy/plushie/nymph
|
||||
name = "diona nymph plush"
|
||||
desc = "A plushie of an adorable diona nymph! While its level of self-awareness is still being debated, its level of cuteness is not."
|
||||
@@ -830,7 +798,7 @@
|
||||
|
||||
/obj/item/toy/plushie/kitten
|
||||
name = "kitten plush"
|
||||
desc = "A plushie of a cute kitten! Watch as it purrs it's way right into your heart."
|
||||
desc = "A plushie of a cute kitten! Watch as it purrs its way right into your heart."
|
||||
icon_state = "kittenplushie"
|
||||
|
||||
/obj/item/toy/plushie/lizard
|
||||
@@ -848,6 +816,49 @@
|
||||
desc = "A farwa plush doll. It's soft and comforting!"
|
||||
icon_state = "farwaplushie"
|
||||
|
||||
/obj/item/toy/plushie/therapy/red
|
||||
name = "red therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is red."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyred"
|
||||
item_state = "egg4" // It's the red egg in items_left/righthand
|
||||
|
||||
/obj/item/toy/plushie/therapy/purple
|
||||
name = "purple therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is purple."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapypurple"
|
||||
item_state = "egg1" // It's the magenta egg in items_left/righthand
|
||||
|
||||
/obj/item/toy/plushie/therapy/blue
|
||||
name = "blue therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is blue."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyblue"
|
||||
item_state = "egg2" // It's the blue egg in items_left/righthand
|
||||
|
||||
/obj/item/toy/plushie/therapy/yellow
|
||||
name = "yellow therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is yellow."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyyellow"
|
||||
item_state = "egg5" // It's the yellow egg in items_left/righthand
|
||||
|
||||
/obj/item/toy/plushie/therapy/orange
|
||||
name = "orange therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is orange."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapyorange"
|
||||
item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless
|
||||
|
||||
/obj/item/toy/plushie/therapy/green
|
||||
name = "green therapy doll"
|
||||
desc = "A toy for therapeutic and recreational purposes. This one is green."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "therapygreen"
|
||||
item_state = "egg3" // It's the green egg in items_left/righthand
|
||||
|
||||
|
||||
//Toy cult sword
|
||||
/obj/item/toy/cultsword
|
||||
name = "foam sword"
|
||||
|
||||
@@ -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)
|
||||
@@ -202,6 +202,15 @@
|
||||
/obj/item/weapon/reagent_containers/syringe = 3,
|
||||
/obj/item/stack/material/glass/reinforced = 2)
|
||||
|
||||
/obj/item/weapon/circuitboard/vr_sleeper
|
||||
name = T_BOARD("VR sleeper")
|
||||
build_path = /obj/machinery/vr_sleeper
|
||||
board_type = new /datum/frame/frame_types/medical_pod
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
/obj/item/stack/material/glass/reinforced = 2)
|
||||
|
||||
/obj/item/weapon/circuitboard/dna_analyzer
|
||||
name = T_BOARD("dna analyzer")
|
||||
build_path = /obj/machinery/dnaforensics
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -373,8 +373,8 @@
|
||||
job_access_type = /datum/job/bartender
|
||||
|
||||
/obj/item/weapon/card/id/civilian/botanist
|
||||
assignment = "Gardener"
|
||||
rank = "Gardener"
|
||||
assignment = "Botanist"
|
||||
rank = "Botanist"
|
||||
job_access_type = /datum/job/hydro
|
||||
|
||||
/obj/item/weapon/card/id/civilian/chaplain
|
||||
|
||||
@@ -92,3 +92,11 @@
|
||||
desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products."
|
||||
force_divisor = 0.25 // 15 when wielded with hardness 60 (steel)
|
||||
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
|
||||
/obj/item/weapon/material/hatchet/tacknife/survival
|
||||
name = "survival knife"
|
||||
desc = "A hunting grade survival knife."
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "survivalknife"
|
||||
item_state = "knife"
|
||||
applies_material_colour = FALSE
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
var/obj/O = AM
|
||||
O.emp_act(3) // A weaker severity is used because this has infinite uses.
|
||||
playsound(get_turf(O), 'sound/effects/EMPulse.ogg', 100, 1)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) // A lot of objects don't set click delay.
|
||||
user.setClickCooldown(user.get_attack_speed(src)) // A lot of objects don't set click delay.
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/ionic_rapier/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "belt"
|
||||
item_state = "security"
|
||||
storage_slots = 8
|
||||
can_hold = list(
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/weapon/dnainjector,
|
||||
@@ -284,6 +285,7 @@
|
||||
new /obj/item/weapon/surgical/FixOVein/alien(src)
|
||||
new /obj/item/weapon/surgical/bone_clamp/alien(src)
|
||||
new /obj/item/weapon/surgical/cautery/alien(src)
|
||||
new /obj/item/weapon/surgical/surgicaldrill/alien(src)
|
||||
|
||||
/obj/item/weapon/storage/belt/champion
|
||||
name = "championship belt"
|
||||
|
||||
@@ -426,12 +426,12 @@
|
||||
for(var/obj/item/weapon/light/L in src.contents)
|
||||
if(L.status == 0)
|
||||
if(LP.uses < LP.max_uses)
|
||||
LP.AddUses(1)
|
||||
LP.add_uses(1)
|
||||
amt_inserted++
|
||||
remove_from_storage(L, T)
|
||||
qdel(L)
|
||||
if(amt_inserted)
|
||||
user << "You inserted [amt_inserted] light\s into \the [LP.name]. You have [LP.uses] light\s remaining."
|
||||
to_chat(user, "You inserted [amt_inserted] light\s into \the [LP.name]. You have [LP.uses] light\s remaining.")
|
||||
return
|
||||
|
||||
if(!can_be_inserted(W))
|
||||
@@ -441,14 +441,14 @@
|
||||
var/obj/item/weapon/tray/T = W
|
||||
if(T.calc_carry() > 0)
|
||||
if(prob(85))
|
||||
user << "<span class='warning'>The tray won't fit in [src].</span>"
|
||||
to_chat(user, "<span class='warning'>The tray won't fit in [src].</span>")
|
||||
return
|
||||
else
|
||||
W.forceMove(get_turf(user))
|
||||
if ((user.client && user.s_active != src))
|
||||
user.client.screen -= W
|
||||
W.dropped(user)
|
||||
user << "<span class='warning'>God damnit!</span>"
|
||||
to_chat(user, "<span class='warning'>God damn it!</span>")
|
||||
|
||||
W.add_fingerprint(user)
|
||||
return handle_item_insertion(W)
|
||||
@@ -506,9 +506,9 @@
|
||||
collection_mode = !collection_mode
|
||||
switch (collection_mode)
|
||||
if(1)
|
||||
usr << "[src] now picks up all items in a tile at once."
|
||||
to_chat(usr, "[src] now picks up all items on a tile at once.")
|
||||
if(0)
|
||||
usr << "[src] now picks up one item at a time."
|
||||
to_chat(usr, "[src] now picks up one item at a time.")
|
||||
|
||||
|
||||
/obj/item/weapon/storage/verb/quick_empty()
|
||||
@@ -539,7 +539,7 @@
|
||||
var/total_storage_space = 0
|
||||
for(var/obj/item/I in contents)
|
||||
total_storage_space += I.get_storage_cost()
|
||||
max_storage_space = max(total_storage_space,max_storage_space) //prevents spawned containers from being too small for their contents
|
||||
max_storage_space = max(total_storage_space,max_storage_space) //Prevents spawned containers from being too small for their contents.
|
||||
|
||||
src.boxes = new /obj/screen/storage( )
|
||||
src.boxes.name = "storage"
|
||||
|
||||
@@ -69,14 +69,24 @@
|
||||
origin_tech = list(TECH_COMBAT = 1, TECH_ILLEGAL = 1)
|
||||
force = 14
|
||||
|
||||
/obj/item/weapon/storage/toolbox/syndicate/New()
|
||||
/obj/item/weapon/storage/toolbox/syndicate/New() // This is found in maint, so it should have the basics, plus some gloves.
|
||||
..()
|
||||
new /obj/item/clothing/gloves/yellow(src)
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
new /obj/item/weapon/wrench(src)
|
||||
new /obj/item/weapon/weldingtool(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/weapon/wirecutters(src)
|
||||
new /obj/item/device/multitool(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/syndicate/powertools/New() // Available in the uplink and is the 'real' syndie toolbox.
|
||||
// ..() isn't called or else this box would contain the basic tools, power tools, and duplicate gloves.
|
||||
new /obj/item/clothing/gloves/yellow(src)
|
||||
new /obj/item/weapon/screwdriver/power(src)
|
||||
new /obj/item/stack/cable_coil/random(src,30)
|
||||
new /obj/item/weapon/weldingtool/experimental(src)
|
||||
new /obj/item/weapon/crowbar/power(src)
|
||||
new /obj/item/device/multitool(src)
|
||||
new /obj/item/stack/cable_coil/random(src,30)
|
||||
new /obj/item/device/analyzer(src)
|
||||
|
||||
/obj/item/weapon/storage/toolbox/lunchbox
|
||||
|
||||
@@ -133,7 +133,7 @@ Frequency:
|
||||
|
||||
/obj/item/weapon/hand_tele/attack_self(mob/user as mob)
|
||||
var/turf/current_location = get_turf(user)//What turf is the user on?
|
||||
if(!current_location||current_location.z==2||current_location.z>=7)//If turf was not found or they're on z level 2 or >7 which does not currently exist.
|
||||
if(!current_location||current_location.z==2||current_location.z>=7 || current_location.block_tele)//If turf was not found or they're on z level 2 or >7 which does not currently exist.
|
||||
user << "<span class='notice'>\The [src] is malfunctioning.</span>"
|
||||
return
|
||||
var/list/L = list( )
|
||||
@@ -148,6 +148,7 @@ Frequency:
|
||||
for(var/turf/T in orange(10))
|
||||
if(T.x>world.maxx-8 || T.x<8) continue //putting them at the edge is dumb
|
||||
if(T.y>world.maxy-8 || T.y<8) continue
|
||||
if(T.block_tele) continue
|
||||
turfs += T
|
||||
if(turfs.len)
|
||||
L["None (Dangerous)"] = pick(turfs)
|
||||
|
||||
@@ -656,6 +656,61 @@
|
||||
nextrefueltick = world.time + 10
|
||||
reagents.add_reagent("fuel", 1)
|
||||
|
||||
/*
|
||||
* Backpack Welder.
|
||||
*/
|
||||
|
||||
/obj/item/weapon/weldingtool/tubefed
|
||||
name = "tube-fed welding tool"
|
||||
desc = "A bulky, cooler-burning welding tool that draws from a worn welding tank."
|
||||
icon_state = "tubewelder"
|
||||
max_fuel = 10
|
||||
w_class = ITEMSIZE_NO_CONTAINER
|
||||
matter = null
|
||||
toolspeed = 1.25
|
||||
change_icons = 0
|
||||
flame_intensity = 1
|
||||
eye_safety_modifier = 1
|
||||
always_process = TRUE
|
||||
var/obj/item/weapon/weldpack/mounted_pack = null
|
||||
|
||||
/obj/item/weapon/weldingtool/tubefed/New(location)
|
||||
..()
|
||||
if(istype(location, /obj/item/weapon/weldpack))
|
||||
var/obj/item/weapon/weldpack/holder = location
|
||||
mounted_pack = holder
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/weldingtool/tubefed/Destroy()
|
||||
mounted_pack.nozzle = null
|
||||
mounted_pack = null
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/weldingtool/tubefed/process()
|
||||
if(mounted_pack)
|
||||
if(!istype(mounted_pack.loc,/mob/living/carbon/human))
|
||||
mounted_pack.return_nozzle()
|
||||
else
|
||||
var/mob/living/carbon/human/H = mounted_pack.loc
|
||||
if(H.back != mounted_pack)
|
||||
mounted_pack.return_nozzle()
|
||||
|
||||
if(mounted_pack.loc != src.loc && src.loc != mounted_pack)
|
||||
mounted_pack.return_nozzle()
|
||||
visible_message("<span class='notice'>\The [src] retracts to its fueltank.</span>")
|
||||
|
||||
if(get_fuel() <= get_max_fuel())
|
||||
mounted_pack.reagents.trans_to_obj(src, 1)
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/weapon/weldingtool/tubefed/dropped(mob/user)
|
||||
..()
|
||||
if(src.loc != user)
|
||||
mounted_pack.return_nozzle()
|
||||
to_chat(user, "<span class='notice'>\The [src] retracts to its fueltank.</span>")
|
||||
|
||||
/*
|
||||
* Electric/Arc Welder
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/max_carry = 10
|
||||
|
||||
/obj/item/weapon/tray/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
// Drop all the things. All of them.
|
||||
overlays.Cut()
|
||||
for(var/obj/item/I in carrying)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
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>)")
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(src))
|
||||
user.do_attack_animation(M)
|
||||
|
||||
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
@@ -134,7 +134,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/energy_net/user_unbuckle_mob(mob/user)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed())
|
||||
visible_message("<span class='danger'>[user] begins to tear at \the [src]!</span>")
|
||||
if(do_after(usr, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
|
||||
if(!buckled_mob)
|
||||
|
||||
@@ -6,46 +6,140 @@
|
||||
icon_state = "welderpack"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
var/max_fuel = 350
|
||||
var/obj/item/weapon/nozzle = null //Attached welder, or other spray device.
|
||||
var/nozzle_attached = 0
|
||||
|
||||
/obj/item/weapon/weldpack/New()
|
||||
var/datum/reagents/R = new/datum/reagents(max_fuel) //Lotsa refills
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("fuel", max_fuel)
|
||||
nozzle = new/obj/item/weapon/weldingtool/tubefed(src)
|
||||
nozzle_attached = 1
|
||||
|
||||
/obj/item/weapon/weldpack/Destroy()
|
||||
qdel(nozzle)
|
||||
nozzle = null
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/weldpack/dropped(mob/user)
|
||||
..()
|
||||
if(nozzle)
|
||||
user.remove_from_mob(nozzle)
|
||||
return_nozzle()
|
||||
to_chat(user, "<span class='notice'>\The [nozzle] retracts to its fueltank.</span>")
|
||||
|
||||
/obj/item/weapon/weldpack/proc/get_nozzle(var/mob/living/user)
|
||||
if(!ishuman(user))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
if(H.hands_are_full()) //Make sure our hands aren't full.
|
||||
to_chat(H, "<span class='warning'>Your hands are full. Drop something first.</span>")
|
||||
return 0
|
||||
|
||||
var/obj/item/weapon/F = nozzle
|
||||
H.put_in_hands(F)
|
||||
nozzle_attached = 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/weldpack/proc/return_nozzle(var/mob/living/user)
|
||||
nozzle.forceMove(src)
|
||||
nozzle_attached = 1
|
||||
|
||||
/obj/item/weapon/weldpack/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/weldingtool))
|
||||
if(istype(W, /obj/item/weapon/weldingtool) && !(W == nozzle))
|
||||
var/obj/item/weapon/weldingtool/T = W
|
||||
if(T.welding & prob(50))
|
||||
message_admins("[key_name_admin(user)] triggered a fueltank explosion.")
|
||||
log_game("[key_name(user)] triggered a fueltank explosion.")
|
||||
user << "<span class='danger'>That was stupid of you.</span>"
|
||||
to_chat(user,"<span class='danger'>That was stupid of you.</span>")
|
||||
explosion(get_turf(src),-1,0,2)
|
||||
if(src)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
else if(T.status)
|
||||
if(T.welding)
|
||||
user << "<span class='danger'>That was close!</span>"
|
||||
to_chat(user,"<span class='danger'>That was close!</span>")
|
||||
src.reagents.trans_to_obj(W, T.max_fuel)
|
||||
user << "<span class='notice'>Welder refilled!</span>"
|
||||
to_chat(user, "<span class='notice'>Welder refilled!</span>")
|
||||
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
return
|
||||
user << "<span class='warning'>The tank scoffs at your insolence. It only provides services to welders.</span>"
|
||||
else if(nozzle)
|
||||
if(nozzle == W)
|
||||
if(!user.unEquip(W))
|
||||
to_chat(user,"<span class='notice'>\The [W] seems to be stuck to your hand.</span>")
|
||||
return
|
||||
if(!nozzle_attached)
|
||||
return_nozzle()
|
||||
to_chat(user,"<span class='notice'>You attach \the [W] to the [src].</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user,"<span class='notice'>The [src] already has a nozzle!</span>")
|
||||
else
|
||||
to_chat(user,"<span class='warning'>The tank scoffs at your insolence. It only provides services to welders.</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/weldpack/attack_hand(mob/user as mob)
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/wearer = user
|
||||
if(wearer.back == src)
|
||||
if(nozzle && nozzle_attached)
|
||||
if(!wearer.incapacitated())
|
||||
get_nozzle(user)
|
||||
else
|
||||
to_chat(user,"<span class='notice'>\The [src] does not have a nozzle attached!</span>")
|
||||
else
|
||||
..()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/weldpack/afterattack(obj/O as obj, mob/user as mob, proximity)
|
||||
if(!proximity) // this replaces and improves the get_dist(src,O) <= 1 checks used previously
|
||||
return
|
||||
if (istype(O, /obj/structure/reagent_dispensers/fueltank) && src.reagents.total_volume < max_fuel)
|
||||
O.reagents.trans_to_obj(src, max_fuel)
|
||||
user << "<span class='notice'>You crack the cap off the top of the pack and fill it back up again from the tank.</span>"
|
||||
to_chat(user,"<span class='notice'>You crack the cap off the top of the pack and fill it back up again from the tank.</span>")
|
||||
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
return
|
||||
else if (istype(O, /obj/structure/reagent_dispensers/fueltank) && src.reagents.total_volume == max_fuel)
|
||||
user << "<span class='warning'>The pack is already full!</span>"
|
||||
to_chat(user,"<span class='warning'>The pack is already full!</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/weldpack/MouseDrop(obj/over_object as obj) //This is terrifying.
|
||||
if(!canremove)
|
||||
return
|
||||
|
||||
if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist
|
||||
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
|
||||
return
|
||||
|
||||
if (!( istype(over_object, /obj/screen) ))
|
||||
return ..()
|
||||
|
||||
//makes sure that the thing is equipped, so that we can't drag it into our hand from miles away.
|
||||
//there's got to be a better way of doing this.
|
||||
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
|
||||
return
|
||||
|
||||
if (( usr.restrained() ) || ( usr.stat ))
|
||||
return
|
||||
|
||||
if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src))
|
||||
return
|
||||
|
||||
switch(over_object.name)
|
||||
if("r_hand")
|
||||
usr.u_equip(src)
|
||||
usr.put_in_r_hand(src)
|
||||
if("l_hand")
|
||||
usr.u_equip(src)
|
||||
usr.put_in_l_hand(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
/obj/item/weapon/weldpack/examine(mob/user)
|
||||
..(user)
|
||||
user << text("\icon[] [] units of fuel left!", src, src.reagents.total_volume)
|
||||
|
||||
@@ -313,7 +313,6 @@
|
||||
prob(2);/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
prob(4);/obj/item/weapon/gun/projectile/shotgun/pump/rifle,
|
||||
prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever,
|
||||
prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/mosin,
|
||||
prob(2);/obj/item/weapon/gun/projectile/silenced)
|
||||
|
||||
/obj/random/projectile/sec
|
||||
@@ -504,12 +503,12 @@
|
||||
|
||||
/obj/random/toy/item_to_spawn()
|
||||
return pick(/obj/item/toy/bosunwhistle,
|
||||
/obj/item/toy/therapy_red,
|
||||
/obj/item/toy/therapy_purple,
|
||||
/obj/item/toy/therapy_blue,
|
||||
/obj/item/toy/therapy_yellow,
|
||||
/obj/item/toy/therapy_orange,
|
||||
/obj/item/toy/therapy_green,
|
||||
/obj/item/toy/plushie/therapy/red,
|
||||
/obj/item/toy/plushie/therapy/purple,
|
||||
/obj/item/toy/plushie/therapy/blue,
|
||||
/obj/item/toy/plushie/therapy/yellow,
|
||||
/obj/item/toy/plushie/therapy/orange,
|
||||
/obj/item/toy/plushie/therapy/green,
|
||||
/obj/item/toy/cultsword,
|
||||
/obj/item/toy/katana,
|
||||
/obj/item/toy/snappop,
|
||||
@@ -1061,3 +1060,21 @@ var/list/multi_point_spawns
|
||||
/obj/item/clothing/head/helmet/space/void/security/riot
|
||||
)
|
||||
)
|
||||
|
||||
/obj/random/multiple/voidsuit/mining
|
||||
name = "Random Mining Voidsuit"
|
||||
desc = "This is a random mining voidsuit."
|
||||
icon = 'icons/obj/clothing/suits.dmi'
|
||||
icon_state = "rig-mining"
|
||||
|
||||
/obj/random/multiple/voidsuit/mining/item_to_spawn()
|
||||
return pick(
|
||||
prob(5);list(
|
||||
/obj/item/clothing/suit/space/void/mining,
|
||||
/obj/item/clothing/head/helmet/space/void/mining
|
||||
),
|
||||
prob(1);list(
|
||||
/obj/item/clothing/suit/space/void/mining/alt,
|
||||
/obj/item/clothing/head/helmet/space/void/mining/alt
|
||||
)
|
||||
)
|
||||
79
code/game/objects/structures/alien_props.dm
Normal file
79
code/game/objects/structures/alien_props.dm
Normal file
@@ -0,0 +1,79 @@
|
||||
// These contain structures to make certain 'alien' (as in the ayyy ones, not xenomorphs) submaps more filled, and don't really do anything.
|
||||
|
||||
/obj/structure/prop/alien
|
||||
name = "some alien thing"
|
||||
desc = "My description is broken, bug a developer."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
var/interaction_message = null
|
||||
|
||||
/obj/structure/prop/alien/attack_hand(mob/living/user) // Used to tell the player that this isn't useful for anything.
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(!interaction_message)
|
||||
return ..()
|
||||
else
|
||||
to_chat(user, interaction_message)
|
||||
|
||||
/obj/structure/prop/alien/computer
|
||||
name = "alien console"
|
||||
desc = "The console flashes what appear to be symbols you've never seen before."
|
||||
icon_state = "console-c"
|
||||
interaction_message = "<span class='warning'>The console flashes a series of unknown symbols as you press a button on what is presumably a keyboard. It probably some sort of \
|
||||
authentication error. Since you're not an alien, you should probably leave it alone.</span>"
|
||||
|
||||
/obj/structure/prop/alien/computer/camera
|
||||
desc = "This console is briefly flashing video feeds of various locations close by."
|
||||
icon_state = "camera"
|
||||
|
||||
/obj/structure/prop/alien/computer/camera/flipped
|
||||
icon_state = "camera_flipped"
|
||||
|
||||
/obj/structure/prop/alien/dispenser
|
||||
name = "alien dispenser"
|
||||
desc = "This looks like it dispenses... something?"
|
||||
icon_state = "dispenser"
|
||||
interaction_message = "<span class='warning'>You don't see any mechanism to operate this. Probably for the best.</span>"
|
||||
|
||||
/obj/structure/prop/alien/pod
|
||||
name = "alien pod"
|
||||
desc = "This seems to be a container for something."
|
||||
icon_state = "experiment"
|
||||
interaction_message = "<span class='warning'>You don't see any mechanism to open this thing. Probably for the best.</span>"
|
||||
|
||||
/obj/structure/prop/alien/pod/open
|
||||
name = "opened alien pod"
|
||||
desc = "At one point, this probably contained something interesting..."
|
||||
icon_state = "experiment-open"
|
||||
interaction_message = "<span class='warning'>You don't see any mechanism to close this thing.</span>"
|
||||
|
||||
/obj/structure/prop/alien/power
|
||||
name = "void core"
|
||||
icon_state = "core"
|
||||
desc = "An alien machine that seems to be producing energy seemingly out of nowhere."
|
||||
interaction_message = "<span class='warning'>Messing with something that makes energy out of nowhere seems very unwise.</span>"
|
||||
|
||||
/obj/item/prop/alien
|
||||
name = "some alien item"
|
||||
desc = "My description is broken, bug a developer."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
|
||||
// Mostly useless. Research might like it, however.
|
||||
/obj/item/prop/alien/junk
|
||||
name = "alien object"
|
||||
desc = "You have no idea what this thing does."
|
||||
icon_state = "health"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/static/list/possible_states = list("health", "spider", "slime", "emp", "species", "egg", "vent", "mindshock", "viral", "gland")
|
||||
var/static/list/possible_tech = list(TECH_MATERIAL, TECH_ENGINEERING, TECH_PHORON, TECH_POWER, TECH_BIO, TECH_COMBAT, TECH_MAGNET, TECH_DATA)
|
||||
|
||||
/obj/item/prop/alien/junk/initialize()
|
||||
..()
|
||||
icon_state = pick(possible_states)
|
||||
var/list/techs = possible_tech.Copy()
|
||||
origin_tech = list()
|
||||
for(var/i = 1 to rand(1, 4))
|
||||
var/new_tech = pick(techs)
|
||||
techs -= new_tech
|
||||
origin_tech[new_tech] = rand(5, 9)
|
||||
@@ -81,7 +81,7 @@
|
||||
health = maxhealth
|
||||
else
|
||||
take_damage(C.force)
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.setClickCooldown(user.get_attack_speed(C))
|
||||
return ..()
|
||||
|
||||
/obj/structure/catwalk/Crossed()
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
playsound(user, 'sound/machines/lockreset.ogg', 50, 1)
|
||||
if(do_after(user, 20 * O.toolspeed))
|
||||
src.locked = 0
|
||||
user << "<span class = 'caution'> You disable the locking modules.</span>"
|
||||
to_chat(user, "<span class = 'caution'> You disable the locking modules.</span>")
|
||||
update_icon()
|
||||
return
|
||||
else if(istype(O, /obj/item/weapon))
|
||||
@@ -50,7 +50,7 @@
|
||||
else
|
||||
playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time
|
||||
if(W.force < 15)
|
||||
user << "<span class='notice'>The cabinet's protective glass glances off the hit.</span>"
|
||||
to_chat(user, "<span class='notice'>The cabinet's protective glass glances off the hit.</span>")
|
||||
else
|
||||
src.hitstaken++
|
||||
if(src.hitstaken == 4)
|
||||
@@ -63,12 +63,14 @@
|
||||
if (istype(O, /obj/item/weapon/material/twohanded/fireaxe) && src.localopened)
|
||||
if(!fireaxe)
|
||||
if(O:wielded)
|
||||
user << "<span class='warning'>Unwield the axe first.</span>"
|
||||
return
|
||||
O:wielded = 0
|
||||
O.update_icon()
|
||||
//to_chat(user, "<span class='warning'>Unwield the axe first.</span>")
|
||||
//return
|
||||
fireaxe = O
|
||||
user.remove_from_mob(O)
|
||||
src.contents += O
|
||||
user << "<span class='notice'>You place the fire axe back in the [src.name].</span>"
|
||||
to_chat(user, "<span class='notice'>You place the fire axe back in the [src.name].</span>")
|
||||
update_icon()
|
||||
else
|
||||
if(src.smashed)
|
||||
@@ -91,11 +93,11 @@
|
||||
spawn(10) update_icon()
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>Resetting circuitry...</span>"
|
||||
to_chat(user, "<span class='warning'>Resetting circuitry...</span>")
|
||||
playsound(user, 'sound/machines/lockenable.ogg', 50, 1)
|
||||
if(do_after(user,20 * O.toolspeed))
|
||||
src.locked = 1
|
||||
user << "<span class = 'caution'> You re-enable the locking modules.</span>"
|
||||
to_chat(user, "<span class = 'caution'> You re-enable the locking modules.</span>")
|
||||
return
|
||||
else
|
||||
localopened = !localopened
|
||||
@@ -116,13 +118,13 @@
|
||||
hasaxe = 1
|
||||
|
||||
if(src.locked)
|
||||
user <<"<span class='warning'>The cabinet won't budge!</span>"
|
||||
to_chat(user, "<span class='warning'>The cabinet won't budge!</span>")
|
||||
return
|
||||
if(localopened)
|
||||
if(fireaxe)
|
||||
user.put_in_hands(fireaxe)
|
||||
fireaxe = null
|
||||
user << "<span class='notice'>You take the fire axe from the [name].</span>"
|
||||
to_chat (user, "<span class='notice'>You take the fire axe from the [name].</span>")
|
||||
src.add_fingerprint(user)
|
||||
update_icon()
|
||||
else
|
||||
@@ -149,7 +151,7 @@
|
||||
attack_tk(mob/user as mob)
|
||||
if(localopened && fireaxe)
|
||||
fireaxe.forceMove(loc)
|
||||
user << "<span class='notice'>You telekinetically remove the fire axe.</span>"
|
||||
to_chat(user, "<span class='notice'>You telekinetically remove the fire axe.</span>")
|
||||
fireaxe = null
|
||||
update_icon()
|
||||
return
|
||||
@@ -161,9 +163,9 @@
|
||||
|
||||
if (isrobot(usr) || src.locked || src.smashed)
|
||||
if(src.locked)
|
||||
usr << "<span class='warning'>The cabinet won't budge!</span>"
|
||||
to_chat(usr, "<span class='warning'>The cabinet won't budge!</span>")
|
||||
else if(src.smashed)
|
||||
usr << "<span class='notice'>The protective glass is broken!</span>"
|
||||
to_chat(usr, "<span class='notice'>The protective glass is broken!</span>")
|
||||
return
|
||||
|
||||
localopened = !localopened
|
||||
@@ -180,23 +182,23 @@
|
||||
if(fireaxe)
|
||||
usr.put_in_hands(fireaxe)
|
||||
fireaxe = null
|
||||
usr << "<span class='notice'>You take the Fire axe from the [name].</span>"
|
||||
to_chat(usr, "<span class='notice'>You take the Fire axe from the [name].</span>")
|
||||
else
|
||||
usr << "<span class='notice'>The [src.name] is empty.</span>"
|
||||
to_chat(usr, "<span class='notice'>The [src.name] is empty.</span>")
|
||||
else
|
||||
usr << "<span class='notice'>The [src.name] is closed.</span>"
|
||||
to_chat(usr, "<span class='notice'>The [src.name] is closed.</span>")
|
||||
update_icon()
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
if(src.smashed)
|
||||
user << "<span class='warning'>The security of the cabinet is compromised.</span>"
|
||||
to_chat(user, "<span class='warning'>The security of the cabinet is compromised.</span>")
|
||||
return
|
||||
else
|
||||
locked = !locked
|
||||
if(locked)
|
||||
user << "<span class='warning'>Cabinet locked.</span>"
|
||||
to_chat(user, "<span class='warning'>Cabinet locked.</span>")
|
||||
else
|
||||
user << "<span class='notice'>Cabinet unlocked.</span>"
|
||||
to_chat(user, "<span class='notice'>Cabinet unlocked.</span>")
|
||||
return
|
||||
|
||||
update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers
|
||||
|
||||
@@ -134,3 +134,12 @@
|
||||
new /obj/item/clothing/head/helmet/thunderdome(src)
|
||||
new /obj/item/clothing/head/helmet/thunderdome(src)
|
||||
new /obj/item/clothing/head/helmet/thunderdome(src)
|
||||
|
||||
/obj/structure/closet/alien
|
||||
name = "alien container"
|
||||
desc = "Contains secrets of the universe."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "alien_locker"
|
||||
icon_closed = "alien_locker"
|
||||
icon_opened = "alien_locker_open"
|
||||
anchored = TRUE
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user