mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-07-12 23:52:34 +01:00
Merge branch 'master' of https://github.com/PolarisSS13/Polaris into theUnboxingBegins
# Conflicts: # code/modules/mob/new_player/sprite_accessories.dm # code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm # icons/mob/human_face.dmi # icons/mob/suit.dmi
This commit is contained in:
+10
-30
@@ -206,37 +206,16 @@
|
||||
R.activate_module(src)
|
||||
R.hud_used.update_robot_modules_display()
|
||||
|
||||
// Due to storage type consolidation this should get used more now.
|
||||
// I have cleaned it up a little, but it could probably use more. -Sayu
|
||||
/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/storage))
|
||||
if(istype(W, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = W
|
||||
if(S.use_to_pickup)
|
||||
if(S.collection_mode) //Mode is set to collect all items on a tile and we clicked on a valid one.
|
||||
if(S.collection_mode) //Mode is set to collect all items
|
||||
if(isturf(src.loc))
|
||||
var/list/rejections = list()
|
||||
var/success = 0
|
||||
var/failure = 0
|
||||
|
||||
for(var/obj/item/I in src.loc)
|
||||
if(I.type in rejections) // To limit bag spamming: any given type only complains once
|
||||
continue
|
||||
if(!S.can_be_inserted(I)) // Note can_be_inserted still makes noise when the answer is no
|
||||
rejections += I.type // therefore full bags are still a little spammy
|
||||
failure = 1
|
||||
continue
|
||||
success = 1
|
||||
S.handle_item_insertion(I, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed.
|
||||
if(success && !failure)
|
||||
user << "<span class='notice'>You put everything in [S].</span>"
|
||||
else if(success)
|
||||
user << "<span class='notice'>You put some things in [S].</span>"
|
||||
else
|
||||
user << "<span class='notice'>You fail to pick anything up with \the [S].</span>"
|
||||
S.gather_all(src.loc, user)
|
||||
|
||||
else if(S.can_be_inserted(src))
|
||||
S.handle_item_insertion(src)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/proc/talk_into(mob/M as mob, text)
|
||||
@@ -461,12 +440,13 @@ var/list/global/slot_flags_enumeration = list(
|
||||
user << "<span class='warning'>You cannot locate any eyes on [M]!</span>"
|
||||
return
|
||||
|
||||
var/hit_zone = get_zone_with_miss_chance(U.zone_sel.selecting, M, U.get_accuracy_penalty(U))
|
||||
if(!hit_zone)
|
||||
U.do_attack_animation(M)
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("\red <B>[U] attempts to stab [M] in the eyes, but misses!</B>")
|
||||
return
|
||||
if(U.get_accuracy_penalty(U)) //Should only trigger if they're not aiming well
|
||||
var/hit_zone = get_zone_with_miss_chance(U.zone_sel.selecting, M, U.get_accuracy_penalty(U))
|
||||
if(!hit_zone)
|
||||
U.do_attack_animation(M)
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("\red <B>[U] attempts to stab [M] in the eyes, but misses!</B>")
|
||||
return
|
||||
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/broken = 0 //Is the flash burnt out?
|
||||
var/last_used = 0 //last world.time it was used.
|
||||
var/max_flashes = 10 // How many times the flash can be used before needing to self recharge.
|
||||
var/halloss_per_flash = 30
|
||||
|
||||
/obj/item/device/flash/proc/clown_check(var/mob/user)
|
||||
if(user && (CLUMSY in user.mutations) && prob(50))
|
||||
@@ -22,15 +24,36 @@
|
||||
return 1
|
||||
|
||||
/obj/item/device/flash/proc/flash_recharge()
|
||||
//capacitor recharges over time
|
||||
for(var/i=0, i<3, i++)
|
||||
if(last_used+600 > world.time)
|
||||
//Every ten seconds the flash doesn't get used, the times_used variable goes down by one, making the flash less likely to burn out,
|
||||
// as well as being able to flash more before reaching max_flashes cap.
|
||||
for(var/i=0, i < max_flashes, i++)
|
||||
if(last_used + 10 SECONDS > world.time)
|
||||
break
|
||||
last_used += 600
|
||||
times_used -= 2
|
||||
last_used += 10 SECONDS
|
||||
times_used--
|
||||
last_used = world.time
|
||||
times_used = max(0,round(times_used)) //sanity
|
||||
|
||||
// Returns true if the device can flash.
|
||||
/obj/item/device/flash/proc/check_capacitor(var/mob/user)
|
||||
//spamming the flash before it's fully charged (60 seconds) increases the chance of it breaking
|
||||
//It will never break on the first use.
|
||||
if(times_used <= max_flashes)
|
||||
last_used = world.time
|
||||
if(prob( round(times_used / 2) )) //if you use it 10 times in a minute it has a 5% chance to break.
|
||||
broken = 1
|
||||
if(user)
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
return FALSE
|
||||
else
|
||||
times_used++
|
||||
return TRUE
|
||||
else //can only use it 10 times a minute
|
||||
if(user)
|
||||
user << "<span class='warning'>*click* *click*</span>"
|
||||
return FALSE
|
||||
|
||||
//attack_as_weapon
|
||||
/obj/item/device/flash/attack(mob/living/M, mob/living/user, var/target_zone)
|
||||
if(!user || !M) return //sanity
|
||||
@@ -49,20 +72,8 @@
|
||||
|
||||
flash_recharge()
|
||||
|
||||
//spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
|
||||
//It will never break on the first use.
|
||||
switch(times_used)
|
||||
if(0 to 5)
|
||||
last_used = world.time
|
||||
if(prob(times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
|
||||
broken = 1
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
return
|
||||
times_used++
|
||||
else //can only use it 5 times a minute
|
||||
user << "<span class='warning'>*click* *click*</span>"
|
||||
return
|
||||
if(!check_capacitor(user))
|
||||
return
|
||||
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
user.do_attack_animation(M)
|
||||
@@ -71,12 +82,13 @@
|
||||
var/flashfail = 0
|
||||
|
||||
if(iscarbon(M))
|
||||
if(M.stat!=DEAD)
|
||||
var/safety = M:eyecheck()
|
||||
var/mob/living/carbon/C = M
|
||||
if(C.stat != DEAD)
|
||||
var/safety = C.eyecheck()
|
||||
if(safety <= 0)
|
||||
var/flash_strength = 5
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
flash_strength *= H.species.flash_mod
|
||||
|
||||
if(flash_strength > 0)
|
||||
@@ -84,6 +96,7 @@
|
||||
H.eye_blind = max(H.eye_blind, flash_strength)
|
||||
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
|
||||
H.flash_eyes()
|
||||
H.adjustHalLoss(halloss_per_flash * (flash_strength / 5)) // Should take four flashes to stun.
|
||||
|
||||
else
|
||||
flashfail = 1
|
||||
@@ -132,19 +145,9 @@
|
||||
|
||||
flash_recharge()
|
||||
|
||||
//spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
|
||||
//It will never break on the first use.
|
||||
switch(times_used)
|
||||
if(0 to 5)
|
||||
if(prob(2*times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
|
||||
broken = 1
|
||||
user << "<span class='warning'>The bulb has burnt out!</span>"
|
||||
icon_state = "flashburnt"
|
||||
return
|
||||
times_used++
|
||||
else //can only use it 5 times a minute
|
||||
user.show_message("<span class='warning'>*click* *click*</span>", 2)
|
||||
return
|
||||
if(!check_capacitor(user))
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
flick("flash2", src)
|
||||
if(user && isrobot(user))
|
||||
@@ -158,32 +161,29 @@
|
||||
sleep(5)
|
||||
qdel(animation)
|
||||
|
||||
for(var/mob/living/carbon/M in oviewers(3, null))
|
||||
var/safety = M:eyecheck()
|
||||
for(var/mob/living/carbon/C in oviewers(3, null))
|
||||
var/safety = C.eyecheck()
|
||||
if(!safety)
|
||||
if(!M.blinded)
|
||||
M.flash_eyes()
|
||||
if(!C.blinded)
|
||||
C.flash_eyes()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/device/flash/emp_act(severity)
|
||||
if(broken) return
|
||||
flash_recharge()
|
||||
switch(times_used)
|
||||
if(0 to 5)
|
||||
if(prob(2*times_used))
|
||||
broken = 1
|
||||
icon_state = "flashburnt"
|
||||
return
|
||||
times_used++
|
||||
if(istype(loc, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = loc
|
||||
var/safety = M.eyecheck()
|
||||
if(safety <= 0)
|
||||
M.Weaken(10)
|
||||
M.flash_eyes()
|
||||
for(var/mob/O in viewers(M, null))
|
||||
O.show_message("<span class='disarm'>[M] is blinded by the flash!</span>")
|
||||
if(!check_capacitor())
|
||||
return
|
||||
|
||||
if(istype(loc, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = loc
|
||||
var/safety = C.eyecheck()
|
||||
if(safety <= 0)
|
||||
C.adjustHalLoss(halloss_per_flash)
|
||||
//C.Weaken(10)
|
||||
C.flash_eyes()
|
||||
for(var/mob/M in viewers(C, null))
|
||||
M.show_message("<span class='disarm'>[C] is blinded by the flash!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/device/flash/synthetic
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
icon_state = "medintercom"
|
||||
frequency = SEC_I_FREQ
|
||||
|
||||
/obj/item/device/radio/intercom/entertainment
|
||||
name = "entertainment intercom"
|
||||
frequency = ENT_FREQ
|
||||
|
||||
/obj/item/device/radio/intercom/New()
|
||||
..()
|
||||
processing_objects += src
|
||||
@@ -59,6 +63,13 @@
|
||||
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"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
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),
|
||||
|
||||
@@ -81,12 +81,14 @@ REAGENT SCANNER
|
||||
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("<span class='notice'> [][]: [][] - []</span>",
|
||||
capitalize(org.name),
|
||||
(org.robotic >= 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)
|
||||
if(org.robotic >= ORGAN_ROBOT)
|
||||
continue
|
||||
else
|
||||
user.show_message(text("<span class='notice'> []: [][] - []</span>",
|
||||
capitalize(org.name),
|
||||
(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("<span class='notice'> Limbs are OK.</span>",1)
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/obj/item/device/tvcamera
|
||||
name = "press camera drone"
|
||||
desc = "A Ward-Takahashi EyeBuddy media streaming hovercam. Weapon of choice for war correspondents and reality show cameramen."
|
||||
icon_state = "camcorder"
|
||||
item_state = "camcorder"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
slot_flags = SLOT_BELT
|
||||
var/channel = "NCS Northern Star News Feed"
|
||||
var/obj/machinery/camera/network/thunder/camera
|
||||
var/obj/item/device/radio/radio
|
||||
|
||||
/obj/item/device/tvcamera/New()
|
||||
..()
|
||||
listening_objects += src
|
||||
|
||||
/obj/item/device/tvcamera/Destroy()
|
||||
listening_objects -= src
|
||||
qdel(camera)
|
||||
qdel(radio)
|
||||
camera = null
|
||||
radio = null
|
||||
..()
|
||||
|
||||
/obj/item/device/tvcamera/examine()
|
||||
..()
|
||||
to_chat(usr, "Video feed is [camera.status ? "on" : "off"]")
|
||||
to_chat(usr, "Audio feed is [radio.broadcasting ? "on" : "off"]")
|
||||
|
||||
/obj/item/device/tvcamera/initialize()
|
||||
..()
|
||||
camera = new(src)
|
||||
camera.c_tag = channel
|
||||
camera.status = FALSE
|
||||
radio = new(src)
|
||||
radio.listening = FALSE
|
||||
radio.set_frequency(ENT_FREQ)
|
||||
radio.icon = src.icon
|
||||
radio.icon_state = src.icon_state
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/tvcamera/hear_talk(mob/living/M, msg, var/verb="says", datum/language/speaking=null)
|
||||
radio.hear_talk(M,msg,verb,speaking)
|
||||
..()
|
||||
|
||||
/obj/item/device/tvcamera/attack_self(mob/user)
|
||||
add_fingerprint(user)
|
||||
user.set_machine(src)
|
||||
var/dat = list()
|
||||
dat += "Channel name is: <a href='?src=\ref[src];channel=1'>[channel ? channel : "unidentified broadcast"]</a><br>"
|
||||
dat += "Video streaming is <a href='?src=\ref[src];video=1'>[camera.status ? "on" : "off"]</a><br>"
|
||||
dat += "Mic is <a href='?src=\ref[src];sound=1'>[radio.broadcasting ? "on" : "off"]</a><br>"
|
||||
dat += "Sound is being broadcasted on frequency [format_frequency(radio.frequency)] ([get_frequency_name(radio.frequency)])<br>"
|
||||
var/datum/browser/popup = new(user, "Hovercamera", "Eye Buddy", 300, 390, src)
|
||||
popup.set_content(jointext(dat,null))
|
||||
popup.open()
|
||||
|
||||
/obj/item/device/tvcamera/Topic(bred, href_list, state = physical_state)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["channel"])
|
||||
var/nc = input(usr, "Channel name", "Select new channel name", channel) as text|null
|
||||
if(nc)
|
||||
channel = nc
|
||||
camera.c_tag = channel
|
||||
to_chat(usr, "<span class='notice'>New channel name - '[channel]' is set</span>")
|
||||
if(href_list["video"])
|
||||
camera.set_status(!camera.status)
|
||||
if(camera.status)
|
||||
to_chat(usr,"<span class='notice'>Video streaming activated. Broadcasting on channel '[channel]'</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='notice'>Video streaming deactivated.</span>")
|
||||
update_icon()
|
||||
if(href_list["sound"])
|
||||
radio.ToggleBroadcast()
|
||||
if(radio.broadcasting)
|
||||
to_chat(usr,"<span class='notice'>Audio streaming activated. Broadcasting on frequency [format_frequency(radio.frequency)].</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='notice'>Audio streaming deactivated.</span>")
|
||||
if(!href_list["close"])
|
||||
attack_self(usr)
|
||||
|
||||
/obj/item/device/tvcamera/update_icon()
|
||||
..()
|
||||
if(camera.status)
|
||||
icon_state = "camcorder_on"
|
||||
item_state = "camcorder_on"
|
||||
else
|
||||
icon_state = "camcorder"
|
||||
item_state = "camcorder"
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(istype(H))
|
||||
H.update_inv_r_hand()
|
||||
H.update_inv_l_hand()
|
||||
H.update_inv_belt()
|
||||
|
||||
@@ -54,6 +54,18 @@
|
||||
part.implants.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/implant/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/implanter))
|
||||
var/obj/item/weapon/implanter/implanter = I
|
||||
if(implanter.imp)
|
||||
return // It's full.
|
||||
user.drop_from_inventory(src)
|
||||
forceMove(implanter)
|
||||
implanter.imp = src
|
||||
implanter.update()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/implant/tracking
|
||||
name = "tracking implant"
|
||||
desc = "Track with this."
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/obj/item/weapon/implant/integrated_circuit
|
||||
name = "electronic implant"
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "setup_implant"
|
||||
var/obj/item/device/electronic_assembly/implant/IC = null
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/islegal()
|
||||
return TRUE
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/New()
|
||||
..()
|
||||
IC = new(src)
|
||||
IC.implant = src
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/Destroy()
|
||||
IC.implant = null
|
||||
qdel(IC)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/get_data()
|
||||
var/dat = {"
|
||||
<b>Implant Specifications:</b><BR>
|
||||
<b>Name:</b> Modular Implant<BR>
|
||||
<b>Life:</b> 3 years.<BR>
|
||||
<b>Important Notes: EMP can cause malfunctions in the internal electronics of this implant.</B><BR>
|
||||
<HR>
|
||||
<b>Implant Details:</b><BR>
|
||||
<b>Function:</b> Contains no innate functions until other components are added.<BR>
|
||||
<b>Special Features:</b>
|
||||
<i>Modular Circuitry</i>- Can be loaded with specific modular circuitry in order to fulfill a wide possibility of functions.<BR>
|
||||
<b>Integrity:</b> Implant is not shielded from electromagnetic interferance, otherwise it is independant of subject's status."}
|
||||
return dat
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/emp_act(severity)
|
||||
IC.emp_act(severity)
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/examine(mob/user)
|
||||
IC.examine(user)
|
||||
|
||||
/obj/item/weapon/implant/integrated_circuit/attackby(var/obj/item/O, var/mob/user)
|
||||
if(istype(O, /obj/item/weapon/crowbar) || istype(O, /obj/item/device/integrated_electronics) || istype(O, /obj/item/integrated_circuit) || istype(O, /obj/item/weapon/screwdriver) )
|
||||
IC.attackby(O, user)
|
||||
else
|
||||
..()
|
||||
@@ -478,6 +478,27 @@
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/proc/gather_all(turf/T as turf, mob/user as mob)
|
||||
var/list/rejections = list()
|
||||
var/success = 0
|
||||
var/failure = 0
|
||||
|
||||
for(var/obj/item/I in T)
|
||||
if(I.type in rejections) // To limit bag spamming: any given type only complains once
|
||||
continue
|
||||
if(!can_be_inserted(I, user)) // Note can_be_inserted still makes noise when the answer is no
|
||||
rejections += I.type // therefore full bags are still a little spammy
|
||||
failure = 1
|
||||
continue
|
||||
success = 1
|
||||
handle_item_insertion(I, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed.
|
||||
if(success && !failure)
|
||||
to_chat(user, "<span class='notice'>You put everything in [src].</span>")
|
||||
else if(success)
|
||||
to_chat(user, "<span class='notice'>You put some things in [src].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You fail to pick anything up with \the [src].</span>")
|
||||
|
||||
/obj/item/weapon/storage/verb/toggle_gathering_mode()
|
||||
set name = "Switch Gathering Method"
|
||||
set category = "Object"
|
||||
|
||||
@@ -78,6 +78,9 @@
|
||||
else
|
||||
user << "<span class='notice'>[src] can't hold any more signs.</span>"
|
||||
|
||||
else if(istype(I, /obj/item/weapon/reagent_containers/glass))
|
||||
return // So we do not put them in the trash bag as we mean to fill the mop bucket
|
||||
|
||||
else if(mybag)
|
||||
mybag.attackby(I, user)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user