mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 06:22:26 +01:00
Merge remote-tracking branch 'bay12-upstream/master' into development
This commit is contained in:
@@ -11,6 +11,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
item_state = "electronic"
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_ID | SLOT_BELT
|
||||
sprite_sheets = list("Resomi" = 'icons/mob/species/resomi/id.dmi')
|
||||
|
||||
//Main variables
|
||||
var/owner = null
|
||||
@@ -746,7 +747,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if(!isnull(P))
|
||||
if (!P.toff && cartridge.charges > 0)
|
||||
cartridge.charges--
|
||||
U.show_message("\blue Virus sent!", 1)
|
||||
U.show_message("<span class='notice'>Virus sent!</span>", 1)
|
||||
P.honkamt = (rand(15,20))
|
||||
else
|
||||
U << "PDA not found."
|
||||
@@ -759,7 +760,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if(!isnull(P))
|
||||
if (!P.toff && cartridge.charges > 0)
|
||||
cartridge.charges--
|
||||
U.show_message("\blue Virus sent!", 1)
|
||||
U.show_message("<span class='notice'>Virus sent!</span>", 1)
|
||||
P.message_silent = 1
|
||||
P.news_silent = 1
|
||||
P.ttone = "silence"
|
||||
@@ -787,10 +788,10 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
var/obj/item/device/pda/P = locate(href_list["target"])
|
||||
var/datum/reception/reception = get_reception(src, P, "", do_sleep = 0)
|
||||
if(!(reception.message_server && reception.telecomms_reception & TELECOMMS_RECEPTION_SENDER))
|
||||
U.show_message("\red An error flashes on your [src]: Connection unavailable", 1)
|
||||
U.show_message("<span class='warning'>An error flashes on your [src]: Connection unavailable</span>", 1)
|
||||
return
|
||||
if(reception.telecomms_reception & TELECOMMS_RECEPTION_RECEIVER == 0) // Does our recepient have a broadcaster on their level?
|
||||
U.show_message("\red An error flashes on your [src]: Recipient unavailable", 1)
|
||||
U.show_message("<span class='warning'>An error flashes on your [src]: Recipient unavailable</span>", 1)
|
||||
return
|
||||
if(!isnull(P))
|
||||
if (!P.toff && cartridge.charges > 0)
|
||||
@@ -808,15 +809,15 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
difficulty += 3
|
||||
|
||||
if(prob(difficulty))
|
||||
U.show_message("\red An error flashes on your [src].", 1)
|
||||
U.show_message("<span class='warning'>An error flashes on your [src].</span>", 1)
|
||||
else if (prob(difficulty * 7))
|
||||
U.show_message("\red Energy feeds back into your [src]!", 1)
|
||||
U.show_message("<span class='warning'>Energy feeds back into your [src]!</span>", 1)
|
||||
ui.close()
|
||||
detonate_act(src)
|
||||
log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge but failed, blowing themselves up")
|
||||
message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge but failed.", 1)
|
||||
else
|
||||
U.show_message("\blue Success!", 1)
|
||||
U.show_message("<span class='notice'>Success!</span>", 1)
|
||||
log_admin("[key_name(U)] just attempted to blow up [P] with the Detomatix cartridge and succeeded")
|
||||
message_admins("[key_name_admin(U)] just attempted to blow up [P] with the Detomatix cartridge and succeeded.", 1)
|
||||
detonate_act(P)
|
||||
@@ -933,7 +934,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
message += "Your [P] shatters in a thousand pieces!"
|
||||
|
||||
if(M && isliving(M))
|
||||
message = "\red" + message
|
||||
message = "<span class='warning'>[message]</span>"
|
||||
M.show_message(message, 1)
|
||||
|
||||
/obj/item/device/pda/proc/remove_id()
|
||||
@@ -948,8 +949,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
|
||||
/obj/item/device/pda/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P, var/tap = 1)
|
||||
if(tap)
|
||||
U.visible_message("<span class='notice'>[U] taps on \his PDA's screen.</span>")
|
||||
U.last_target_click = world.time
|
||||
U.visible_message("<span class='notice'>\The [U] taps on \his PDA's screen.</span>")
|
||||
var/t = input(U, "Please enter message", P.name, null) as text
|
||||
t = sanitize(t)
|
||||
//t = readd_quotes(t)
|
||||
@@ -1147,21 +1147,22 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if(choice == 1)
|
||||
if (id)
|
||||
remove_id()
|
||||
return 1
|
||||
else
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card/id))
|
||||
user.drop_item()
|
||||
if (istype(I, /obj/item/weapon/card/id) && user.unEquip(I))
|
||||
I.loc = src
|
||||
id = I
|
||||
return 1
|
||||
else
|
||||
var/obj/item/weapon/card/I = user.get_active_hand()
|
||||
if (istype(I, /obj/item/weapon/card/id) && I:registered_name)
|
||||
if (istype(I, /obj/item/weapon/card/id) && I:registered_name && user.unEquip(I))
|
||||
var/obj/old_id = id
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
id = I
|
||||
user.put_in_hands(old_id)
|
||||
return
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// access to status display signals
|
||||
/obj/item/device/pda/attackby(obj/item/C as obj, mob/user as mob)
|
||||
@@ -1189,9 +1190,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
else
|
||||
//Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand.
|
||||
if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) )
|
||||
id_check(user, 2)
|
||||
user << "<span class='notice'>You put the ID into \the [src]'s slot.</span>"
|
||||
updateSelfDialog()//Update self dialog on success.
|
||||
if(id_check(user, 2))
|
||||
user << "<span class='notice'>You put the ID into \the [src]'s slot.</span>"
|
||||
updateSelfDialog()//Update self dialog on success.
|
||||
return //Return in case of failed check or when successful.
|
||||
updateSelfDialog()//For the non-input related code.
|
||||
else if(istype(C, /obj/item/device/paicard) && !src.pai)
|
||||
@@ -1217,53 +1218,59 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if(1)
|
||||
|
||||
for (var/mob/O in viewers(C, null))
|
||||
O.show_message("\red [user] has analyzed [C]'s vitals!", 1)
|
||||
O.show_message("<span class='warning'>\The [user] has analyzed [C]'s vitals!</span>", 1)
|
||||
|
||||
user.show_message("\blue Analyzing Results for [C]:")
|
||||
user.show_message("\blue \t Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]", 1)
|
||||
user.show_message("\blue \t Damage Specifics: [C.getOxyLoss() > 50 ? "\red" : "\blue"][C.getOxyLoss()]-[C.getToxLoss() > 50 ? "\red" : "\blue"][C.getToxLoss()]-[C.getFireLoss() > 50 ? "\red" : "\blue"][C.getFireLoss()]-[C.getBruteLoss() > 50 ? "\red" : "\blue"][C.getBruteLoss()]", 1)
|
||||
user.show_message("\blue \t Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue \t Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)", 1)
|
||||
user.show_message("<span class='notice'>Analyzing Results for [C]:</span>")
|
||||
user.show_message("<span class='notice'> Overall Status: [C.stat > 1 ? "dead" : "[C.health - C.halloss]% healthy"]</span>", 1)
|
||||
user.show_message(text("<span class='notice'> Damage Specifics:</span> <span class='[]'>[]</span>-<span class='[]'>[]</span>-<span class='[]'>[]</span>-<span class='[]'>[]</span>",
|
||||
(C.getOxyLoss() > 50) ? "warning" : "", C.getOxyLoss(),
|
||||
(C.getToxLoss() > 50) ? "warning" : "", C.getToxLoss(),
|
||||
(C.getFireLoss() > 50) ? "warning" : "", C.getFireLoss(),
|
||||
(C.getBruteLoss() > 50) ? "warning" : "", C.getBruteLoss()
|
||||
), 1)
|
||||
user.show_message("<span class='notice'> Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||
user.show_message("<span class='notice'> Body Temperature: [C.bodytemperature-T0C]°C ([C.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||
if(C.tod && (C.stat == DEAD || (C.status_flags & FAKEDEATH)))
|
||||
user.show_message("\blue \t Time of Death: [C.tod]")
|
||||
user.show_message("<span class='notice'> Time of Death: [C.tod]</span>")
|
||||
if(istype(C, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = C
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Burn:",1)
|
||||
user.show_message("<span class='notice'>Localized Damage, Brute/Burn:</span>",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/obj/item/organ/external/org in damaged)
|
||||
user.show_message(text("\blue \t []: []\blue-[]",capitalize(org.name),(org.brute_dam > 0)?"\red [org.brute_dam]":0,(org.burn_dam > 0)?"\red [org.burn_dam]":0),1)
|
||||
user.show_message(text("<span class='notice'> []: <span class='[]'>[]</span>-<span class='[]'>[]</span></span>",
|
||||
capitalize(org.name), (org.brute_dam > 0) ? "warning" : "notice", org.brute_dam, (org.burn_dam > 0) ? "warning" : "notice", org.burn_dam),1)
|
||||
else
|
||||
user.show_message("\blue \t Limbs are OK.",1)
|
||||
user.show_message("<span class='notice'> Limbs are OK.</span>",1)
|
||||
|
||||
for(var/datum/disease/D in C.viruses)
|
||||
if(!D.hidden[SCANNER])
|
||||
user.show_message(text("\red <b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
|
||||
user.show_message("<span class='warning'><b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]</span>")
|
||||
|
||||
if(2)
|
||||
if (!istype(C:dna, /datum/dna))
|
||||
user << "\blue No fingerprints found on [C]"
|
||||
user << "<span class='notice'>No fingerprints found on [C]</span>"
|
||||
else
|
||||
user << text("\blue [C]'s Fingerprints: [md5(C:dna.uni_identity)]")
|
||||
user << text("<span class='notice'>\The [C]'s Fingerprints: [md5(C:dna.uni_identity)]</span>")
|
||||
if ( !(C:blood_DNA) )
|
||||
user << "\blue No blood found on [C]"
|
||||
user << "<span class='notice'>No blood found on [C]</span>"
|
||||
if(C:blood_DNA)
|
||||
qdel(C:blood_DNA)
|
||||
else
|
||||
user << "\blue Blood found on [C]. Analysing..."
|
||||
user << "<span class='notice'>Blood found on [C]. Analysing...</span>"
|
||||
spawn(15)
|
||||
for(var/blood in C:blood_DNA)
|
||||
user << "\blue Blood type: [C:blood_DNA[blood]]\nDNA: [blood]"
|
||||
user << "<span class='notice'>Blood type: [C:blood_DNA[blood]]\nDNA: [blood]</span>"
|
||||
|
||||
if(4)
|
||||
for (var/mob/O in viewers(C, null))
|
||||
O.show_message("\red [user] has analyzed [C]'s radiation levels!", 1)
|
||||
O.show_message("<span class='warning'>\The [user] has analyzed [C]'s radiation levels!</span>", 1)
|
||||
|
||||
user.show_message("\blue Analyzing Results for [C]:")
|
||||
user.show_message("<span class='notice'>Analyzing Results for [C]:</span>")
|
||||
if(C.radiation)
|
||||
user.show_message("\green Radiation Level: \black [C.radiation]")
|
||||
user.show_message("<span class='notice'>Radiation Level: [C.radiation]</span>")
|
||||
else
|
||||
user.show_message("\blue No radiation detected.")
|
||||
user.show_message("<span class='notice'>No radiation detected.</span>")
|
||||
|
||||
/obj/item/device/pda/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
@@ -1275,49 +1282,16 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
if(!isnull(A.reagents))
|
||||
if(A.reagents.reagent_list.len > 0)
|
||||
var/reagents_length = A.reagents.reagent_list.len
|
||||
user << "\blue [reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found."
|
||||
user << "<span class='notice'>[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.</span>"
|
||||
for (var/re in A.reagents.reagent_list)
|
||||
user << "\blue \t [re]"
|
||||
user << "<span class='notice'> [re]</span>"
|
||||
else
|
||||
user << "\blue No active chemical agents found in [A]."
|
||||
user << "<span class='notice'>No active chemical agents found in [A].</span>"
|
||||
else
|
||||
user << "\blue No significant chemical agents found in [A]."
|
||||
user << "<span class='notice'>No significant chemical agents found in [A].</span>"
|
||||
|
||||
if(5)
|
||||
if((istype(A, /obj/item/weapon/tank)) || (istype(A, /obj/machinery/portable_atmospherics)))
|
||||
var/obj/icon = A
|
||||
for (var/mob/O in viewers(user, null))
|
||||
O << "\red [user] has used [src] on \icon[icon] [A]"
|
||||
var/pressure = A:air_contents.return_pressure()
|
||||
|
||||
var/total_moles = A:air_contents.total_moles
|
||||
|
||||
user << "\blue Results of analysis of \icon[icon]"
|
||||
if (total_moles>0)
|
||||
user << "\blue Pressure: [round(pressure,0.1)] kPa"
|
||||
for(var/g in A:air_contents.gas)
|
||||
user << "\blue [gas_data.name[g]]: [round((A:air_contents.gas[g] / total_moles) * 100)]%"
|
||||
user << "\blue Temperature: [round(A:air_contents.temperature-T0C)]°C"
|
||||
else
|
||||
user << "\blue Tank is empty!"
|
||||
|
||||
if (istype(A, /obj/machinery/atmospherics/pipe/tank))
|
||||
var/obj/icon = A
|
||||
for (var/mob/O in viewers(user, null))
|
||||
O << "\red [user] has used [src] on \icon[icon] [A]"
|
||||
|
||||
var/obj/machinery/atmospherics/pipe/tank/T = A
|
||||
var/pressure = T.parent.air.return_pressure()
|
||||
var/total_moles = T.parent.air.total_moles
|
||||
|
||||
user << "\blue Results of analysis of \icon[icon]"
|
||||
if (total_moles>0)
|
||||
user << "\blue Pressure: [round(pressure,0.1)] kPa"
|
||||
for(var/g in T.parent.air.gas)
|
||||
user << "\blue [gas_data.name[g]]: [round((T.parent.air.gas[g] / total_moles) * 100)]%"
|
||||
user << "\blue Temperature: [round(T.parent.air.temperature-T0C)]°C"
|
||||
else
|
||||
user << "\blue Tank is empty!"
|
||||
analyze_gases(A, user)
|
||||
|
||||
if (!scanmode && istype(A, /obj/item/weapon/paper) && owner)
|
||||
// JMO 20140705: Makes scanned document show up properly in the notes. Not pretty for formatted documents,
|
||||
@@ -1366,7 +1340,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
// feature to the PDA, which would better convey the availability of the feature, but this will work for now.
|
||||
|
||||
// Inform the user
|
||||
user << "\blue Paper scanned and OCRed to notekeeper." //concept of scanning paper copyright brainoblivion 2009
|
||||
user << "<span class='notice'>Paper scanned and OCRed to notekeeper.</span>" //concept of scanning paper copyright brainoblivion 2009
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/radio/integrated
|
||||
name = "\improper PDA radio module"
|
||||
desc = "An electronic radio system of nanotrasen origin."
|
||||
desc = "An electronic radio system."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "power_mod"
|
||||
var/obj/item/device/pda/hostpda = null
|
||||
@@ -221,7 +221,7 @@
|
||||
if(!radio_controller)
|
||||
return
|
||||
|
||||
if (src.frequency < 1441 || src.frequency > 1489)
|
||||
if (src.frequency < PUBLIC_LOW_FREQ || src.frequency > PUBLIC_HIGH_FREQ)
|
||||
src.frequency = sanitize_frequency(src.frequency)
|
||||
|
||||
set_frequency(frequency)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_BELT
|
||||
var/flush = null
|
||||
origin_tech = "programming=4;materials=4"
|
||||
origin_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
|
||||
|
||||
var/mob/living/silicon/ai/carded_ai
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/device/aicard/Topic(href, href_list, nowindow, state)
|
||||
/obj/item/device/aicard/Topic(href, href_list, state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
@@ -59,9 +59,8 @@
|
||||
if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE))
|
||||
admin_attack_log(user, carded_ai, "Wiped using \the [src.name]", "Was wiped with \the [src.name]", "used \the [src.name] to wipe")
|
||||
flush = 1
|
||||
carded_ai.suiciding = 1
|
||||
carded_ai << "Your core files are being wiped!"
|
||||
while (carded_ai && carded_ai.stat != 2)
|
||||
while (carded_ai && carded_ai.stat != DEAD)
|
||||
carded_ai.adjustOxyLoss(2)
|
||||
carded_ai.updatehealth()
|
||||
sleep(10)
|
||||
@@ -105,12 +104,13 @@
|
||||
if(istype(ai.loc, /turf/))
|
||||
new /obj/structure/AIcore/deactivated(get_turf(ai))
|
||||
|
||||
ai.carded = 1
|
||||
admin_attack_log(user, ai, "Carded with [src.name]", "Was carded with [src.name]", "used the [src.name] to card")
|
||||
src.name = "[initial(name)] - [ai.name]"
|
||||
|
||||
ai.loc = src
|
||||
ai.cancel_camera()
|
||||
ai.destroy_eyeobj(src)
|
||||
ai.cancel_camera()
|
||||
ai.control_disabled = 1
|
||||
ai.aiRestorePowerRoutine = 0
|
||||
carded_ai = ai
|
||||
@@ -118,12 +118,16 @@
|
||||
if(ai.client)
|
||||
ai << "You have been downloaded to a mobile storage device. Remote access lost."
|
||||
if(user.client)
|
||||
user << "\blue <b>Transfer successful</b>: \black [ai.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
user << "<span class='notice'><b>Transfer successful:</b></span> [ai.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
|
||||
|
||||
ai.canmove = 1
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/item/device/aicard/proc/clear()
|
||||
if(carded_ai && istype(carded_ai.loc, /turf))
|
||||
carded_ai.canmove = 0
|
||||
carded_ai.carded = 0
|
||||
name = initial(name)
|
||||
carded_ai = null
|
||||
update_icon()
|
||||
@@ -133,10 +137,16 @@
|
||||
var/rendered = "<span class='message'>[text]</span>"
|
||||
carded_ai.show_message(rendered, 2)
|
||||
..()
|
||||
/*
|
||||
|
||||
/obj/item/device/aicard/show_message(msg, type, alt, alt_type)
|
||||
if(carded_ai && carded_ai.client)
|
||||
var/rendered = "<span class='message'>[msg]</span>"
|
||||
carded_ai.show_message(rendered, type)
|
||||
..()
|
||||
|
||||
/obj/item/device/aicard/relaymove(var/mob/user, var/direction)
|
||||
if(src.loc && istype(src.loc.loc, /obj/item/rig_module))
|
||||
var/obj/item/rig_module/module = src.loc.loc
|
||||
if(!module.holder || !direction)
|
||||
return
|
||||
module.holder.forced_move(direction)*/
|
||||
if(user.stat || user.stunned)
|
||||
return
|
||||
var/obj/item/weapon/rig/rig = src.get_rig()
|
||||
if(istype(rig))
|
||||
rig.forced_move(direction, user)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
throw_speed = 1
|
||||
throw_range = 5
|
||||
w_class = 2.0
|
||||
origin_tech = "syndicate=4;magnets=4"
|
||||
origin_tech = list(TECH_ILLEGAL = 4, TECH_MAGNET = 4)
|
||||
var/can_use = 1
|
||||
var/obj/effect/dummy/chameleon/active_dummy = null
|
||||
var/saved_item = /obj/item/weapon/cigbutt
|
||||
@@ -32,7 +32,7 @@
|
||||
if(!active_dummy)
|
||||
if(istype(target,/obj/item) && !istype(target, /obj/item/weapon/disk/nuclear))
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 100, 1, -6)
|
||||
user << "\blue Scanned [target]."
|
||||
user << "<span class='notice'>Scanned [target].</span>"
|
||||
saved_item = target.type
|
||||
saved_icon = target.icon
|
||||
saved_icon_state = target.icon_state
|
||||
@@ -45,7 +45,7 @@
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
qdel(active_dummy)
|
||||
active_dummy = null
|
||||
usr << "\blue You deactivate the [src]."
|
||||
usr << "<span class='notice'>You deactivate the [src].</span>"
|
||||
var/obj/effect/overlay/T = PoolOrNew(/obj/effect/overlay, get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
@@ -57,7 +57,7 @@
|
||||
var/obj/effect/dummy/chameleon/C = PoolOrNew(/obj/effect/dummy/chameleon, usr.loc)
|
||||
C.activate(O, usr, saved_icon, saved_icon_state, saved_overlays, src)
|
||||
qdel(O)
|
||||
usr << "\blue You activate the [src]."
|
||||
usr << "<span class='notice'>You activate the [src].</span>"
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
@@ -104,22 +104,22 @@
|
||||
|
||||
/obj/effect/dummy/chameleon/attackby()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
M << "<span class='warning'>Your chameleon-projector deactivates.</span>"
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_hand()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
M << "<span class='warning'>Your chameleon-projector deactivates.</span>"
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/ex_act()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
M << "<span class='warning'>Your chameleon-projector deactivates.</span>"
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/bullet_act()
|
||||
for(var/mob/M in src)
|
||||
M << "\red Your chameleon-projector deactivates."
|
||||
M << "<span class='warning'>Your chameleon-projector deactivates.</span>"
|
||||
..()
|
||||
master.disrupt()
|
||||
|
||||
|
||||
@@ -19,28 +19,28 @@
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
|
||||
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
|
||||
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
|
||||
|
||||
/obj/item/device/debugger/is_used_on(obj/O, mob/user)
|
||||
if(istype(O, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = O
|
||||
if(A.emagged || A.hacker)
|
||||
user << "\red There is a software error with the device."
|
||||
user << "<span class='warning'>There is a software error with the device.</span>"
|
||||
else
|
||||
user << "\blue The device's software appears to be fine."
|
||||
user << "<span class='notice'>The device's software appears to be fine.</span>"
|
||||
return 1
|
||||
if(istype(O, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = O
|
||||
if(D.operating == -1)
|
||||
user << "\red There is a software error with the device."
|
||||
user << "<span class='warning'>There is a software error with the device.</span>"
|
||||
else
|
||||
user << "\blue The device's software appears to be fine."
|
||||
user << "<span class='notice'>The device's software appears to be fine.</span>"
|
||||
return 1
|
||||
else if(istype(O, /obj/machinery))
|
||||
var/obj/machinery/A = O
|
||||
if(A.emagged)
|
||||
user << "\red There is a software error with the device."
|
||||
user << "<span class='warning'>There is a software error with the device.</span>"
|
||||
else
|
||||
user << "\blue The device's software appears to be fine."
|
||||
user << "<span class='notice'>The device's software appears to be fine.</span>"
|
||||
return 1
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
flags = CONDUCT
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
|
||||
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/broken = 0 //Is the flash burnt out?
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/obj/item/device/flash/proc/clown_check(var/mob/user)
|
||||
if(user && (CLUMSY in user.mutations) && prob(50))
|
||||
user << "\red \The [src] slips out of your hand."
|
||||
user << "<span class='warning'>\The [src] slips out of your hand.</span>"
|
||||
user.drop_item()
|
||||
return 0
|
||||
return 1
|
||||
@@ -31,14 +31,17 @@
|
||||
last_used = world.time
|
||||
times_used = max(0,round(times_used)) //sanity
|
||||
|
||||
|
||||
/obj/item/device/flash/attack(mob/living/M as mob, mob/user as mob)
|
||||
//attack_as_weapon
|
||||
/obj/item/device/flash/attack(mob/living/M, mob/living/user, var/target_zone)
|
||||
if(!user || !M) return //sanity
|
||||
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to flash [M.name] ([M.ckey])</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.do_attack_animation(M)
|
||||
|
||||
if(!clown_check(user)) return
|
||||
if(broken)
|
||||
user << "<span class='warning'>\The [src] is broken.</span>"
|
||||
@@ -64,48 +67,37 @@
|
||||
var/flashfail = 0
|
||||
|
||||
if(iscarbon(M))
|
||||
var/safety = M:eyecheck()
|
||||
if(safety <= 0)
|
||||
M.Weaken(10)
|
||||
flick("e_flash", M.flash)
|
||||
//Vaurca damage 15/01/16
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.name == "Vaurca")
|
||||
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
|
||||
if(!E)
|
||||
return
|
||||
usr << "\red Your eyes burn with the intense light of the flash!."
|
||||
E.damage += rand(10, 11)
|
||||
if(E.damage > 12)
|
||||
M.eye_blurry += rand(3,6)
|
||||
if (E.damage >= E.min_broken_damage)
|
||||
M.sdisabilities |= BLIND
|
||||
else if (E.damage >= E.min_bruised_damage)
|
||||
M.eye_blind = 5
|
||||
M.eye_blurry = 5
|
||||
M.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
M.disabilities &= ~NEARSIGHTED
|
||||
|
||||
if(ishuman(M) && ishuman(user) && M.stat!=DEAD)
|
||||
if(user.mind && user.mind in revs.current_antagonists)
|
||||
var/revsafe = 0
|
||||
for(var/obj/item/weapon/implant/loyalty/L in M)
|
||||
if(L && L.implanted)
|
||||
revsafe = 1
|
||||
break
|
||||
M.mind_initialize() //give them a mind datum if they don't have one.
|
||||
if(M.mind.has_been_rev)
|
||||
revsafe = 2
|
||||
if(!revsafe)
|
||||
M.mind.has_been_rev = 1
|
||||
revs.add_antagonist(M.mind)
|
||||
else if(revsafe == 1)
|
||||
user << "<span class='warning'>Something seems to be blocking the flash!</span>"
|
||||
else
|
||||
user << "<span class='warning'>This mind seems resistant to the flash!</span>"
|
||||
else
|
||||
flashfail = 1
|
||||
if(M.stat!=DEAD)
|
||||
var/mob/living/carbon/C = M
|
||||
var/safety = C.eyecheck()
|
||||
if(safety < FLASH_PROTECTION_MODERATE)
|
||||
var/flash_strength = 10
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
flash_strength *= H.species.flash_mod
|
||||
if(flash_strength > 0)
|
||||
M.Weaken(flash_strength)
|
||||
flick("e_flash", M.flash)
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.name == "Vaurca")
|
||||
var/obj/item/organ/eyes/E = H.internal_organs_by_name["eyes"]
|
||||
if(!E)
|
||||
return
|
||||
usr << "\red Your eyes burn with the intense light of the flash!."
|
||||
E.damage += rand(10, 11)
|
||||
if(E.damage > 12)
|
||||
M.eye_blurry += rand(3,6)
|
||||
if (E.damage >= E.min_broken_damage)
|
||||
M.sdisabilities |= BLIND
|
||||
else if (E.damage >= E.min_bruised_damage)
|
||||
M.eye_blind = 5
|
||||
M.eye_blurry = 5
|
||||
M.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
M.disabilities &= ~NEARSIGHTED
|
||||
else
|
||||
flashfail = 1
|
||||
|
||||
else if(issilicon(M))
|
||||
M.Weaken(rand(5,10))
|
||||
@@ -142,6 +134,9 @@
|
||||
|
||||
/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
if(!user || !clown_check(user)) return
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
|
||||
if(broken)
|
||||
user.show_message("<span class='warning'>The [src.name] is broken</span>", 2)
|
||||
return
|
||||
@@ -180,8 +175,8 @@
|
||||
for(var/obj/item/weapon/cloaking_device/S in M)
|
||||
S.active = 0
|
||||
S.icon_state = "shield0"
|
||||
var/safety = M:eyecheck()
|
||||
if(!safety)
|
||||
var/safety = M.eyecheck()
|
||||
if(safety < FLASH_PROTECTION_MODERATE)
|
||||
if(!M.blinded)
|
||||
flick("flash", M.flash)
|
||||
|
||||
@@ -200,7 +195,7 @@
|
||||
if(istype(loc, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = loc
|
||||
var/safety = M.eyecheck()
|
||||
if(safety <= 0)
|
||||
if(safety < FLASH_PROTECTION_MODERATE)
|
||||
M.Weaken(10)
|
||||
flick("e_flash", M.flash)
|
||||
for(var/mob/O in viewers(M, null))
|
||||
@@ -211,20 +206,19 @@
|
||||
name = "synthetic flash"
|
||||
desc = "When a problem arises, SCIENCE is the solution."
|
||||
icon_state = "sflash"
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
var/construction_cost = list(DEFAULT_WALL_MATERIAL=750,"glass"=750)
|
||||
var/construction_time=100
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
|
||||
|
||||
/obj/item/device/flash/synthetic/attack(mob/living/M as mob, mob/user as mob)
|
||||
//attack_as_weapon
|
||||
/obj/item/device/flash/synthetic/attack(mob/living/M, mob/living/user, var/target_zone)
|
||||
..()
|
||||
if(!broken)
|
||||
broken = 1
|
||||
user << "\red The bulb has burnt out!"
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
|
||||
/obj/item/device/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
..()
|
||||
if(!broken)
|
||||
broken = 1
|
||||
user << "\red The bulb has burnt out!"
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
|
||||
|
||||
icon_action_button = "action_flashlight"
|
||||
action_button_name = "Toggle Flashlight"
|
||||
var/on = 0
|
||||
var/brightness_on = 4 //luminosity when on
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
return 0
|
||||
on = !on
|
||||
update_icon()
|
||||
user.update_action_buttons()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -42,38 +43,45 @@
|
||||
if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
|
||||
return ..() //just hit them in the head
|
||||
|
||||
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") //don't have dexterity
|
||||
user << "<span class='notice'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = M //mob has protective eyewear
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
user << "<span class='notice'>You're going to need to remove that [(H.head && H.head.flags & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags & MASKCOVERSEYES) ? "mask": "glasses"] first.</span>"
|
||||
return
|
||||
if(istype(H))
|
||||
for(var/obj/item/clothing/C in list(H.head,H.wear_mask,H.glasses))
|
||||
if(istype(C) && (C.body_parts_covered & EYES))
|
||||
user << "<span class='warning'>You're going to need to remove [C.name] first.</span>"
|
||||
return
|
||||
|
||||
if(M == user) //they're using it on themselves
|
||||
if(!M.blinded)
|
||||
flick("flash", M.flash)
|
||||
M.visible_message("<span class='notice'>[M] directs [src] to \his eyes.</span>", \
|
||||
"<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] directs [src] to \his eyes.</span>", \
|
||||
"<span class='notice'>You wave the light in front of your eyes.</span>")
|
||||
return
|
||||
var/obj/item/organ/vision
|
||||
if(H.species.vision_organ)
|
||||
vision = H.internal_organs_by_name[H.species.vision_organ]
|
||||
if(!vision)
|
||||
user << "<span class='warning'>You can't find any [H.species.vision_organ ? H.species.vision_organ : "eyes"] on [H]!</span>"
|
||||
|
||||
user.visible_message("<span class='notice'>[user] directs [src] to [M]'s eyes.</span>", \
|
||||
"<span class='notice'>You direct [src] to [M]'s eyes.</span>")
|
||||
user.visible_message("<span class='notice'>\The [user] directs [src] to [M]'s eyes.</span>", \
|
||||
"<span class='notice'>You direct [src] to [M]'s eyes.</span>")
|
||||
if(H == user) //can't look into your own eyes buster
|
||||
if(M.stat == DEAD || M.blinded) //mob is dead or fully blind
|
||||
user << "<span class='warning'>\The [M]'s pupils do not react to the light!</span>"
|
||||
return
|
||||
if(XRAY in M.mutations)
|
||||
user << "<span class='notice'>\The [M] pupils give an eerie glow!</span>"
|
||||
if(vision.damage)
|
||||
user << "<span class='warning'>There's visible damage to [M]'s [vision.name]!</span>"
|
||||
else if(M.eye_blurry)
|
||||
user << "<span class='notice'>\The [M]'s pupils react slower than normally.</span>"
|
||||
if(M.getBrainLoss() > 15)
|
||||
user << "<span class='notice'>There's visible lag between left and right pupils' reactions.</span>"
|
||||
|
||||
if(istype(M, /mob/living/carbon/human)) //robots and aliens are unaffected
|
||||
if(M.stat == DEAD || M.sdisabilities & BLIND) //mob is dead or fully blind
|
||||
user << "<span class='notice'>[M] pupils does not react to the light!</span>"
|
||||
else if(XRAY in M.mutations) //mob has X-RAY vision
|
||||
flick("flash", M.flash) //Yes, you can still get flashed wit X-Ray.
|
||||
user << "<span class='notice'>[M] pupils give an eerie glow!</span>"
|
||||
else //they're okay!
|
||||
if(!M.blinded)
|
||||
flick("flash", M.flash) //flash the affected mob
|
||||
user << "<span class='notice'>[M]'s pupils narrow.</span>"
|
||||
var/list/pinpoint = list("oxycodone"=1,"tramadol"=5)
|
||||
var/list/dilating = list("space_drugs"=5,"mindbreaker"=1)
|
||||
if(M.reagents.has_any_reagent(pinpoint) || H.ingested.has_any_reagent(pinpoint))
|
||||
user << "<span class='notice'>\The [M]'s pupils are already pinpoint and cannot narrow any more.</span>"
|
||||
else if(M.reagents.has_any_reagent(dilating) || H.ingested.has_any_reagent(dilating))
|
||||
user << "<span class='notice'>\The [M]'s pupils narrow slightly, but are still very dilated.</span>"
|
||||
else
|
||||
user << "<span class='notice'>\The [M]'s pupils narrow.</span>"
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //can be used offensively
|
||||
flick("flash", M.flash)
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -130,14 +138,14 @@
|
||||
|
||||
/obj/item/device/flashlight/flare
|
||||
name = "flare"
|
||||
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
|
||||
desc = "A red standard-issue flare. There are instructions on the side reading 'pull cord, make light'."
|
||||
w_class = 2.0
|
||||
brightness_on = 8 // Pretty bright.
|
||||
light_power = 3
|
||||
light_color = "#e58775"
|
||||
icon_state = "flare"
|
||||
item_state = "flare"
|
||||
icon_action_button = null //just pull it manually, neckbeard.
|
||||
action_button_name = null //just pull it manually, neckbeard.
|
||||
var/fuel = 0
|
||||
var/on_damage = 7
|
||||
var/produce_heat = 1500
|
||||
|
||||
@@ -4,212 +4,153 @@
|
||||
icon_state = "labeler1"
|
||||
item_state = "flight"
|
||||
|
||||
var/mode_nice = "standard"
|
||||
var/mode = "floor"
|
||||
var/tile_dir_mode = 0
|
||||
var/decal = "remove all decals"
|
||||
var/paint_dir = "precise"
|
||||
var/paint_colour = COLOR_WHITE
|
||||
|
||||
// mode 0 ignore direction; sets dir=0
|
||||
// mode 1 all-direction
|
||||
// mode 2 corner selecting the side CW from the selected corner
|
||||
// mode 3 cardinal
|
||||
// mode 4 warningcorner and warnwhitecorner direction fix
|
||||
// mode 5 Opposite corner tiles where the second icon_state is "[mode]_inv"
|
||||
/obj/item/device/floor_painter/afterattack(atom/A, mob/user as mob, proximity)
|
||||
var/list/decals = list(
|
||||
"quarter-turf" = list("path" = /obj/effect/floor_decal/corner, "precise" = 1, "coloured" = 1),
|
||||
"hazard stripes" = list("path" = /obj/effect/floor_decal/industrial/warning),
|
||||
"corner, hazard" = list("path" = /obj/effect/floor_decal/industrial/warning/corner),
|
||||
"hatched marking" = list("path" = /obj/effect/floor_decal/industrial/hatch, "coloured" = 1),
|
||||
"dotted outline" = list("path" = /obj/effect/floor_decal/industrial/outline, "coloured" = 1),
|
||||
"loading sign" = list("path" = /obj/effect/floor_decal/industrial/loading),
|
||||
"1" = list("path" = /obj/effect/floor_decal/sign),
|
||||
"2" = list("path" = /obj/effect/floor_decal/sign/two),
|
||||
"A" = list("path" = /obj/effect/floor_decal/sign/a),
|
||||
"B" = list("path" = /obj/effect/floor_decal/sign/b),
|
||||
"C" = list("path" = /obj/effect/floor_decal/sign/c),
|
||||
"D" = list("path" = /obj/effect/floor_decal/sign/d),
|
||||
"Ex" = list("path" = /obj/effect/floor_decal/sign/ex),
|
||||
"M" = list("path" = /obj/effect/floor_decal/sign/m),
|
||||
"CMO" = list("path" = /obj/effect/floor_decal/sign/cmo),
|
||||
"V" = list("path" = /obj/effect/floor_decal/sign/v),
|
||||
"Psy" = list("path" = /obj/effect/floor_decal/sign/p),
|
||||
"remove all decals" = list("path" = /obj/effect/floor_decal/reset)
|
||||
)
|
||||
var/list/paint_dirs = list(
|
||||
"north" = NORTH,
|
||||
"northwest" = NORTHWEST,
|
||||
"west" = WEST,
|
||||
"southwest" = SOUTHWEST,
|
||||
"south" = SOUTH,
|
||||
"southeast" = SOUTHEAST,
|
||||
"east" = EAST,
|
||||
"northeast" = NORTHEAST,
|
||||
"precise" = 0
|
||||
)
|
||||
|
||||
/obj/item/device/floor_painter/afterattack(var/atom/A, var/mob/user, proximity, params)
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
if(istype(A, /turf/simulated/floor))
|
||||
var/turf/simulated/floor/F = A
|
||||
var/turf/simulated/floor/F = A
|
||||
if(!istype(F))
|
||||
user << "<span class='warning'>\The [src] can only be used on station flooring.</span>"
|
||||
return
|
||||
|
||||
if(F.is_steel_floor()) // only tiled floors
|
||||
if(tile_dir_mode)
|
||||
var/D = get_dir(usr, F)
|
||||
if(usr.loc == F)
|
||||
D = usr.dir
|
||||
if(!F.flooring || !F.flooring.can_paint || F.broken || F.burnt)
|
||||
user << "<span class='warning'>\The [src] cannot paint broken or missing tiles.</span>"
|
||||
return
|
||||
|
||||
switch(tile_dir_mode)
|
||||
if(1) // All directions accepted
|
||||
F.set_dir(D)
|
||||
F.icon_state = mode
|
||||
if(2) // Corner mode - diagonal directions converted CW around.
|
||||
switch(D)
|
||||
if(NORTHEAST)
|
||||
D = EAST
|
||||
if(SOUTHEAST)
|
||||
D = SOUTH
|
||||
if(SOUTHWEST)
|
||||
D = WEST
|
||||
if(NORTHWEST)
|
||||
D = NORTH
|
||||
F.set_dir(D)
|
||||
F.icon_state = mode
|
||||
if(3) // cardinal directions only. I've adjusted diagonals the same way the facing code does.
|
||||
switch(D)
|
||||
if(NORTHEAST)
|
||||
D = EAST
|
||||
if(SOUTHEAST)
|
||||
D = EAST
|
||||
if(SOUTHWEST)
|
||||
D = WEST
|
||||
if(NORTHWEST)
|
||||
D = WEST
|
||||
F.set_dir(D)
|
||||
F.icon_state = mode
|
||||
if(4) // floors.dmi icon_states "warningcorner" and "warnwhitecorner" are incorrect, this fixes it
|
||||
var/D2
|
||||
switch(D)
|
||||
if(NORTHEAST)
|
||||
D2 = WEST
|
||||
if(SOUTHEAST)
|
||||
D2 = SOUTH
|
||||
if(SOUTHWEST)
|
||||
D2 = NORTH
|
||||
if(NORTHWEST)
|
||||
D2 = EAST
|
||||
F.set_dir(D2)
|
||||
F.icon_state = mode
|
||||
if(5)
|
||||
F.set_dir(0)
|
||||
if(D == NORTH || D == SOUTH || D == NORTHEAST || D == SOUTHWEST)
|
||||
F.icon_state = mode
|
||||
else
|
||||
F.icon_state = "[mode]_inv"
|
||||
else
|
||||
F.set_dir(0)
|
||||
F.icon_state = mode
|
||||
var/list/decal_data = decals[decal]
|
||||
var/config_error
|
||||
if(!islist(decal_data))
|
||||
config_error = 1
|
||||
var/painting_decal
|
||||
if(!config_error)
|
||||
painting_decal = decal_data["path"]
|
||||
if(!ispath(painting_decal))
|
||||
config_error = 1
|
||||
|
||||
if(config_error)
|
||||
user << "<span class='warning'>\The [src] flashes an error light. You might need to reconfigure it.</span>"
|
||||
return
|
||||
|
||||
if(F.decals && F.decals.len > 5 && painting_decal != /obj/effect/floor_decal/reset)
|
||||
user << "<span class='warning'>\The [F] has been painted too much; you need to clear it off.</span>"
|
||||
return
|
||||
|
||||
var/painting_dir = 0
|
||||
if(paint_dir == "precise")
|
||||
if(!decal_data["precise"])
|
||||
painting_dir = user.dir
|
||||
else
|
||||
usr << "You can't paint that!"
|
||||
|
||||
/obj/item/device/floor_painter/attack_self(mob/user as mob)
|
||||
var/type = input("What type of floor?", "Floor painter", "solid") in list("solid", "corner", "opposite corners", "side/three corners", "special", "letters")
|
||||
|
||||
tile_dir_mode = 0
|
||||
|
||||
switch(type)
|
||||
if("solid")
|
||||
tile_dir_mode = 0
|
||||
var/design = input("Which color?", "Floor painter") in list("standard", "dark", "red", "blue", "green", "yellow", "purple", "neutral", "white", "white-red", "white-blue", "white-green", "white-yellow", "white-purple", "freezer", "hydro", "showroom")
|
||||
if(design == "standard")
|
||||
mode = "floor"
|
||||
mode_nice = "standard"
|
||||
return
|
||||
if(design == "white")
|
||||
mode = "white"
|
||||
mode_nice = "white"
|
||||
return
|
||||
if(design == "dark")
|
||||
mode = "dark"
|
||||
mode_nice = "dark"
|
||||
return
|
||||
if(design == "showroom" || design == "hydro" || design == "freezer")
|
||||
mode = "[design]floor"
|
||||
mode_nice = design
|
||||
return
|
||||
mode_nice = design
|
||||
mode = "[replacetext(design, "-", "")]full"
|
||||
if("corner")
|
||||
var/design = input("Which design?", "Floor painter") in list("black", "red", "blue", "green", "yellow", "purple", "neutral", "white", "white-red", "white-blue", "white-green", "white-yellow", "white-purple")
|
||||
mode_nice = "[design] corner"
|
||||
mode = "[replacetext(design, "-", "")]corner"
|
||||
tile_dir_mode = 2
|
||||
if("opposite corners")
|
||||
var/design = input("Which design?", "Floor painter") in list("bar", "cmo", "yellowpatch", "cafeteria", "red-yellow", "red-blue", "red-green", "green-yellow", "green-blue", "blue-yellow")
|
||||
mode_nice = design
|
||||
if(design == "bar" || design == "cmo" || design == "yellowpatch" || design == "cafeteria")
|
||||
mode = design
|
||||
else
|
||||
mode = "[replacetext(design, "-", "")]full"
|
||||
if(design == "yellowpatch")
|
||||
tile_dir_mode = 5
|
||||
else
|
||||
tile_dir_mode = 0
|
||||
if("side/three corners")
|
||||
var/design = input("Which design?", "Floor painter") in list("black", "red", "blue", "green", "yellow", "purple", "neutral", "white", "white-red", "white-blue", "white-green", "white-yellow", "white-purple", "red-yellow", "red-blue", "blue-red", "red-green", "green-yellow", "green-blue", "blue-yellow")
|
||||
if(design == "white")
|
||||
mode = "whitehall"
|
||||
mode_nice = "white side"
|
||||
else if(design == "black") // because SOMEONE made the black/grey side/corner sprite have the same name as the 'empty space' sprite :(
|
||||
mode = "blackfloor"
|
||||
mode_nice = design
|
||||
else
|
||||
mode_nice = design
|
||||
mode = replacetext(design, "-", "")
|
||||
tile_dir_mode = 1
|
||||
if("special")
|
||||
var/design = input("Which design?", "Floor painter") in list("arrival", "escape", "caution", "warning", "white-warning", "white-blue-green", "loadingarea", "delivery", "bot", "white-delivery", "white-bot")
|
||||
if(design == "white-blue-green")
|
||||
mode_nice = design
|
||||
mode = "whitebluegreencorners"
|
||||
tile_dir_mode = 2
|
||||
else if(design == "delivery" || design == "bot" || design == "white-delivery" || design == "white-bot")
|
||||
mode_nice = design
|
||||
mode = replacetext(design, "-", "")
|
||||
tile_dir_mode = 0
|
||||
else if(design == "loadingarea")
|
||||
mode_nice = design
|
||||
mode = design
|
||||
tile_dir_mode = 3
|
||||
else
|
||||
if(design == "white-warning")
|
||||
mode_nice = design
|
||||
design = "warnwhite"
|
||||
var/s_corner = alert("Do you want to paint a single corner of the tile?", "Floor painter","Yes","No") == "Yes"
|
||||
if(s_corner)
|
||||
mode_nice = "[design] corner"
|
||||
mode = "[design]corner"
|
||||
if(design == "warning" || design == "white-warning") // sprites for these are weird, need to fix dirs (icons/turf/floors.dmi, "warningcorner" and "warnwhitecorner")
|
||||
tile_dir_mode = 4
|
||||
var/list/mouse_control = params2list(params)
|
||||
var/mouse_x = text2num(mouse_control["icon-x"])
|
||||
var/mouse_y = text2num(mouse_control["icon-y"])
|
||||
if(isnum(mouse_x) && isnum(mouse_y))
|
||||
if(mouse_x <= 16)
|
||||
if(mouse_y <= 16)
|
||||
painting_dir = WEST
|
||||
else
|
||||
tile_dir_mode = 2
|
||||
painting_dir = NORTH
|
||||
else
|
||||
mode_nice = design
|
||||
mode = design
|
||||
tile_dir_mode = 1
|
||||
if("letters")
|
||||
var/which = input("Which letters/design?", "Floor painter") in list("A1", "A2", "DI", "SA", "SA (red)", "SB", "SB (red)", "SC", "SC (red)", "W (red)", "V (green)", "Psy", "Ex", "Ex (blue)", "CMO", "O (OP)", "P (OP)")
|
||||
mode_nice = which
|
||||
switch(which)
|
||||
if("A1")
|
||||
mode = "white_1"
|
||||
if("A2")
|
||||
mode = "white_2"
|
||||
if("DI")
|
||||
mode = "white_d"
|
||||
if("SA")
|
||||
mode = "white_a"
|
||||
if("SA (red)")
|
||||
mode = "whitered_a"
|
||||
tile_dir_mode = 3
|
||||
if("SB")
|
||||
mode = "white_b"
|
||||
if("SB (red)")
|
||||
mode = "whitered_b"
|
||||
tile_dir_mode = 3
|
||||
if("SC")
|
||||
mode = "white_c"
|
||||
if("SC (red)")
|
||||
mode = "whitered_c"
|
||||
tile_dir_mode = 3
|
||||
if("W (red)")
|
||||
mode = "whitered_w"
|
||||
tile_dir_mode = 3
|
||||
if("V (green)")
|
||||
mode = "whitegreen_v"
|
||||
tile_dir_mode = 3
|
||||
if("Psy")
|
||||
mode = "white_p"
|
||||
if("Ex")
|
||||
mode = "white_ex"
|
||||
if("Ex (blue)")
|
||||
mode = "whiteblue_ex"
|
||||
tile_dir_mode = 3
|
||||
if("CMO") // yes this is also in "opposite corners" choices, but it's a different icon_state (!!)
|
||||
mode = "white_cmo"
|
||||
if("O (OP)")
|
||||
mode = "white_halfo"
|
||||
if("P (OP)")
|
||||
mode = "white_halfp"
|
||||
if(mouse_y <= 16)
|
||||
painting_dir = SOUTH
|
||||
else
|
||||
painting_dir = EAST
|
||||
else
|
||||
painting_dir = user.dir
|
||||
else if(paint_dirs[paint_dir])
|
||||
painting_dir = paint_dirs[paint_dir]
|
||||
|
||||
var/painting_colour
|
||||
if(decal_data["coloured"] && paint_colour)
|
||||
painting_colour = paint_colour
|
||||
|
||||
new painting_decal(F, painting_dir, painting_colour)
|
||||
|
||||
/obj/item/device/floor_painter/attack_self(var/mob/user)
|
||||
var/choice = input("Do you wish to change the decal type, paint direction, or paint colour?") as null|anything in list("Decal","Direction", "Colour")
|
||||
if(choice == "Decal")
|
||||
choose_decal()
|
||||
else if(choice == "Direction")
|
||||
choose_direction()
|
||||
else if(choice == "Colour")
|
||||
choose_colour()
|
||||
|
||||
/obj/item/device/floor_painter/examine(mob/user)
|
||||
..(user)
|
||||
user << "It is in [mode_nice] mode."
|
||||
user << "It is configured to produce the '[decal]' decal with a direction of '[paint_dir]' using [paint_colour] paint."
|
||||
|
||||
/obj/item/device/floor_painter/verb/choose_colour()
|
||||
set name = "Choose Colour"
|
||||
set desc = "Choose a floor painter colour."
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
var/new_colour = input(usr, "Choose a colour.", "Floor painter", paint_colour) as color|null
|
||||
if(new_colour && new_colour != paint_colour)
|
||||
paint_colour = new_colour
|
||||
usr << "<span class='notice'>You set \the [src] to paint with <font color='[paint_colour]'>a new colour</font>.</span>"
|
||||
|
||||
/obj/item/device/floor_painter/verb/choose_decal()
|
||||
set name = "Choose Decal"
|
||||
set desc = "Choose a floor painter decal."
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
var/new_decal = input("Select a decal.") as null|anything in decals
|
||||
if(new_decal && !isnull(decals[new_decal]))
|
||||
decal = new_decal
|
||||
usr << "<span class='notice'>You set \the [src] decal to '[decal]'.</span>"
|
||||
|
||||
/obj/item/device/floor_painter/verb/choose_direction()
|
||||
set name = "Choose Direction"
|
||||
set desc = "Choose a floor painter direction."
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
var/new_dir = input("Select a direction.") as null|anything in paint_dirs
|
||||
if(new_dir && !isnull(paint_dirs[new_dir]))
|
||||
paint_dir = new_dir
|
||||
usr << "<span class='notice'>You set \the [src] direction to '[paint_dir]'.</span>"
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/obj/item/device/multitool/hacktool
|
||||
var/is_hacking = 0
|
||||
var/max_known_targets
|
||||
|
||||
var/in_hack_mode = 0
|
||||
var/list/known_targets
|
||||
var/list/supported_types
|
||||
var/datum/topic_state/default/must_hack/hack_state
|
||||
|
||||
/obj/item/device/multitool/hacktool/New()
|
||||
..()
|
||||
known_targets = list()
|
||||
max_known_targets = 5 + rand(1,3)
|
||||
supported_types = list(/obj/machinery/door/airlock)
|
||||
hack_state = new(src)
|
||||
|
||||
/obj/item/device/multitool/hacktool/Destroy()
|
||||
for(var/T in known_targets)
|
||||
var/atom/target = T
|
||||
destroyed_event.unregister(target, src)
|
||||
known_targets.Cut()
|
||||
qdel(hack_state)
|
||||
hack_state = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/multitool/hacktool/attackby(var/obj/W, var/mob/user)
|
||||
if(isscrewdriver(W))
|
||||
in_hack_mode = !in_hack_mode
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/multitool/hacktool/resolve_attackby(atom/A, mob/user)
|
||||
sanity_check()
|
||||
|
||||
if(!in_hack_mode)
|
||||
return ..()
|
||||
|
||||
if(!attempt_hack(user, A))
|
||||
return 0
|
||||
|
||||
A.ui_interact(user, state = hack_state)
|
||||
return 1
|
||||
|
||||
/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target)
|
||||
if(is_hacking)
|
||||
user << "<span class='warning'>You are already hacking!</span>"
|
||||
return 0
|
||||
if(!is_type_in_list(target, supported_types))
|
||||
user << "\icon[src] <span class='warning'>Unable to hack this target!</span>"
|
||||
return 0
|
||||
var/found = known_targets.Find(target)
|
||||
if(found)
|
||||
known_targets.Swap(1, found) // Move the last hacked item first
|
||||
return 1
|
||||
|
||||
user << "<span class='notice'>You begin hacking \the [target]...</span>"
|
||||
is_hacking = 1
|
||||
// On average hackin takes ~30 seconds. Fairly small random span to avoid people simply aborting and trying again
|
||||
var/hack_result = do_after(user, (20 SECONDS + rand(0, 10 SECONDS) + rand(0, 10 SECONDS)))
|
||||
is_hacking = 0
|
||||
|
||||
if(hack_result && in_hack_mode)
|
||||
user << "<span class='notice'>Your hacking attempt was succesful!</span>"
|
||||
playsound(src.loc, 'sound/piano/A#6.ogg', 75)
|
||||
else
|
||||
user << "<span class='warning'>Your hacking attempt failed!</span>"
|
||||
return 0
|
||||
|
||||
known_targets.Insert(1, target) // Insert the newly hacked target first,
|
||||
destroyed_event.register(target, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy)
|
||||
return 1
|
||||
|
||||
/obj/item/device/multitool/hacktool/proc/sanity_check()
|
||||
if(max_known_targets < 1) max_known_targets = 1
|
||||
// Cut away the oldest items if the capacity has been reached
|
||||
if(known_targets.len > max_known_targets)
|
||||
for(var/i = (max_known_targets + 1) to known_targets.len)
|
||||
var/atom/A = known_targets[i]
|
||||
destroyed_event.unregister(A, src)
|
||||
known_targets.Cut(max_known_targets + 1)
|
||||
|
||||
/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target)
|
||||
known_targets -= target
|
||||
|
||||
/datum/topic_state/default/must_hack
|
||||
var/obj/item/device/multitool/hacktool/hacktool
|
||||
|
||||
/datum/topic_state/default/must_hack/New(var/hacktool)
|
||||
src.hacktool = hacktool
|
||||
..()
|
||||
|
||||
/datum/topic_state/default/must_hack/Destroy()
|
||||
hacktool = null
|
||||
return ..()
|
||||
|
||||
/datum/topic_state/default/must_hack/can_use_topic(var/src_object, var/mob/user)
|
||||
if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
@@ -15,7 +15,7 @@
|
||||
//
|
||||
// HOW TO REFILL THE DEVICE
|
||||
//
|
||||
// It will need to be manually refilled with lights.
|
||||
// It can be manually refilled or by clicking on a storage item containing lights.
|
||||
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
|
||||
//
|
||||
// EMAGGED FEATURES
|
||||
@@ -41,7 +41,7 @@
|
||||
/obj/item/device/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with working lightbulbs."
|
||||
desc = "A device to automatically replace lights. Refill with working lightbulbs or sheets of glass."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
@@ -49,16 +49,15 @@
|
||||
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=3;materials=2"
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 2)
|
||||
|
||||
var/max_uses = 20
|
||||
var/uses = 0
|
||||
var/max_uses = 32
|
||||
var/uses = 32
|
||||
var/emagged = 0
|
||||
var/failmsg = ""
|
||||
var/charge = 0
|
||||
|
||||
/obj/item/device/lightreplacer/New()
|
||||
uses = max_uses / 2
|
||||
failmsg = "The [name]'s refill light blinks red."
|
||||
..()
|
||||
|
||||
@@ -67,18 +66,14 @@
|
||||
user << "It has [uses] lights remaining."
|
||||
|
||||
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
|
||||
if(istype(W, /obj/item/weapon/card/emag) && emagged == 0)
|
||||
Emag()
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/stack/material) && W.get_material_name() == "glass")
|
||||
var/obj/item/stack/G = W
|
||||
if(uses >= max_uses)
|
||||
user << "<span class='warning'>[src.name] is full."
|
||||
user << "<span class='warning'>[src.name] is full.</span>"
|
||||
return
|
||||
else if(G.use(1))
|
||||
AddUses(5)
|
||||
user << "<span class='notice'>You insert a piece of glass into the [src.name]. You have [uses] lights remaining.</span>"
|
||||
AddUses(16) //Autolathe converts 1 sheet into 16 lights.
|
||||
user << "<span class='notice'>You insert a piece of glass into \the [src.name]. You have [uses] light\s remaining.</span>"
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You need one sheet of glass to replace lights.</span>"
|
||||
@@ -88,7 +83,7 @@
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
AddUses(1)
|
||||
user << "You insert the [L.name] into the [src.name]. You have [uses] lights remaining."
|
||||
user << "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining."
|
||||
user.drop_item()
|
||||
qdel(L)
|
||||
return
|
||||
@@ -96,7 +91,6 @@
|
||||
user << "You need a working light."
|
||||
return
|
||||
|
||||
|
||||
/obj/item/device/lightreplacer/attack_self(mob/user)
|
||||
/* // This would probably be a bit OP. If you want it though, uncomment the code.
|
||||
if(isrobot(user))
|
||||
@@ -173,14 +167,11 @@
|
||||
U << "There is a working [target.fitting] already inserted."
|
||||
return
|
||||
|
||||
/obj/item/device/lightreplacer/proc/Emag()
|
||||
/obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user)
|
||||
emagged = !emagged
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
if(emagged)
|
||||
name = "Shortcircuited [initial(name)]"
|
||||
else
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
//Can you use it?
|
||||
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
/obj/item/device/megaphone/attack_self(mob/living/user as mob)
|
||||
if (user.client)
|
||||
if(user.client.prefs.muted & MUTE_IC)
|
||||
src << "\red You cannot speak in IC (muted)."
|
||||
src << "<span class='warning'>You cannot speak in IC (muted).</span>"
|
||||
return
|
||||
if(!ishuman(user))
|
||||
user << "\red You don't know how to use this!"
|
||||
user << "<span class='warning'>You don't know how to use this!</span>"
|
||||
return
|
||||
if(user.silent)
|
||||
return
|
||||
if(spamcheck)
|
||||
user << "\red \The [src] needs to recharge!"
|
||||
user << "<span class='warning'>\The [src] needs to recharge!</span>"
|
||||
return
|
||||
|
||||
var/message = sanitize(input(user, "Shout a message?", "Megaphone", null) as text)
|
||||
@@ -36,7 +36,7 @@
|
||||
O.show_message("<B>[user]</B> broadcasts, <FONT size=3>\"[pick(insultmsg)]\"</FONT>",2) // 2 stands for hearable message
|
||||
insults--
|
||||
else
|
||||
user << "\red *BZZZZzzzzzt*"
|
||||
user << "<span class='warning'>*BZZZZzzzzzt*</span>"
|
||||
else
|
||||
for(var/mob/O in (viewers(user)))
|
||||
O.show_message("<B>[user]</B> broadcasts, <FONT size=3>\"[message]\"</FONT>",2) // 2 stands for hearable message
|
||||
@@ -46,10 +46,9 @@
|
||||
spamcheck = 0
|
||||
return
|
||||
|
||||
/obj/item/device/megaphone/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/card/emag) && !emagged)
|
||||
user << "\red You overload \the [src]'s voice synthesizer."
|
||||
/obj/item/device/megaphone/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(!emagged)
|
||||
user << "<span class='warning'>You overload \the [src]'s voice synthesizer.</span>"
|
||||
emagged = 1
|
||||
insults = rand(1, 3)//to prevent dickflooding
|
||||
return
|
||||
return
|
||||
return 1
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
playsound(user.loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
|
||||
user.visible_message("\red [user] opens \the [src] and modifies \the [O].","\red You open \the [src] and modify \the [O].")
|
||||
user.visible_message("<span class='notice'>\The [user] opens \the [src] and modifies \the [O].</span>","<span class='notice'>You open \the [src] and modify \the [O].</span>")
|
||||
|
||||
I.refit_for_species(target_species)
|
||||
|
||||
|
||||
@@ -18,6 +18,54 @@
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 50,"glass" = 20)
|
||||
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
|
||||
var/obj/machinery/clonepod/connecting //same for cryopod linkage
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
|
||||
|
||||
var/buffer_name
|
||||
var/atom/buffer_object
|
||||
|
||||
/obj/item/device/multitool/Destroy()
|
||||
unregister_buffer(buffer_object)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/multitool/proc/get_buffer(var/typepath)
|
||||
// Only allow clearing the buffer name when someone fetches the buffer.
|
||||
// Means you cannot be sure the source hasn't been destroyed until the very moment it's needed.
|
||||
get_buffer_name(TRUE)
|
||||
if(buffer_object && (!typepath || istype(buffer_object, typepath)))
|
||||
return buffer_object
|
||||
|
||||
/obj/item/device/multitool/proc/get_buffer_name(var/null_name_if_missing = FALSE)
|
||||
if(buffer_object)
|
||||
buffer_name = buffer_object.name
|
||||
else if(null_name_if_missing)
|
||||
buffer_name = null
|
||||
return buffer_name
|
||||
|
||||
/obj/item/device/multitool/proc/set_buffer(var/atom/buffer)
|
||||
if(!buffer || istype(buffer))
|
||||
buffer_name = buffer ? buffer.name : null
|
||||
if(buffer != buffer_object)
|
||||
unregister_buffer(buffer_object)
|
||||
buffer_object = buffer
|
||||
if(buffer_object)
|
||||
destroyed_event.register(buffer_object, src, /obj/item/device/multitool/proc/unregister_buffer)
|
||||
|
||||
/obj/item/device/multitool/proc/unregister_buffer(var/atom/buffer_to_unregister)
|
||||
// Only remove the buffered object, don't reset the name
|
||||
// This means one cannot know if the buffer has been destroyed until one attempts to use it.
|
||||
if(buffer_to_unregister == buffer_object && buffer_object)
|
||||
destroyed_event.unregister(buffer_object, src)
|
||||
buffer_object = null
|
||||
|
||||
/obj/item/device/multitool/resolve_attackby(atom/A, mob/user)
|
||||
if(!isobj(A))
|
||||
return ..(A, user)
|
||||
|
||||
var/obj/O = A
|
||||
var/datum/expansion/multitool/MT = O.expansions[/datum/expansion/multitool]
|
||||
if(!MT)
|
||||
return ..(A, user)
|
||||
|
||||
user.AddTopicPrint(src)
|
||||
MT.interact(src, user)
|
||||
return 1
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
item_state = "electronic"
|
||||
w_class = 2.0
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "programming=2"
|
||||
origin_tech = list(TECH_DATA = 2)
|
||||
var/obj/item/device/radio/radio
|
||||
var/looking_for_personality = 0
|
||||
var/mob/living/silicon/pai/pai
|
||||
|
||||
/*/obj/item/device/paicard/relaymove(var/mob/user, var/direction)
|
||||
if(src.loc && istype(src.loc.loc, /obj/item/rig_module))
|
||||
var/obj/item/rig_module/module = src.loc.loc
|
||||
if(!module.holder || !direction)
|
||||
return
|
||||
module.holder.forced_move(direction)*/
|
||||
/obj/item/device/paicard/relaymove(var/mob/user, var/direction)
|
||||
if(user.stat || user.stunned)
|
||||
return
|
||||
var/obj/item/weapon/rig/rig = src.get_rig()
|
||||
if(istype(rig))
|
||||
rig.forced_move(direction, user)
|
||||
|
||||
/obj/item/device/paicard/New()
|
||||
..()
|
||||
@@ -181,7 +181,7 @@
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
else
|
||||
else //</font></font>
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
|
||||
dat += {"
|
||||
@@ -307,7 +307,7 @@
|
||||
/obj/item/device/paicard/proc/alertUpdate()
|
||||
var/turf/T = get_turf_or_move(src.loc)
|
||||
for (var/mob/M in viewers(T))
|
||||
M.show_message("\blue [src] flashes a message across its screen, \"Additional personalities available for download.\"", 3, "\blue [src] bleeps electronically.", 2)
|
||||
M.show_message("<span class='notice'>\The [src] flashes a message across its screen, \"Additional personalities available for download.\"</span>", 3, "<span class='notice'>\The [src] bleeps electronically.</span>", 2)
|
||||
|
||||
/obj/item/device/paicard/emp_act(severity)
|
||||
for(var/mob/M in src)
|
||||
@@ -343,4 +343,10 @@
|
||||
if (istype(loc, /mob))
|
||||
slotnumber = get_equip_slot()
|
||||
|
||||
report_onmob_location(1, slotnumber, pai)
|
||||
report_onmob_location(1, slotnumber, pai)
|
||||
|
||||
/obj/item/device/paicard/show_message(msg, type, alt, alt_type)
|
||||
if(pai && pai.client)
|
||||
var/rendered = "<span class='message'>[msg]</span>"
|
||||
pai.show_message(rendered, type)
|
||||
..()
|
||||
|
||||
@@ -16,16 +16,11 @@
|
||||
/obj/item/device/pipe_painter/afterattack(atom/A, mob/user as mob, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
|
||||
if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/tank) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated) || !in_range(user, A))
|
||||
return
|
||||
var/obj/machinery/atmospherics/pipe/P = A
|
||||
|
||||
var/turf/T = P.loc
|
||||
if (P.level < 2 && T.level==1 && isturf(T) && T.intact)
|
||||
user << "\red You must remove the plating first."
|
||||
return
|
||||
|
||||
P.change_color(pipe_colors[mode])
|
||||
|
||||
/obj/item/device/pipe_painter/attack_self(mob/user as mob)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 750,"waste" = 750)
|
||||
|
||||
origin_tech = "powerstorage=3;syndicate=5"
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ILLEGAL = 5)
|
||||
var/drain_rate = 1500000 // amount of power to drain per tick
|
||||
var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts.
|
||||
var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts.
|
||||
@@ -34,7 +34,7 @@
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(mode == 0)
|
||||
var/turf/T = loc
|
||||
if(isturf(T) && !T.intact)
|
||||
if(isturf(T) && !!T.is_plating())
|
||||
attached = locate() in T
|
||||
if(!attached)
|
||||
user << "No exposed cable here to attach to."
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "beacon"
|
||||
item_state = "signaler"
|
||||
var/code = "electronic"
|
||||
origin_tech = "bluespace=1"
|
||||
origin_tech = list(TECH_BLUESPACE = 1)
|
||||
|
||||
/obj/item/device/radio/beacon/hear_talk()
|
||||
return
|
||||
@@ -38,11 +38,11 @@
|
||||
/obj/item/device/radio/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Activate to have a singularity beacon teleported to your location</i>."
|
||||
origin_tech = "bluespace=1;syndicate=7"
|
||||
origin_tech = list(TECH_BLUESPACE = 1, TECH_ILLEGAL = 7)
|
||||
|
||||
/obj/item/device/radio/beacon/syndicate/attack_self(mob/user as mob)
|
||||
if(user)
|
||||
user << "\blue Locked In"
|
||||
user << "<span class='notice'>Locked In</span>"
|
||||
new /obj/machinery/power/singularity_beacon/syndicate( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
/obj/item/device/encryptionkey/
|
||||
name = "standard encrpytion key"
|
||||
name = "standard encryption key"
|
||||
desc = "An encryption key for a radio headset. Contains cypherkeys."
|
||||
icon = 'icons/obj/radio.dmi'
|
||||
icon_state = "cypherkey"
|
||||
@@ -13,21 +13,18 @@
|
||||
var/syndie = 0
|
||||
var/list/channels = list()
|
||||
|
||||
|
||||
/obj/item/device/encryptionkey/New()
|
||||
|
||||
/obj/item/device/encryptionkey/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
/obj/item/device/encryptionkey/syndicate
|
||||
icon_state = "cypherkey"
|
||||
channels = list("Mercenary" = 1)
|
||||
origin_tech = "syndicate=3"
|
||||
origin_tech = list(TECH_ILLEGAL = 3)
|
||||
syndie = 1//Signifies that it de-crypts Syndicate transmissions
|
||||
|
||||
/obj/item/device/encryptionkey/binary
|
||||
icon_state = "cypherkey"
|
||||
translate_binary = 1
|
||||
origin_tech = "syndicate=3"
|
||||
origin_tech = list(TECH_ILLEGAL = 3)
|
||||
|
||||
/obj/item/device/encryptionkey/hivenet
|
||||
name = "hivenet encryption chip"
|
||||
@@ -106,6 +103,8 @@
|
||||
name = "head of personnel's encryption key"
|
||||
icon_state = "hop_cypherkey"
|
||||
channels = list("Supply" = 1, "Service" = 1, "Command" = 1, "Security" = 0)
|
||||
|
||||
|
||||
/*
|
||||
/obj/item/device/encryptionkey/headset_mine
|
||||
name = "mining radio encryption key"
|
||||
@@ -128,5 +127,9 @@
|
||||
channels = list("Service" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/ert
|
||||
name = "\improper NanoTrasen ERT radio encryption key"
|
||||
name = "\improper ERT radio encryption key"
|
||||
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1)
|
||||
|
||||
/obj/item/device/encryptionkey/entertainment
|
||||
name = "entertainment radio key"
|
||||
channels = list("Entertainment" = 1)
|
||||
|
||||
@@ -14,13 +14,15 @@
|
||||
var/translate_hivenet = 0
|
||||
var/obj/item/device/encryptionkey/keyslot1 = null
|
||||
var/obj/item/device/encryptionkey/keyslot2 = null
|
||||
maxf = 1489
|
||||
|
||||
var/ks1type = /obj/item/device/encryptionkey
|
||||
var/ks2type = null
|
||||
|
||||
sprite_sheets = list("Resomi" = 'icons/mob/species/resomi/ears.dmi')
|
||||
|
||||
/obj/item/device/radio/headset/New()
|
||||
..()
|
||||
internal_channels.Cut()
|
||||
if(ks1type)
|
||||
keyslot1 = new ks1type(src)
|
||||
if(ks2type)
|
||||
@@ -32,13 +34,16 @@
|
||||
qdel(keyslot2)
|
||||
keyslot1 = null
|
||||
keyslot2 = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/radio/headset/list_channels(var/mob/user)
|
||||
return list_secure_channels()
|
||||
|
||||
/obj/item/device/radio/headset/examine(mob/user)
|
||||
if(!(..(user, 1) && radio_desc))
|
||||
return
|
||||
|
||||
user << "The following channels are built-in:"
|
||||
user << "The following channels are available:"
|
||||
user << radio_desc
|
||||
|
||||
/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel)
|
||||
@@ -70,12 +75,12 @@
|
||||
ks1type = /obj/item/device/encryptionkey/hivenet
|
||||
|
||||
/obj/item/device/radio/headset/syndicate
|
||||
origin_tech = "syndicate=3"
|
||||
origin_tech = list(TECH_ILLEGAL = 3)
|
||||
syndie = 1
|
||||
ks1type = /obj/item/device/encryptionkey/syndicate
|
||||
|
||||
/obj/item/device/radio/headset/binary
|
||||
origin_tech = "syndicate=3"
|
||||
origin_tech = list(TECH_ILLEGAL = 3)
|
||||
ks1type = /obj/item/device/encryptionkey/binary
|
||||
|
||||
/obj/item/device/radio/headset/headset_sec
|
||||
@@ -183,21 +188,7 @@
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/hop
|
||||
/*
|
||||
/obj/item/device/radio/headset/headset_mine
|
||||
name = "mining radio headset"
|
||||
desc = "Headset used by miners. How useless. To access the mining channel, use :d."
|
||||
icon_state = "mine_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/headset_mine
|
||||
|
||||
/obj/item/device/radio/headset/heads/qm
|
||||
name = "quartermaster's headset"
|
||||
desc = "The headset of the man who control your toiletpaper supply. To access the cargo channel, use :q. For mining, use :d."
|
||||
icon_state = "cargo_headset"
|
||||
item_state = "headset"
|
||||
keyslot2 = new /obj/item/device/encryptionkey/heads/qm
|
||||
*/
|
||||
/obj/item/device/radio/headset/headset_cargo
|
||||
name = "supply radio headset"
|
||||
desc = "A headset used by the QM and their slaves."
|
||||
@@ -217,7 +208,6 @@
|
||||
desc = "The headset of the boss's boss."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
freerange = 1
|
||||
ks2type = /obj/item/device/encryptionkey/ert
|
||||
|
||||
/obj/item/device/radio/headset/ia
|
||||
@@ -227,6 +217,13 @@
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/heads/hos
|
||||
|
||||
/obj/item/device/radio/headset/entertainment
|
||||
name = "actor's radio headset"
|
||||
desc = "specially made to make you sound less cheesy."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/device/encryptionkey/entertainment
|
||||
|
||||
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
// ..()
|
||||
user.set_machine(src)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/item/device/radio/intercom
|
||||
name = "station intercom"
|
||||
name = "station intercom (General)"
|
||||
desc = "Talk through this."
|
||||
icon_state = "intercom"
|
||||
anchored = 1
|
||||
@@ -7,14 +7,76 @@
|
||||
canhear_range = 2
|
||||
flags = CONDUCT | NOBLOODY
|
||||
var/number = 0
|
||||
var/anyai = 1
|
||||
var/mob/living/silicon/ai/ai = list()
|
||||
var/last_tick //used to delay the powercheck
|
||||
|
||||
/obj/item/device/radio/intercom/custom
|
||||
name = "station intercom (Custom)"
|
||||
broadcasting = 0
|
||||
listening = 0
|
||||
|
||||
/obj/item/device/radio/intercom/interrogation
|
||||
name = "station intercom (Interrogation)"
|
||||
frequency = 1449
|
||||
|
||||
/obj/item/device/radio/intercom/private
|
||||
name = "station intercom (Private)"
|
||||
frequency = AI_FREQ
|
||||
|
||||
/obj/item/device/radio/intercom/specops
|
||||
name = "\improper Spec Ops intercom"
|
||||
frequency = ERT_FREQ
|
||||
|
||||
/obj/item/device/radio/intercom/department
|
||||
canhear_range = 5
|
||||
broadcasting = 0
|
||||
listening = 1
|
||||
|
||||
/obj/item/device/radio/intercom/department/medbay
|
||||
name = "station intercom (Medbay)"
|
||||
frequency = MED_I_FREQ
|
||||
|
||||
/obj/item/device/radio/intercom/department/security
|
||||
name = "station intercom (Security)"
|
||||
frequency = SEC_I_FREQ
|
||||
|
||||
/obj/item/device/radio/intercom/entertainment
|
||||
name = "entertainment intercom"
|
||||
frequency = ENT_FREQ
|
||||
canhear_range = 4
|
||||
|
||||
/obj/item/device/radio/intercom/New()
|
||||
..()
|
||||
processing_objects += src
|
||||
|
||||
/obj/item/device/radio/intercom/department/medbay/New()
|
||||
..()
|
||||
internal_channels = default_medbay_channels.Copy()
|
||||
|
||||
/obj/item/device/radio/intercom/department/security/New()
|
||||
..()
|
||||
internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(SEC_I_FREQ) = list(access_security)
|
||||
)
|
||||
|
||||
/obj/item/device/radio/intercom/entertainment/New()
|
||||
..()
|
||||
internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(ENT_FREQ) = list()
|
||||
)
|
||||
|
||||
/obj/item/device/radio/intercom/syndicate
|
||||
name = "illicit intercom"
|
||||
desc = "Talk through this. Evilly"
|
||||
frequency = SYND_FREQ
|
||||
subspace_transmission = 1
|
||||
syndie = 1
|
||||
|
||||
/obj/item/device/radio/intercom/syndicate/New()
|
||||
..()
|
||||
internal_channels[num2text(SYND_FREQ)] = list(access_syndicate)
|
||||
|
||||
/obj/item/device/radio/intercom/Destroy()
|
||||
processing_objects -= src
|
||||
..()
|
||||
@@ -44,12 +106,6 @@
|
||||
|
||||
return canhear_range
|
||||
|
||||
|
||||
/obj/item/device/radio/intercom/hear_talk(mob/M as mob, msg)
|
||||
if(!src.anyai && !(M in src.ai))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/radio/intercom/process()
|
||||
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
|
||||
last_tick = world.timeofday
|
||||
@@ -57,8 +113,8 @@
|
||||
if(!src.loc)
|
||||
on = 0
|
||||
else
|
||||
var/area/A = src.loc.loc
|
||||
if(!A || !isarea(A))
|
||||
var/area/A = get_area(src)
|
||||
if(!A)
|
||||
on = 0
|
||||
else
|
||||
on = A.powered(EQUIP) // set "on" to the power status
|
||||
@@ -68,9 +124,25 @@
|
||||
else
|
||||
icon_state = "intercom"
|
||||
|
||||
/obj/item/device/radio/intercom/broadcasting
|
||||
broadcasting = 1
|
||||
|
||||
/obj/item/device/radio/intercom/locked
|
||||
freerange = 1
|
||||
var/locked_frequency
|
||||
|
||||
/obj/item/device/radio/intercom/locked/set_frequency()
|
||||
..(locked_frequency)
|
||||
|
||||
/obj/item/device/radio/intercom/locked/set_frequency(var/frequency)
|
||||
if(frequency == locked_frequency)
|
||||
..(locked_frequency)
|
||||
|
||||
/obj/item/device/radio/intercom/locked/list_channels()
|
||||
return ""
|
||||
|
||||
/obj/item/device/radio/intercom/locked/ai_private
|
||||
name = "\improper AI intercom"
|
||||
frequency = AI_FREQ
|
||||
broadcasting = 1
|
||||
listening = 1
|
||||
|
||||
/obj/item/device/radio/intercom/locked/confessional
|
||||
name = "confessional intercom"
|
||||
frequency = 1480
|
||||
|
||||
@@ -1,25 +1,45 @@
|
||||
// Access check is of the type requires one. These have been carefully selected to avoid allowing the janitor to see channels he shouldn't
|
||||
var/global/list/default_internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(AI_FREQ) = list(access_synth),
|
||||
num2text(ENT_FREQ) = list(),
|
||||
num2text(ERT_FREQ) = list(access_cent_specops),
|
||||
num2text(COMM_FREQ)= list(access_heads),
|
||||
num2text(ENG_FREQ) = list(access_engine_equip, access_atmospherics),
|
||||
num2text(MED_FREQ) = list(access_medical_equip),
|
||||
num2text(MED_I_FREQ)=list(access_medical_equip),
|
||||
num2text(SEC_FREQ) = list(access_security),
|
||||
num2text(SEC_I_FREQ)=list(access_security),
|
||||
num2text(SCI_FREQ) = list(access_tox,access_robotics,access_xenobiology),
|
||||
num2text(SUP_FREQ) = list(access_cargo),
|
||||
num2text(SRV_FREQ) = list(access_janitor, access_hydroponics)
|
||||
)
|
||||
|
||||
var/global/list/default_medbay_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(MED_FREQ) = list(access_medical_equip),
|
||||
num2text(MED_I_FREQ) = list(access_medical_equip)
|
||||
)
|
||||
|
||||
/obj/item/device/radio
|
||||
icon = 'icons/obj/radio.dmi'
|
||||
name = "station bounced radio"
|
||||
suffix = "\[3\]"
|
||||
icon_state = "walkietalkie"
|
||||
item_state = "walkietalkie"
|
||||
|
||||
var/on = 1 // 0 for off
|
||||
var/last_transmission
|
||||
var/frequency = PUB_FREQ //common chat
|
||||
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
|
||||
var/canhear_range = 3 // the range which mobs can hear this radio from
|
||||
var/obj/item/device/radio/patch_link = null
|
||||
var/datum/wires/radio/wires = null
|
||||
var/b_stat = 0
|
||||
var/broadcasting = 0
|
||||
var/listening = 1
|
||||
var/freerange = 0 // 0 - Sanitize frequencies, 1 - Full range
|
||||
var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
|
||||
var/list/channels = list() //see communications.dm for full list. First channel is a "default" for :h
|
||||
var/subspace_transmission = 0
|
||||
var/syndie = 0//Holder to see if it's a syndicate encrpyed radio
|
||||
var/maxf = 1499
|
||||
// "Example" = FREQ_LISTENING|FREQ_BROADCASTING
|
||||
var/syndie = 0//Holder to see if it's a syndicate encrypted radio
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
throw_speed = 2
|
||||
@@ -28,7 +48,7 @@
|
||||
|
||||
matter = list("glass" = 25,DEFAULT_WALL_MATERIAL = 75)
|
||||
var/const/FREQ_LISTENING = 1
|
||||
|
||||
var/list/internal_channels
|
||||
|
||||
/obj/item/device/radio
|
||||
var/datum/radio_frequency/radio_connection
|
||||
@@ -42,6 +62,7 @@
|
||||
/obj/item/device/radio/New()
|
||||
..()
|
||||
wires = new(src)
|
||||
internal_channels = default_internal_channels.Copy()
|
||||
|
||||
/obj/item/device/radio/Destroy()
|
||||
qdel(wires)
|
||||
@@ -50,19 +71,13 @@
|
||||
radio_controller.remove_object(src, frequency)
|
||||
for (var/ch_name in channels)
|
||||
radio_controller.remove_object(src, radiochannels[ch_name])
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device/radio/initialize()
|
||||
|
||||
if(freerange)
|
||||
if(frequency < 1200 || frequency > 1600)
|
||||
frequency = sanitize_frequency(frequency, maxf)
|
||||
// The max freq is higher than a regular headset to decrease the chance of people listening in, if you use the higher channels.
|
||||
else if (frequency < 1441 || frequency > maxf)
|
||||
//world.log << "[src] ([type]) has a frequency of [frequency], sanitizing."
|
||||
frequency = sanitize_frequency(frequency, maxf)
|
||||
|
||||
if(frequency < RADIO_LOW_FREQ || frequency > RADIO_HIGH_FREQ)
|
||||
frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
|
||||
set_frequency(frequency)
|
||||
|
||||
for (var/ch_name in channels)
|
||||
@@ -72,38 +87,77 @@
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/radio/attack_self(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
interact(user)
|
||||
/obj/item/device/radio/interact(mob/user)
|
||||
if(!user)
|
||||
return 0
|
||||
|
||||
/obj/item/device/radio/interact(mob/user as mob)
|
||||
if(!on)
|
||||
return
|
||||
if(b_stat)
|
||||
wires.Interact(user)
|
||||
|
||||
if(active_uplink_check(user))
|
||||
return
|
||||
return ui_interact(user)
|
||||
|
||||
var/dat = "<html><head><title>[src]</title></head><body><TT>"
|
||||
/obj/item/device/radio/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
if(!istype(src, /obj/item/device/radio/headset)) //Headsets dont get a mic button
|
||||
dat += "Microphone: [broadcasting ? "<A href='byond://?src=\ref[src];talk=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];talk=1'>Disengaged</A>"]<BR>"
|
||||
data["mic_status"] = broadcasting
|
||||
data["speaker"] = listening
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["rawfreq"] = num2text(frequency)
|
||||
|
||||
dat += {"
|
||||
Speaker: [listening ? "<A href='byond://?src=\ref[src];listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];listen=1'>Disengaged</A>"]<BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
||||
[format_frequency(frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
"}
|
||||
data["mic_cut"] = (wires.IsIndexCut(WIRE_TRANSMIT) || wires.IsIndexCut(WIRE_SIGNAL))
|
||||
data["spk_cut"] = (wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL))
|
||||
|
||||
for (var/ch_name in channels)
|
||||
dat+=text_sec_channel(ch_name, channels[ch_name])
|
||||
dat+={"[text_wires()]</TT></body></html>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
var/list/chanlist = list_channels(user)
|
||||
if(islist(chanlist) && chanlist.len)
|
||||
data["chan_list"] = chanlist
|
||||
data["chan_list_len"] = chanlist.len
|
||||
|
||||
if(syndie)
|
||||
data["useSyndMode"] = 1
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/radio/proc/list_channels(var/mob/user)
|
||||
return list_internal_channels(user)
|
||||
|
||||
/obj/item/device/radio/proc/list_secure_channels(var/mob/user)
|
||||
var/dat[0]
|
||||
|
||||
for(var/ch_name in channels)
|
||||
var/chan_stat = channels[ch_name]
|
||||
var/listening = !!(chan_stat & FREQ_LISTENING) != 0
|
||||
|
||||
dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = frequency_span_class(radiochannels[ch_name]))))
|
||||
|
||||
return dat
|
||||
|
||||
/obj/item/device/radio/proc/list_internal_channels(var/mob/user)
|
||||
var/dat[0]
|
||||
for(var/internal_chan in internal_channels)
|
||||
if(has_channel_access(user, internal_chan))
|
||||
dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = frequency_span_class(text2num(internal_chan)))))
|
||||
|
||||
return dat
|
||||
|
||||
/obj/item/device/radio/proc/has_channel_access(var/mob/user, var/freq)
|
||||
if(!user)
|
||||
return 0
|
||||
|
||||
if(!(freq in internal_channels))
|
||||
return 0
|
||||
|
||||
return user.has_internal_radio_channel_access(internal_channels[freq])
|
||||
|
||||
/mob/proc/has_internal_radio_channel_access(var/list/req_one_accesses)
|
||||
var/obj/item/weapon/card/id/I = GetIdCard()
|
||||
return has_access(list(), req_one_accesses, I ? I.GetAccess() : list())
|
||||
|
||||
/mob/dead/observer/has_internal_radio_channel_access(var/list/req_one_accesses)
|
||||
return can_admin_interact()
|
||||
|
||||
/obj/item/device/radio/proc/text_wires()
|
||||
if (b_stat)
|
||||
@@ -124,10 +178,14 @@
|
||||
/obj/item/device/radio/proc/ToggleReception()
|
||||
listening = !listening && !(wires.IsIndexCut(WIRE_RECEIVE) || wires.IsIndexCut(WIRE_SIGNAL))
|
||||
|
||||
/obj/item/device/radio/CanUseTopic()
|
||||
if(!on)
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/item/device/radio/Topic(href, href_list)
|
||||
if(..() || !on)
|
||||
usr << browse(null, "window=radio")
|
||||
return
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
usr.set_machine(src)
|
||||
if (href_list["track"])
|
||||
@@ -135,20 +193,20 @@
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
if(A && target)
|
||||
A.ai_actual_track(target)
|
||||
return
|
||||
. = 1
|
||||
|
||||
else if (href_list["freq"])
|
||||
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
||||
if (!freerange || (frequency < 1200 || frequency > 1600))
|
||||
new_frequency = sanitize_frequency(new_frequency, maxf)
|
||||
if ((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ))
|
||||
new_frequency = sanitize_frequency(new_frequency)
|
||||
set_frequency(new_frequency)
|
||||
if(hidden_uplink)
|
||||
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
|
||||
usr << browse(null, "window=radio")
|
||||
return
|
||||
|
||||
. = 1
|
||||
else if (href_list["talk"])
|
||||
ToggleBroadcast()
|
||||
. = 1
|
||||
else if (href_list["listen"])
|
||||
var/chan_name = href_list["ch_name"]
|
||||
if (!chan_name)
|
||||
@@ -158,11 +216,17 @@
|
||||
channels[chan_name] &= ~FREQ_LISTENING
|
||||
else
|
||||
channels[chan_name] |= FREQ_LISTENING
|
||||
|
||||
. = 1
|
||||
else if(href_list["spec_freq"])
|
||||
var freq = href_list["spec_freq"]
|
||||
if(has_channel_access(usr, freq))
|
||||
set_frequency(text2num(freq))
|
||||
. = 1
|
||||
if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk
|
||||
return
|
||||
return 1
|
||||
|
||||
interact(usr)
|
||||
if(.)
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
|
||||
var/datum/radio_frequency/connection = null
|
||||
@@ -210,13 +274,13 @@
|
||||
// Fix for permacell radios, but kinda eh about actually fixing them.
|
||||
if(!M || !message) return 0
|
||||
|
||||
if(istype(M)) M.trigger_aiming(TARGET_CAN_RADIO)
|
||||
|
||||
// Uncommenting this. To the above comment:
|
||||
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
|
||||
if(wires.IsIndexCut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
|
||||
return 0
|
||||
|
||||
M.last_target_radio = world.time // For the projectile targeting system
|
||||
|
||||
if(!radio_connection)
|
||||
set_frequency(frequency)
|
||||
|
||||
@@ -467,16 +531,16 @@
|
||||
|
||||
var/range = receive_range(freq, level)
|
||||
if(range > -1)
|
||||
return get_mobs_in_view(canhear_range, src)
|
||||
return get_mobs_or_objects_in_view(canhear_range, src)
|
||||
|
||||
|
||||
/obj/item/device/radio/examine(mob/user)
|
||||
. = ..()
|
||||
if ((in_range(src, user) || loc == user))
|
||||
if (b_stat)
|
||||
user.show_message("\blue \the [src] can be attached and modified!")
|
||||
user.show_message("<span class='notice'>\The [src] can be attached and modified!</span>")
|
||||
else
|
||||
user.show_message("\blue \the [src] can not be modified or attached!")
|
||||
user.show_message("<span class='notice'>\The [src] can not be modified or attached!</span>")
|
||||
return
|
||||
|
||||
/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
@@ -487,9 +551,9 @@
|
||||
b_stat = !( b_stat )
|
||||
if(!istype(src, /obj/item/device/radio/beacon))
|
||||
if (b_stat)
|
||||
user.show_message("\blue The radio can now be attached and modified!")
|
||||
user.show_message("<span class='notice'>\The [src] can now be attached and modified!</span>")
|
||||
else
|
||||
user.show_message("\blue The radio can no longer be modified or attached!")
|
||||
user.show_message("<span class='notice'>\The [src] can no longer be modified or attached!</span>")
|
||||
updateDialog()
|
||||
//Foreach goto(83)
|
||||
add_fingerprint(user)
|
||||
@@ -511,12 +575,19 @@
|
||||
/obj/item/device/radio/borg
|
||||
var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks
|
||||
var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
|
||||
var/shut_up = 0
|
||||
var/shut_up = 1
|
||||
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
|
||||
icon_state = "radio"
|
||||
canhear_range = 3
|
||||
canhear_range = 0
|
||||
subspace_transmission = 1
|
||||
|
||||
/obj/item/device/radio/borg/Destroy()
|
||||
myborg = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/radio/borg/list_channels(var/mob/user)
|
||||
return list_secure_channels(user)
|
||||
|
||||
/obj/item/device/radio/borg/talk_into()
|
||||
. = ..()
|
||||
if (isrobot(src.loc))
|
||||
@@ -598,52 +669,69 @@
|
||||
return
|
||||
|
||||
/obj/item/device/radio/borg/Topic(href, href_list)
|
||||
if(usr.stat || !on)
|
||||
return
|
||||
if(..())
|
||||
return 1
|
||||
if (href_list["mode"])
|
||||
if(subspace_transmission != 1)
|
||||
subspace_transmission = 1
|
||||
usr << "Subspace Transmission is enabled"
|
||||
else
|
||||
subspace_transmission = 0
|
||||
usr << "Subspace Transmission is disabled"
|
||||
if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
|
||||
channels = list()
|
||||
else
|
||||
recalculateChannels()
|
||||
if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
|
||||
shut_up = !shut_up
|
||||
if(shut_up)
|
||||
canhear_range = 0
|
||||
else
|
||||
canhear_range = 3
|
||||
var/enable_subspace_transmission = text2num(href_list["mode"])
|
||||
if(enable_subspace_transmission != subspace_transmission)
|
||||
subspace_transmission = !subspace_transmission
|
||||
if(subspace_transmission)
|
||||
usr << "<span class='notice'>Subspace Transmission is enabled</span>"
|
||||
else
|
||||
usr << "<span class='notice'>Subspace Transmission is disabled</span>"
|
||||
|
||||
..()
|
||||
if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
|
||||
channels = list()
|
||||
else
|
||||
recalculateChannels()
|
||||
. = 1
|
||||
if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
|
||||
var/do_shut_up = text2num(href_list["shutup"])
|
||||
if(do_shut_up != shut_up)
|
||||
shut_up = !shut_up
|
||||
if(shut_up)
|
||||
canhear_range = 0
|
||||
usr << "<span class='notice'>Loadspeaker disabled.</span>"
|
||||
else
|
||||
canhear_range = 3
|
||||
usr << "<span class='notice'>Loadspeaker enabled.</span>"
|
||||
. = 1
|
||||
|
||||
if(.)
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
/obj/item/device/radio/borg/interact(mob/user as mob)
|
||||
if(!on)
|
||||
return
|
||||
|
||||
var/dat = "<html><head><title>[src]</title></head><body><TT>"
|
||||
dat += {"
|
||||
Speaker: [listening ? "<A href='byond://?src=\ref[src];listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];listen=1'>Disengaged</A>"]<BR>
|
||||
Frequency:
|
||||
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
||||
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
||||
[format_frequency(frequency)]
|
||||
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
||||
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
||||
<A href='byond://?src=\ref[src];mode=1'>Toggle Broadcast Mode</A><BR>
|
||||
Loudspeaker: [shut_up ? "<A href='byond://?src=\ref[src];shutup=0'>Disengaged</A>" : "<A href='byond://?src=\ref[src];shutup=1'>Engaged</A>"]<BR>
|
||||
"}
|
||||
. = ..()
|
||||
|
||||
if(subspace_transmission)//Don't even bother if subspace isn't turned on
|
||||
for (var/ch_name in channels)
|
||||
dat+=text_sec_channel(ch_name, channels[ch_name])
|
||||
dat+={"[text_wires()]</TT></body></html>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
/obj/item/device/radio/borg/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
data["mic_status"] = broadcasting
|
||||
data["speaker"] = listening
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["rawfreq"] = num2text(frequency)
|
||||
|
||||
var/list/chanlist = list_channels(user)
|
||||
if(islist(chanlist) && chanlist.len)
|
||||
data["chan_list"] = chanlist
|
||||
data["chan_list_len"] = chanlist.len
|
||||
|
||||
if(syndie)
|
||||
data["useSyndMode"] = 1
|
||||
|
||||
data["has_loudspeaker"] = 1
|
||||
data["loudspeaker"] = !shut_up
|
||||
data["has_subspace"] = 1
|
||||
data["subspace"] = subspace_transmission
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/radio/proc/config(op)
|
||||
if(radio_controller)
|
||||
@@ -658,3 +746,17 @@
|
||||
|
||||
/obj/item/device/radio/off
|
||||
listening = 0
|
||||
|
||||
/obj/item/device/radio/phone
|
||||
broadcasting = 0
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "red_phone"
|
||||
listening = 1
|
||||
name = "phone"
|
||||
|
||||
/obj/item/device/radio/phone/medbay
|
||||
frequency = MED_I_FREQ
|
||||
|
||||
/obj/item/device/radio/phone/medbay/New()
|
||||
..()
|
||||
internal_channels = default_medbay_channels.Copy()
|
||||
|
||||
@@ -7,59 +7,6 @@ GAS ANALYZER
|
||||
MASS SPECTROMETER
|
||||
REAGENT SCANNER
|
||||
*/
|
||||
/obj/item/device/t_scanner
|
||||
name = "\improper T-ray scanner"
|
||||
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
||||
icon_state = "t-ray0"
|
||||
var/on = 0
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = 2
|
||||
item_state = "electronic"
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 150)
|
||||
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
|
||||
/obj/item/device/t_scanner/attack_self(mob/user)
|
||||
|
||||
on = !on
|
||||
icon_state = "t-ray[on]"
|
||||
|
||||
if(on)
|
||||
processing_objects.Add(src)
|
||||
|
||||
|
||||
/obj/item/device/t_scanner/process()
|
||||
if(!on)
|
||||
processing_objects.Remove(src)
|
||||
return null
|
||||
|
||||
for(var/turf/T in range(1, src.loc) )
|
||||
|
||||
if(!T.intact)
|
||||
continue
|
||||
|
||||
for(var/obj/O in T.contents)
|
||||
|
||||
if(O.level != 1)
|
||||
continue
|
||||
|
||||
if(O.invisibility == 101)
|
||||
O.invisibility = 0
|
||||
O.alpha = 128
|
||||
spawn(10)
|
||||
if(O)
|
||||
var/turf/U = O.loc
|
||||
if(U.intact)
|
||||
O.invisibility = 101
|
||||
O.alpha = 255
|
||||
|
||||
var/mob/living/M = locate() in T
|
||||
if(M && M.invisibility == 2)
|
||||
M.invisibility = 0
|
||||
spawn(2)
|
||||
if(M)
|
||||
M.invisibility = INVISIBILITY_LEVEL_TWO
|
||||
|
||||
|
||||
/obj/item/device/healthanalyzer
|
||||
@@ -74,33 +21,34 @@ REAGENT SCANNER
|
||||
throw_speed = 5
|
||||
throw_range = 10
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 200)
|
||||
origin_tech = "magnets=1;biotech=1"
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
|
||||
var/mode = 1;
|
||||
|
||||
|
||||
/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
if (( (CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50))
|
||||
user << text("\red You try to analyze the floor's vitals!")
|
||||
user << text("<span class='warning'>You try to analyze the floor's vitals!</span>")
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message(text("\red [user] has analyzed the floor's vitals!"), 1)
|
||||
user.show_message(text("\blue Analyzing Results for The floor:\n\t Overall Status: Healthy"), 1)
|
||||
user.show_message(text("\blue \t Damage Specifics: [0]-[0]-[0]-[0]"), 1)
|
||||
user.show_message("\blue Key: Suffocation/Toxin/Burns/Brute", 1)
|
||||
user.show_message("\blue Body Temperature: ???", 1)
|
||||
O.show_message("<span class='warning'>\The [user] has analyzed the floor's vitals!</span>", 1)
|
||||
user.show_message("<span class='notice'>Analyzing Results for The floor:</span>", 1)
|
||||
user.show_message("Overall Status: Healthy</span>", 1)
|
||||
user.show_message("<span class='notice'> Damage Specifics: 0-0-0-0</span>", 1)
|
||||
user.show_message("<span class='notice'>Key: Suffocation/Toxin/Burns/Brute</span>", 1)
|
||||
user.show_message("<span class='notice'>Body Temperature: ???</span>", 1)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
user.visible_message("<span class='notice'> [user] has analyzed [M]'s vitals.</span>","<span class='notice'> You have analyzed [M]'s vitals.</span>")
|
||||
user.visible_message("<span class='notice'>[user] has analyzed [M]'s vitals.</span>","<span class='notice'>You have analyzed [M]'s vitals.</span>")
|
||||
|
||||
if (!istype(M, /mob/living/carbon) || (ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
|
||||
if (!istype(M,/mob/living/carbon/human) || M.isSynthetic())
|
||||
//these sensors are designed for organic life
|
||||
user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR")
|
||||
user.show_message("\t Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font>", 1)
|
||||
user.show_message("\t Damage Specifics: <font color='blue'>?</font> - <font color='green'>?</font> - <font color='#FFA500'>?</font> - <font color='red'>?</font>")
|
||||
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
|
||||
user.show_message("\red <b>Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR</b>")
|
||||
user.show_message("\blue Subject's pulse: <font color='red'>-- bpm.</font>")
|
||||
user.show_message("<span class='notice'>Analyzing Results for ERROR:\n\t Overall Status: ERROR</span>")
|
||||
user.show_message("<span class='notice'> Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font></span>", 1)
|
||||
user.show_message("<span class='notice'> Damage Specifics: <font color='blue'>?</font> - <font color='green'>?</font> - <font color='#FFA500'>?</font> - <font color='red'>?</font></span>")
|
||||
user.show_message("<span class='notice'>Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||
user.show_message("<span class='warning'>Warning: Blood Level ERROR: --% --cl.</span> <span class='notice'>Type: ERROR</span>")
|
||||
user.show_message("<span class='notice'>Subject's pulse: <font color='red'>-- bpm.</font></span>")
|
||||
return
|
||||
|
||||
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
|
||||
@@ -110,34 +58,36 @@ REAGENT SCANNER
|
||||
var/BR = M.getBruteLoss() > 50 ? "<b>[M.getBruteLoss()]</b>" : M.getBruteLoss()
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
OX = fake_oxy > 50 ? "<b>[fake_oxy]</b>" : fake_oxy
|
||||
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: dead")
|
||||
user.show_message("<span class='notice'>Analyzing Results for [M]:</span>")
|
||||
user.show_message("<span class='notice'>Overall Status: dead</span>")
|
||||
else
|
||||
user.show_message("\blue Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health - M.halloss]% healthy"]")
|
||||
user.show_message("\t Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font>", 1)
|
||||
user.show_message("\t Damage Specifics: <font color='blue'>[OX]</font> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
|
||||
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
|
||||
user.show_message("<span class='notice'>Analyzing Results for [M]:\n\t Overall Status: [M.stat > 1 ? "dead" : "[M.health - M.halloss]% healthy"]</span>")
|
||||
user.show_message("<span class='notice'> Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font></span>", 1)
|
||||
user.show_message("<span class='notice'> Damage Specifics: <font color='blue'>[OX]</font> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font></span>")
|
||||
user.show_message("<span class='notice'>Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)</span>", 1)
|
||||
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
|
||||
user.show_message("\blue Time of Death: [M.tod]")
|
||||
user.show_message("<span class='notice'>Time of Death: [M.tod]</span>")
|
||||
if(istype(M, /mob/living/carbon/human) && mode == 1)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Burn:",1)
|
||||
user.show_message("<span class='notice'>Localized Damage, Brute/Burn:</span>",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/obj/item/organ/external/org in damaged)
|
||||
user.show_message(text("\blue \t []: [][]\blue - []", \
|
||||
"[capitalize(org.name)][org.status & ORGAN_ROBOT ? "(Cybernetic)" : ""]", \
|
||||
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
|
||||
(org.status & ORGAN_BLEEDING)?"\red <b>\[Bleeding\]</b>":"\t", \
|
||||
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
|
||||
user.show_message(text("<span class='notice'> [][]: [][] - []</span>",
|
||||
capitalize(org.name),
|
||||
(org.status & ORGAN_ROBOT) ? "(Cybernetic)" : "",
|
||||
(org.brute_dam > 0) ? "<span class='warning'>[org.brute_dam]</span>" : 0,
|
||||
(org.status & ORGAN_BLEEDING)?"<span class='danger'>\[Bleeding\]</span>":"",
|
||||
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" : 0),1)
|
||||
else
|
||||
user.show_message("\blue \t Limbs are OK.",1)
|
||||
user.show_message("<span class='notice'> Limbs are OK.</span>",1)
|
||||
|
||||
OX = M.getOxyLoss() > 50 ? "<font color='blue'><b>Severe oxygen deprivation detected</b></font>" : "Subject bloodstream oxygen level normal"
|
||||
TX = M.getToxLoss() > 50 ? "<font color='green'><b>Dangerous amount of toxins detected</b></font>" : "Subject bloodstream toxin level minimal"
|
||||
BU = M.getFireLoss() > 50 ? "<font color='#FFA500'><b>Severe burn damage detected</b></font>" : "Subject burn injury status O.K"
|
||||
BR = M.getBruteLoss() > 50 ? "<font color='red'><b>Severe anatomical damage detected</b></font>" : "Subject brute-force injury status O.K"
|
||||
if(M.status_flags & FAKEDEATH)
|
||||
OX = fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal"
|
||||
OX = fake_oxy > 50 ? "<span class='warning'>Severe oxygen deprivation detected</span>" : "Subject bloodstream oxygen level normal"
|
||||
user.show_message("[OX] | [TX] | [BU] | [BR]")
|
||||
if(istype(M, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = M
|
||||
@@ -147,15 +97,15 @@ REAGENT SCANNER
|
||||
for(var/A in C.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(R.scannable)
|
||||
reagentdata["[R.id]"] = "\t \blue [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]"
|
||||
reagentdata["[R.id]"] = "<span class='notice'> [round(C.reagents.get_reagent_amount(R.id), 1)]u [R.name]</span>"
|
||||
else
|
||||
unknown++
|
||||
if(reagentdata.len)
|
||||
user.show_message("\blue Beneficial reagents detected in subject's blood:")
|
||||
user.show_message("<span class='notice'>Beneficial reagents detected in subject's blood:</span>")
|
||||
for(var/d in reagentdata)
|
||||
user.show_message(reagentdata[d])
|
||||
if(unknown)
|
||||
user.show_message(text("\red Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood."))
|
||||
user.show_message("<span class='warning'>Warning: Unknown substance[(unknown>1)?"s":""] detected in subject's blood.</span>")
|
||||
if(C.ingested && C.ingested.total_volume)
|
||||
var/unknown = 0
|
||||
for(var/datum/reagent/R in C.ingested.reagent_list)
|
||||
@@ -169,23 +119,24 @@ REAGENT SCANNER
|
||||
for (var/ID in C.virus2)
|
||||
if (ID in virusDB)
|
||||
var/datum/data/record/V = virusDB[ID]
|
||||
user.show_message(text("\red Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]"))
|
||||
// user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood."))
|
||||
user.show_message("<span class='warning'>Warning: Pathogen [V.fields["name"]] detected in subject's blood. Known antigen : [V.fields["antigen"]]</span>")
|
||||
// user.show_message(text("<span class='warning'>Warning: Unknown pathogen detected in subject's blood.</span>"))
|
||||
if (M.getCloneLoss())
|
||||
user.show_message("\red Subject appears to have been imperfectly cloned.")
|
||||
user.show_message("<span class='warning'>Subject appears to have been imperfectly cloned.</span>")
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if(!D.hidden[SCANNER])
|
||||
user.show_message(text("\red <b>Warning: [D.form] Detected</b>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]"))
|
||||
user.show_message(text("<span class='danger'>Warning: [D.form] Detected</span><span class='warning'>\nName: [D.name].\nType: [D.spread].\nStage: [D.stage]/[D.max_stages].\nPossible Cure: [D.cure]</span>"))
|
||||
// if (M.reagents && M.reagents.get_reagent_amount("inaprovaline"))
|
||||
// user.show_message("\blue Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.")
|
||||
// user.show_message("<span class='notice'>Bloodstream Analysis located [M.reagents:get_reagent_amount("inaprovaline")] units of rejuvenation chemicals.</span>")
|
||||
// Remove brain worm scans. Bad.
|
||||
// if (M.has_brain_worms())
|
||||
// user.show_message("\red Subject suffering from aberrant brain activity. Recommend further scanning.") //Cortical borer disable
|
||||
// user.show_message("<span class='warning'>Subject suffering from aberrant brain activity. Recommend further scanning.</span>")
|
||||
if (M.getBrainLoss() >= 100 || !M.has_brain())
|
||||
user.show_message("\red Subject is brain dead.")
|
||||
user.show_message("<span class='warning'>Subject is brain dead.</span>")
|
||||
else if (M.getBrainLoss() >= 60)
|
||||
user.show_message("\red Severe brain damage detected. Subject likely to have mental retardation.")
|
||||
user.show_message("<span class='warning'>Severe brain damage detected. Subject likely to have mental retardation.</span>")
|
||||
else if (M.getBrainLoss() >= 10)
|
||||
user.show_message("\red Significant brain damage detected. Subject may have had a concussion.")
|
||||
user.show_message("<span class='warning'>Significant brain damage detected. Subject may have had a concussion.</span>")
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
for(var/name in H.organs_by_name)
|
||||
@@ -195,20 +146,20 @@ REAGENT SCANNER
|
||||
var/limb = e.name
|
||||
if(e.status & ORGAN_BROKEN)
|
||||
if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED)))
|
||||
user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport."
|
||||
user << "<span class='warning'>Unsecured fracture in subject [limb]. Splinting recommended for transport.</span>"
|
||||
if(e.has_infected_wound())
|
||||
user << "\red Infected wound detected in subject [limb]. Disinfection recommended."
|
||||
user << "<span class='warning'>Infected wound detected in subject [limb]. Disinfection recommended.</span>"
|
||||
|
||||
for(var/name in H.organs_by_name)
|
||||
var/obj/item/organ/external/e = H.organs_by_name[name]
|
||||
if(e && e.status & ORGAN_BROKEN)
|
||||
user.show_message(text("\red Bone fractures detected. Advanced scanner required for location."), 1)
|
||||
user.show_message(text("<span class='warning'>Bone fractures detected. Advanced scanner required for location.</span>"), 1)
|
||||
break
|
||||
for(var/obj/item/organ/external/e in H.organs)
|
||||
if(!e)
|
||||
continue
|
||||
for(var/datum/wound/W in e.wounds) if(W.internal)
|
||||
user.show_message(text("\red Internal bleeding detected. Advanced scanner required for location."), 1)
|
||||
user.show_message(text("<span class='warning'>Internal bleeding detected. Advanced scanner required for location.</span>"), 1)
|
||||
break
|
||||
if(M:vessel)
|
||||
var/blood_volume = round(M:vessel.get_reagent_amount("blood"))
|
||||
@@ -216,12 +167,12 @@ REAGENT SCANNER
|
||||
var/blood_type = M.dna.b_type
|
||||
blood_percent *= 100
|
||||
if(blood_volume <= 500 && blood_volume > 336)
|
||||
user.show_message("\red <b>Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl.</b>\blue Type: [blood_type]")
|
||||
user.show_message("<span class='danger'>Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl.</span> <span class='notice'>Type: [blood_type]</span>")
|
||||
else if(blood_volume <= 336)
|
||||
user.show_message("\red <b>Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl.</b>\blue Type: [blood_type]")
|
||||
user.show_message("<span class='danger'><i>Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl.</i></span> <span class='notice'>Type: [blood_type]</span>")
|
||||
else
|
||||
user.show_message("\blue Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]")
|
||||
user.show_message("\blue Subject's pulse: <font color='[H.pulse == PULSE_THREADY || H.pulse == PULSE_NONE ? "red" : "blue"]'>[H.get_pulse(GETPULSE_TOOL)] bpm.</font>")
|
||||
user.show_message("<span class='notice'>Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span>")
|
||||
user.show_message("<span class='notice'>Subject's pulse: <font color='[H.pulse == PULSE_THREADY || H.pulse == PULSE_NONE ? "red" : "blue"]'>[H.get_pulse(GETPULSE_TOOL)] bpm.</font></span>")
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
@@ -251,37 +202,24 @@ REAGENT SCANNER
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 20)
|
||||
|
||||
origin_tech = "magnets=1;engineering=1"
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
|
||||
|
||||
/obj/item/device/analyzer/atmosanalyze(var/mob/user)
|
||||
var/air = user.return_air()
|
||||
if (!air)
|
||||
return
|
||||
|
||||
return atmosanalyzer_scan(src, air, user)
|
||||
|
||||
/obj/item/device/analyzer/attack_self(mob/user as mob)
|
||||
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
|
||||
var/turf/location = user.loc
|
||||
if (!( istype(location, /turf) ))
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles
|
||||
|
||||
user.show_message("\blue <B>Results:</B>", 1)
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
user.show_message("\blue Pressure: [round(pressure,0.1)] kPa", 1)
|
||||
else
|
||||
user.show_message("\red Pressure: [round(pressure,0.1)] kPa", 1)
|
||||
if(total_moles)
|
||||
for(var/g in environment.gas)
|
||||
user.show_message("\blue [gas_data.name[g]]: [round((environment.gas[g] / total_moles)*100)]%", 1)
|
||||
|
||||
user.show_message("\blue Temperature: [round(environment.temperature-T0C)]°C", 1)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
analyze_gases(src, user)
|
||||
return
|
||||
|
||||
/obj/item/device/mass_spectrometer
|
||||
@@ -298,7 +236,7 @@ REAGENT SCANNER
|
||||
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 20)
|
||||
|
||||
origin_tech = "magnets=2;biotech=2"
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
||||
var/details = 0
|
||||
var/recent_fail = 0
|
||||
|
||||
@@ -317,37 +255,25 @@ REAGENT SCANNER
|
||||
/obj/item/device/mass_spectrometer/attack_self(mob/user as mob)
|
||||
if (user.stat)
|
||||
return
|
||||
if (crit_fail)
|
||||
user << "\red This device has critically failed and is no longer functional!"
|
||||
return
|
||||
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
user << "\red You don't have the dexterity to do this!"
|
||||
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
if(reagents.total_volume)
|
||||
var/list/blood_traces = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.id != "blood")
|
||||
reagents.clear_reagents()
|
||||
user << "\red The sample was contaminated! Please insert another sample"
|
||||
user << "<span class='warning'>The sample was contaminated! Please insert another sample</span>"
|
||||
return
|
||||
else
|
||||
blood_traces = params2list(R.data["trace_chem"])
|
||||
break
|
||||
var/dat = "Trace Chemicals Found: "
|
||||
for(var/R in blood_traces)
|
||||
if(prob(reliability))
|
||||
if(details)
|
||||
dat += "[R] ([blood_traces[R]] units) "
|
||||
else
|
||||
dat += "[R] "
|
||||
recent_fail = 0
|
||||
if(details)
|
||||
dat += "[R] ([blood_traces[R]] units) "
|
||||
else
|
||||
if(recent_fail)
|
||||
crit_fail = 1
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
else
|
||||
recent_fail = 1
|
||||
dat += "[R] "
|
||||
user << "[dat]"
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
@@ -356,7 +282,7 @@ REAGENT SCANNER
|
||||
name = "advanced mass spectrometer"
|
||||
icon_state = "adv_spectrometer"
|
||||
details = 1
|
||||
origin_tech = "magnets=4;biotech=2"
|
||||
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
|
||||
|
||||
/obj/item/device/reagent_scanner
|
||||
name = "reagent scanner"
|
||||
@@ -371,7 +297,7 @@ REAGENT SCANNER
|
||||
throw_range = 20
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 30,"glass" = 20)
|
||||
|
||||
origin_tech = "magnets=2;biotech=2"
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_BIO = 2)
|
||||
var/details = 0
|
||||
var/recent_fail = 0
|
||||
|
||||
@@ -381,34 +307,23 @@ REAGENT SCANNER
|
||||
if (user.stat)
|
||||
return
|
||||
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
user << "\red You don't have the dexterity to do this!"
|
||||
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return
|
||||
if(!istype(O))
|
||||
return
|
||||
if (crit_fail)
|
||||
user << "\red This device has critically failed and is no longer functional!"
|
||||
return
|
||||
|
||||
if(!isnull(O.reagents))
|
||||
var/dat = ""
|
||||
if(O.reagents.reagent_list.len > 0)
|
||||
var/one_percent = O.reagents.total_volume / 100
|
||||
for (var/datum/reagent/R in O.reagents.reagent_list)
|
||||
if(prob(reliability))
|
||||
dat += "\n \t \blue [R][details ? ": [R.volume / one_percent]%" : ""]"
|
||||
recent_fail = 0
|
||||
else if(recent_fail)
|
||||
crit_fail = 1
|
||||
dat = null
|
||||
break
|
||||
else
|
||||
recent_fail = 1
|
||||
dat += "\n \t <span class='notice'>[R][details ? ": [R.volume / one_percent]%" : ""]"
|
||||
if(dat)
|
||||
user << "\blue Chemicals found: [dat]"
|
||||
user << "<span class='notice'>Chemicals found: [dat]</span>"
|
||||
else
|
||||
user << "\blue No active chemical agents found in [O]."
|
||||
user << "<span class='notice'>No active chemical agents found in [O].</span>"
|
||||
else
|
||||
user << "\blue No significant chemical agents found in [O]."
|
||||
user << "<span class='notice'>No significant chemical agents found in [O].</span>"
|
||||
|
||||
return
|
||||
|
||||
@@ -416,13 +331,13 @@ REAGENT SCANNER
|
||||
name = "advanced reagent scanner"
|
||||
icon_state = "adv_spectrometer"
|
||||
details = 1
|
||||
origin_tech = "magnets=4;biotech=2"
|
||||
origin_tech = list(TECH_MAGNET = 4, TECH_BIO = 2)
|
||||
|
||||
/obj/item/device/slime_scanner
|
||||
name = "slime scanner"
|
||||
icon_state = "adv_spectrometer"
|
||||
item_state = "analyzer"
|
||||
origin_tech = "biotech=1"
|
||||
origin_tech = list(TECH_BIO = 1)
|
||||
w_class = 2.0
|
||||
flags = CONDUCT
|
||||
throwforce = 0
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
throw_range = 15
|
||||
throw_speed = 3
|
||||
|
||||
origin_tech = "programming=1;engineering=1;syndicate=3"
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
|
||||
|
||||
var/obj/item/device/radio/spy/radio
|
||||
var/obj/machinery/camera/spy/camera
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
w_class = 2.0
|
||||
|
||||
origin_tech = "programming=1;engineering=1;syndicate=3"
|
||||
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
|
||||
|
||||
var/operating = 0
|
||||
var/obj/item/device/radio/spy/radio
|
||||
@@ -135,7 +135,7 @@
|
||||
|
||||
/obj/machinery/camera/spy
|
||||
// These cheap toys are accessible from the mercenary camera console as well
|
||||
network = list("NUKE")
|
||||
network = list(NETWORK_MERCENARY)
|
||||
|
||||
/obj/machinery/camera/spy/New()
|
||||
..()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
throw_speed = 1
|
||||
throw_range = 4
|
||||
|
||||
origin_tech = "magnets=2;materials=2"
|
||||
origin_tech = list(TECH_MAGNET = 2, TECH_MATERIAL = 2)
|
||||
|
||||
var/on = 0 //is it turned on?
|
||||
var/cover_open = 0 //is the cover open?
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#define OVERLAY_CACHE_LEN 50
|
||||
|
||||
/obj/item/device/t_scanner
|
||||
name = "\improper T-ray scanner"
|
||||
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
|
||||
icon_state = "t-ray0"
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = 2
|
||||
item_state = "electronic"
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 150)
|
||||
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
|
||||
|
||||
var/scan_range = 1
|
||||
|
||||
var/on = 0
|
||||
var/list/active_scanned = list() //assoc list of objects being scanned, mapped to their overlay
|
||||
var/client/user_client //since making sure overlays are properly added and removed is pretty important, so we track the current user explicitly
|
||||
var/flicker = 0
|
||||
|
||||
var/global/list/overlay_cache = list() //cache recent overlays
|
||||
|
||||
/obj/item/device/t_scanner/update_icon()
|
||||
icon_state = "t-ray[on]"
|
||||
|
||||
/obj/item/device/t_scanner/attack_self(mob/user)
|
||||
set_active(!on)
|
||||
|
||||
/obj/item/device/t_scanner/proc/set_active(var/active)
|
||||
on = active
|
||||
if(on)
|
||||
processing_objects.Add(src)
|
||||
flicker = 0
|
||||
else
|
||||
processing_objects.Remove(src)
|
||||
set_user_client(null)
|
||||
update_icon()
|
||||
|
||||
//If reset is set, then assume the client has none of our overlays, otherwise we only send new overlays.
|
||||
/obj/item/device/t_scanner/process()
|
||||
if(!on) return
|
||||
|
||||
//handle clients changing
|
||||
var/client/loc_client = null
|
||||
if(ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
loc_client = M.client
|
||||
set_user_client(loc_client)
|
||||
|
||||
//no sense processing if no-one is going to see it.
|
||||
if(!user_client) return
|
||||
|
||||
//get all objects in scan range
|
||||
var/list/scanned = get_scanned_objects(scan_range)
|
||||
var/list/update_add = scanned - active_scanned
|
||||
var/list/update_remove = active_scanned - scanned
|
||||
|
||||
//Add new overlays
|
||||
for(var/obj/O in update_add)
|
||||
var/image/overlay = get_overlay(O)
|
||||
active_scanned[O] = overlay
|
||||
user_client.images += overlay
|
||||
|
||||
//Remove stale overlays
|
||||
for(var/obj/O in update_remove)
|
||||
user_client.images -= active_scanned[O]
|
||||
active_scanned -= O
|
||||
|
||||
//Flicker effect
|
||||
for(var/obj/O in active_scanned)
|
||||
var/image/overlay = active_scanned[O]
|
||||
if(flicker)
|
||||
overlay.alpha = 0
|
||||
else
|
||||
overlay.alpha = 128
|
||||
flicker = !flicker
|
||||
|
||||
//creates a new overlay for a scanned object
|
||||
/obj/item/device/t_scanner/proc/get_overlay(obj/scanned)
|
||||
//Use a cache so we don't create a whole bunch of new images just because someone's walking back and forth in a room.
|
||||
//Also means that images are reused if multiple people are using t-rays to look at the same objects.
|
||||
if(scanned in overlay_cache)
|
||||
. = overlay_cache[scanned]
|
||||
else
|
||||
var/image/I = image(loc = scanned, icon = scanned.icon, icon_state = scanned.icon_state, layer = HUD_LAYER)
|
||||
|
||||
//Pipes are special
|
||||
if(istype(scanned, /obj/machinery/atmospherics/pipe))
|
||||
var/obj/machinery/atmospherics/pipe/P = scanned
|
||||
I.color = P.pipe_color
|
||||
I.overlays += P.overlays
|
||||
|
||||
I.alpha = 128
|
||||
I.mouse_opacity = 0
|
||||
. = I
|
||||
|
||||
// Add it to cache, cutting old entries if the list is too long
|
||||
overlay_cache[scanned] = .
|
||||
if(overlay_cache.len > OVERLAY_CACHE_LEN)
|
||||
overlay_cache.Cut(1, overlay_cache.len-OVERLAY_CACHE_LEN-1)
|
||||
|
||||
/obj/item/device/t_scanner/proc/get_scanned_objects(var/scan_dist)
|
||||
. = list()
|
||||
|
||||
var/turf/center = get_turf(src.loc)
|
||||
if(!center) return
|
||||
|
||||
for(var/turf/T in range(scan_range, center))
|
||||
if(!!T.is_plating())
|
||||
continue
|
||||
|
||||
for(var/obj/O in T.contents)
|
||||
if(O.level != 1)
|
||||
continue
|
||||
if(!O.invisibility)
|
||||
continue //if it's already visible don't need an overlay for it
|
||||
. += O
|
||||
|
||||
/obj/item/device/t_scanner/proc/set_user_client(var/client/new_client)
|
||||
if(new_client == user_client)
|
||||
return
|
||||
if(user_client)
|
||||
for(var/scanned in active_scanned)
|
||||
user_client.images -= active_scanned[scanned]
|
||||
if(new_client)
|
||||
for(var/scanned in active_scanned)
|
||||
new_client.images += active_scanned[scanned]
|
||||
else
|
||||
active_scanned.Cut()
|
||||
|
||||
user_client = new_client
|
||||
|
||||
/obj/item/device/t_scanner/dropped(mob/user)
|
||||
set_user_client(null)
|
||||
|
||||
#undef OVERLAY_CACHE_LEN
|
||||
@@ -29,16 +29,34 @@
|
||||
else
|
||||
storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [M.name] [verb], \"[msg]\""
|
||||
|
||||
/obj/item/device/taperecorder/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/card/emag))
|
||||
if(emagged == 0)
|
||||
emagged = 1
|
||||
recording = 0
|
||||
user << "<span class='warning'>PZZTTPFFFT</span>"
|
||||
icon_state = "taperecorderidle"
|
||||
else
|
||||
user << "<span class='warning'>It is already emagged!</span>"
|
||||
/obj/item/device/taperecorder/see_emote(mob/M as mob, text, var/emote_type)
|
||||
if(emote_type != 2) //only hearable emotes
|
||||
return
|
||||
if(recording)
|
||||
timestamp += timerecorded
|
||||
storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] [strip_html_properly(text)]"
|
||||
|
||||
/obj/item/device/taperecorder/show_message(msg, type, alt, alt_type)
|
||||
var/recordedtext
|
||||
if (msg && type == 2) //must be hearable
|
||||
recordedtext = msg
|
||||
else if (alt && alt_type == 2)
|
||||
recordedtext = alt
|
||||
else
|
||||
return
|
||||
if(recording)
|
||||
timestamp += timerecorded
|
||||
storedinfo += "*\[[time2text(timerecorded*10,"mm:ss")]\] *[strip_html_properly(recordedtext)]*" //"*" at front as a marker
|
||||
|
||||
/obj/item/device/taperecorder/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(emagged == 0)
|
||||
emagged = 1
|
||||
recording = 0
|
||||
user << "<span class='warning'>PZZTTPFFFT</span>"
|
||||
icon_state = "taperecorderidle"
|
||||
return 1
|
||||
else
|
||||
user << "<span class='warning'>It is already emagged!</span>"
|
||||
|
||||
/obj/item/device/taperecorder/proc/explode()
|
||||
var/turf/T = get_turf(loc)
|
||||
@@ -58,7 +76,7 @@
|
||||
if(usr.stat)
|
||||
return
|
||||
if(emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
usr << "<span class='warning'>The tape recorder makes a scratchy noise.</span>"
|
||||
return
|
||||
icon_state = "taperecorderrecording"
|
||||
if(timerecorded < 3600 && playing == 0)
|
||||
@@ -85,7 +103,7 @@
|
||||
if(usr.stat)
|
||||
return
|
||||
if(emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
usr << "<span class='warning'>The tape recorder makes a scratchy noise.</span>"
|
||||
return
|
||||
if(recording == 1)
|
||||
recording = 0
|
||||
@@ -97,7 +115,7 @@
|
||||
else if(playing == 1)
|
||||
playing = 0
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Playback stopped.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Playback stopped.</font>")
|
||||
icon_state = "taperecorderidle"
|
||||
return
|
||||
|
||||
@@ -129,7 +147,7 @@
|
||||
if(usr.stat)
|
||||
return
|
||||
if(emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
usr << "<span class='warning'>The tape recorder makes a scratchy noise.</span>"
|
||||
return
|
||||
if(recording == 1)
|
||||
usr << "<span class='notice'>You can't playback when recording!</span>"
|
||||
@@ -146,37 +164,40 @@
|
||||
if(storedinfo.len < i)
|
||||
break
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: [storedinfo[i]]</font>")
|
||||
var/playedmessage = storedinfo[i]
|
||||
if (findtextEx(playedmessage,"*",1,2)) //remove marker for action sounds
|
||||
playedmessage = copytext(playedmessage,2)
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: [playedmessage]</font>")
|
||||
if(storedinfo.len < i+1)
|
||||
playsleepseconds = 1
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: End of recording.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: End of recording.</font>")
|
||||
else
|
||||
playsleepseconds = timestamp[i+1] - timestamp[i]
|
||||
if(playsleepseconds > 14)
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Skipping [playsleepseconds] seconds of silence</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Skipping [playsleepseconds] seconds of silence</font>")
|
||||
playsleepseconds = 1
|
||||
i++
|
||||
icon_state = "taperecorderidle"
|
||||
playing = 0
|
||||
if(emagged == 1.0)
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: This tape recorder will self-destruct in... Five.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: This tape recorder will self-destruct in... Five.</font>")
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Four.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Four.</font>")
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Three.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Three.</font>")
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: Two.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: Two.</font>")
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
T.visible_message("<font color=Maroon><B>Tape Recorder</B>: One.</font>")
|
||||
T.audible_message("<font color=Maroon><B>Tape Recorder</B>: One.</font>")
|
||||
sleep(10)
|
||||
explode()
|
||||
|
||||
@@ -188,7 +209,7 @@
|
||||
if(usr.stat)
|
||||
return
|
||||
if(emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
usr << "<span class='warning'>The tape recorder makes a scratchy noise.</span>"
|
||||
return
|
||||
if(!canprint)
|
||||
usr << "<span class='notice'>The recorder can't print that fast!</span>"
|
||||
@@ -200,7 +221,10 @@
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
|
||||
var/t1 = "<B>Transcript:</B><BR><BR>"
|
||||
for(var/i=1,storedinfo.len >= i,i++)
|
||||
t1 += "[storedinfo[i]]<BR>"
|
||||
var/printedmessage = storedinfo[i]
|
||||
if (findtextEx(printedmessage,"*",1,2)) //replace action sounds
|
||||
printedmessage = "\[[time2text(timestamp[i]*10,"mm:ss")]\] (Unrecognized sound)"
|
||||
t1 += "[printedmessage]<BR>"
|
||||
P.info = t1
|
||||
P.name = "Transcript"
|
||||
canprint = 0
|
||||
@@ -213,11 +237,11 @@
|
||||
if(usr.stat)
|
||||
return
|
||||
if(emagged == 1)
|
||||
usr << "\red The tape recorder makes a scratchy noise."
|
||||
usr << "<span class='warning'>The tape recorder makes a scratchy noise.</span>"
|
||||
return
|
||||
icon_state = "taperecorderrecording"
|
||||
if(timerecorded < 3600 && playing == 0)
|
||||
usr << "\blue Recording started."
|
||||
usr << "<span class='notice'>Recording started.</span>"
|
||||
recording = 1
|
||||
timestamp+= timerecorded
|
||||
storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] Recording started."
|
||||
@@ -230,7 +254,7 @@
|
||||
icon_state = "taperecorderidle"
|
||||
return
|
||||
else
|
||||
usr << "\red Either your tape recorder's memory is full, or it is currently playing back its memory."
|
||||
usr << "<span class='warning'>Either your tape recorder's memory is full, or it is currently playing back its memory.</span>"
|
||||
else
|
||||
if(usr.stat)
|
||||
usr << "Not when you're incapacitated."
|
||||
@@ -239,7 +263,7 @@
|
||||
recording = 0
|
||||
timestamp+= timerecorded
|
||||
storedinfo += "\[[time2text(timerecorded*10,"mm:ss")]\] Recording stopped."
|
||||
usr << "\blue Recording stopped."
|
||||
usr << "<span class='notice'>Recording stopped.</span>"
|
||||
icon_state = "taperecorderidle"
|
||||
return
|
||||
else if(playing == 1)
|
||||
@@ -250,5 +274,5 @@
|
||||
icon_state = "taperecorderidle"
|
||||
return
|
||||
else
|
||||
usr << "\red Stop what?"
|
||||
usr << "<span class='warning'>Stop what?</span>"
|
||||
return
|
||||
|
||||
@@ -24,7 +24,7 @@ effective or pretty fucking useless.
|
||||
throw_range = 10
|
||||
flags = CONDUCT
|
||||
item_state = "electronic"
|
||||
origin_tech = "magnets=3;combat=3;syndicate=3"
|
||||
origin_tech = list(TECH_MAGNET = 3, TECH_COMBAT = 3, TECH_ILLEGAL = 3)
|
||||
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/max_uses = 2
|
||||
@@ -32,7 +32,7 @@ effective or pretty fucking useless.
|
||||
/obj/item/device/batterer/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
|
||||
if(!user) return
|
||||
if(times_used >= max_uses)
|
||||
user << "\red The mind batterer has been burnt out!"
|
||||
user << "<span class='warning'>The mind batterer has been burnt out!</span>"
|
||||
return
|
||||
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [src] to knock down people in the area.</font>")
|
||||
@@ -44,13 +44,13 @@ effective or pretty fucking useless.
|
||||
M.Weaken(rand(10,20))
|
||||
if(prob(25))
|
||||
M.Stun(rand(5,10))
|
||||
M << "\red <b>You feel a tremendous, paralyzing wave flood your mind.</b>"
|
||||
M << "<span class='danger'>You feel a tremendous, paralyzing wave flood your mind.</span>"
|
||||
|
||||
else
|
||||
M << "\red <b>You feel a sudden, electric jolt travel through your head.</b>"
|
||||
M << "<span class='danger'>You feel a sudden, electric jolt travel through your head.</span>"
|
||||
|
||||
playsound(src.loc, 'sound/misc/interference.ogg', 50, 1)
|
||||
user << "\blue You trigger [src]."
|
||||
user << "<span class='notice'>You trigger [src].</span>"
|
||||
times_used += 1
|
||||
if(times_used >= max_uses)
|
||||
icon_state = "battererburnt"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
var/mob/attacher = null
|
||||
var/valve_open = 0
|
||||
var/toggle = 1
|
||||
flags = PROXMOVE
|
||||
|
||||
/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D)
|
||||
|
||||
@@ -69,7 +70,7 @@
|
||||
|
||||
/obj/item/device/transfer_valve/attack_self(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
|
||||
/obj/item/device/transfer_valve/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
|
||||
// this is the data which will be sent to the ui
|
||||
@@ -80,7 +81,7 @@
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
|
||||
+68
-188
@@ -6,48 +6,14 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
|
||||
*/
|
||||
|
||||
/datum/uplink_item/
|
||||
var/name = ""
|
||||
var/cost = 0
|
||||
var/path = null
|
||||
var/reference = ""
|
||||
var/description = ""
|
||||
|
||||
datum/uplink_item/New(var/itemPath, var/itemCost, var/itemName, var/itemReference, var/itemDescription)
|
||||
cost = itemCost
|
||||
path = itemPath
|
||||
name = itemName
|
||||
reference = itemReference
|
||||
description = itemDescription
|
||||
|
||||
datum/uplink_item/proc/description()
|
||||
if(!description)
|
||||
// Fallback description
|
||||
var/obj/temp = src.path
|
||||
description = replacetext(initial(temp.desc), "\n", "<br>")
|
||||
return description
|
||||
|
||||
/datum/uplink_item/proc/generate_item(var/newloc)
|
||||
var/list/L = list()
|
||||
if(ispath(path))
|
||||
L += new path(newloc)
|
||||
else if(islist(path))
|
||||
for(var/item_path in path)
|
||||
L += new item_path(newloc)
|
||||
return L
|
||||
|
||||
datum/nano_item_lists
|
||||
var/list/items_nano
|
||||
var/list/items_reference
|
||||
|
||||
/obj/item/device/uplink
|
||||
var/welcome // Welcoming menu message
|
||||
var/uses // Numbers of crystals
|
||||
var/list/ItemsCategory // List of categories with lists of items
|
||||
var/list/ItemsReference // List of references with an associated item
|
||||
var/list/nanoui_items // List of items for NanoUI use
|
||||
var/nanoui_menu = 0 // The current menu we are in
|
||||
var/list/nanoui_data = new // Additional data for NanoUI use
|
||||
var/welcome = "Welcome, Operative" // Welcoming menu message
|
||||
var/uses // Numbers of crystals
|
||||
var/list/ItemsCategory // List of categories with lists of items
|
||||
var/list/ItemsReference // List of references with an associated item
|
||||
var/list/nanoui_items // List of items for NanoUI use
|
||||
var/nanoui_menu = 0 // The current menu we are in
|
||||
var/list/nanoui_data = new // Additional data for NanoUI use
|
||||
|
||||
var/list/purchase_log = new
|
||||
var/datum/mind/uplink_owner = null
|
||||
@@ -56,109 +22,16 @@ datum/nano_item_lists
|
||||
/obj/item/device/uplink/nano_host()
|
||||
return loc
|
||||
|
||||
/obj/item/device/uplink/New()
|
||||
/obj/item/device/uplink/New(var/location, var/datum/mind/owner, var/telecrystals = DEFAULT_TELECRYSTAL_AMOUNT)
|
||||
..()
|
||||
welcome = ticker.mode.uplink_welcome
|
||||
uses = ticker.mode.uplink_uses
|
||||
ItemsCategory = ticker.mode.uplink_items
|
||||
|
||||
src.uplink_owner = owner
|
||||
purchase_log = list()
|
||||
world_uplinks += src
|
||||
uses = telecrystals
|
||||
|
||||
/obj/item/device/uplink/Destroy()
|
||||
world_uplinks -= src
|
||||
..()
|
||||
|
||||
/obj/item/device/uplink/proc/generate_items()
|
||||
var/datum/nano_item_lists/IL = generate_item_lists()
|
||||
nanoui_items = IL.items_nano
|
||||
ItemsReference = IL.items_reference
|
||||
|
||||
// BS12 no longer use this menu but there are forks that do, hency why we keep it
|
||||
/obj/item/device/uplink/proc/generate_menu()
|
||||
var/dat = "<B>[src.welcome]</B><BR>"
|
||||
dat += "Tele-Crystals left: [src.uses]<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<B>Request item:</B><BR>"
|
||||
dat += "<I>Each item costs a number of tele-crystals as indicated by the number following their name.</I><br>"
|
||||
|
||||
var/category_items = 1
|
||||
for(var/category in ItemsCategory)
|
||||
if(category_items < 1)
|
||||
dat += "<i>We apologize, as you could not afford anything from this category.</i><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>[category]</b><br>"
|
||||
category_items = 0
|
||||
|
||||
for(var/datum/uplink_item/I in ItemsCategory[category])
|
||||
if(I.cost > uses)
|
||||
continue
|
||||
dat += "<A href='byond://?src=\ref[src];buy_item=[I.reference];cost=[I.cost]'>[I.name]</A> ([I.cost])<BR>"
|
||||
category_items++
|
||||
|
||||
dat += "<A href='byond://?src=\ref[src];buy_item=random'>Random Item (??)</A><br>"
|
||||
dat += "<HR>"
|
||||
return dat
|
||||
|
||||
/*
|
||||
Built the item lists for use with NanoUI
|
||||
*/
|
||||
/obj/item/device/uplink/proc/generate_item_lists()
|
||||
var/list/nano = new
|
||||
var/list/reference = new
|
||||
|
||||
for(var/category in ItemsCategory)
|
||||
nano[++nano.len] = list("Category" = category, "items" = list())
|
||||
for(var/datum/uplink_item/I in ItemsCategory[category])
|
||||
nano[nano.len]["items"] += list(list("Name" = I.name, "Description" = I.description(),"Cost" = I.cost, "obj_path" = I.reference))
|
||||
reference[I.reference] = I
|
||||
|
||||
var/datum/nano_item_lists/result = new
|
||||
result.items_nano = nano
|
||||
result.items_reference = reference
|
||||
return result
|
||||
|
||||
//If 'random' was selected
|
||||
/obj/item/device/uplink/proc/chooseRandomItem()
|
||||
if(uses <= 0)
|
||||
return
|
||||
|
||||
var/list/random_items = new
|
||||
for(var/IR in ItemsReference)
|
||||
var/datum/uplink_item/UI = ItemsReference[IR]
|
||||
if(UI.cost <= uses)
|
||||
random_items += UI
|
||||
return pick(random_items)
|
||||
|
||||
/obj/item/device/uplink/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["buy_item"] == "random")
|
||||
var/datum/uplink_item/UI = chooseRandomItem()
|
||||
href_list["buy_item"] = UI.reference
|
||||
return buy(UI, "RN")
|
||||
else
|
||||
var/datum/uplink_item/UI = ItemsReference[href_list["buy_item"]]
|
||||
return buy(UI, UI ? UI.reference : "")
|
||||
return 0
|
||||
|
||||
/obj/item/device/uplink/proc/buy(var/datum/uplink_item/UI, var/reference)
|
||||
if(UI && UI.cost <= uses)
|
||||
uses -= UI.cost
|
||||
used_TC += UI.cost
|
||||
feedback_add_details("traitor_uplink_items_bought", reference)
|
||||
log_and_message_admins("used \the [src.loc] uplink to buy \a [UI].")
|
||||
|
||||
var/list/L = UI.generate_item(get_turf(usr))
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/A = usr
|
||||
for(var/obj/I in L)
|
||||
A.put_in_any_hand_if_possible(I)
|
||||
|
||||
purchase_log[UI] = purchase_log[UI] + 1
|
||||
|
||||
return 1
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
// HIDDEN UPLINK - Can be stored in anything but the host item has to have a trigger for it.
|
||||
/* How to create an uplink in 3 easy steps!
|
||||
@@ -176,6 +49,9 @@ datum/nano_item_lists
|
||||
name = "hidden uplink"
|
||||
desc = "There is something wrong if you're examining this."
|
||||
var/active = 0
|
||||
var/datum/uplink_category/category = 0 // The current category we are in
|
||||
var/exploit_id // Id of the current exploit record we are viewing
|
||||
|
||||
|
||||
// The hidden uplink MUST be inside an obj/item's contents.
|
||||
/obj/item/device/uplink/hidden/New()
|
||||
@@ -183,6 +59,8 @@ datum/nano_item_lists
|
||||
if(!istype(src.loc, /obj/item))
|
||||
qdel(src)
|
||||
..()
|
||||
nanoui_data = list()
|
||||
update_nano_data()
|
||||
|
||||
// Toggles the uplink on and off. Normally this will bypass the item's normal functions and go to the uplink menu, if activated.
|
||||
/obj/item/device/uplink/hidden/proc/toggle()
|
||||
@@ -213,23 +91,13 @@ datum/nano_item_lists
|
||||
data["welcome"] = welcome
|
||||
data["crystals"] = uses
|
||||
data["menu"] = nanoui_menu
|
||||
//Small hack for the contract_uplink device, to make sure the data is initialized properly.
|
||||
if(nanoui_menu == 2)
|
||||
update_nano_data()
|
||||
if(!nanoui_items)
|
||||
generate_items()
|
||||
data["nano_items"] = nanoui_items
|
||||
data += nanoui_data
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
if (!ui) // No auto-refresh
|
||||
ui = new(user, src, ui_key, "uplink.tmpl", title, 450, 600, state = inventory_state)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
|
||||
|
||||
@@ -239,53 +107,65 @@ datum/nano_item_lists
|
||||
|
||||
// The purchasing code.
|
||||
/obj/item/device/uplink/hidden/Topic(href, href_list)
|
||||
if (usr.stat || usr.restrained())
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if (!( istype(usr, /mob/living/carbon/human)))
|
||||
return 1
|
||||
var/mob/user = usr
|
||||
var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
|
||||
if ((usr.contents.Find(src.loc) || (in_range(src.loc, usr) && istype(src.loc.loc, /turf))))
|
||||
usr.set_machine(src)
|
||||
if(..(href, href_list))
|
||||
return 1
|
||||
else if(href_list["lock"])
|
||||
toggle()
|
||||
ui.close()
|
||||
return 1
|
||||
if(href_list["return"])
|
||||
nanoui_menu = round(nanoui_menu/10)
|
||||
update_nano_data()
|
||||
if(href_list["menu"])
|
||||
nanoui_menu = text2num(href_list["menu"])
|
||||
update_nano_data(href_list["id"])
|
||||
if(href_list["contract_interact"])
|
||||
var/list/params = list("location" = "contract_details", "contract" = href_list["contract_interact"])
|
||||
usr.client.process_webint_link("interface/login/sso_server", list2params(params))
|
||||
if(href_list["contract_page"])
|
||||
nanoui_data["contracts_current_page"] = text2num(href_list["contract_page"])
|
||||
update_nano_data()
|
||||
if(href_list["contract_view"])
|
||||
nanoui_data["contracts_view"] = text2num(href_list["contract_view"])
|
||||
nanoui_data["contracts_current_page"] = 1
|
||||
update_nano_data()
|
||||
if(href_list["buy_item"])
|
||||
var/datum/uplink_item/UI = (locate(href_list["buy_item"]) in uplink.items)
|
||||
UI.buy(src, usr)
|
||||
else if(href_list["lock"])
|
||||
toggle()
|
||||
var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, "main")
|
||||
ui.close()
|
||||
else if(href_list["return"])
|
||||
nanoui_menu = round(nanoui_menu/10)
|
||||
else if(href_list["menu"])
|
||||
nanoui_menu = text2num(href_list["menu"])
|
||||
if(href_list["id"])
|
||||
exploit_id = href_list["id"]
|
||||
if(href_list["category"])
|
||||
category = locate(href_list["category"]) in uplink.categories
|
||||
// #TODO-MERGE: Check NanoUI on PDAs
|
||||
if(href_list["contract_interact"])
|
||||
var/list/params = list("location" = "contract_details", "contract" = href_list["contract_interact"])
|
||||
usr.client.process_webint_link("interface/login/sso_server", list2params(params))
|
||||
if(href_list["contract_page"])
|
||||
nanoui_data["contracts_current_page"] = text2num(href_list["contract_page"])
|
||||
update_nano_data()
|
||||
if(href_list["contract_view"])
|
||||
nanoui_data["contracts_view"] = text2num(href_list["contract_view"])
|
||||
nanoui_data["contracts_current_page"] = 1
|
||||
update_nano_data()
|
||||
|
||||
interact(usr)
|
||||
update_nano_data()
|
||||
return 1
|
||||
|
||||
/obj/item/device/uplink/hidden/proc/update_nano_data(var/id)
|
||||
if(nanoui_menu == 1)
|
||||
/obj/item/device/uplink/hidden/proc/update_nano_data()
|
||||
if(nanoui_menu == 0)
|
||||
var/categories[0]
|
||||
for(var/datum/uplink_category/category in uplink.categories)
|
||||
if(category.can_view(src))
|
||||
categories[++categories.len] = list("name" = category.name, "ref" = "\ref[category]")
|
||||
nanoui_data["categories"] = categories
|
||||
else if(nanoui_menu == 1)
|
||||
var/items[0]
|
||||
for(var/datum/uplink_item/item in category.items)
|
||||
if(item.can_view(src))
|
||||
var/cost = item.cost(uses)
|
||||
if(!cost) cost = "???"
|
||||
items[++items.len] = list("name" = item.name, "description" = replacetext(item.description(), "\n", "<br>"), "can_buy" = item.can_buy(src), "cost" = cost, "ref" = "\ref[item]")
|
||||
nanoui_data["items"] = items
|
||||
else if(nanoui_menu == 2)
|
||||
var/permanentData[0]
|
||||
for(var/datum/data/record/L in sortRecord(data_core.locked))
|
||||
permanentData[++permanentData.len] = list(Name = L.fields["name"],"id" = L.fields["id"])
|
||||
nanoui_data["exploit_records"] = permanentData
|
||||
|
||||
if(nanoui_menu == 11)
|
||||
else if(nanoui_menu == 21)
|
||||
nanoui_data["exploit_exists"] = 0
|
||||
|
||||
for(var/datum/data/record/L in data_core.locked)
|
||||
if(L.fields["id"] == id)
|
||||
if(L.fields["id"] == exploit_id)
|
||||
nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
|
||||
// We trade off being able to automatically add shit for more control over what gets passed to json
|
||||
// and if it's sanitized for html.
|
||||
@@ -305,7 +185,7 @@ datum/nano_item_lists
|
||||
nanoui_data["exploit_exists"] = 1
|
||||
break
|
||||
|
||||
if(nanoui_menu == 2)
|
||||
else if(nanoui_menu == 3)
|
||||
nanoui_data["contracts_found"] = 0
|
||||
|
||||
establish_db_connection(dbcon)
|
||||
@@ -372,7 +252,7 @@ datum/nano_item_lists
|
||||
|
||||
nanoui_data["contracts_found"] = 1
|
||||
|
||||
if(nanoui_menu == 21)
|
||||
if(nanoui_menu == 31)
|
||||
nanoui_data["contracts_found"] = 0
|
||||
|
||||
establish_db_connection(dbcon)
|
||||
@@ -446,7 +326,7 @@ datum/nano_item_lists
|
||||
/obj/item/device/radio/headset/uplink/New()
|
||||
..()
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 10
|
||||
hidden_uplink.uses = DEFAULT_TELECRYSTAL_AMOUNT
|
||||
|
||||
/*
|
||||
* A simple device for accessing the SQL based contract database
|
||||
@@ -464,7 +344,7 @@ datum/nano_item_lists
|
||||
..()
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 0
|
||||
hidden_uplink.nanoui_menu = 2
|
||||
hidden_uplink.nanoui_menu = 3
|
||||
|
||||
/obj/item/device/contract_uplink/attack_self(mob/user as mob)
|
||||
if (hidden_uplink)
|
||||
@@ -0,0 +1,101 @@
|
||||
var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_random_selection/default()
|
||||
|
||||
/datum/uplink_random_item
|
||||
var/uplink_item // The uplink item
|
||||
var/keep_probability // The probability we'll decide to keep this item if selected
|
||||
var/reselect_probability // Probability that we'll decide to keep this item if previously selected.
|
||||
// Is done together with the keep_probability check. Being selected more than once does not affect this probability.
|
||||
|
||||
/datum/uplink_random_item/New(var/uplink_item, var/keep_probability = 100, var/reselect_propbability = 33)
|
||||
..()
|
||||
src.uplink_item = uplink_item
|
||||
src.keep_probability = keep_probability
|
||||
src.reselect_probability = reselect_probability
|
||||
|
||||
/datum/uplink_random_selection
|
||||
var/list/datum/uplink_random_item/items
|
||||
|
||||
/datum/uplink_random_selection/New()
|
||||
..()
|
||||
items = list()
|
||||
|
||||
/datum/uplink_random_selection/proc/get_random_item(var/telecrystals, obj/item/device/uplink/U, var/list/bought_items)
|
||||
var/const/attempts = 50
|
||||
|
||||
for(var/i = 0; i < attempts; i++)
|
||||
var/datum/uplink_random_item/RI = pick(items)
|
||||
if(!prob(RI.keep_probability))
|
||||
continue
|
||||
var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
|
||||
if(I.cost(telecrystals) > telecrystals)
|
||||
continue
|
||||
if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
|
||||
continue
|
||||
if(U && !I.can_buy(U))
|
||||
continue
|
||||
return I
|
||||
|
||||
/datum/uplink_random_selection/default/New()
|
||||
..()
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/g9mm)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/mc9mm)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/revolver)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/a357)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/heavysniper, 15, 0)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/sniperammo, 15, 0)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/grenades/emp, 50)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/crossbow, 33)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/energy_sword, 75)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/soap, 5, 100)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/concealed_cane, 50, 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/detomatix, 20, 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/parapen)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/cigarette_kit)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/id)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/spy)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/toolbox, reselect_propbability = 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/plastique)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_radio)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_binary)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/emag, 100, 50)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/clerical)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/space_suit, 50, 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/thermal)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/heavy_vest)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/powersink, 10, 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/teleporter, 10, 0)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_freedom)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_compress)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_explosive)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/sinpockets, reselect_propbability = 20)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/surgery, reselect_propbability = 10)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/combat, reselect_propbability = 10)
|
||||
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/thermal, reselect_propbability = 15)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/energy_net, reselect_propbability = 15)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/ewar_voice, reselect_propbability = 15)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/maneuvering_jets, reselect_propbability = 15)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/egun, reselect_propbability = 15)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/power_sink, reselect_propbability = 15)
|
||||
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/laser_canon, reselect_propbability = 5)
|
||||
|
||||
#ifdef DEBUG
|
||||
/proc/debug_uplink_purchage_log()
|
||||
for(var/antag_type in all_antag_types)
|
||||
var/datum/antagonist/A = all_antag_types[antag_type]
|
||||
A.print_player_summary()
|
||||
|
||||
/proc/debug_uplink_item_assoc_list()
|
||||
for(var/key in uplink.items_assoc)
|
||||
world << "[key] - [uplink.items_assoc[key]]"
|
||||
#endif
|
||||
@@ -271,7 +271,7 @@
|
||||
Notes are played by the names of the note, and optionally, the accidental, and/or the octave number.<br>
|
||||
By default, every note is natural and in octave 3. Defining otherwise is remembered for each note.<br>
|
||||
Example: <i>C,D,E,F,G,A,B</i> will play a C major scale.<br>
|
||||
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is C3,C4,C4,C3</i><br>
|
||||
After a note has an accidental placed, it will be remembered: <i>C,C4,C,C3</i> is <i>C3,C4,C4,C3</i><br>
|
||||
Chords can be played simply by seperating each note with a hyphon: <i>A-C#,Cn-E,E-G#,Gn-B</i><br>
|
||||
A pause may be denoted by an empty chord: <i>C,E,,C,G</i><br>
|
||||
To make a chord be a different time, end it with /x, where the chord length will be length<br>
|
||||
|
||||
@@ -47,12 +47,10 @@ obj/item/device/hailer/attack_self(mob/living/carbon/user as mob)
|
||||
spawn(20)
|
||||
spamcheck = 0
|
||||
|
||||
/obj/item/device/hailer/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/card/emag))
|
||||
if(isnull(insults))
|
||||
user << "<span class='danger'>You overload \the [src]'s voice synthesizer.</span>"
|
||||
insults = rand(1, 3)//to prevent dickflooding
|
||||
else
|
||||
user << "The hailer is fried. You can't even fit the sequencer into the input slot."
|
||||
/obj/item/device/hailer/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(isnull(insults))
|
||||
user << "<span class='danger'>You overload \the [src]'s voice synthesizer.</span>"
|
||||
insults = rand(1, 3)//to prevent dickflooding
|
||||
return 1
|
||||
else
|
||||
return .. ()
|
||||
user << "The hailer is fried. You can't even fit the sequencer into the input slot."
|
||||
|
||||
Reference in New Issue
Block a user