Merge remote-tracking branch 'upstream/dev' into mercenary

This commit is contained in:
mwerezak
2015-02-21 13:22:51 -05:00
70 changed files with 1818 additions and 1020 deletions
+8 -3
View File
@@ -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]
+2 -2
View File
@@ -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))
+2 -10
View File
@@ -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
@@ -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
@@ -38,9 +38,9 @@ emp_act
return -1 // complete projectile permutation
//Shrapnel
if (P.can_embed())
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]."
@@ -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)
@@ -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)
@@ -929,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.
@@ -967,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
+2 -2
View File
@@ -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
@@ -23,14 +23,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 = ""
@@ -63,15 +55,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]--;
@@ -579,6 +579,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
+1 -1
View File
@@ -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
+12
View File
@@ -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
+7 -7
View File
@@ -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()
+120
View File
@@ -0,0 +1,120 @@
/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
/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))
. = 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()
+2 -1
View File
@@ -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)
-11
View File
@@ -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))
+21 -118
View File
@@ -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)
+10 -10
View File
@@ -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.
+17 -8
View File
@@ -482,6 +482,15 @@ 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/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>")
@@ -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)
@@ -118,14 +118,14 @@
/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.56 bullet casing."
desc = "A 5.56mm bullet casing."
caliber = "a556"
projectile_type = /obj/item/projectile/bullet/rifle/a556
@@ -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()
@@ -70,15 +70,16 @@
/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.56 rounds. Makes you feel like a space marine when you hold it."
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.0
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
@@ -92,13 +93,13 @@
/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."
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
@@ -117,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'
@@ -1,6 +1,6 @@
/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 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 = "shotgun"
w_class = 4
+7 -8
View File
@@ -66,14 +66,10 @@
return
//Checks if the projectile is eligible for embedding. Not that it necessarily will.
//Mainly used to ensure that projectiles won't embed if they are penetrating the mob.
/obj/item/projectile/proc/can_embed()
//embed must be enabled and damage type must be brute
if(!embed || damage_type != BRUTE)
return 0
//can't embed if the projectile is penetrating through the mob
if(penetrating > 0 && damage > 20 && prob(damage))
return 0
return 1
//return 1 if the projectile should be allowed to pass through after all, 0 if not.
@@ -167,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)
@@ -206,9 +205,9 @@
for(var/mob/M in A)
attack_mob(M, distance)
//penetrating projectiles can pass through things that otherwise would not let them
//penetrating projectiles can pass through things that otherwise would not let them
if(!passthrough && penetrating > 0)
if(check_penetrate(A))
if(check_penetrate(A))
passthrough = 1
penetrating--
@@ -311,4 +310,4 @@
trace.firer = user
var/output = trace.process() //Test it!
del(trace) //No need for it anymore
return output //Send it back to the gun!
return output //Send it back to the gun!
+18 -4
View File
@@ -7,12 +7,26 @@
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/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
@@ -20,10 +34,10 @@
return 1 //mecha have their own penetration handling
if(ismob(A))
if(iscarbon(A))
//squishy mobs absorb KE
if(can_embed()) return 0
damage *= 0.7
if(!mob_passthrough_check)
return 0
if(iscarbon(A))
damage *= 0.7 //squishy mobs absorb KE
return 1
var/chance = 0
+3
View File
@@ -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")