mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Merge remote-tracking branch 'upstream/dev' into subsystems
This commit is contained in:
@@ -292,7 +292,7 @@
|
||||
if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob )
|
||||
if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob )
|
||||
if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob )
|
||||
if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/Runtime , null, null, delmob )
|
||||
if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/fluff/Runtime , null, null, delmob )
|
||||
if("corgi") M.change_mob_type( /mob/living/simple_animal/corgi , null, null, delmob )
|
||||
if("ian") M.change_mob_type( /mob/living/simple_animal/corgi/Ian , null, null, delmob )
|
||||
if("crab") M.change_mob_type( /mob/living/simple_animal/crab , null, null, delmob )
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
set desc = "Fires a laser bolt at your position. You should only do this as a(n) (a)ghost"
|
||||
set category = "Fun"
|
||||
|
||||
var/turf/target = get_turf(src.mob)
|
||||
admin_log_and_message_admins("has fired the Icarus point defense laser at [target.x]-[target.y]-[target.z]")
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
|
||||
Icarus_FireLaser(get_turf(src.mob))
|
||||
Icarus_FireLaser(target)
|
||||
|
||||
|
||||
/client/proc/FireCannons()
|
||||
@@ -15,11 +17,13 @@
|
||||
set desc = "Fires an explosive missile at your position. You should only do this as a(n) (a)ghost."
|
||||
set category = "Fun"
|
||||
|
||||
var/turf/target = get_turf(src.mob)
|
||||
admin_log_and_message_admins("has fired the Icarus main gun projectile at [target.x]-[target.y]-[target.z]")
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
|
||||
Icarus_FireCannon(get_turf(src.mob))
|
||||
Icarus_FireCannon(target)
|
||||
|
||||
|
||||
/client/proc/ChangeIcarusPosition()
|
||||
@@ -27,6 +31,7 @@
|
||||
set desc = "Lets you chose the position of the Icarus in regards to the map."
|
||||
set category = "Fun"
|
||||
|
||||
admin_log_and_message_admins("is changing the Icarus position.")
|
||||
if(!src.holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
@@ -122,4 +127,4 @@ proc/Icarus_SetPosition(var/user)
|
||||
if(!direction)
|
||||
return
|
||||
|
||||
icarus_position = directions[direction]
|
||||
icarus_position = directions[direction]
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/receive_signal()
|
||||
if(istype(loc, /obj/structure/stool/bed/chair/e_chair))
|
||||
var/obj/structure/stool/bed/chair/e_chair/C = loc
|
||||
if(istype(loc, /obj/structure/bed/chair/e_chair))
|
||||
var/obj/structure/bed/chair/e_chair/C = loc
|
||||
C.shock()
|
||||
return
|
||||
|
||||
@@ -416,11 +416,25 @@ var/global/list/gear_datums = list()
|
||||
cost = 1
|
||||
|
||||
/datum/gear/armpit
|
||||
display_name = "shoulder holster"
|
||||
display_name = "holster, armpit"
|
||||
path = /obj/item/clothing/accessory/holster/armpit
|
||||
slot = slot_tie
|
||||
cost = 2
|
||||
allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security")
|
||||
allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security","Detective")
|
||||
|
||||
/datum/gear/hip
|
||||
display_name = "holster, hip"
|
||||
path = /obj/item/clothing/accessory/holster/hip
|
||||
slot = slot_tie
|
||||
cost = 2
|
||||
allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security", "Detective")
|
||||
|
||||
/datum/gear/waist
|
||||
display_name = "holster, waist"
|
||||
path = /obj/item/clothing/accessory/holster/waist
|
||||
slot = slot_tie
|
||||
cost = 2
|
||||
allowed_roles = list("Captain", "Head of Personnel", "Security Officer", "Warden", "Head of Security", "Detective")
|
||||
|
||||
/datum/gear/tie_blue
|
||||
display_name = "tie, blue"
|
||||
|
||||
@@ -191,9 +191,11 @@
|
||||
|
||||
if(isnull(species) || !(species in playable_species))
|
||||
species = "Human"
|
||||
|
||||
if(isnum(underwear))
|
||||
var/list/undies = gender == MALE ? underwear_m : underwear_f
|
||||
underwear = undies[undies[underwear]]
|
||||
|
||||
if(isnum(undershirt))
|
||||
undershirt = undershirt_t[undershirt_t[undershirt]]
|
||||
|
||||
@@ -219,8 +221,6 @@
|
||||
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
|
||||
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
|
||||
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
|
||||
underwear = sanitize_integer(underwear, 1, underwear_m.len, initial(underwear))
|
||||
undershirt = sanitize_integer(undershirt, 1, undershirt_t.len, initial(undershirt))
|
||||
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
|
||||
b_type = sanitize_text(b_type, initial(b_type))
|
||||
|
||||
|
||||
@@ -84,3 +84,18 @@
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0.9
|
||||
body_parts_covered = UPPER_TORSO|ARMS
|
||||
|
||||
//Orange emergency space suit
|
||||
/obj/item/clothing/head/helmet/space/emergency
|
||||
name = "Emergency Space Helmet"
|
||||
icon_state = "emergencyhelm"
|
||||
item_state = "emergencyhelm"
|
||||
desc = "A simple helmet with a built in light, smells like mothballs."
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/emergency
|
||||
name = "Emergency Softsuit"
|
||||
icon_state = "syndicate-orange"
|
||||
item_state = "syndicate-orange"
|
||||
desc = "A thin, ungainly softsuit colored in blaze orange for rescuers to easily locate, looks pretty fragile."
|
||||
slowdown = 4
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0.7
|
||||
var/obj/item/clothing/accessory/holster/holster
|
||||
|
||||
|
||||
/obj/item/clothing/suit/armor/tactical/New()
|
||||
..()
|
||||
holster = new(src)
|
||||
@@ -212,7 +212,7 @@
|
||||
set src in usr
|
||||
if(!istype(usr, /mob/living)) return
|
||||
if(usr.stat) return
|
||||
|
||||
|
||||
if(!holster.holstered)
|
||||
var/obj/item/W = usr.get_active_hand()
|
||||
if(!istype(W, /obj/item))
|
||||
@@ -220,7 +220,7 @@
|
||||
return
|
||||
holster.holster(W, usr)
|
||||
else
|
||||
holster.unholster(usr)
|
||||
holster.unholster(usr)
|
||||
|
||||
//Non-hardsuit ERT armor.
|
||||
/obj/item/clothing/suit/armor/vest/ert
|
||||
@@ -252,3 +252,101 @@
|
||||
name = "emergency response team medical armor"
|
||||
desc = "A set of armor worn by medical members of the NanoTrasen Emergency Response Team. Has red and white highlights."
|
||||
icon_state = "ertarmor_med"
|
||||
|
||||
//New Vests
|
||||
/obj/item/clothing/suit/storage/vest
|
||||
name = "armor vest"
|
||||
desc = "A simple kevlar plate carrier."
|
||||
icon_state = "kvest"
|
||||
item_state = "kvest"
|
||||
armor = list(melee = 50, bullet = 15, laser = 50, energy = 10, bomb = 25, bio = 0, rad = 0)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/weapon/reagent_containers/spray/pepper,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/officer
|
||||
name = "officer armor vest"
|
||||
desc = "A simple kevlar plate carrier beloning to Nanotrasen. This one has a security holobadge clipped to the chest."
|
||||
icon_state = "officervest_nobadge"
|
||||
item_state = "officervest_nobadge"
|
||||
icon_badge = "officervest_badge"
|
||||
icon_nobadge = "officervest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/warden
|
||||
name = "warden armor vest"
|
||||
desc = "A simple kevlar plate carrier belonging to Nanotrasen. This one has a silver badge clipped to the chest."
|
||||
icon_state = "wardenvest_nobadge"
|
||||
item_state = "wardenvest_nobadge"
|
||||
icon_badge = "wardenvest_badge"
|
||||
icon_nobadge = "wardenvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/hos
|
||||
name = "commander armor vest"
|
||||
desc = "A simple kevlar plate carrier belonging to Nanotrasen. This one has a gold badge clipped to the chest."
|
||||
icon_state = "hosvest_nobadge"
|
||||
item_state = "hosvest_nobadge"
|
||||
icon_badge = "hosvest_badge"
|
||||
icon_nobadge = "hosvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/pcrc
|
||||
name = "PCRC armor vest"
|
||||
desc = "A simple kevlar plate carrier belonging to Proxima Centauri Risk Control. This one has a PCRC crest clipped to the chest."
|
||||
icon_state = "pcrcvest_nobadge"
|
||||
item_state = "pcrcvest_nobadge"
|
||||
icon_badge = "pcrcvest_badge"
|
||||
icon_nobadge = "pcrcvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/detective
|
||||
name = "detective armor vest"
|
||||
desc = "A simple kevlar plate carrier in a vintage brown, it has a badge clipped to the chest that reads, 'Private investigator'."
|
||||
icon_state = "detectivevest_nobadge"
|
||||
item_state = "detectivevest_nobadge"
|
||||
icon_badge = "detectivevest_badge"
|
||||
icon_nobadge = "detectivevest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/heavy
|
||||
name = "heavy armor vest"
|
||||
desc = "A heavy kevlar plate carrier with webbing attached."
|
||||
icon_state = "webvest"
|
||||
item_state = "webvest"
|
||||
armor = list(melee = 50, bullet = 40, laser = 50, energy = 25, bomb = 30, bio = 0, rad = 0)
|
||||
slowdown = 1
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/heavy/officer
|
||||
name = "officer heavy armor vest"
|
||||
desc = "A heavy kevlar plate carrier belonging to Nanotrasen with webbing attached. This one has a security holobadge clipped to the chest."
|
||||
icon_state = "officerwebvest_nobadge"
|
||||
item_state = "officerwebvest_nobadge"
|
||||
icon_badge = "officerwebvest_badge"
|
||||
icon_nobadge = "officerwebvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/heavy/warden
|
||||
name = "warden heavy armor vest"
|
||||
desc = "A heavy kevlar plate carrier belonging to Nanotrasen with webbing attached. This one has a silver badge clipped to the chest."
|
||||
icon_state = "wardenwebvest_nobadge"
|
||||
item_state = "wardenwebvest_nobadge"
|
||||
icon_badge = "wardenwebvest_badge"
|
||||
icon_nobadge = "wardenwebvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/heavy/hos
|
||||
name = "commander heavy armor vest"
|
||||
desc = "A heavy kevlar plate carrier belonging to Nanotrasen with webbing attached. This one has a gold badge clipped to the chest."
|
||||
icon_state = "hoswebvest_nobadge"
|
||||
item_state = "hoswebvest_nobadge"
|
||||
icon_badge = "hoswebvest_badge"
|
||||
icon_nobadge = "hoswebvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/heavy/pcrc
|
||||
name = "PCRC heavy armor vest"
|
||||
desc = "A heavy kevlar plate carrier belonging to Proxima Centauri Risk Control with webbing attached. This one has a PCRC crest clipped to the chest."
|
||||
icon_state = "pcrcwebvest_nobadge"
|
||||
item_state = "pcrcwebvest_nobadge"
|
||||
icon_badge = "pcrcwebvest_badge"
|
||||
icon_nobadge = "pcrcwebvest_nobadge"
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/heavy/merc
|
||||
name = "comfortable heavy armor vest"
|
||||
desc = "A heavy kevlar plate carrier in a fetching tan. Fits pretty well."
|
||||
icon_state = "mercwebvest"
|
||||
item_state = "mercwebvest"
|
||||
armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 40, bio = 0, rad = 0)
|
||||
slowdown = 0
|
||||
|
||||
|
||||
@@ -48,4 +48,36 @@
|
||||
else //in case some goofy admin switches icon states around without switching the icon_open or icon_closed
|
||||
usr << "You attempt to button-up the velcro on your [src], before promptly realising how silly you are."
|
||||
return
|
||||
update_clothing_icon() //so our overlays update
|
||||
update_clothing_icon() //so our overlays update
|
||||
|
||||
|
||||
//New Vest 4 pocket storage and badge toggles, until suit accessories are a thing.
|
||||
/obj/item/clothing/suit/storage/vest/heavy/New()
|
||||
..()
|
||||
pockets = new/obj/item/weapon/storage/internal(src)
|
||||
pockets.storage_slots = 4
|
||||
pockets.max_w_class = 2
|
||||
pockets.max_combined_w_class = 8
|
||||
|
||||
|
||||
/obj/item/clothing/suit/storage/vest
|
||||
var/icon_badge
|
||||
var/icon_nobadge
|
||||
verb/toggle()
|
||||
set name ="Adjust Badge"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
return 0
|
||||
|
||||
if(icon_state == icon_badge)
|
||||
icon_state = icon_nobadge
|
||||
usr << "You unclip the badge from the vest."
|
||||
else if(icon_state == icon_nobadge)
|
||||
icon_state = icon_badge
|
||||
usr << "You clip the badge to the vest."
|
||||
else
|
||||
usr << "You can't find a badge for [src]."
|
||||
return
|
||||
update_clothing_icon()
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
else
|
||||
if(user.a_intent == "hurt")
|
||||
usr.visible_message(
|
||||
"\red [user] draws \the [holstered], ready to shoot!</span>",
|
||||
"\red [user] draws \the [holstered], ready to shoot!</span>",
|
||||
"<span class='warning'>You draw \the [holstered], ready to shoot!</span>"
|
||||
)
|
||||
else
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] draws \the [holstered], pointing it at the ground.</span>",
|
||||
"<span class='notice'>[user] draws \the [holstered], pointing it at the ground.</span>",
|
||||
"<span class='notice'>You draw \the [holstered], pointing it at the ground.</span>"
|
||||
)
|
||||
user.put_in_hands(holstered)
|
||||
@@ -103,13 +103,19 @@
|
||||
H.unholster(usr)
|
||||
|
||||
/obj/item/clothing/accessory/holster/armpit
|
||||
name = "shoulder holster"
|
||||
name = "armpit holster"
|
||||
desc = "A worn-out handgun holster. Perfect for concealed carry"
|
||||
icon_state = "holster"
|
||||
item_color = "holster"
|
||||
|
||||
/obj/item/clothing/accessory/holster/waist
|
||||
name = "shoulder holster"
|
||||
name = "waist holster"
|
||||
desc = "A handgun holster. Made of expensive leather."
|
||||
icon_state = "holster"
|
||||
item_color = "holster_low"
|
||||
item_color = "holster_low"
|
||||
|
||||
/obj/item/clothing/accessory/holster/hip
|
||||
name = "hip holster"
|
||||
desc = "A handgun holster slung low on the hip, draw pardner!"
|
||||
icon_state = "holster_hip"
|
||||
item_color = "holster_hip"
|
||||
@@ -1412,12 +1412,6 @@
|
||||
|
||||
////////////////////////////// Foxler - Erstatz Vryroxes /////////////////////////////////////////////////
|
||||
|
||||
/obj/item/weapon/holder/cat/fluff/bones
|
||||
name = "Bones"
|
||||
desc = "It's Bones! Meow."
|
||||
gender = MALE
|
||||
icon_state = "cat3"
|
||||
|
||||
//Use this subtype for spawning in the custom item.
|
||||
/obj/item/weapon/holder/cat/fluff/bones/custom_item
|
||||
|
||||
@@ -1426,6 +1420,12 @@
|
||||
new/mob/living/simple_animal/cat/fluff/bones (src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holder/cat/fluff/bones
|
||||
name = "Bones"
|
||||
desc = "It's Bones! Meow."
|
||||
gender = MALE
|
||||
icon_state = "cat3"
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/bones
|
||||
name = "Bones"
|
||||
desc = "That's Bones the cat. He's a laid back, black cat. Meow."
|
||||
@@ -1434,61 +1434,12 @@
|
||||
icon_living = "cat3"
|
||||
icon_dead = "cat3_dead"
|
||||
holder_type = /obj/item/weapon/holder/cat/fluff/bones
|
||||
bff_name = "Erstatz Vryroxes"
|
||||
var/friend_name = "Erstatz Vryroxes"
|
||||
|
||||
/mob/living/simple_animal/cat/fluff
|
||||
var/bff_name
|
||||
var/mob/living/carbon/human/bff
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/handle_movement_target()
|
||||
if (!bff)
|
||||
/mob/living/simple_animal/cat/fluff/bones/handle_movement_target()
|
||||
if (!friend)
|
||||
for (var/mob/living/carbon/human/M in player_list)
|
||||
if (M.real_name == bff_name)
|
||||
bff = M
|
||||
if (M.real_name == friend_name)
|
||||
friend = M
|
||||
break
|
||||
|
||||
if (bff)
|
||||
var/follow_dist = 5
|
||||
if (bff.stat >= DEAD || bff.health <= config.health_threshold_softcrit) //danger
|
||||
follow_dist = 1
|
||||
else if (bff.stat || bff.health <= 50) //danger or just sleeping
|
||||
follow_dist = 2
|
||||
var/near_dist = max(follow_dist - 3, 1)
|
||||
var/current_dist = get_dist(src, bff)
|
||||
|
||||
if (movement_target != bff)
|
||||
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (bff in oview(src)))
|
||||
//stop existing movement
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
|
||||
//walk to bff
|
||||
stop_automated_movement = 1
|
||||
movement_target = bff
|
||||
walk_to(src, movement_target, near_dist, 4)
|
||||
|
||||
//already following and close enough, stop
|
||||
else if (current_dist <= near_dist)
|
||||
walk_to(src,0)
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
|
||||
if (!(bff && movement_target == bff))
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/Life()
|
||||
..()
|
||||
if (stat || !bff)
|
||||
return
|
||||
if (get_dist(src, bff) <= 1)
|
||||
if (bff.stat >= DEAD || bff.health <= config.health_threshold_softcrit)
|
||||
if (prob((bff.stat < DEAD)? 50 : 15))
|
||||
audible_emote(pick("meows in distress.", "meows anxiously."))
|
||||
else
|
||||
if (prob(5))
|
||||
visible_emote(pick("nuzzles [bff].",
|
||||
"brushes against [bff].",
|
||||
"rubs against [bff].",
|
||||
"purrs."))
|
||||
else if (bff.health <= 50)
|
||||
if (prob(10)) audible_emote("meows anxiously.")
|
||||
|
||||
166
code/modules/examine/descriptions/atmospherics.dm
Normal file
166
code/modules/examine/descriptions/atmospherics.dm
Normal file
@@ -0,0 +1,166 @@
|
||||
/obj/machinery/atmospherics/pipe
|
||||
description_info = "This pipe, and all other pipes, can be connected or disconnected by a wrench. The internal pressure of the pipe must \
|
||||
be below 300 kPa to do this. More pipes can be obtained from the pipe dispenser."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/New() //This is needed or else 20+ lines of copypasta to dance around inheritence.
|
||||
..()
|
||||
description_info += "<br>Most pipes and atmospheric devices can be connected or disconnected with a wrench. The pipe's pressure must not be too high, \
|
||||
or if it is a device, it must be turned off first."
|
||||
|
||||
//HE pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
|
||||
description_info = "This radiates heat from the pipe's gas to space, cooling it down."
|
||||
|
||||
//Supply/Scrubber pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Universal adapters
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/universal
|
||||
description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/universal
|
||||
description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes."
|
||||
|
||||
//Three way manifolds
|
||||
/obj/machinery/atmospherics/pipe/manifold
|
||||
description_info = "A normal pipe with three ends to connect to."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Insulated pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/insulated
|
||||
description_info = "This is completely useless, use a normal pipe." //Sorry, but it's true.
|
||||
|
||||
//Four way manifolds
|
||||
/obj/machinery/atmospherics/pipe/manifold4w
|
||||
description_info = "This is a four-way pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Endcaps
|
||||
/obj/machinery/atmospherics/pipe/cap
|
||||
description_info = "This is a cosmetic attachment, as pipes currently do not spill their contents into the air."
|
||||
|
||||
//T-shaped valves
|
||||
/obj/machinery/atmospherics/tvalve
|
||||
description_info = "Click this to toggle the mode. The direction with the green light is where the gas will flow."
|
||||
|
||||
//Normal valves
|
||||
/obj/machinery/atmospherics/valve
|
||||
description_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected."
|
||||
|
||||
//TEG ports
|
||||
/obj/machinery/atmospherics/binary/circulator
|
||||
description_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \
|
||||
the center of the machine gives an indicator of how much elecrtricity is being generated."
|
||||
|
||||
//Passive gates
|
||||
/obj/machinery/atmospherics/binary/passive_gate
|
||||
description_info = "This is a one-way regulator, allowing gas to flow only at a specific pressure and flow rate. If the light is green, it is flowing."
|
||||
|
||||
//Normal pumps (high power one inherits from this)
|
||||
/obj/machinery/atmospherics/binary/pump
|
||||
description_info = "This moves gas from one pipe to another. A higher target pressure demands more energy. The side with the red end is the output."
|
||||
|
||||
//Vents
|
||||
/obj/machinery/atmospherics/unary/vent_pump
|
||||
description_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm."
|
||||
|
||||
//Freezers
|
||||
/obj/machinery/atmospherics/unary/freezer
|
||||
description_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
|
||||
//Heaters
|
||||
/obj/machinery/atmospherics/unary/heater
|
||||
description_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
|
||||
//Gas injectors
|
||||
/obj/machinery/atmospherics/unary/outlet_injector
|
||||
description_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \
|
||||
A green light on it means it is on."
|
||||
|
||||
//Scrubbers
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber
|
||||
description_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \
|
||||
It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm."
|
||||
|
||||
//Omni filters
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \
|
||||
output. The filtered output's arrows glow orange."
|
||||
|
||||
//Omni mixers
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
description_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined."
|
||||
|
||||
//Canisters
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
description_info = "The canister can be connected to a connector port with a wrench. Tanks of gas (the kind you can hold in your hand) \
|
||||
can be filled by the canister, by using the tank on the canister, increasing the release pressure, then opening the valve until it is full, and then close it. \
|
||||
*DO NOT* remove the tank until the valve is closed. A gas analyzer can be used to check the contents of the canister."
|
||||
|
||||
description_antag = "Canisters can be damaged, spilling their contents into the air, or you can just leave the release valve open."
|
||||
|
||||
//Portable pumps
|
||||
/obj/machinery/portable_atmospherics/powered/pump
|
||||
description_info = "Invaluable for filling air in a room rapidly after a breach repair. The internal gas container can be filled by \
|
||||
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
|
||||
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the air pump."
|
||||
|
||||
//Portable scrubbers
|
||||
/obj/machinery/portable_atmospherics/powered/scrubber
|
||||
description_info = "Filters the air, placing harmful gases into the internal gas container. The container can be emptied by \
|
||||
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
|
||||
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the scrubber. "
|
||||
|
||||
//Meters
|
||||
/obj/machinery/meter
|
||||
description_info = "Measures the volume and temperature of the pipe under the meter."
|
||||
|
||||
//Pipe dispensers
|
||||
/obj/machinery/pipedispenser
|
||||
description_info = "This can be moved by using a wrench. You will need to wrench it again when you want to use it. You can put \
|
||||
excess (atmospheric) pipes into the dispenser, as well. The dispenser requires electricity to function."
|
||||
|
||||
35
code/modules/examine/descriptions/engineering.dm
Normal file
35
code/modules/examine/descriptions/engineering.dm
Normal file
@@ -0,0 +1,35 @@
|
||||
/obj/machinery/power/supermatter
|
||||
description_info = "When energized by a laser (or something hitting it), it emits radiation and heat. If the heat reaches above 7000 kelvin, it will send an alert and start taking damage. \
|
||||
After integrity falls to zero percent, it will delaminate, causing a massive explosion, station-wide radiation spikes, and hallucinations. \
|
||||
Supermatter reacts badly to oxygen in the atmosphere. It'll also heat up really quick if it is in vacuum.<br>\
|
||||
<br>\
|
||||
Supermatter cores are extremely dangerous to be close to, and requires protection to handle properly. The protection you will need is:<br>\
|
||||
Optical meson scanners on your eyes, to prevent hallucinations when looking at the supermatter.<br>\
|
||||
Radiation helmet and suit, as the supermatter is radioactive.<br>\
|
||||
<br>\
|
||||
Touching the supermatter will result in *instant death*, with no corpse left behind! You can drag the supermatter, but anything else will kill you. \
|
||||
It is advised to obtain a genetic backup before trying to drag it."
|
||||
|
||||
description_antag = "Exposing the supermatter to oxygen or vaccum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
|
||||
cause a period of lag as the explosion is processed by the server, as well as irradiating the entire station and causing hallucinations to happen. \
|
||||
Wearing radiation equipment will protect you from most of the delamination effects sans explosion."
|
||||
|
||||
/obj/machinery/power/apc
|
||||
description_info = "An APC (Area Power Controller) regulates and supplies backup power for the area they are in. Their power channels are divided \
|
||||
out into 'environmental' (Items that manipulate airflow and temperature), 'lighting' (the lights), and 'equipment' (Everything else that consumes power). \
|
||||
Power consumption and backup power cell charge can be seen from the interface, further controls (turning a specific channel on, off or automatic, \
|
||||
toggling the APC's ability to charge the backup cell, or toggling power for the entire area via master breaker) first requires the interface to be unlocked \
|
||||
with an ID with Engineering access or by one of the station's robots or the artificial intelligence."
|
||||
|
||||
description_antag = "This can be emagged to unlock it. It will cause the APC to have a blue error screen. \
|
||||
Wires can be pulsed remotely with a signaler attached to it. A powersink will also drain any APCs connected to the same wire the powersink is on."
|
||||
|
||||
/obj/item/inflatable
|
||||
description_info = "Inflate by using it in your hand. The inflatable barrier will inflate on your tile. To deflate it, use the 'deflate' verb."
|
||||
|
||||
/obj/structure/inflatable
|
||||
description_info = "To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
|
||||
|
||||
/obj/structure/inflatable/door
|
||||
description_info = "Click the door to open or close it. It only stops air while closed.<br>\
|
||||
To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
|
||||
8
code/modules/examine/descriptions/mobs.dm
Normal file
8
code/modules/examine/descriptions/mobs.dm
Normal file
@@ -0,0 +1,8 @@
|
||||
/mob/living/silicon/robot/drone
|
||||
description_info = "Drones are player-controlled synthetics which are lawed to maintain the station and not \
|
||||
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
|
||||
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
|
||||
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
|
||||
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access."
|
||||
|
||||
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
|
||||
24
code/modules/examine/descriptions/stacks.dm
Normal file
24
code/modules/examine/descriptions/stacks.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/obj/item/stack/rods
|
||||
description_info = "Made from metal sheets. You can build a grille by using it in your hand. \
|
||||
Clicking on a floor without any tiles will reinforce the floor. You can make reinforced glass by combining rods and normal glass sheets."
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets."
|
||||
|
||||
/obj/item/stack/sheet/glass/cyborg
|
||||
description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets.<br>\
|
||||
As a synthetic, you can acquire more sheets of glass by recharging."
|
||||
|
||||
/obj/item/stack/sheet/glass/reinforced
|
||||
description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage."
|
||||
|
||||
/obj/item/stack/sheet/glass/reinforced/cyborg
|
||||
description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage.<br>\
|
||||
As a synthetic, you can gain more reinforced glass by recharging."
|
||||
|
||||
/obj/item/stack/sheet/metal/cyborg
|
||||
description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it.<br>\
|
||||
You can replenish your supply of metal as a synthetic by recharging."
|
||||
|
||||
/obj/item/stack/sheet
|
||||
description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it."
|
||||
15
code/modules/examine/descriptions/structures.dm
Normal file
15
code/modules/examine/descriptions/structures.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
/obj/structure/girder
|
||||
description_info = "Use metal sheets on this to build a normal wall. Adding plasteel instead will make a reinforced wall.<br>\
|
||||
A false wall can be made by using a crowbar on this girder, and then adding metal or plasteel.<br>\
|
||||
You can dismantle the grider with a wrench."
|
||||
|
||||
/obj/structure/girder/reinforced
|
||||
description_info = "Add another sheet of plasteel to finish."
|
||||
|
||||
/obj/structure/grille
|
||||
description_info = "A powered and knotted wire underneath this will cause the grille to shock anyone not wearing insulated gloves.<br>\
|
||||
Wirecutters will turn the grille into metal rods instantly. Grilles are made with metal rods."
|
||||
|
||||
/obj/structure/lattice
|
||||
description_info = "Add a metal floor tile to build a floor on top of the lattice.<br>\
|
||||
Lattices can be made by applying metal rods to a space tile."
|
||||
3
code/modules/examine/descriptions/turfs.dm
Normal file
3
code/modules/examine/descriptions/turfs.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
/turf/simulated/wall
|
||||
description_info = "You can deconstruct this by welding it, and then wrenching the girder.<br>\
|
||||
You can build a wall by using metal sheets and making a girder, then adding more metal or plasteel."
|
||||
71
code/modules/examine/examine.dm
Normal file
71
code/modules/examine/examine.dm
Normal file
@@ -0,0 +1,71 @@
|
||||
/* This code is responsible for the examine tab. When someone examines something, it copies the examined object's description_info,
|
||||
description_fluff, and description_antag, and shows it in a new tab.
|
||||
|
||||
In this file, some atom and mob stuff is defined here. It is defined here instead of in the normal files, to keep the whole system self-contained.
|
||||
This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort.
|
||||
*/
|
||||
|
||||
|
||||
/atom/
|
||||
var/description_info = null //Helpful blue text.
|
||||
var/description_fluff = null //Green text about the atom's fluff, if any exists.
|
||||
var/description_antag = null //Malicious red text, for the antags.
|
||||
|
||||
/atom/examine(mob/user)
|
||||
..()
|
||||
user.description_holders["info"] = get_description_info()
|
||||
user.description_holders["fluff"] = get_description_fluff()
|
||||
if(user.mind && user.mind.special_role || isobserver(user)) //Runtime prevention, as ghosts don't have minds.
|
||||
user.description_holders["antag"] = get_description_antag()
|
||||
|
||||
if(name) //This shouldn't be needed but I'm paranoid.
|
||||
user.description_holders["name"] = "[src.name]" //\icon[src]
|
||||
|
||||
user.description_holders["icon"] = "\icon[src]"
|
||||
|
||||
if(desc)
|
||||
user << desc
|
||||
user.description_holders["desc"] = src.desc
|
||||
else
|
||||
user.description_holders["desc"] = null //This is needed, or else if you examine one thing with a desc, then another without, the panel will retain the first examined's desc.
|
||||
|
||||
//Override these if you need special behaviour for a specific type.
|
||||
|
||||
/atom/proc/get_description_info()
|
||||
if(description_info)
|
||||
return description_info
|
||||
return
|
||||
|
||||
/atom/proc/get_description_fluff()
|
||||
if(description_fluff)
|
||||
return description_fluff
|
||||
return
|
||||
|
||||
/atom/proc/get_description_antag()
|
||||
if(description_antag)
|
||||
return description_antag
|
||||
return
|
||||
|
||||
/mob/
|
||||
var/description_holders[0]
|
||||
|
||||
/mob/Stat()
|
||||
..()
|
||||
if(statpanel("Examine"))
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
if(description_holders["info"])
|
||||
stat(null,"<font color='#084B8A'><b>[description_holders["info"]]</b></font>") //Blue, informative text.
|
||||
if(description_holders["fluff"])
|
||||
stat(null,"<font color='#298A08'><b>[description_holders["fluff"]]</b></font>") //Yellow, fluff-related text.
|
||||
if(description_holders["antag"])
|
||||
stat(null,"<font color='#8A0808'><b>[description_holders["antag"]]</b></font>") //Red, malicious antag-related text
|
||||
|
||||
/mob/living/get_description_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
return flavor_text
|
||||
else //No flavor text? Try for hardcoded fluff instead.
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_description_fluff()
|
||||
return print_flavor_text(0)
|
||||
@@ -182,10 +182,10 @@
|
||||
visible_message("[src] fades away as it shatters!")
|
||||
del(src)
|
||||
|
||||
/obj/structure/stool/bed/chair/holochair/Del()
|
||||
/obj/structure/bed/chair/holochair/Del()
|
||||
..()
|
||||
|
||||
/obj/structure/stool/bed/chair/holochair/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
/obj/structure/bed/chair/holochair/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/wrench))
|
||||
user << ("<span class='notice'>It's a holochair, you can't dismantle it!</span>")
|
||||
return
|
||||
|
||||
@@ -335,6 +335,14 @@
|
||||
icon_state = "unathiknife"
|
||||
attack_verb = list("ripped", "torn", "cut")
|
||||
|
||||
/obj/item/weapon/hatchet/tacknife
|
||||
name = "tactical knife"
|
||||
desc = "You'd be killing loads of people if this was Medal of Valor: Heroes of Nyx."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "tacknife"
|
||||
item_state = "knife"
|
||||
attack_verb = list("stabbed", "chopped", "cut")
|
||||
|
||||
/obj/item/weapon/scythe
|
||||
icon_state = "scythe0"
|
||||
name = "scythe"
|
||||
|
||||
@@ -1635,7 +1635,7 @@ proc/populate_seed_list()
|
||||
seed_noun = "data"
|
||||
display_name = "runtimes"
|
||||
packet_icon = "seed-replicapod"
|
||||
products = list(/mob/living/simple_animal/cat/Runtime)
|
||||
products = list(/mob/living/simple_animal/cat/fluff/Runtime)
|
||||
plant_icon = "replicapod"
|
||||
|
||||
requires_nutrients = 0
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
return 1
|
||||
|
||||
//Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob.
|
||||
//It does call u_equip() though. So it can drop items to the floor but only if src is human.
|
||||
/mob/proc/remove_from_mob(var/obj/O)
|
||||
src.u_equip(O)
|
||||
if (src.client)
|
||||
@@ -242,16 +243,7 @@
|
||||
|
||||
/** BS12's proc to get the item in the active hand. Couldn't find the /tg/ equivalent. **/
|
||||
/mob/proc/equipped()
|
||||
if(issilicon(src))
|
||||
if(isrobot(src))
|
||||
if(src:module_active)
|
||||
return src:module_active
|
||||
else
|
||||
if (hand)
|
||||
return l_hand
|
||||
else
|
||||
return r_hand
|
||||
return
|
||||
return get_active_hand() //TODO: get rid of this proc
|
||||
|
||||
/mob/living/carbon/human/proc/equip_if_possible(obj/item/W, slot, del_on_fail = 1) // since byond doesn't seem to have pointers, this seems like the best way to do this :/
|
||||
//warning: icky code
|
||||
|
||||
@@ -341,7 +341,7 @@
|
||||
/mob/living/carbon/can_use_hands()
|
||||
if(handcuffed)
|
||||
return 0
|
||||
if(buckled && ! istype(buckled, /obj/structure/stool/bed/chair)) // buckling does not restrict hands
|
||||
if(buckled && ! istype(buckled, /obj/structure/bed/chair)) // buckling does not restrict hands
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
distance = 1
|
||||
if (src.stat)
|
||||
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
|
||||
if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3)
|
||||
if((stat == 2 || src.losebreath) && distance <= 3)
|
||||
msg += "<span class='warning'>[t_He] does not appear to be breathing.</span>\n"
|
||||
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
|
||||
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
|
||||
@@ -451,6 +451,7 @@
|
||||
msg += "\n[t_He] is [pose]"
|
||||
|
||||
user << msg
|
||||
..()
|
||||
|
||||
//Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records.
|
||||
/proc/hasHUD(mob/M as mob, hudtype)
|
||||
|
||||
@@ -696,6 +696,8 @@
|
||||
number += 2
|
||||
if(istype(src.head, /obj/item/clothing/head/helmet/space))
|
||||
number += 2
|
||||
if(istype(src.head, /obj/item/clothing/head/helmet/space/emergency))
|
||||
number -= 2
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/thermal))
|
||||
number -= 1
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses/sunglasses))
|
||||
@@ -1237,7 +1239,7 @@
|
||||
// Might need re-wording.
|
||||
user << "<span class='alert'>There is no exposed flesh or thin material [target_zone == "head" ? "on their head" : "on their body"] to inject into.</span>"
|
||||
|
||||
/mob/living/carbon/human/print_flavor_text()
|
||||
/mob/living/carbon/human/print_flavor_text(var/shrink = 1)
|
||||
var/list/equipment = list(src.head,src.wear_mask,src.glasses,src.w_uniform,src.wear_suit,src.gloves,src.shoes)
|
||||
var/head_exposed = 1
|
||||
var/face_exposed = 1
|
||||
@@ -1273,7 +1275,10 @@
|
||||
if((T == "head" && head_exposed) || (T == "face" && face_exposed) || (T == "eyes" && eyes_exposed) || (T == "torso" && torso_exposed) || (T == "arms" && arms_exposed) || (T == "hands" && hands_exposed) || (T == "legs" && legs_exposed) || (T == "feet" && feet_exposed))
|
||||
flavor_text += flavor_texts[T]
|
||||
flavor_text += "\n\n"
|
||||
return ..()
|
||||
if(!shrink)
|
||||
return flavor_text
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/getDNA()
|
||||
if(species.flags & NO_SCAN)
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
|
||||
if(src.grabbed_by.len || src.buckled || !src.canmove || src==H)
|
||||
accurate = 1 // certain circumstances make it impossible for us to evade punches
|
||||
rand_damage = 5
|
||||
|
||||
// Process evasion and blocking
|
||||
var/miss_type = 0
|
||||
@@ -209,7 +210,7 @@
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
|
||||
|
||||
if (istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
|
||||
if(istype(r_hand,/obj/item/weapon/gun) || istype(l_hand,/obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/W = null
|
||||
var/chance = 0
|
||||
|
||||
@@ -231,9 +232,13 @@
|
||||
|
||||
var/randn = rand(1, 100)
|
||||
if(!(species.flags & NO_SLIP) && randn <= 25)
|
||||
apply_effect(3, WEAKEN, run_armor_check(affecting, "melee"))
|
||||
var/armor_check = run_armor_check(affecting, "melee")
|
||||
apply_effect(3, WEAKEN, armor_check)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("\red <B>[M] has pushed [src]!</B>")
|
||||
if(armor_check < 2)
|
||||
visible_message("<span class='danger'>[M] has pushed [src]!</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[M] attempted to push [src]!</span>")
|
||||
return
|
||||
|
||||
var/talked = 0 // BubbleWrap
|
||||
|
||||
@@ -38,9 +38,9 @@ emp_act
|
||||
return -1 // complete projectile permutation
|
||||
|
||||
//Shrapnel
|
||||
if (P.damage_type == BRUTE)
|
||||
if(P.can_embed())
|
||||
var/armor = getarmor_organ(organ, "bullet")
|
||||
if((P.embed && prob(20 + max(P.damage - armor, -10))))
|
||||
if(prob(20 + max(P.damage - armor, -10)))
|
||||
var/obj/item/weapon/shard/shrapnel/SP = new()
|
||||
SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel"
|
||||
SP.desc = "[SP.desc] It looks like it was fired from [P.shot_from]."
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
if(wear_suit)
|
||||
tally += wear_suit.slowdown
|
||||
|
||||
if(istype(buckled, /obj/structure/stool/bed/chair/wheelchair))
|
||||
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
|
||||
for(var/organ_name in list("l_hand","r_hand","l_arm","r_arm"))
|
||||
var/datum/organ/external/E = get_organ(organ_name)
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
|
||||
@@ -771,13 +771,7 @@ It can still be worn/put on as normal.
|
||||
if(slot_to_process)
|
||||
if(strip_item) //Stripping an item from the mob
|
||||
var/obj/item/W = strip_item
|
||||
target.u_equip(W)
|
||||
if (target.client)
|
||||
target.client.screen -= W
|
||||
if (W)
|
||||
W.loc = target.loc
|
||||
W.layer = initial(W.layer)
|
||||
W.dropped(target)
|
||||
target.remove_from_mob(W)
|
||||
W.add_fingerprint(source)
|
||||
if(slot_to_process == slot_l_store) //pockets! Needs to process the other one too. Snowflake code, wooo! It's not like anyone will rewrite this anytime soon. If I'm wrong then... CONGRATULATIONS! ;)
|
||||
if(target.r_store)
|
||||
|
||||
@@ -326,7 +326,6 @@
|
||||
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
|
||||
|
||||
proc/breathe()
|
||||
if(reagents.has_reagent("lexorin")) return
|
||||
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
|
||||
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
|
||||
|
||||
@@ -439,17 +438,15 @@
|
||||
return
|
||||
|
||||
if(!breath || (breath.total_moles == 0) || suiciding)
|
||||
failed_last_breath = 1
|
||||
if(suiciding)
|
||||
adjustOxyLoss(2)//If you are suiciding, you should die a little bit faster
|
||||
failed_last_breath = 1
|
||||
oxygen_alert = max(oxygen_alert, 1)
|
||||
return 0
|
||||
if(health > config.health_threshold_crit)
|
||||
adjustOxyLoss(HUMAN_MAX_OXYLOSS)
|
||||
failed_last_breath = 1
|
||||
else
|
||||
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
|
||||
failed_last_breath = 1
|
||||
|
||||
oxygen_alert = max(oxygen_alert, 1)
|
||||
|
||||
|
||||
@@ -209,5 +209,5 @@
|
||||
if("resin membrane")
|
||||
new /obj/effect/alien/resin/membrane(loc)
|
||||
if("resin nest")
|
||||
new /obj/structure/stool/bed/nest(loc)
|
||||
new /obj/structure/bed/nest(loc)
|
||||
return
|
||||
@@ -64,7 +64,7 @@
|
||||
target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour)
|
||||
if("l_leg", "l_foot", "r_leg", "r_foot")
|
||||
if(!target.lying)
|
||||
target.visible_message("<span class='warning'>[src] gives way slightly.</span>")
|
||||
target.visible_message("<span class='warning'>[target] gives way slightly.</span>")
|
||||
target.apply_effect(attack_damage*3, AGONY, armour)
|
||||
else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 2) // Chance to get the usual throwdown as well (25% standard chance)
|
||||
if(!target.lying)
|
||||
@@ -118,22 +118,28 @@
|
||||
user.visible_message("<span class='danger'>[user] slapped [target] across \his cheek!</span>")
|
||||
if(3 to 4)
|
||||
user.visible_message(pick(
|
||||
80; "<span class='danger'>[user] [pick(attack_verb)] [target] in the head!</span>", //striking someone with a 'closed fist' is called punching them.
|
||||
20; "<span class='danger'>[user] struck [target] in the head[pick("", " with a closed fist")]!</span>"
|
||||
40; "<span class='danger'>[user] [pick(attack_verb)] [target] in the head!</span>",
|
||||
30; "<span class='danger'>[user] struck [target] in the head[pick("", " with a closed fist")]!</span>",
|
||||
30; "<span class='danger'>[user] threw a hook against [target]'s head!</span>"
|
||||
))
|
||||
if(5)
|
||||
user.visible_message(pick(
|
||||
10; "<span class='danger'>[user] gave [target] a resounding slap to the face!</span>",
|
||||
90; "<span class='danger'>[user] smashed \his [pick(attack_noun)] into [target]'s [organ]!</span>"
|
||||
30; "<span class='danger'>[user] gave [target] a resounding [pick("slap", "punch")] to the face!</span>",
|
||||
40; "<span class='danger'>[user] smashed \his [pick(attack_noun)] into [target]'s face!</span>",
|
||||
30; "<span class='danger'>[user] gave a strong blow against [target]'s jaw!</span>"
|
||||
))
|
||||
else
|
||||
// ----- BODY ----- //
|
||||
switch(attack_damage)
|
||||
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target]'s [organ]!</span>")
|
||||
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
|
||||
if(5) user.visible_message("<span class='danger'>[user] smashed \his [pick(attack_noun)] into [target]'s [organ]!</span>")
|
||||
if(1 to 2) user.visible_message("<span class='danger'>[user] threw a glancing punch at [target]'s [organ]!</span>")
|
||||
if(1 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
|
||||
if(5)
|
||||
user.visible_message(pick(
|
||||
50; "<span class='danger'>[user] smashed \his [pick(attack_noun)] into [target]'s [organ]!</span>",
|
||||
50; "<span class='danger'>[user] landed a striking [pick(attack_noun)] on [target]'s [organ]!</span>"
|
||||
))
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch", "struck", "slapped", "slammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>") //why do we have a separate set of verbs for lying targets?
|
||||
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch against", "struck", "slammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>") //why do we have a separate set of verbs for lying targets?
|
||||
|
||||
/datum/unarmed_attack/kick
|
||||
attack_verb = list("kicked", "kicked", "kicked", "kneed")
|
||||
@@ -177,7 +183,7 @@
|
||||
|
||||
/datum/unarmed_attack/stomp
|
||||
attack_verb = null
|
||||
attack_noun = list("kick")
|
||||
attack_noun = list("stomp")
|
||||
attack_sound = "swing_hit"
|
||||
damage = 0
|
||||
|
||||
@@ -189,7 +195,7 @@
|
||||
if(!istype(target))
|
||||
return 0
|
||||
|
||||
if (!user.lying && (target.lying || zone in list("l_foot", "r_foot")))
|
||||
if (!user.lying && (target.lying || (zone in list("l_foot", "r_foot"))))
|
||||
if(target.grabbed_by == user && target.lying)
|
||||
return 0
|
||||
var/datum/organ/external/E = user.organs_by_name["l_foot"]
|
||||
@@ -214,6 +220,5 @@
|
||||
attack_damage = Clamp(attack_damage, 1, 5)
|
||||
|
||||
switch(attack_damage)
|
||||
if(1 to 2) user.visible_message("<span class='danger'>[user] [pick("stepped on", "treaded on")] [target]'s [organ]!</span>") //stepped on conveys the same meaning and is more recognizable as an actual word than "clomped"
|
||||
if(3 to 4) user.visible_message("<span class='danger'>[pick("[user] stomped on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
|
||||
if(1 to 4) user.visible_message("<span class='danger'>[pick("[user] stomped on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
|
||||
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
|
||||
@@ -107,28 +107,29 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
//Human Overlays Indexes/////////
|
||||
#define MUTATIONS_LAYER 1
|
||||
#define DAMAGE_LAYER 2
|
||||
#define UNIFORM_LAYER 3
|
||||
#define TAIL_LAYER 4 //bs12 specific. this hack is probably gonna come back to haunt me
|
||||
#define ID_LAYER 5
|
||||
#define SHOES_LAYER 6
|
||||
#define GLOVES_LAYER 7
|
||||
#define SUIT_LAYER 8
|
||||
#define GLASSES_LAYER 9
|
||||
#define BELT_LAYER 10 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 11
|
||||
#define BACK_LAYER 12
|
||||
#define HAIR_LAYER 13 //TODO: make part of head layer?
|
||||
#define EARS_LAYER 14
|
||||
#define FACEMASK_LAYER 15
|
||||
#define HEAD_LAYER 16
|
||||
#define COLLAR_LAYER 17
|
||||
#define HANDCUFF_LAYER 18
|
||||
#define LEGCUFF_LAYER 19
|
||||
#define L_HAND_LAYER 20
|
||||
#define R_HAND_LAYER 21
|
||||
#define FIRE_LAYER 22 //If you're on fire
|
||||
#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 23
|
||||
#define SURGERY_LEVEL 3 //bs12 specific.
|
||||
#define UNIFORM_LAYER 4
|
||||
#define TAIL_LAYER 5 //bs12 specific. this hack is probably gonna come back to haunt me
|
||||
#define ID_LAYER 6
|
||||
#define SHOES_LAYER 7
|
||||
#define GLOVES_LAYER 8
|
||||
#define SUIT_LAYER 9
|
||||
#define GLASSES_LAYER 10
|
||||
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 12
|
||||
#define BACK_LAYER 13
|
||||
#define HAIR_LAYER 14 //TODO: make part of head layer?
|
||||
#define EARS_LAYER 15
|
||||
#define FACEMASK_LAYER 16
|
||||
#define HEAD_LAYER 17
|
||||
#define COLLAR_LAYER 18
|
||||
#define HANDCUFF_LAYER 19
|
||||
#define LEGCUFF_LAYER 20
|
||||
#define L_HAND_LAYER 21
|
||||
#define R_HAND_LAYER 22
|
||||
#define FIRE_LAYER 23 //If you're on fire
|
||||
#define TARGETED_LAYER 24 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 24
|
||||
//////////////////////////////////
|
||||
|
||||
/mob/living/carbon/human
|
||||
@@ -509,6 +510,7 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
update_inv_legcuffed(0)
|
||||
update_inv_pockets(0)
|
||||
update_fire(0)
|
||||
update_surgery(0)
|
||||
UpdateDamageIcon()
|
||||
update_icons()
|
||||
//Hud Stuff
|
||||
@@ -547,16 +549,9 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
overlays_standing[UNIFORM_LAYER] = null
|
||||
// This really, really seems like it should not be mixed in the middle of display code...
|
||||
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
|
||||
for( var/obj/item/thing in list(r_store, l_store, wear_id, belt) ) //
|
||||
if(thing) //
|
||||
u_equip(thing) //
|
||||
if (client) //
|
||||
client.screen -= thing //
|
||||
//
|
||||
if (thing) //
|
||||
thing.loc = loc //
|
||||
thing.dropped(src) //
|
||||
thing.layer = initial(thing.layer)
|
||||
for( var/obj/item/thing in list(r_store, l_store, wear_id, belt) )
|
||||
if(thing)
|
||||
remove_from_mob(thing)
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1)
|
||||
@@ -723,13 +718,22 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
belt.screen_loc = ui_belt //TODO
|
||||
var/t_state = belt.item_state
|
||||
if(!t_state) t_state = belt.icon_state
|
||||
var/image/standing = image("icon_state" = "[t_state]")
|
||||
|
||||
if(belt.icon_override)
|
||||
overlays_standing[BELT_LAYER] = image("icon" = belt.icon_override, "icon_state" = "[t_state]")
|
||||
standing.icon = belt.icon_override
|
||||
else if(belt.sprite_sheets && belt.sprite_sheets[species.name])
|
||||
overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[species.name], "icon_state" = "[t_state]")
|
||||
standing.icon = belt.sprite_sheets[species.name]
|
||||
else
|
||||
overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]")
|
||||
standing.icon = 'icons/mob/belt.dmi'
|
||||
|
||||
if(belt.contents.len && istype(belt, /obj/item/weapon/storage/belt))
|
||||
for(var/obj/item/i in belt.contents)
|
||||
var/i_state = i.item_state
|
||||
if(!i_state) i_state = i.icon_state
|
||||
standing.overlays += image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[i_state]")
|
||||
|
||||
overlays_standing[BELT_LAYER] = standing
|
||||
else
|
||||
overlays_standing[BELT_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
@@ -920,6 +924,16 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_surgery(var/update_icons=1)
|
||||
overlays_standing[SURGERY_LEVEL] = null
|
||||
var/image/total = new
|
||||
for(var/datum/organ/external/E in organs)
|
||||
if(E.open)
|
||||
var/image/I = image("icon"='icons/mob/surgery.dmi', "icon_state"="[E.name][round(E.open)]", "layer"=-SURGERY_LEVEL)
|
||||
total.overlays += I
|
||||
overlays_standing[SURGERY_LEVEL] = total
|
||||
if(update_icons) update_icons()
|
||||
|
||||
// Used mostly for creating head items
|
||||
/mob/living/carbon/human/proc/generate_head_icon()
|
||||
//gender no longer matters for the mouth, although there should probably be seperate base head icons.
|
||||
@@ -958,6 +972,7 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
//Human Overlays Indexes/////////
|
||||
#undef MUTATIONS_LAYER
|
||||
#undef DAMAGE_LAYER
|
||||
#undef SURGERY_LEVEL
|
||||
#undef UNIFORM_LAYER
|
||||
#undef TAIL_LAYER
|
||||
#undef ID_LAYER
|
||||
|
||||
@@ -171,7 +171,6 @@
|
||||
|
||||
// ++++ROCKDTBEN++++ MOB PROCS //END
|
||||
|
||||
|
||||
/mob/proc/get_contents()
|
||||
|
||||
|
||||
@@ -514,7 +513,7 @@
|
||||
return
|
||||
|
||||
//resisting grabs (as if it helps anyone...)
|
||||
if ((!( L.stat ) && L.canmove && !( L.restrained() )))
|
||||
if ((!( L.stat ) && !( L.restrained() )))
|
||||
var/resisting = 0
|
||||
for(var/obj/O in L.requests)
|
||||
L.requests.Remove(O)
|
||||
@@ -522,23 +521,20 @@
|
||||
resisting++
|
||||
for(var/obj/item/weapon/grab/G in usr.grabbed_by)
|
||||
resisting++
|
||||
if (G.state == 1)
|
||||
del(G)
|
||||
else
|
||||
if (G.state == 2)
|
||||
if (prob(25))
|
||||
for(var/mob/O in viewers(L, null))
|
||||
O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1)
|
||||
switch(G.state)
|
||||
if(GRAB_PASSIVE)
|
||||
del(G)
|
||||
if(GRAB_AGGRESSIVE)
|
||||
if(prob(60)) //same chance of breaking the grab as disarm
|
||||
L.visible_message("<span class='warning'>[L] has broken free of [G.assailant]'s grip!</span>")
|
||||
del(G)
|
||||
if(GRAB_NECK)
|
||||
//If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
|
||||
if (((world.time - G.assailant.l_move_time < 20 || !L.stunned) && prob(15)) || prob(3))
|
||||
L.visible_message("<span class='warning'>[L] has broken free of [G.assailant]'s headlock!</span>")
|
||||
del(G)
|
||||
else
|
||||
if (G.state == 3)
|
||||
if (prob(5))
|
||||
for(var/mob/O in viewers(usr, null))
|
||||
O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1)
|
||||
del(G)
|
||||
if(resisting)
|
||||
for(var/mob/O in viewers(usr, null))
|
||||
O.show_message(text("\red <B>[] resists!</B>", L), 1)
|
||||
L.visible_message("<span class='danger'>[L] resists!</span>")
|
||||
|
||||
|
||||
//unbuckling yourself
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
if(stat == DEAD || paralysis || weakened || stunned || restrained())
|
||||
return
|
||||
|
||||
if (layer != TURF_LAYER+0.2)
|
||||
layer = TURF_LAYER+0.2
|
||||
if (layer != 2.45)
|
||||
layer = 2.45 //Just above cables with their 2.44
|
||||
src << text("\blue You are now hiding.")
|
||||
else
|
||||
layer = MOB_LAYER
|
||||
|
||||
@@ -16,14 +16,6 @@
|
||||
integrated_light_power = 2
|
||||
local_transmit = 1
|
||||
|
||||
// We need to keep track of a few module items so we don't need to do list operations
|
||||
// every time we need them. These get set in New() after the module is chosen.
|
||||
var/obj/item/stack/sheet/metal/cyborg/stack_metal = null
|
||||
var/obj/item/stack/sheet/wood/cyborg/stack_wood = null
|
||||
var/obj/item/stack/sheet/glass/cyborg/stack_glass = null
|
||||
var/obj/item/stack/sheet/mineral/plastic/cyborg/stack_plastic = null
|
||||
var/obj/item/weapon/matter_decompiler/decompiler = null
|
||||
|
||||
//Used for self-mailing.
|
||||
var/mail_destination = ""
|
||||
|
||||
@@ -56,15 +48,6 @@
|
||||
verbs -= /mob/living/silicon/robot/verb/Namepick
|
||||
module = new /obj/item/weapon/robot_module/drone(src)
|
||||
|
||||
//Grab stacks.
|
||||
stack_metal = locate(/obj/item/stack/sheet/metal/cyborg) in src.module
|
||||
stack_wood = locate(/obj/item/stack/sheet/wood/cyborg) in src.module
|
||||
stack_glass = locate(/obj/item/stack/sheet/glass/cyborg) in src.module
|
||||
stack_plastic = locate(/obj/item/stack/sheet/mineral/plastic/cyborg) in src.module
|
||||
|
||||
//Grab decompiler.
|
||||
decompiler = locate(/obj/item/weapon/matter_decompiler) in src.module
|
||||
|
||||
//Some tidying-up.
|
||||
flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'"
|
||||
updateicon()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/mob/living/silicon/robot/drone/verb/set_mail_tag()
|
||||
set name = "Set Mail Tag"
|
||||
set desc = "Tag yourself for delivery through the disposals system."
|
||||
set category = "Drone"
|
||||
set category = "Robot Commands"
|
||||
|
||||
var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in tagger_locations
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
set name = "Drop Item"
|
||||
set desc = "Release an item from your magnetic gripper."
|
||||
set category = "Drone"
|
||||
set category = "Robot Commands"
|
||||
|
||||
if(!wrapped)
|
||||
//There's some weirdness with items being lost inside the arm. Trying to fix all cases. ~Z
|
||||
@@ -151,12 +151,10 @@
|
||||
icon_state = "decompiler"
|
||||
|
||||
//Metal, glass, wood, plastic.
|
||||
var/list/stored_comms = list(
|
||||
"metal" = 0,
|
||||
"glass" = 0,
|
||||
"wood" = 0,
|
||||
"plastic" = 0
|
||||
)
|
||||
var/datum/matter_synth/metal = null
|
||||
var/datum/matter_synth/glass = null
|
||||
var/datum/matter_synth/wood = null
|
||||
var/datum/matter_synth/plastic = null
|
||||
|
||||
/obj/item/weapon/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
return
|
||||
@@ -178,10 +176,10 @@
|
||||
src.loc.visible_message("\red [src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.","\red It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
del(M)
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(2000)
|
||||
return
|
||||
|
||||
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
|
||||
@@ -203,61 +201,66 @@
|
||||
del(M)
|
||||
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
|
||||
|
||||
stored_comms["metal"] += 15
|
||||
stored_comms["glass"] += 15
|
||||
stored_comms["wood"] += 5
|
||||
stored_comms["plastic"] += 5
|
||||
if(metal)
|
||||
metal.add_charge(15000)
|
||||
if(glass)
|
||||
glass.add_charge(15000)
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(1000)
|
||||
return
|
||||
else
|
||||
continue
|
||||
|
||||
for(var/obj/W in T)
|
||||
//Different classes of items give different commodities.
|
||||
if (istype(W,/obj/item/weapon/cigbutt))
|
||||
stored_comms["plastic"]++
|
||||
if(istype(W,/obj/item/weapon/cigbutt))
|
||||
if(plastic)
|
||||
plastic.add_charge(500)
|
||||
else if(istype(W,/obj/effect/spider/spiderling))
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(2000)
|
||||
else if(istype(W,/obj/item/weapon/light))
|
||||
var/obj/item/weapon/light/L = W
|
||||
if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
|
||||
stored_comms["metal"]++
|
||||
stored_comms["glass"]++
|
||||
if(metal)
|
||||
metal.add_charge(250)
|
||||
if(glass)
|
||||
glass.add_charge(250)
|
||||
else
|
||||
continue
|
||||
else if(istype(W,/obj/effect/decal/remains/robot))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["metal"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["glass"]++
|
||||
if(metal)
|
||||
metal.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(2000)
|
||||
if(glass)
|
||||
glass.add_charge(1000)
|
||||
else if(istype(W,/obj/item/trash))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
if(metal)
|
||||
metal.add_charge(1000)
|
||||
if(plastic)
|
||||
plastic.add_charge(3000)
|
||||
else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["metal"]++
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
if(metal)
|
||||
metal.add_charge(2000)
|
||||
if(glass)
|
||||
glass.add_charge(2000)
|
||||
else if(istype(W,/obj/item/ammo_casing))
|
||||
stored_comms["metal"]++
|
||||
if(metal)
|
||||
metal.add_charge(1000)
|
||||
else if(istype(W,/obj/item/weapon/shard/shrapnel))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["metal"]++
|
||||
stored_comms["metal"]++
|
||||
if(metal)
|
||||
metal.add_charge(1000)
|
||||
else if(istype(W,/obj/item/weapon/shard))
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
if(glass)
|
||||
glass.add_charge(1000)
|
||||
else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks/grown))
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
if(wood)
|
||||
wood.add_charge(4000)
|
||||
else if(istype(W,/obj/item/pipe))
|
||||
// This allows drones and engiborgs to clear pipe assemblies from floors.
|
||||
else
|
||||
@@ -325,39 +328,3 @@
|
||||
dat += resources
|
||||
|
||||
src << browse(dat, "window=robotmod")
|
||||
|
||||
//Putting the decompiler here to avoid doing list checks every tick.
|
||||
/mob/living/silicon/robot/drone/use_power()
|
||||
|
||||
..()
|
||||
if(!src.has_power || !decompiler)
|
||||
return
|
||||
|
||||
//The decompiler replenishes drone stores from hoovered-up junk each tick.
|
||||
for(var/type in decompiler.stored_comms)
|
||||
if(decompiler.stored_comms[type] > 0)
|
||||
var/obj/item/stack/sheet/stack
|
||||
switch(type)
|
||||
if("metal")
|
||||
if(!stack_metal)
|
||||
stack_metal = new /obj/item/stack/sheet/metal/cyborg(src.module)
|
||||
stack_metal.amount = 1
|
||||
stack = stack_metal
|
||||
if("glass")
|
||||
if(!stack_glass)
|
||||
stack_glass = new /obj/item/stack/sheet/glass/cyborg(src.module)
|
||||
stack_glass.amount = 1
|
||||
stack = stack_glass
|
||||
if("wood")
|
||||
if(!stack_wood)
|
||||
stack_wood = new /obj/item/stack/sheet/wood/cyborg(src.module)
|
||||
stack_wood.amount = 1
|
||||
stack = stack_wood
|
||||
if("plastic")
|
||||
if(!stack_plastic)
|
||||
stack_plastic = new /obj/item/stack/sheet/mineral/plastic/cyborg(src.module)
|
||||
stack_plastic.amount = 1
|
||||
stack = stack_plastic
|
||||
|
||||
stack.amount++
|
||||
decompiler.stored_comms[type]--;
|
||||
|
||||
@@ -552,6 +552,9 @@ var/list/robot_verbs_default = list(
|
||||
show_cell_power()
|
||||
show_jetpack_pressure()
|
||||
stat(null, text("Lights: [lights_on ? "ON" : "OFF"]"))
|
||||
if(module)
|
||||
for(var/datum/matter_synth/ms in module.synths)
|
||||
stat("[ms.name]: [ms.energy]/[ms.max_energy]")
|
||||
|
||||
/mob/living/silicon/robot/restrained()
|
||||
return 0
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
flags = CONDUCT
|
||||
var/channels = list()
|
||||
var/list/modules = list()
|
||||
var/list/datum/matter_synth/synths = list()
|
||||
var/obj/item/emag = null
|
||||
var/obj/item/borg/upgrade/jetpack = null
|
||||
var/list/stacktypes
|
||||
|
||||
/obj/item/weapon/robot_module/emp_act(severity)
|
||||
if(modules)
|
||||
@@ -17,40 +17,19 @@
|
||||
O.emp_act(severity)
|
||||
if(emag)
|
||||
emag.emp_act(severity)
|
||||
if(synths)
|
||||
for(var/datum/matter_synth/S in synths)
|
||||
S.emp_act(severity)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/New()
|
||||
..()
|
||||
// Build initial inventory.
|
||||
if(stacktypes && stacktypes.len)
|
||||
for(var/stack_type in stacktypes)
|
||||
var/obj/item/stack/new_stack = new stack_type (src)
|
||||
new_stack.amount = stacktypes[stack_type]
|
||||
modules |= new_stack
|
||||
/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate)
|
||||
|
||||
/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
if(!synths || !synths.len)
|
||||
return
|
||||
|
||||
if(!stacktypes || !stacktypes.len) return
|
||||
|
||||
for(var/T in stacktypes)
|
||||
var/obj/item/stack/S
|
||||
for(var/obj/O in src.modules)
|
||||
if(O.type == T)
|
||||
S = O
|
||||
break
|
||||
|
||||
if(!S)
|
||||
src.modules -= null
|
||||
S = new T(src)
|
||||
src.modules |= S
|
||||
S.amount = 1
|
||||
|
||||
if(!istype(S))
|
||||
continue
|
||||
|
||||
if(S && S.amount < stacktypes[T])
|
||||
S.amount++
|
||||
for(var/datum/matter_synth/T in synths)
|
||||
T.add_charge(T.recharge_rate * rate)
|
||||
|
||||
/obj/item/weapon/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
|
||||
var/list/temp_list = modules
|
||||
@@ -84,10 +63,6 @@
|
||||
|
||||
/obj/item/weapon/robot_module/surgeon
|
||||
name = "surgeon robot module"
|
||||
stacktypes = list(
|
||||
/obj/item/stack/medical/advanced/bruise_pack = 5,
|
||||
/obj/item/stack/nanopaste = 5
|
||||
)
|
||||
|
||||
/obj/item/weapon/robot_module/surgeon/New()
|
||||
..()
|
||||
@@ -104,26 +79,34 @@
|
||||
src.modules += new /obj/item/weapon/circular_saw(src)
|
||||
src.modules += new /obj/item/weapon/surgicaldrill(src)
|
||||
src.modules += new /obj/item/weapon/extinguisher/mini(src)
|
||||
src.modules += new /obj/item/stack/medical/advanced/bruise_pack(src)
|
||||
src.modules += new /obj/item/stack/nanopaste(src)
|
||||
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
|
||||
src.emag.reagents.add_reagent("pacid", 250)
|
||||
src.emag.name = "Polyacid spray"
|
||||
|
||||
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(10000)
|
||||
synths += medicine
|
||||
|
||||
var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
|
||||
var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
|
||||
N.uses_charge = 1
|
||||
N.charge_costs = list(1000)
|
||||
N.synths = list(medicine)
|
||||
B.uses_charge = 1
|
||||
B.charge_costs = list(1000)
|
||||
B.synths = list(medicine)
|
||||
src.modules += N
|
||||
src.modules += B
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
/obj/item/weapon/robot_module/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
if(src.emag)
|
||||
var/obj/item/weapon/reagent_containers/spray/PS = src.emag
|
||||
PS.reagents.add_reagent("pacid", 2)
|
||||
PS.reagents.add_reagent("pacid", 2 * amount)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/robot_module/crisis
|
||||
name = "crisis robot module"
|
||||
stacktypes = list(
|
||||
/obj/item/stack/medical/ointment = 5,
|
||||
/obj/item/stack/medical/bruise_pack = 5,
|
||||
/obj/item/stack/medical/splint = 5
|
||||
)
|
||||
|
||||
/obj/item/weapon/robot_module/crisis/New()
|
||||
..()
|
||||
@@ -132,9 +115,6 @@
|
||||
src.modules += new /obj/item/device/healthanalyzer(src)
|
||||
src.modules += new /obj/item/device/reagent_scanner/adv(src)
|
||||
src.modules += new /obj/item/roller_holder(src)
|
||||
src.modules += new /obj/item/stack/medical/ointment(src)
|
||||
src.modules += new /obj/item/stack/medical/bruise_pack(src)
|
||||
src.modules += new /obj/item/stack/medical/splint(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/borghypo/crisis(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
|
||||
@@ -143,9 +123,29 @@
|
||||
src.emag = new /obj/item/weapon/reagent_containers/spray(src)
|
||||
src.emag.reagents.add_reagent("pacid", 250)
|
||||
src.emag.name = "Polyacid spray"
|
||||
|
||||
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
|
||||
synths += medicine
|
||||
|
||||
var/obj/item/stack/medical/ointment/O = new /obj/item/stack/medical/ointment(src)
|
||||
var/obj/item/stack/medical/bruise_pack/B = new /obj/item/stack/medical/bruise_pack(src)
|
||||
var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
|
||||
O.uses_charge = 1
|
||||
O.charge_costs = list(1000)
|
||||
O.synths = list(medicine)
|
||||
B.uses_charge = 1
|
||||
B.charge_costs = list(1000)
|
||||
B.synths = list(medicine)
|
||||
S.uses_charge = 1
|
||||
S.charge_costs = list(1000)
|
||||
S.synths = list(medicine)
|
||||
src.modules += O
|
||||
src.modules += B
|
||||
src.modules += S
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
/obj/item/weapon/robot_module/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = locate() in src.modules
|
||||
if(S.mode == 2)
|
||||
@@ -156,20 +156,13 @@
|
||||
|
||||
if(src.emag)
|
||||
var/obj/item/weapon/reagent_containers/spray/PS = src.emag
|
||||
PS.reagents.add_reagent("pacid", 2)
|
||||
PS.reagents.add_reagent("pacid", 2 * amount)
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/weapon/robot_module/construction
|
||||
name = "construction robot module"
|
||||
|
||||
stacktypes = list(
|
||||
/obj/item/stack/sheet/metal = 50,
|
||||
/obj/item/stack/sheet/plasteel = 10,
|
||||
/obj/item/stack/sheet/glass/reinforced = 50,
|
||||
/obj/item/stack/rods = 50
|
||||
)
|
||||
|
||||
/obj/item/weapon/robot_module/construction/New()
|
||||
..()
|
||||
src.modules += new /obj/item/device/flash(src)
|
||||
@@ -182,18 +175,32 @@
|
||||
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
|
||||
src.modules += new /obj/item/device/pipe_painter(src)
|
||||
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
|
||||
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel()
|
||||
var/datum/matter_synth/glass = new /datum/matter_synth/glass()
|
||||
synths += metal
|
||||
synths += plasteel
|
||||
synths += glass
|
||||
|
||||
var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
|
||||
M.synths = list(metal)
|
||||
src.modules += M
|
||||
|
||||
var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
|
||||
R.synths = list(metal)
|
||||
src.modules += R
|
||||
|
||||
var/obj/item/stack/sheet/plasteel/cyborg/S = new /obj/item/stack/sheet/plasteel/cyborg(src)
|
||||
S.synths = list(metal)
|
||||
src.modules += S
|
||||
|
||||
var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src)
|
||||
RG.synths = list(metal, glass)
|
||||
src.modules += R
|
||||
|
||||
/obj/item/weapon/robot_module/engineering
|
||||
name = "engineering robot module"
|
||||
|
||||
stacktypes = list(
|
||||
/obj/item/stack/sheet/metal = 50,
|
||||
/obj/item/stack/sheet/glass = 50,
|
||||
/obj/item/stack/sheet/glass/reinforced = 50,
|
||||
/obj/item/stack/cable_coil/robot = 50,
|
||||
/obj/item/stack/rods = 15,
|
||||
/obj/item/stack/tile/plasteel = 15
|
||||
)
|
||||
|
||||
/obj/item/weapon/robot_module/engineering/New()
|
||||
..()
|
||||
src.modules += new /obj/item/device/flash(src)
|
||||
@@ -209,9 +216,45 @@
|
||||
src.modules += new /obj/item/device/analyzer(src)
|
||||
src.modules += new /obj/item/taperoll/engineering(src)
|
||||
src.modules += new /obj/item/weapon/gripper(src)
|
||||
src.modules += new /obj/item/weapon/matter_decompiler(src)
|
||||
src.modules += new /obj/item/device/pipe_painter(src)
|
||||
src.emag = new /obj/item/borg/stun(src)
|
||||
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
|
||||
var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
|
||||
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
|
||||
synths += metal
|
||||
synths += glass
|
||||
synths += wire
|
||||
|
||||
var/obj/item/weapon/matter_decompiler/MD = new /obj/item/weapon/matter_decompiler(src)
|
||||
MD.metal = metal
|
||||
MD.glass = glass
|
||||
src.modules += MD
|
||||
|
||||
var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
|
||||
M.synths = list(metal)
|
||||
src.modules += M
|
||||
|
||||
var/obj/item/stack/sheet/glass/cyborg/G = new /obj/item/stack/sheet/glass/cyborg(src)
|
||||
G.synths = list(glass)
|
||||
src.modules += G
|
||||
|
||||
var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
|
||||
R.synths = list(metal)
|
||||
src.modules += R
|
||||
|
||||
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
|
||||
C.synths = list(wire)
|
||||
src.modules += C
|
||||
|
||||
var/obj/item/stack/tile/plasteel/cyborg/S = new /obj/item/stack/tile/plasteel/cyborg(src)
|
||||
S.synths = list(metal)
|
||||
src.modules += S
|
||||
|
||||
var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src)
|
||||
RG.synths = list(metal, glass)
|
||||
src.modules += RG
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/security
|
||||
@@ -228,7 +271,7 @@
|
||||
src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/device/flash/F = locate() in src.modules
|
||||
if(F.broken)
|
||||
F.broken = 0
|
||||
@@ -238,7 +281,7 @@
|
||||
F.times_used--
|
||||
var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in src.modules
|
||||
if(T.power_supply.charge < T.power_supply.maxcharge)
|
||||
T.power_supply.give(T.charge_cost)
|
||||
T.power_supply.give(T.charge_cost * amount)
|
||||
T.update_icon()
|
||||
else
|
||||
T.charge_tick = 0
|
||||
@@ -258,12 +301,12 @@
|
||||
src.emag.name = "Lube spray"
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/device/lightreplacer/LR = locate() in src.modules
|
||||
LR.Charge(R)
|
||||
LR.Charge(R, amount)
|
||||
if(src.emag)
|
||||
var/obj/item/weapon/reagent_containers/spray/S = src.emag
|
||||
S.reagents.add_reagent("lube", 2)
|
||||
S.reagents.add_reagent("lube", 2 * amount)
|
||||
|
||||
/obj/item/weapon/robot_module/butler
|
||||
name = "service robot module"
|
||||
@@ -327,12 +370,12 @@
|
||||
R.add_language("Tradeband", 1)
|
||||
R.add_language("Gutter", 1)
|
||||
|
||||
/obj/item/weapon/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
/obj/item/weapon/robot_module/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
|
||||
E.reagents.add_reagent("enzyme", 2)
|
||||
E.reagents.add_reagent("enzyme", 2 * amount)
|
||||
if(src.emag)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/cans/beer/B = src.emag
|
||||
B.reagents.add_reagent("beer2", 2)
|
||||
B.reagents.add_reagent("beer2", 2 * amount)
|
||||
|
||||
/obj/item/weapon/robot_module/miner
|
||||
name = "miner robot module"
|
||||
@@ -392,17 +435,6 @@
|
||||
|
||||
/obj/item/weapon/robot_module/drone
|
||||
name = "drone module"
|
||||
stacktypes = list(
|
||||
/obj/item/stack/sheet/wood = 1,
|
||||
/obj/item/stack/sheet/mineral/plastic = 1,
|
||||
/obj/item/stack/sheet/glass/reinforced = 5,
|
||||
/obj/item/stack/tile/wood = 5,
|
||||
/obj/item/stack/rods = 15,
|
||||
/obj/item/stack/tile/plasteel = 15,
|
||||
/obj/item/stack/sheet/metal = 20,
|
||||
/obj/item/stack/sheet/glass = 20,
|
||||
/obj/item/stack/cable_coil/robot = 30
|
||||
)
|
||||
|
||||
/obj/item/weapon/robot_module/drone/New()
|
||||
..()
|
||||
@@ -414,20 +446,73 @@
|
||||
src.modules += new /obj/item/device/multitool(src)
|
||||
src.modules += new /obj/item/device/lightreplacer(src)
|
||||
src.modules += new /obj/item/weapon/gripper(src)
|
||||
src.modules += new /obj/item/weapon/matter_decompiler(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/spray/cleaner/drone(src)
|
||||
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
|
||||
src.emag.name = "Plasma Cutter"
|
||||
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal(25000)
|
||||
var/datum/matter_synth/glass = new /datum/matter_synth/glass(25000)
|
||||
var/datum/matter_synth/wood = new /datum/matter_synth/wood(2000)
|
||||
var/datum/matter_synth/plastic = new /datum/matter_synth/plastic(1000)
|
||||
var/datum/matter_synth/wire = new /datum/matter_synth/wire(30)
|
||||
synths += metal
|
||||
synths += glass
|
||||
synths += wood
|
||||
synths += plastic
|
||||
synths += wire
|
||||
|
||||
var/obj/item/weapon/matter_decompiler/MD = new /obj/item/weapon/matter_decompiler(src)
|
||||
MD.metal = metal
|
||||
MD.glass = glass
|
||||
MD.wood = wood
|
||||
MD.plastic = plastic
|
||||
src.modules += MD
|
||||
|
||||
var/obj/item/stack/sheet/metal/cyborg/M = new /obj/item/stack/sheet/metal/cyborg(src)
|
||||
M.synths = list(metal)
|
||||
src.modules += M
|
||||
|
||||
var/obj/item/stack/sheet/glass/cyborg/G = new /obj/item/stack/sheet/glass/cyborg(src)
|
||||
G.synths = list(glass)
|
||||
src.modules += G
|
||||
|
||||
var/obj/item/stack/rods/cyborg/R = new /obj/item/stack/rods/cyborg(src)
|
||||
R.synths = list(metal)
|
||||
src.modules += R
|
||||
|
||||
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
|
||||
C.synths = list(wire)
|
||||
src.modules += C
|
||||
|
||||
var/obj/item/stack/tile/plasteel/cyborg/S = new /obj/item/stack/tile/plasteel/cyborg(src)
|
||||
S.synths = list(metal)
|
||||
src.modules += S
|
||||
|
||||
var/obj/item/stack/sheet/glass/reinforced/cyborg/RG = new /obj/item/stack/sheet/glass/reinforced/cyborg(src)
|
||||
RG.synths = list(metal, glass)
|
||||
src.modules += RG
|
||||
|
||||
var/obj/item/stack/tile/wood/cyborg/WT = new /obj/item/stack/tile/wood/cyborg(src)
|
||||
WT.synths = list(wood)
|
||||
src.modules += WT
|
||||
|
||||
var/obj/item/stack/sheet/wood/cyborg/W = new /obj/item/stack/sheet/wood/cyborg(src)
|
||||
W.synths = list(wood)
|
||||
src.modules += W
|
||||
|
||||
var/obj/item/stack/sheet/mineral/plastic/cyborg/P = new /obj/item/stack/sheet/mineral/plastic/cyborg(src)
|
||||
P.synths = list(plastic)
|
||||
src.modules += P
|
||||
|
||||
/obj/item/weapon/robot_module/drone/add_languages(var/mob/living/silicon/robot/R)
|
||||
return //not much ROM to spare in that tiny microprocessor!
|
||||
|
||||
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
/obj/item/weapon/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/weapon/reagent_containers/spray/cleaner/C = locate() in src.modules
|
||||
C.reagents.add_reagent("cleaner", 3)
|
||||
C.reagents.add_reagent("cleaner", 3 * amount)
|
||||
|
||||
var/obj/item/device/lightreplacer/LR = locate() in src.modules
|
||||
LR.Charge(R)
|
||||
LR.Charge(R, amount)
|
||||
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
response_harm = "kicks"
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
var/mob/flee_target
|
||||
min_oxy = 16 //Require atleast 16kPA oxygen
|
||||
minbodytemp = 223 //Below -50 Degrees Celcius
|
||||
maxbodytemp = 323 //Above 50 Degrees Celcius
|
||||
@@ -44,27 +45,71 @@
|
||||
break
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
handle_movement_target()
|
||||
turns_since_scan++
|
||||
if (turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
|
||||
if (flee_target) //fleeing takes precendence
|
||||
handle_flee_target()
|
||||
else
|
||||
handle_movement_target()
|
||||
|
||||
/mob/living/simple_animal/cat/proc/handle_movement_target()
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
/mob/living/simple_animal/cat/proc/handle_movement_target()
|
||||
//if our target is neither inside a turf or inside a human(???), stop
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
//if we have no target or our current one is out of sight/too far away
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 4)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src)) //search for a new target
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 4)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src))
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
/mob/living/simple_animal/cat/proc/handle_flee_target()
|
||||
//see if we should stop fleeing
|
||||
if (flee_target && !(flee_target.loc in view(src)))
|
||||
flee_target = null
|
||||
stop_automated_movement = 0
|
||||
|
||||
if (flee_target)
|
||||
if(prob(25)) say("HSSSSS")
|
||||
stop_automated_movement = 1
|
||||
walk_away(src, flee_target, 7, 2)
|
||||
|
||||
/mob/living/simple_animal/cat/proc/set_flee_target(atom/A)
|
||||
if(A)
|
||||
flee_target = A
|
||||
turns_since_scan = 5
|
||||
|
||||
/mob/living/simple_animal/cat/attackby(var/obj/item/O, var/mob/user)
|
||||
. = ..()
|
||||
if(O.force)
|
||||
set_flee_target(user? user : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/attack_hand(mob/living/carbon/human/M as mob)
|
||||
. = ..()
|
||||
if(M.a_intent == "hurt")
|
||||
set_flee_target(M)
|
||||
|
||||
/mob/living/simple_animal/cat/ex_act()
|
||||
. = ..()
|
||||
set_flee_target(src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/bullet_act(var/obj/item/projectile/proj)
|
||||
. = ..()
|
||||
set_flee_target(proj.firer? proj.firer : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/hitby(atom/movable/AM)
|
||||
. = ..()
|
||||
set_flee_target(AM.thrower? AM.thrower : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/MouseDrop(atom/over_object)
|
||||
|
||||
@@ -82,14 +127,91 @@
|
||||
return //since the holder icon looks like a living cat
|
||||
..()
|
||||
|
||||
//Basic friend AI
|
||||
/mob/living/simple_animal/cat/fluff
|
||||
var/mob/living/carbon/human/friend
|
||||
var/befriend_job = null
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/handle_movement_target()
|
||||
if (friend)
|
||||
var/follow_dist = 5
|
||||
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger
|
||||
follow_dist = 1
|
||||
else if (friend.stat || friend.health <= 50) //danger or just sleeping
|
||||
follow_dist = 2
|
||||
var/near_dist = max(follow_dist - 2, 1)
|
||||
var/current_dist = get_dist(src, friend)
|
||||
|
||||
if (movement_target != friend)
|
||||
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (friend in oview(src)))
|
||||
//stop existing movement
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
|
||||
//walk to friend
|
||||
stop_automated_movement = 1
|
||||
movement_target = friend
|
||||
walk_to(src, movement_target, near_dist, 4)
|
||||
|
||||
//already following and close enough, stop
|
||||
else if (current_dist <= near_dist)
|
||||
walk_to(src,0)
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if (prob(10))
|
||||
say("Meow!")
|
||||
|
||||
if (!friend || movement_target != friend)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/Life()
|
||||
..()
|
||||
if (stat || !friend)
|
||||
return
|
||||
if (get_dist(src, friend) <= 1)
|
||||
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
|
||||
if (prob((friend.stat < DEAD)? 50 : 15))
|
||||
var/verb = pick("meows", "mews", "mrowls")
|
||||
audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
|
||||
else
|
||||
if (prob(5))
|
||||
visible_emote(pick("nuzzles [friend].",
|
||||
"brushes against [friend].",
|
||||
"rubs against [friend].",
|
||||
"purrs."))
|
||||
else if (friend.health <= 50)
|
||||
if (prob(10))
|
||||
var/verb = pick("meows", "mews", "mrowls")
|
||||
audible_emote("[verb] anxiously.")
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/verb/friend()
|
||||
set name = "Become Friends"
|
||||
set category = "IC"
|
||||
set src in view(1)
|
||||
|
||||
if(friend && usr == friend)
|
||||
set_dir(get_dir(src, friend))
|
||||
say("Meow!")
|
||||
return
|
||||
|
||||
if (!(ishuman(usr) && befriend_job && usr.job == befriend_job))
|
||||
usr << "<span class='notice'>[src] ignores you.</span>"
|
||||
return
|
||||
|
||||
friend = usr
|
||||
|
||||
set_dir(get_dir(src, friend))
|
||||
say("Meow!")
|
||||
|
||||
//RUNTIME IS ALIVE! SQUEEEEEEEE~
|
||||
/mob/living/simple_animal/cat/Runtime
|
||||
/mob/living/simple_animal/cat/fluff/Runtime
|
||||
name = "Runtime"
|
||||
desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally."
|
||||
gender = FEMALE
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
befriend_job = "Chief Medical Officer"
|
||||
|
||||
/mob/living/simple_animal/cat/kitten
|
||||
name = "kitten"
|
||||
@@ -97,4 +219,8 @@
|
||||
icon_state = "kitten"
|
||||
icon_living = "kitten"
|
||||
icon_dead = "kitten_dead"
|
||||
gender = NEUTER
|
||||
gender = NEUTER
|
||||
|
||||
/mob/living/simple_animal/cat/kitten/New()
|
||||
gender = pick(MALE, FEMALE)
|
||||
..()
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
adjustBruteLoss(-medical_pack.heal_brute)
|
||||
visible_message("<span class='warning'>\The [user] applies the [medical_pack] to \the [src].</span>")
|
||||
else
|
||||
user << "<span class='warning'>\The [src] cannot benefit from medical items in its current state.</span>"
|
||||
user << "<span class='warning'>\The [src] cannot benefit from medical items in \his current state.</span>"
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
|
||||
|
||||
@@ -183,7 +183,7 @@ var/list/slot_equipment_priority = list( \
|
||||
if(!istype(W)) return 0
|
||||
|
||||
for(var/slot in slot_equipment_priority)
|
||||
if(equip_to_slot_if_possible(W, slot, 0, 1, 1)) //del_on_fail = 0; disable_warning = 0; redraw_mob = 1
|
||||
if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -836,6 +836,7 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
|
||||
|
||||
|
||||
|
||||
// facing verbs
|
||||
/mob/proc/canface()
|
||||
if(!canmove) return 0
|
||||
@@ -867,7 +868,7 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
|
||||
lying = 1
|
||||
canmove = 0
|
||||
else if( stunned )
|
||||
else if(stunned)
|
||||
canmove = 0
|
||||
else if(captured)
|
||||
anchored = 1
|
||||
@@ -884,6 +885,11 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
else
|
||||
density = 1
|
||||
|
||||
for(var/obj/item/weapon/grab/G in grabbed_by)
|
||||
if(G.state >= GRAB_AGGRESSIVE)
|
||||
canmove = 0
|
||||
break
|
||||
|
||||
//Temporarily moved here from the various life() procs
|
||||
//I'm fixing stuff incrementally so this will likely find a better home.
|
||||
//It just makes sense for now. ~Carn
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
var/m_int = null//Living
|
||||
var/m_intent = "run"//Living
|
||||
var/lastKnownIP = null
|
||||
var/obj/structure/stool/bed/buckled = null//Living
|
||||
var/obj/structure/bed/buckled = null//Living
|
||||
var/obj/item/l_hand = null//Living
|
||||
var/obj/item/r_hand = null//Living
|
||||
var/obj/item/weapon/back = null//Human/Monkey
|
||||
@@ -223,3 +223,5 @@
|
||||
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
|
||||
|
||||
var/list/active_genes=list()
|
||||
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
hud.name = "reinforce grab"
|
||||
hud.master = src
|
||||
|
||||
/obj/item/weapon/grab/Del()
|
||||
//make sure the grabbed_by list doesn't fill up with nulls
|
||||
if(affecting) affecting.grabbed_by -= src
|
||||
..()
|
||||
|
||||
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
|
||||
/obj/item/weapon/grab/proc/throw()
|
||||
@@ -67,6 +71,7 @@
|
||||
|
||||
if(state <= GRAB_AGGRESSIVE)
|
||||
allow_upgrade = 1
|
||||
//disallow upgrading if we're grabbing more than one person
|
||||
if((assailant.l_hand && assailant.l_hand != src && istype(assailant.l_hand, /obj/item/weapon/grab)))
|
||||
var/obj/item/weapon/grab/G = assailant.l_hand
|
||||
if(G.affecting != affecting)
|
||||
@@ -76,31 +81,29 @@
|
||||
if(G.affecting != affecting)
|
||||
allow_upgrade = 0
|
||||
if(state == GRAB_AGGRESSIVE)
|
||||
var/h = affecting.hand
|
||||
affecting.hand = 0
|
||||
affecting.drop_item()
|
||||
affecting.hand = 1
|
||||
affecting.drop_item()
|
||||
affecting.hand = h
|
||||
affecting.drop_l_hand()
|
||||
affecting.drop_r_hand()
|
||||
//disallow upgrading past aggressive if we're being grabbed aggressively
|
||||
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
|
||||
if(G == src) continue
|
||||
if(G.state == GRAB_AGGRESSIVE)
|
||||
if(G.state >= GRAB_AGGRESSIVE)
|
||||
allow_upgrade = 0
|
||||
if(allow_upgrade)
|
||||
hud.icon_state = "reinforce"
|
||||
else
|
||||
hud.icon_state = "!reinforce"
|
||||
else
|
||||
if(!affecting.buckled)
|
||||
affecting.loc = assailant.loc
|
||||
else if(!affecting.buckled)
|
||||
affecting.loc = assailant.loc
|
||||
|
||||
if(state >= GRAB_NECK)
|
||||
affecting.Stun(5) //It will hamper your voice, being choked and all.
|
||||
affecting.Stun(1)
|
||||
if(isliving(affecting))
|
||||
var/mob/living/L = affecting
|
||||
L.adjustOxyLoss(1)
|
||||
|
||||
if(state >= GRAB_KILL)
|
||||
//affecting.apply_effect(STUTTER, 5) //would do this, but affecting isn't declared as mob/living for some stupid reason.
|
||||
affecting.stuttering = max(affecting.stuttering, 5) //It will hamper your voice, being choked and all.
|
||||
affecting.Weaken(5) //Should keep you down unless you get help.
|
||||
affecting.losebreath = min(affecting.losebreath + 2, 3)
|
||||
|
||||
@@ -126,48 +129,46 @@
|
||||
assailant.visible_message("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
|
||||
state = GRAB_AGGRESSIVE
|
||||
icon_state = "grabbed1"
|
||||
else
|
||||
if(state < GRAB_NECK)
|
||||
if(isslime(affecting))
|
||||
assailant << "<span class='notice'>You squeeze [affecting], but nothing interesting happens.</span>"
|
||||
else if(state < GRAB_NECK)
|
||||
if(isslime(affecting))
|
||||
assailant << "<span class='notice'>You squeeze [affecting], but nothing interesting happens.</span>"
|
||||
return
|
||||
|
||||
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
|
||||
state = GRAB_NECK
|
||||
icon_state = "grabbed+1"
|
||||
if(!affecting.buckled)
|
||||
affecting.loc = assailant.loc
|
||||
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has had their neck grabbed by [assailant.name] ([assailant.ckey])</font>"
|
||||
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Grabbed the neck of [affecting.name] ([affecting.ckey])</font>"
|
||||
msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]")
|
||||
hud.icon_state = "disarm/kill"
|
||||
hud.name = "disarm/kill"
|
||||
else if(state < GRAB_UPGRADING)
|
||||
assailant.visible_message("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
|
||||
hud.icon_state = "disarm/kill1"
|
||||
state = GRAB_UPGRADING
|
||||
if(do_after(assailant, UPGRADE_KILL_TIMER))
|
||||
if(state == GRAB_KILL)
|
||||
return
|
||||
if(!affecting)
|
||||
del(src)
|
||||
return
|
||||
if(!assailant.canmove || assailant.lying)
|
||||
del(src)
|
||||
return
|
||||
state = GRAB_KILL
|
||||
assailant.visible_message("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
|
||||
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
|
||||
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
|
||||
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
|
||||
|
||||
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
|
||||
state = GRAB_NECK
|
||||
icon_state = "grabbed+1"
|
||||
if(!affecting.buckled)
|
||||
affecting.loc = assailant.loc
|
||||
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has had their neck grabbed by [assailant.name] ([assailant.ckey])</font>"
|
||||
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Grabbed the neck of [affecting.name] ([affecting.ckey])</font>"
|
||||
msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]")
|
||||
hud.icon_state = "disarm/kill"
|
||||
hud.name = "disarm/kill"
|
||||
assailant.next_move = world.time + 10
|
||||
affecting.losebreath += 1
|
||||
else
|
||||
if(state < GRAB_UPGRADING)
|
||||
assailant.visible_message("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
|
||||
hud.icon_state = "disarm/kill1"
|
||||
state = GRAB_UPGRADING
|
||||
if(do_after(assailant, UPGRADE_KILL_TIMER))
|
||||
if(state == GRAB_KILL)
|
||||
return
|
||||
if(!affecting)
|
||||
del(src)
|
||||
return
|
||||
if(!assailant.canmove || assailant.lying)
|
||||
del(src)
|
||||
return
|
||||
state = GRAB_KILL
|
||||
assailant.visible_message("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
|
||||
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
|
||||
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
|
||||
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
|
||||
|
||||
assailant.next_move = world.time + 10
|
||||
affecting.losebreath += 1
|
||||
else
|
||||
assailant.visible_message("<span class='warning'>[assailant] was unable to tighten \his grip on [affecting]'s neck!</span>")
|
||||
hud.icon_state = "disarm/kill"
|
||||
state = GRAB_NECK
|
||||
assailant.visible_message("<span class='warning'>[assailant] was unable to tighten \his grip on [affecting]'s neck!</span>")
|
||||
hud.icon_state = "disarm/kill"
|
||||
state = GRAB_NECK
|
||||
|
||||
|
||||
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
|
||||
|
||||
@@ -80,6 +80,18 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/proc/isSilicon()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/isSilicon()
|
||||
return 1
|
||||
|
||||
/mob/proc/isAI()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/isAI()
|
||||
return 1
|
||||
|
||||
/proc/ispAI(A)
|
||||
if(istype(A, /mob/living/silicon/pai))
|
||||
return 1
|
||||
|
||||
@@ -284,9 +284,9 @@
|
||||
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
||||
if(istype(mob.loc, /turf/space))
|
||||
return // No wheelchair driving in space
|
||||
if(istype(mob.pulledby, /obj/structure/stool/bed/chair/wheelchair))
|
||||
if(istype(mob.pulledby, /obj/structure/bed/chair/wheelchair))
|
||||
return mob.pulledby.relaymove(mob, direct)
|
||||
else if(istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair))
|
||||
else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
if(ishuman(mob.buckled))
|
||||
var/mob/living/carbon/human/driver = mob.buckled
|
||||
var/datum/organ/external/l_hand = driver.get_organ("l_hand")
|
||||
@@ -351,30 +351,13 @@
|
||||
|
||||
///Process_Grab()
|
||||
///Called by client/Move()
|
||||
///Checks to see if you are being grabbed and if so attemps to break it
|
||||
///Checks to see if you are grabbing anything and if moving will affect your grab.
|
||||
/client/proc/Process_Grab()
|
||||
if(locate(/obj/item/weapon/grab, locate(/obj/item/weapon/grab, mob.grabbed_by.len)))
|
||||
var/list/grabbing = list()
|
||||
if(istype(mob.l_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = mob.l_hand
|
||||
grabbing += G.affecting
|
||||
if(istype(mob.r_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = mob.r_hand
|
||||
grabbing += G.affecting
|
||||
for(var/obj/item/weapon/grab/G in mob.grabbed_by)
|
||||
if((G.state == 1)&&(!grabbing.Find(G.assailant))) del(G)
|
||||
if(G.state == 2)
|
||||
move_delay = world.time + 10
|
||||
if(!prob(25)) return 1
|
||||
mob.visible_message("\red [mob] has broken free of [G.assailant]'s grip!")
|
||||
del(G)
|
||||
if(G.state == 3)
|
||||
move_delay = world.time + 10
|
||||
if(!prob(5)) return 1
|
||||
mob.visible_message("\red [mob] has broken free of [G.assailant]'s headlock!")
|
||||
del(G)
|
||||
return 0
|
||||
|
||||
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
|
||||
if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone
|
||||
mob.visible_message("<span class='warning'>[mob] lost \his tight grip on [G.affecting]'s neck!</span>")
|
||||
G.hud.icon_state = "disarm/kill"
|
||||
G.state = GRAB_NECK
|
||||
|
||||
///Process_Incorpmove
|
||||
///Called by client/Move()
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
|
||||
character.lastarea = get_area(loc)
|
||||
// Moving wheelchair if they have one
|
||||
if(character.buckled && istype(character.buckled, /obj/structure/stool/bed/chair/wheelchair))
|
||||
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
character.buckled.loc = character.loc
|
||||
character.buckled.set_dir(character.dir)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file contains all Nano procs/definitions for external classes/objects
|
||||
|
||||
// This file contains all Nano procs/definitions for external classes/objects
|
||||
|
||||
/**
|
||||
* Called when a Nano UI window is closed
|
||||
* This is how Nano handles closed windows
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
if (istype(ui))
|
||||
ui.close()
|
||||
|
||||
|
||||
if(ui.ref)
|
||||
var/href = "close=1"
|
||||
src.Topic(href, params2list(href), ui.ref) // this will direct to the atom's Topic() proc via client.Topic()
|
||||
@@ -31,14 +31,14 @@
|
||||
* ui_interact is currently defined for /atom/movable
|
||||
*
|
||||
* @param user /mob The mob who is interacting with this ui
|
||||
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
||||
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
|
||||
* @param ui /datum/nanoui This parameter is passed by the nanoui process() proc when updating an open ui
|
||||
* @param force_open boolean Force the UI to (re)open, even if it's already open
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/nano_ui/master_ui = null, var/datum/topic_state/custom_state = null)
|
||||
return
|
||||
|
||||
|
||||
// Used by the Nano UI Manager (/datum/nanomanager) to track UIs opened by this mob
|
||||
/mob/var/list/open_uis = list()
|
||||
|
||||
127
code/modules/nano/nanointeraction.dm
Normal file
127
code/modules/nano/nanointeraction.dm
Normal file
@@ -0,0 +1,127 @@
|
||||
/atom/movable/proc/nano_host()
|
||||
return src
|
||||
|
||||
/obj/nano_module/nano_host()
|
||||
return loc
|
||||
|
||||
|
||||
/atom/movable/proc/CanUseTopic(var/mob/user, href_list, var/datum/topic_state/custom_state)
|
||||
return user.can_use_topic(nano_host(), custom_state)
|
||||
|
||||
|
||||
/mob/proc/can_use_topic(var/mob/user, var/datum/topic_state/custom_state)
|
||||
return STATUS_CLOSE // By default no mob can do anything with NanoUI
|
||||
|
||||
/mob/dead/observer/can_use_topic()
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
return STATUS_INTERACTIVE // Admins are more equal
|
||||
return STATUS_UPDATE // Ghosts can view updates
|
||||
|
||||
/mob/living/silicon/pai/can_use_topic(var/src_object)
|
||||
if(src_object == src && !stat)
|
||||
return STATUS_INTERACTIVE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
if(stat || !client)
|
||||
return STATUS_CLOSE
|
||||
if(lockcharge || stunned || weakened)
|
||||
return STATUS_DISABLED
|
||||
// robots can interact with things they can see within their view range
|
||||
if(!(custom_state.flags & NANO_IGNORE_DISTANCE) && (src_object in view(src)))
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
|
||||
/mob/living/silicon/robot/syndicate/can_use_topic(var/src_object)
|
||||
. = ..()
|
||||
if(. != STATUS_INTERACTIVE)
|
||||
return
|
||||
|
||||
if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level
|
||||
return STATUS_INTERACTIVE
|
||||
if(istype(get_area(src), /area/syndicate_station)) // If elsewhere, they can interact with everything on the syndicate shuttle
|
||||
return STATUS_INTERACTIVE
|
||||
if(istype(src_object, /obj/machinery)) // Otherwise they can only interact with emagged machinery
|
||||
var/obj/machinery/Machine = src_object
|
||||
if(Machine.emagged)
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/silicon/ai/can_use_topic(var/src_object)
|
||||
if(!client || check_unable(1))
|
||||
return STATUS_CLOSE
|
||||
// Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras)
|
||||
// unless it's on the same level as the object it's interacting with.
|
||||
var/turf/T = get_turf(src_object)
|
||||
if(!T || !(z == T.z || (T.z in config.player_levels)))
|
||||
return STATUS_CLOSE
|
||||
|
||||
// If an object is in view then we can interact with it
|
||||
if(src_object in view(client.view, src))
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
// If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view
|
||||
if(is_in_chassis())
|
||||
//stop AIs from leaving windows open and using then after they lose vision
|
||||
//apc_override is needed here because AIs use their own APC when powerless
|
||||
if(cameranet && !cameranet.checkTurfVis(get_turf(src_object)))
|
||||
return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/proc/shared_living_nano_interaction(var/src_object)
|
||||
if (src.stat != CONSCIOUS)
|
||||
return STATUS_CLOSE // no updates, close the interface
|
||||
else if (restrained() || lying || stat || stunned || weakened)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI.
|
||||
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||
return user.shared_living_nano_distance(src_object)
|
||||
|
||||
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
|
||||
if(!isturf(src_object.loc))
|
||||
if(src_object.loc == src) // Item in the inventory
|
||||
return STATUS_INTERACTIVE
|
||||
if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates
|
||||
return STATUS_CLOSE
|
||||
|
||||
var/dist = get_dist(src_object, src)
|
||||
if (dist <= 1)
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
else if (dist <= 2)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
else if (dist <= 4)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE))
|
||||
if(loc)
|
||||
. = loc.contents_nano_distance(src_object, src)
|
||||
else
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(STATUS_INTERACTIVE)
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/carbon/human/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE))
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction.
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
/var/global/datum/topic_state/default_state = new()
|
||||
|
||||
/datum/topic_state
|
||||
var/flags = 0
|
||||
|
||||
/datum/topic_state/proc/href_list(var/mob/user)
|
||||
return list()
|
||||
@@ -186,7 +186,8 @@
|
||||
return 0 // wasn't open
|
||||
|
||||
processing_uis.Remove(ui)
|
||||
ui.user.open_uis.Remove(ui)
|
||||
if(ui.user) // Sanity check in case a user has been deleted (say a blown up borg watching the alarm interface)
|
||||
ui.user.open_uis.Remove(ui)
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||
uis.Remove(ui)
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/atom/movable/proc/nano_host()
|
||||
return src
|
||||
|
||||
/obj/nano_module/nano_host()
|
||||
return loc
|
||||
|
||||
/atom/movable/proc/nano_can_update()
|
||||
return 1
|
||||
|
||||
/obj/machinery/nano_can_update()
|
||||
return !(stat & (NOPOWER|BROKEN))
|
||||
@@ -52,6 +52,11 @@ nanoui is used to open and update nano browser uis
|
||||
// the current status/visibility of the ui
|
||||
var/status = STATUS_INTERACTIVE
|
||||
|
||||
// Relationship between a master interface and its children. Used in update_status
|
||||
var/datum/nanoui/master_ui
|
||||
var/list/datum/nanoui/children = list()
|
||||
var/datum/topic_state/custom_state = null
|
||||
|
||||
var/cached_data = null
|
||||
|
||||
/**
|
||||
@@ -68,17 +73,22 @@ nanoui is used to open and update nano browser uis
|
||||
*
|
||||
* @return /nanoui new nanoui object
|
||||
*/
|
||||
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null)
|
||||
/datum/nanoui/New(nuser, nsrc_object, nui_key, ntemplate_filename, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, var/datum/nanoui/master_ui = null, var/datum/topic_state/custom_state = null)
|
||||
user = nuser
|
||||
src_object = nsrc_object
|
||||
ui_key = nui_key
|
||||
window_id = "[ui_key]\ref[src_object]"
|
||||
|
||||
src.master_ui = master_ui
|
||||
if(master_ui)
|
||||
master_ui.children += src
|
||||
src.custom_state = custom_state ? custom_state : new/datum/topic_state()
|
||||
|
||||
// add the passed template filename as the "main" template, this is required
|
||||
add_template("main", ntemplate_filename)
|
||||
|
||||
if (ntitle)
|
||||
title = ntitle
|
||||
title = sanitize(ntitle)
|
||||
if (nwidth)
|
||||
width = nwidth
|
||||
if (nheight)
|
||||
@@ -133,120 +143,13 @@ nanoui is used to open and update nano browser uis
|
||||
*/
|
||||
/datum/nanoui/proc/update_status(var/push_update = 0)
|
||||
var/atom/movable/host = src_object.nano_host()
|
||||
if(!host.nano_can_update())
|
||||
close()
|
||||
return
|
||||
|
||||
var/status = user.can_interact_with_interface(host.nano_host())
|
||||
if(status == STATUS_CLOSE)
|
||||
var/new_status = host.CanUseTopic(user, list(), custom_state)
|
||||
if(master_ui)
|
||||
new_status = min(new_status, master_ui.status)
|
||||
if(new_status == STATUS_CLOSE)
|
||||
close()
|
||||
else
|
||||
set_status(status, push_update)
|
||||
|
||||
/*
|
||||
Procs called by update_status()
|
||||
*/
|
||||
|
||||
/mob/living/silicon/pai/can_interact_with_interface(src_object)
|
||||
if(src_object == src && !stat)
|
||||
return STATUS_INTERACTIVE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/proc/can_interact_with_interface(var/src_object)
|
||||
return STATUS_CLOSE // By default no mob can do anything with NanoUI
|
||||
|
||||
/mob/dead/observer/can_interact_with_interface()
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
return STATUS_INTERACTIVE // Admins are more equal
|
||||
return STATUS_UPDATE // Ghosts can view updates
|
||||
|
||||
/mob/living/silicon/robot/can_interact_with_interface(var/src_object)
|
||||
if(stat || !client)
|
||||
return STATUS_CLOSE
|
||||
if(lockcharge || stunned || weakened)
|
||||
return STATUS_DISABLED
|
||||
if (src_object in view(client.view, src)) // robots can see and interact with things they can see within their view range
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
|
||||
/mob/living/silicon/robot/syndicate/can_interact_with_interface(var/src_object)
|
||||
. = ..()
|
||||
if(. != STATUS_INTERACTIVE)
|
||||
return
|
||||
|
||||
if(z in config.admin_levels) // Syndicate borgs can interact with everything on the admin level
|
||||
return STATUS_INTERACTIVE
|
||||
if(istype(get_area(src), /area/syndicate_station)) // If elsewhere, they can interact with everything on the syndicate shuttle
|
||||
return STATUS_INTERACTIVE
|
||||
if(istype(src_object, /obj/machinery)) // Otherwise they can only interact with emagged machinery
|
||||
var/obj/machinery/Machine = src_object
|
||||
if(Machine.emagged)
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/silicon/ai/can_interact_with_interface(var/src_object)
|
||||
if(!client || check_unable(1))
|
||||
return STATUS_CLOSE
|
||||
// Prevents the AI from using Topic on admin levels (by for example viewing through the court/thunderdome cameras)
|
||||
// unless it's on the same level as the object it's interacting with.
|
||||
var/turf/T = get_turf(src_object)
|
||||
if(!T || !(z == T.z || (T.z in config.player_levels)))
|
||||
return STATUS_CLOSE
|
||||
|
||||
// If an object is in view then we can interact with it
|
||||
if(src_object in view(client.view, src))
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
// If we're installed in a chassi, rather than transfered to an inteliCard or other container, then check if we have camera view
|
||||
if(is_in_chassis())
|
||||
//stop AIs from leaving windows open and using then after they lose vision
|
||||
//apc_override is needed here because AIs use their own APC when powerless
|
||||
if(cameranet && !cameranet.checkTurfVis(get_turf(src_object)))
|
||||
return apc_override ? STATUS_INTERACTIVE : STATUS_CLOSE
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/proc/shared_living_nano_interaction(var/src_object)
|
||||
if (src.stat != CONSCIOUS)
|
||||
return STATUS_CLOSE // no updates, close the interface
|
||||
else if (restrained() || lying || stat || stunned || weakened)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
|
||||
if(!isturf(src_object.loc))
|
||||
if(src_object.loc == src) // Item in the inventory
|
||||
return STATUS_INTERACTIVE
|
||||
if(src.contents.Find(src_object.loc)) // A hidden uplink inside an item
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
if (!(src_object in view(4, src))) // If the src object is not in visable, disable updates
|
||||
return STATUS_CLOSE
|
||||
|
||||
var/dist = get_dist(src_object, src)
|
||||
if (dist <= 1)
|
||||
return STATUS_INTERACTIVE // interactive (green visibility)
|
||||
else if (dist <= 2)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
else if (dist <= 4)
|
||||
return STATUS_DISABLED // no updates, completely disabled (red visibility)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/mob/living/can_interact_with_interface(var/src_object, var/be_close = 1)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && be_close)
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(STATUS_INTERACTIVE)
|
||||
return STATUS_UPDATE
|
||||
|
||||
/mob/living/carbon/human/can_interact_with_interface(var/src_object, var/be_close = 1)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && be_close)
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(. == STATUS_UPDATE && (TK in mutations)) // If we have telekinesis and remain close enough, allow interaction.
|
||||
return STATUS_INTERACTIVE
|
||||
set_status(new_status, push_update)
|
||||
|
||||
/**
|
||||
* Set the ui to auto update (every master_controller tick)
|
||||
@@ -489,7 +392,6 @@ nanoui is used to open and update nano browser uis
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/open()
|
||||
|
||||
var/window_size = ""
|
||||
if (width && height)
|
||||
window_size = "size=[width]x[height];"
|
||||
@@ -509,6 +411,8 @@ nanoui is used to open and update nano browser uis
|
||||
is_auto_updating = 0
|
||||
nanomanager.ui_closed(src)
|
||||
user << browse(null, "window=[window_id]")
|
||||
for(var/datum/nanoui/child in children)
|
||||
child.close()
|
||||
|
||||
/**
|
||||
* Set the UI window to call the nanoclose verb when the window is closed
|
||||
@@ -573,7 +477,7 @@ nanoui is used to open and update nano browser uis
|
||||
set_map_z_level(text2num(href_list["mapZLevel"]))
|
||||
map_update = 1
|
||||
|
||||
if ((src_object && src_object.Topic(href, href_list)) || map_update)
|
||||
if ((src_object && src_object.Topic(href, href_list, 0, custom_state)) || map_update)
|
||||
nanomanager.update_uis(src_object) // update all UIs attached to src_object
|
||||
|
||||
/**
|
||||
@@ -600,5 +504,4 @@ nanoui is used to open and update nano browser uis
|
||||
* @return nothing
|
||||
*/
|
||||
/datum/nanoui/proc/update(var/force_open = 0)
|
||||
src_object.ui_interact(user, ui_key, src, force_open)
|
||||
|
||||
src_object.ui_interact(user, ui_key, src, force_open, master_ui, custom_state)
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
stance_damage = 0
|
||||
|
||||
// Buckled to a bed/chair. Stance damage is forced to 0 since they're sitting on something solid
|
||||
if (istype(buckled, /obj/structure/stool/bed))
|
||||
if (istype(buckled, /obj/structure/bed))
|
||||
return
|
||||
|
||||
for (var/organ in list("l_leg","l_foot","r_leg","r_foot"))
|
||||
|
||||
@@ -596,14 +596,11 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
update_damages()
|
||||
|
||||
var/obj/organ //Dropped limb object
|
||||
var/list/dropped_items
|
||||
switch(body_part)
|
||||
if(HEAD)
|
||||
organ= new /obj/item/weapon/organ/head(owner.loc, owner)
|
||||
owner.u_equip(owner.glasses)
|
||||
owner.u_equip(owner.head)
|
||||
owner.u_equip(owner.l_ear)
|
||||
owner.u_equip(owner.r_ear)
|
||||
owner.u_equip(owner.wear_mask)
|
||||
organ = new /obj/item/weapon/organ/head(owner.loc, owner)
|
||||
dropped_items = list(owner.glasses, owner.head, owner.l_ear, owner.r_ear, owner.wear_mask)
|
||||
if(ARM_RIGHT)
|
||||
if(status & ORGAN_ROBOT)
|
||||
organ = new /obj/item/robot_parts/r_arm(owner.loc)
|
||||
@@ -627,19 +624,22 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
if(HAND_RIGHT)
|
||||
if(!(status & ORGAN_ROBOT))
|
||||
organ= new /obj/item/weapon/organ/r_hand(owner.loc, owner)
|
||||
owner.u_equip(owner.gloves)
|
||||
dropped_items = list(owner.gloves) //should probably make it so that you can still wear gloves if you have one hand
|
||||
if(HAND_LEFT)
|
||||
if(!(status & ORGAN_ROBOT))
|
||||
organ= new /obj/item/weapon/organ/l_hand(owner.loc, owner)
|
||||
owner.u_equip(owner.gloves)
|
||||
dropped_items = list(owner.gloves)
|
||||
if(FOOT_RIGHT)
|
||||
if(!(status & ORGAN_ROBOT))
|
||||
organ= new /obj/item/weapon/organ/r_foot/(owner.loc, owner)
|
||||
owner.u_equip(owner.shoes)
|
||||
dropped_items = list(owner.shoes)
|
||||
if(FOOT_LEFT)
|
||||
if(!(status & ORGAN_ROBOT))
|
||||
organ = new /obj/item/weapon/organ/l_foot(owner.loc, owner)
|
||||
owner.u_equip(owner.shoes)
|
||||
dropped_items = list(owner.shoes)
|
||||
if(dropped_items)
|
||||
for(var/obj/O in dropped_items)
|
||||
owner.remove_from_mob(O)
|
||||
|
||||
destspawn = 1
|
||||
//Robotic limbs explode if sabotaged.
|
||||
|
||||
@@ -482,8 +482,17 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
item_state = "coil"
|
||||
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
|
||||
|
||||
/obj/item/stack/cable_coil/cyborg
|
||||
name = "cable coil synthesizer"
|
||||
desc = "A device that makes cable."
|
||||
gender = NEUTER
|
||||
matter = null
|
||||
uses_charge = 1
|
||||
charge_costs = list(1)
|
||||
stacktype = /obj/item/stack/cable_coil
|
||||
|
||||
/obj/item/stack/cable_coil/suicide_act(mob/user)
|
||||
if(locate(/obj/structure/stool) in user.loc)
|
||||
if(locate(/obj/item/weapon/stool) in user.loc)
|
||||
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
else
|
||||
user.visible_message("<span class='suicide'>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</span>")
|
||||
@@ -576,7 +585,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
usr << "\blue You cannot do that."
|
||||
..()
|
||||
|
||||
/obj/item/stack/cable_coil/robot/verb/set_colour()
|
||||
/obj/item/stack/cable_coil/cyborg/verb/set_colour()
|
||||
set name = "Change Colour"
|
||||
set category = "Object"
|
||||
|
||||
@@ -606,26 +615,26 @@ obj/structure/cable/proc/cableColor(var/colorC)
|
||||
// - Cable coil : merge cables
|
||||
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
|
||||
..()
|
||||
if( istype(W, /obj/item/weapon/wirecutters) && src.amount > 1)
|
||||
src.amount--
|
||||
if( istype(W, /obj/item/weapon/wirecutters) && src.get_amount() > 1)
|
||||
src.use(1)
|
||||
new/obj/item/stack/cable_coil(user.loc, 1,color)
|
||||
user << "You cut a piece off the cable coil."
|
||||
src.update_icon()
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = W
|
||||
if(C.amount >= MAXCOIL)
|
||||
if(C.get_amount() >= get_max_amount())
|
||||
user << "The coil is too long, you cannot add any more cable to it."
|
||||
return
|
||||
|
||||
if( (C.amount + src.amount <= MAXCOIL) )
|
||||
if( (C.get_amount() + src.get_amount() <= get_max_amount()) )
|
||||
user << "You join the cable coils together."
|
||||
C.give(src.amount) // give it cable
|
||||
src.use(src.amount) // make sure this one cleans up right
|
||||
C.give(src.get_amount()) // give it cable
|
||||
src.use(src.get_amount()) // make sure this one cleans up right
|
||||
return
|
||||
|
||||
else
|
||||
var/amt = MAXCOIL - C.amount
|
||||
var/amt = get_max_amount() - C.get_amount()
|
||||
user << "You transfer [amt] length\s of cable from one coil to the other."
|
||||
C.give(amt)
|
||||
src.use(amt)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/mc9mm/flash
|
||||
ammo_type = /obj/item/ammo_casing/c9mmf
|
||||
ammo_type = /obj/item/ammo_casing/c9mmf
|
||||
|
||||
/obj/item/ammo_magazine/c9mm
|
||||
name = "ammunition Box (9mm)"
|
||||
@@ -68,6 +68,22 @@
|
||||
/obj/item/ammo_magazine/c9mm/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/mc9mmt
|
||||
name = "top mounted magazine (9mm)"
|
||||
icon_state = "9mmt"
|
||||
mag_type = MAGAZINE
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
caliber = "9mm"
|
||||
max_ammo = 20
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/mc9mmt/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/mc9mmt/rubber
|
||||
name = "top mounted magazine (9mm rubber)"
|
||||
ammo_type = /obj/item/ammo_casing/c9mmr
|
||||
|
||||
/obj/item/ammo_magazine/c45
|
||||
name = "ammunition Box (.45)"
|
||||
icon_state = "9mm"
|
||||
@@ -92,6 +108,19 @@
|
||||
/obj/item/ammo_magazine/a12mm/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a556
|
||||
name = "magazine (5.56)"
|
||||
icon_state = "5.56"
|
||||
origin_tech = "combat=2"
|
||||
mag_type = MAGAZINE
|
||||
caliber = "a556"
|
||||
ammo_type = /obj/item/ammo_casing/a556
|
||||
max_ammo = 10
|
||||
multiple_sprites = 1
|
||||
|
||||
/obj/item/ammo_magazine/a556/empty
|
||||
initial_ammo = 0
|
||||
|
||||
/obj/item/ammo_magazine/a50
|
||||
name = "magazine (.50)"
|
||||
icon_state = "50ae"
|
||||
@@ -168,4 +197,4 @@
|
||||
ammo_type = "/obj/item/ammo_casing/a666"
|
||||
max_ammo = 4
|
||||
multiple_sprites = 1
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
caliber = "9mm"
|
||||
projectile_type = /obj/item/projectile/energy/flash
|
||||
|
||||
/obj/item/ammo_casing/c9mmr
|
||||
desc = "A 9mm rubber bullet casing."
|
||||
caliber = "9mm"
|
||||
projectile_type = /obj/item/projectile/bullet/pistol/rubber
|
||||
|
||||
|
||||
/obj/item/ammo_casing/c45
|
||||
desc = "A .45 bullet casing."
|
||||
@@ -84,7 +89,7 @@
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun/beanbag
|
||||
matter = list("metal" = 500)
|
||||
|
||||
//Can stun in one hit if aimed at the head, but
|
||||
//Can stun in one hit if aimed at the head, but
|
||||
//is blocked by clothing that stops tasers and is vulnerable to EMP
|
||||
/obj/item/ammo_casing/shotgun/stunshell
|
||||
name = "stun shell"
|
||||
@@ -113,12 +118,17 @@
|
||||
|
||||
/obj/item/ammo_casing/a145
|
||||
name = "shell casing"
|
||||
desc = "A 14.5mm AP shell."
|
||||
desc = "A 14.5mm shell."
|
||||
icon_state = "lcasing"
|
||||
spent_icon = "lcasing-spent"
|
||||
caliber = "14.5mm"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a145
|
||||
|
||||
/obj/item/ammo_casing/a556
|
||||
desc = "A 5.56mm bullet casing."
|
||||
caliber = "a556"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a556
|
||||
|
||||
/obj/item/ammo_casing/rocket
|
||||
name = "rocket shell"
|
||||
desc = "A high explosive designed to be fired from a launcher."
|
||||
|
||||
@@ -258,6 +258,10 @@
|
||||
accuracy = scoped_accuracy + scoped_accuracy_mod
|
||||
if(recoil)
|
||||
recoil = round(recoil*zoom_amount+1) //recoil is worse when looking through a scope
|
||||
else
|
||||
accuracy = (accuracy)
|
||||
|
||||
//make sure accuracy and recoil are reset regardless of how the item is unzoomed.
|
||||
/obj/item/weapon/gun/zoom()
|
||||
..()
|
||||
if(!zoom)
|
||||
accuracy = initial(accuracy)
|
||||
recoil = initial(recoil)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/weapon/gun/energy/laser
|
||||
name = "laser carbine"
|
||||
desc = "A basic weapon designed to kill with concentrated energy bolts."
|
||||
desc = "A common laser weapon, designed to kill with concentrated energy blasts."
|
||||
icon_state = "laser"
|
||||
item_state = "laser"
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
@@ -10,6 +10,8 @@
|
||||
matter = list("metal" = 2000)
|
||||
origin_tech = "combat=3;magnets=2"
|
||||
projectile_type = /obj/item/projectile/beam
|
||||
charge_cost = 75
|
||||
fire_delay = 1
|
||||
|
||||
/obj/item/weapon/gun/energy/laser/mounted
|
||||
self_recharge = 1
|
||||
@@ -42,7 +44,7 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
item_state = "laser"
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
origin_tech = "combat=4;materials=3;powerstorage=3"
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/beam/heavylaser
|
||||
charge_cost = 250
|
||||
fire_delay = 20
|
||||
@@ -50,7 +52,7 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
/obj/item/weapon/gun/energy/lasercannon/mounted
|
||||
self_recharge = 1
|
||||
use_external_power = 1
|
||||
recharge_time = 25
|
||||
recharge_time = 25
|
||||
|
||||
/obj/item/weapon/gun/energy/xray
|
||||
name = "xray laser gun"
|
||||
@@ -90,12 +92,12 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
name = "laser tag gun"
|
||||
item_state = "laser"
|
||||
desc = "Standard issue weapon of the Imperial Guard"
|
||||
origin_tech = "combat=1;magnets=2"
|
||||
origin_tech = "combat=1;magnets=2"
|
||||
self_recharge = 1
|
||||
matter = list("metal" = 2000)
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
projectile_type = /obj/item/projectile/beam/lastertag/blue
|
||||
var/required_vest
|
||||
var/required_vest
|
||||
|
||||
/obj/item/weapon/gun/energy/lasertag/special_check(var/mob/living/carbon/human/M)
|
||||
if(ishuman(M))
|
||||
@@ -112,4 +114,4 @@ obj/item/weapon/gun/energy/laser/retro
|
||||
/obj/item/weapon/gun/energy/lasertag/red
|
||||
icon_state = "redtag"
|
||||
projectile_type = /obj/item/projectile/beam/lastertag/red
|
||||
required_vest = /obj/item/clothing/suit/redtag
|
||||
required_vest = /obj/item/clothing/suit/redtag
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
name = "stun revolver"
|
||||
desc = "A high-tech revolver that fires stun cartridges. The stun cartridges can be recharged using a conventional energy weapon recharger."
|
||||
icon_state = "stunrevolver"
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
origin_tech = "combat=3;materials=3;powerstorage=2"
|
||||
charge_cost = 125
|
||||
projectile_type = /obj/item/projectile/beam/stun
|
||||
projectile_type = /obj/item/projectile/energy/electrode/stunshot
|
||||
cell_type = /obj/item/weapon/cell
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/obj/item/weapon/gun/launcher
|
||||
name = "launcher"
|
||||
desc = "A device that launches things."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
w_class = 5.0
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
/obj/item/weapon/gun/launcher/crossbow
|
||||
name = "powered crossbow"
|
||||
desc = "A 2557AD twist on an old classic. Pick up that can."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "crossbow"
|
||||
item_state = "crossbow-solid"
|
||||
fire_sound = 'sound/weapons/punchmiss.ogg' // TODO: Decent THWOK noise.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/obj/item/weapon/gun/launcher/grenade
|
||||
name = "grenade launcher"
|
||||
desc = "A bulky pump-action grenade launcher. Holds up to 5 grenades in a revolving magazine."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "riotgun"
|
||||
item_state = "riotgun"
|
||||
w_class = 4
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/obj/item/weapon/gun/launcher/pneumatic
|
||||
name = "pneumatic cannon"
|
||||
desc = "A large gas-powered cannon."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "pneumatic"
|
||||
item_state = "pneumatic"
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/weapon/syringe_cartridge
|
||||
name = "syringe gun cartridge"
|
||||
desc = "An impact-triggered compressed gas cartridge that can fitted to a syringe for rapid injection."
|
||||
desc = "An impact-triggered compressed gas cartridge that can be fitted to a syringe for rapid injection."
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
icon_state = "syringe-cartridge"
|
||||
var/icon_flight = "syringe-cartridge-flight" //so it doesn't look so weird when shot
|
||||
@@ -25,6 +25,7 @@
|
||||
user.remove_from_mob(syringe)
|
||||
syringe.loc = src
|
||||
sharp = 1
|
||||
name = "syringe dart"
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/syringe_cartridge/attack_self(mob/user)
|
||||
@@ -33,6 +34,7 @@
|
||||
user.put_in_hands(syringe)
|
||||
syringe = null
|
||||
sharp = initial(sharp)
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/syringe_cartridge/proc/prime()
|
||||
@@ -61,7 +63,6 @@
|
||||
/obj/item/weapon/gun/launcher/syringe
|
||||
name = "syringe gun"
|
||||
desc = "A spring loaded rifle designed to fit syringes, designed to incapacitate unruly patients from a distance."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "syringegun"
|
||||
item_state = "syringegun"
|
||||
w_class = 3
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
var/obj/item/ammo_magazine/ammo_magazine = null //stored magazine
|
||||
var/auto_eject = 0 //if the magazine should automatically eject itself when empty.
|
||||
var/auto_eject_sound = null
|
||||
//TODO generalize ammo icon states for guns
|
||||
//var/magazine_states = 0
|
||||
//var/list/icon_keys = list() //keys
|
||||
//var/list/ammo_states = list() //values
|
||||
|
||||
/obj/item/weapon/gun/projectile/New()
|
||||
..()
|
||||
@@ -37,8 +41,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/consume_next_projectile()
|
||||
//store the next ammo_casing in a var so that handle_post_fire() knows which one to eject
|
||||
//also we might as well remove chambered here, so that we don't have to figure out where it came from later
|
||||
//get the next casing
|
||||
if(loaded.len)
|
||||
chambered = loaded[1] //load next casing.
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
@@ -47,25 +50,36 @@
|
||||
chambered = ammo_magazine.stored_ammo[1]
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
ammo_magazine.stored_ammo -= chambered
|
||||
return chambered.BB
|
||||
|
||||
if (chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/handle_post_fire()
|
||||
..()
|
||||
if(chambered)
|
||||
chambered.expend()
|
||||
|
||||
//check chambered again in case it deleted itself
|
||||
if(chambered && handle_casings != HOLD_CASINGS)
|
||||
switch(handle_casings)
|
||||
if(EJECT_CASINGS) //eject casing onto ground.
|
||||
chambered.loc = get_turf(src)
|
||||
if(CYCLE_CASINGS) //cycle the casing back to the end.
|
||||
if(ammo_magazine)
|
||||
ammo_magazine.stored_ammo += chambered
|
||||
else
|
||||
loaded += chambered
|
||||
process_chambered()
|
||||
|
||||
/obj/item/weapon/gun/projectile/handle_click_empty()
|
||||
..()
|
||||
process_chambered()
|
||||
|
||||
/obj/item/weapon/gun/projectile/proc/process_chambered()
|
||||
if (!chambered) return
|
||||
|
||||
switch(handle_casings)
|
||||
if(EJECT_CASINGS) //eject casing onto ground.
|
||||
chambered.loc = get_turf(src)
|
||||
if(CYCLE_CASINGS) //cycle the casing back to the end.
|
||||
if(ammo_magazine)
|
||||
ammo_magazine.stored_ammo += chambered
|
||||
else
|
||||
loaded += chambered
|
||||
|
||||
if(handle_casings != HOLD_CASINGS)
|
||||
chambered = null
|
||||
|
||||
|
||||
|
||||
//Attempts to load A into src, depending on the type of thing being loaded and the load_method
|
||||
//Maybe this should be broken up into separate procs for each load method?
|
||||
@@ -118,7 +132,6 @@
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
//attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled
|
||||
/obj/item/weapon/gun/projectile/proc/unload_ammo(mob/user, var/allow_dump=1)
|
||||
if(ammo_magazine)
|
||||
@@ -170,8 +183,9 @@
|
||||
)
|
||||
if(auto_eject_sound)
|
||||
playsound(user, auto_eject_sound, 40, 1)
|
||||
ammo_magazine.update_icon()
|
||||
ammo_magazine = null
|
||||
update_icon()
|
||||
update_icon() //make sure to do this after unsetting ammo_magazine
|
||||
|
||||
/obj/item/weapon/gun/projectile/examine(mob/user)
|
||||
..(user)
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
load_method = SPEEDLOADER //yup. until someone sprites a magazine for it.
|
||||
max_shells = 22
|
||||
caliber = "9mm"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
slot_flags = SLOT_BELT
|
||||
ammo_type = /obj/item/ammo_casing/c9mm
|
||||
multi_aim = 1
|
||||
fire_delay = 0
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/mini_uzi
|
||||
name = "\improper Uzi"
|
||||
desc = "A lightweight, fast firing gun, for when you want someone dead. Uses .45 rounds."
|
||||
@@ -42,20 +42,64 @@
|
||||
/obj/item/weapon/gun/projectile/automatic/c20r/update_icon()
|
||||
..()
|
||||
if(ammo_magazine)
|
||||
icon_state = "c20r-[round(loaded.len,4)]"
|
||||
icon_state = "c20r-[round(ammo_magazine.stored_ammo.len,4)]"
|
||||
else
|
||||
icon_state = "c20r"
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550
|
||||
name = "\improper W-T 550 Saber"
|
||||
desc = "A cheap, mass produced Ward-Takahashi PDW. Uses 9mm rounds."
|
||||
icon_state = "wt550"
|
||||
w_class = 3.0
|
||||
caliber = "9mm"
|
||||
origin_tech = "combat=5;materials=2"
|
||||
slot_flags = SLOT_BELT
|
||||
ammo_type = "/obj/item/ammo_casing/c9mmr"
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/mc9mmt/rubber
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550/update_icon()
|
||||
..()
|
||||
if(ammo_magazine)
|
||||
icon_state = "wt550-[round(ammo_magazine.stored_ammo.len,4)]"
|
||||
else
|
||||
icon_state = "wt550"
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/z8
|
||||
name = "\improper Z8 Bulldog"
|
||||
desc = "An older model bullpup carbine, made by the now defunct Zendai Foundries. Uses armor piercing 5.56mm rounds. Makes you feel like a space marine when you hold it."
|
||||
icon_state = "carbine"
|
||||
item_state = "shotgun"
|
||||
w_class = 4
|
||||
force = 10
|
||||
caliber = "a556"
|
||||
origin_tech = "combat=8;materials=3"
|
||||
ammo_type = "/obj/item/ammo_casing/a556"
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
slot_flags = SLOT_BACK
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/a556
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/z8/update_icon()
|
||||
..()
|
||||
if(ammo_magazine)
|
||||
icon_state = "carbine-[round(ammo_magazine.stored_ammo.len,2)]"
|
||||
else
|
||||
icon_state = "carbine"
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/sts35
|
||||
name = "\improper STS-35 Automatic Rifle"
|
||||
desc = "A durable, rugged looking automatic weapon of make popular on the frontier, despite it's bulk. Uses 7.62mm rounds. It is unmarked."
|
||||
name = "\improper STS-35 automatic rifle"
|
||||
desc = "A durable, rugged looking automatic weapon of a make popular on the frontier. Uses 7.62mm rounds. It is unmarked."
|
||||
icon_state = "assltrifle"
|
||||
item_state = "shotgun"
|
||||
w_class = 4
|
||||
force = 10
|
||||
caliber = "a762"
|
||||
origin_tech = "combat=5;materials=1;syndicate=8"
|
||||
origin_tech = "combat=6;materials=1;syndicate=4"
|
||||
slot_flags = SLOT_BACK
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/c762
|
||||
@@ -74,7 +118,7 @@
|
||||
slot_flags = 0
|
||||
max_shells = 50
|
||||
caliber = "a762"
|
||||
origin_tech = "combat=5;materials=1;syndicate=2"
|
||||
origin_tech = "combat=6;materials=1;syndicate=2"
|
||||
slot_flags = SLOT_BACK
|
||||
ammo_type = "/obj/item/ammo_casing/a762"
|
||||
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
|
||||
@@ -88,7 +132,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/update_icon()
|
||||
icon_state = "l6[cover_open ? "open" : "closed"][ammo_magazine ? round(loaded.len, 25) : "-empty"]"
|
||||
icon_state = "l6[cover_open ? "open" : "closed"][ammo_magazine ? round(ammo_magazine.stored_ammo.len, 25) : "-empty"]"
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/special_check(mob/user)
|
||||
if(cover_open)
|
||||
@@ -102,7 +146,7 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/unload_ammo(mob/user)
|
||||
/obj/item/weapon/gun/projectile/automatic/l6_saw/unload_ammo(mob/user, var/allow_dump=1)
|
||||
if(!cover_open)
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -34,6 +34,21 @@
|
||||
M << "You name the gun [input]. Say hello to your new friend."
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/gun/projectile/sec
|
||||
desc = "A Nanotrasen designed sidearm, found pretty much everywhere humans are. Uses less-than-lethal .45 rounds."
|
||||
name = "\improper NT Mk58"
|
||||
icon_state = "secguncomp"
|
||||
magazine_type = /obj/item/ammo_magazine/c45m/rubber
|
||||
caliber = ".45"
|
||||
origin_tech = "combat=3;materials=2"
|
||||
load_method = MAGAZINE
|
||||
|
||||
|
||||
/obj/item/weapon/gun/projectile/sec/wood
|
||||
desc = "A Nanotrasen designed sidearm, this one has a sweet wooden grip. Uses less-than-lethal .45 rounds."
|
||||
name = "\improper Custom NT Mk58"
|
||||
icon_state = "secgundark"
|
||||
|
||||
/obj/item/weapon/gun/projectile/silenced
|
||||
name = "silenced pistol"
|
||||
desc = "A small, quiet, easily concealable gun. Uses .45 rounds."
|
||||
@@ -98,7 +113,7 @@
|
||||
silenced = 0
|
||||
origin_tech = "combat=2;materials=2;syndicate=2"
|
||||
load_method = MAGAZINE
|
||||
magazine_type = /obj/item/ammo_magazine/mc9mm
|
||||
magazine_type = /obj/item/ammo_magazine/mc9mm
|
||||
|
||||
/obj/item/weapon/gun/projectile/pistol/flash
|
||||
name = "\improper Stechtkin signal pistol"
|
||||
|
||||
@@ -11,33 +11,33 @@
|
||||
caliber = "shotgun"
|
||||
origin_tech = "combat=4;materials=2"
|
||||
load_method = SINGLE_CASING
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/pellet
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
handle_casings = HOLD_CASINGS
|
||||
var/recentpump = 0 // to prevent spammage
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/consume_next_projectile()
|
||||
if(chambered)
|
||||
return chambered.BB
|
||||
return null
|
||||
return null
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/attack_self(mob/living/user as mob)
|
||||
if(world.time >= recentpump + 10)
|
||||
pump(user)
|
||||
pump(user)
|
||||
recentpump = world.time
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/proc/pump(mob/M as mob)
|
||||
playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1)
|
||||
|
||||
|
||||
if(chambered)//We have a shell in the chamber
|
||||
chambered.loc = get_turf(src)//Eject casing
|
||||
chambered = null
|
||||
|
||||
|
||||
if(loaded.len)
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
chambered = AC
|
||||
|
||||
update_icon()
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat
|
||||
name = "combat shotgun"
|
||||
@@ -62,7 +62,7 @@
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
caliber = "shotgun"
|
||||
origin_tech = "combat=3;materials=1"
|
||||
origin_tech = "combat=3;materials=1"
|
||||
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
|
||||
|
||||
//this is largely hacky and bad :( -Pete
|
||||
@@ -71,7 +71,7 @@
|
||||
user << "<span class='notice'>You begin to shorten the barrel of \the [src].</span>"
|
||||
if(loaded.len)
|
||||
for(var/i in 1 to max_shells)
|
||||
afterattack(user, user) //will this work? //it will. we call it twice, for twice the FUN
|
||||
afterattack(user, user) //will this work? //it will. we call it twice, for twice the FUN
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
user.visible_message("<span class='danger'>The shotgun goes off!</span>", "<span class='danger'>The shotgun goes off in your face!</span>")
|
||||
return
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/obj/item/weapon/gun/projectile/heavysniper
|
||||
name = "\improper PTRS-7 rifle"
|
||||
desc = "A portable anti-armour rifle fitted with a scope. Originally designed to used against lightly armoured exosuits, it is capable of punching through non-reinforced walls with ease. Fires 14.5mm AP shells."
|
||||
desc = "A portable anti-armour rifle fitted with a scope. Originally designed to used against armoured exosuits, it is capable of punching through non-reinforced walls with ease. Fires armor piercing 14.5mm shells."
|
||||
icon_state = "heavysniper"
|
||||
item_state = "sniper0"
|
||||
item_state = "shotgun"
|
||||
w_class = 4
|
||||
force = 10
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
@@ -65,8 +65,15 @@
|
||||
/obj/item/projectile/proc/on_impact(var/atom/A)
|
||||
return
|
||||
|
||||
//Checks if the projectile is eligible for embedding. Not that it necessarily will.
|
||||
/obj/item/projectile/proc/can_embed()
|
||||
//embed must be enabled and damage type must be brute
|
||||
if(!embed || damage_type != BRUTE)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//return 1 if the projectile should be allowed to pass through after all, 0 if not.
|
||||
/obj/item/projectile/proc/on_penetrate(var/atom/A)
|
||||
/obj/item/projectile/proc/check_penetrate(var/atom/A)
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/proc/check_fire(atom/target as mob, var/mob/living/user as mob) //Checks if you can hit them or not.
|
||||
@@ -156,9 +163,12 @@
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
firer.attack_log += "\[[time_stamp()]\] <b>[firer]/[firer.ckey]</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src.type]</b>"
|
||||
msg_admin_attack("[firer] ([firer.ckey]) shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
else
|
||||
else if(firer)
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src]</b>"
|
||||
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[firer.x];Y=[firer.y];Z=[firer.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
else
|
||||
target_mob.attack_log += "\[[time_stamp()]\] <b>UNKNOWN SUBJECT (No longer exists)</b> shot <b>[target_mob]/[target_mob.ckey]</b> with a <b>[src]</b>"
|
||||
msg_admin_attack("UNKNOWN shot [target_mob] ([target_mob.ckey]) with a [src] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target_mob.x];Y=[target_mob.y];Z=[target_mob.z]'>JMP</a>)") //BS12 EDIT ALG
|
||||
|
||||
//sometimes bullet_act() will want the projectile to continue flying
|
||||
if (target_mob.bullet_act(src, def_zone) == -1)
|
||||
@@ -174,7 +184,7 @@
|
||||
loc = A.loc
|
||||
return 0 //cannot shoot yourself
|
||||
|
||||
if(bumped)
|
||||
if(bumped || (A in permutated))
|
||||
return 0
|
||||
|
||||
var/passthrough = 0 //if the projectile should continue flying
|
||||
@@ -196,19 +206,21 @@
|
||||
attack_mob(M, distance)
|
||||
|
||||
//penetrating projectiles can pass through things that otherwise would not let them
|
||||
if(penetrating > 0)
|
||||
if(on_penetrate(A))
|
||||
if(!passthrough && penetrating > 0)
|
||||
if(check_penetrate(A))
|
||||
passthrough = 1
|
||||
penetrating--
|
||||
|
||||
//the bullet passes through a dense object!
|
||||
if(passthrough)
|
||||
//move ourselves onto A so we can continue on our way.
|
||||
if(A)
|
||||
if(istype(A, /turf))
|
||||
loc = A
|
||||
else
|
||||
loc = A.loc
|
||||
permutated.Add(A)
|
||||
bumped = 0 //reset bumped variable!
|
||||
if(istype(A, /turf))
|
||||
loc = A
|
||||
else
|
||||
loc = A.loc
|
||||
permutated.Add(A)
|
||||
return 0
|
||||
|
||||
//stop flying
|
||||
|
||||
@@ -7,22 +7,37 @@
|
||||
check_armour = "bullet"
|
||||
embed = 1
|
||||
sharp = 1
|
||||
var/mob_passthrough_check = 0
|
||||
|
||||
/obj/item/projectile/bullet/on_hit(var/atom/target, var/blocked = 0)
|
||||
if (..(target, blocked))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
|
||||
/obj/item/projectile/bullet/on_penetrate(var/atom/A)
|
||||
if(!A) return 1 //if whatever it was got destroyed when we hit it, then I guess we can just keep going
|
||||
/obj/item/projectile/bullet/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
if(penetrating > 0 && damage > 20 && prob(damage))
|
||||
mob_passthrough_check = 1
|
||||
else
|
||||
mob_passthrough_check = 0
|
||||
..()
|
||||
|
||||
/obj/item/projectile/bullet/can_embed()
|
||||
//prevent embedding if the projectile is passing through the mob
|
||||
if(mob_passthrough_check)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/bullet/check_penetrate(var/atom/A)
|
||||
if(!A || !A.density) return 1 //if whatever it was got destroyed when we hit it, then I guess we can just keep going
|
||||
|
||||
if(istype(A, /obj/mecha))
|
||||
return 1 //mecha have their own penetration handling
|
||||
|
||||
if(ismob(A))
|
||||
if(iscarbon(A))
|
||||
if (damage <= 20 && !prob(damage)) return 0
|
||||
damage *= 0.7 //squishy mobs absorb KE
|
||||
if(!mob_passthrough_check)
|
||||
return 0
|
||||
if(iscarbon(A))
|
||||
damage *= 0.7 //squishy mobs absorb KE
|
||||
return 1
|
||||
|
||||
var/chance = 0
|
||||
@@ -33,10 +48,10 @@
|
||||
var/obj/machinery/door/D = A
|
||||
chance = round(damage/D.maxhealth*100)
|
||||
else if(istype(A, /obj/structure/girder) || istype(A, /obj/structure/cultgirder))
|
||||
chance = 100
|
||||
chance = 100
|
||||
else if(istype(A, /obj/machinery) || istype(A, /obj/structure))
|
||||
chance = 15
|
||||
|
||||
chance = 25
|
||||
|
||||
if(prob(chance))
|
||||
if(A.opacity)
|
||||
//display a message so that people on the other side aren't so confused
|
||||
@@ -131,6 +146,10 @@
|
||||
weaken = 3
|
||||
penetrating = 5
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a556
|
||||
damage = 50
|
||||
penetrating = 1
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
/obj/item/projectile/bullet/suffocationbullet//How does this even work?
|
||||
|
||||
@@ -1702,8 +1702,8 @@ datum
|
||||
if(!M) M = holder.my_atom
|
||||
if(prob(33))
|
||||
M.take_organ_damage(1*REM, 0)
|
||||
M.adjustOxyLoss(3)
|
||||
if(prob(20)) M.emote("gasp")
|
||||
if(M.losebreath < 15)
|
||||
M.losebreath++
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -3180,17 +3180,17 @@ datum
|
||||
if(!data) data = 1
|
||||
data++
|
||||
M.dizziness +=6
|
||||
if(data >= 15 && data <45)
|
||||
if (!M.stuttering) M.stuttering = 1
|
||||
M.stuttering += 3
|
||||
else if(data >= 45 && prob(50) && data <55)
|
||||
M.confused = max(M.confused+3,0)
|
||||
else if(data >=55)
|
||||
M.druggy = max(M.druggy, 55)
|
||||
else if(data >=200)
|
||||
M.adjustToxLoss(2)
|
||||
switch(data)
|
||||
if(15 to 45)
|
||||
M.stuttering = max(M.stuttering+3,0)
|
||||
if(45 to 55)
|
||||
if (prob(50))
|
||||
M.confused = max(M.confused+3,0)
|
||||
if(55 to 200)
|
||||
M.druggy = max(M.druggy, 55)
|
||||
if(200 to INFINITY)
|
||||
M.adjustToxLoss(2)
|
||||
..()
|
||||
return
|
||||
|
||||
neurotoxin
|
||||
name = "Neurotoxin"
|
||||
@@ -3210,17 +3210,17 @@ datum
|
||||
if(!data) data = 1
|
||||
data++
|
||||
M.dizziness +=6
|
||||
if(data >= 15 && data <45)
|
||||
if (!M.stuttering) M.stuttering = 1
|
||||
M.stuttering += 3
|
||||
else if(data >= 45 && prob(50) && data <55)
|
||||
M.confused = max(M.confused+3,0)
|
||||
else if(data >=55)
|
||||
M.druggy = max(M.druggy, 55)
|
||||
else if(data >=200)
|
||||
M.adjustToxLoss(2)
|
||||
switch(data)
|
||||
if(15 to 45)
|
||||
M.stuttering = max(M.stuttering+3,0)
|
||||
if(45 to 55)
|
||||
if (prob(50))
|
||||
M.confused = max(M.confused+3,0)
|
||||
if(55 to 200)
|
||||
M.druggy = max(M.druggy, 55)
|
||||
if(200 to INFINITY)
|
||||
M.adjustToxLoss(2)
|
||||
..()
|
||||
return
|
||||
|
||||
hippies_delight
|
||||
name = "Hippies' Delight"
|
||||
|
||||
@@ -2997,3 +2997,38 @@
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 3)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood
|
||||
name = "\improper LiquidFood Ration"
|
||||
desc = "A prepackaged grey slurry of all the essential nutrients for a spacefarer on the go. Should this be crunchy?"
|
||||
icon_state = "liquidfood"
|
||||
trash = /obj/item/trash/liquidfood
|
||||
filling_color = "#A8A8A8"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 20)
|
||||
reagents.add_reagent("iron", 3)
|
||||
bitesize = 4
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/tastybread
|
||||
name = "Bread Tube"
|
||||
desc = "Chewy...and surprisingly tasty."
|
||||
icon_state = "tastybread"
|
||||
filling_color = "#A66829"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 12)
|
||||
bitesize = 2
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/skrellsnacks
|
||||
name = "\improper SkrellSnax"
|
||||
desc = "Cured fungus shipped all the way from Jargon 4, almost like jerky! Almost."
|
||||
icon_state = "skrellsnacks"
|
||||
filling_color = "#A66829"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 10)
|
||||
bitesize = 3
|
||||
@@ -238,3 +238,15 @@
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("virusfood", 1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/acid
|
||||
name = "Sulphuric Acid Dispenser"
|
||||
desc = "A dispenser of acid for industrial processes."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "acidtank"
|
||||
amount_per_transfer_from_this = 10
|
||||
anchored = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("sacid", 1000)
|
||||
|
||||
@@ -103,6 +103,9 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
|
||||
else // This failing silently was a pain.
|
||||
user << "\red You must remain close to your patient to conduct surgery."
|
||||
M.op_stage.in_progress = 0 // Clear the in-progress flag.
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_surgery()
|
||||
return 1 //don't want to do weapony things after surgery
|
||||
|
||||
if (user.a_intent == "help")
|
||||
|
||||
Reference in New Issue
Block a user