mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-27 14:07:51 +01:00
Massive traitor item overhaul
This commit is contained in:
@@ -76,6 +76,7 @@ BLIND // can't see anything
|
||||
body_parts_covered = HANDS
|
||||
slot_flags = SLOT_GLOVES
|
||||
attack_verb = list("challenged")
|
||||
var/pickpocket = 0 //Master pickpocket?
|
||||
species_restricted = list("exclude","Unathi","Tajaran")
|
||||
|
||||
/obj/item/clothing/gloves/examine()
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
permeability_coefficient = 0.05
|
||||
_color="yellow"
|
||||
|
||||
power
|
||||
var/next_shock = 0
|
||||
|
||||
/obj/item/clothing/gloves/fyellow //Cheap Chinese Crap
|
||||
desc = "These gloves are cheap copies of the coveted gloves, no way this can end badly."
|
||||
name = "budget insulated gloves"
|
||||
@@ -39,6 +42,9 @@
|
||||
ce
|
||||
_color = "chief" //Exists for washing machines. Is not different from black gloves in any way.
|
||||
|
||||
thief
|
||||
pickpocket = 1
|
||||
|
||||
/obj/item/clothing/gloves/orange
|
||||
name = "orange gloves"
|
||||
desc = "A pair of gloves, they don't look special in any way."
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
//CONTAINS: Detective's Scanner
|
||||
|
||||
|
||||
/obj/item/device/detective_scanner
|
||||
name = "Scanner"
|
||||
desc = "Used to scan objects for DNA and fingerprints."
|
||||
icon_state = "forensic1"
|
||||
var/amount = 20.0
|
||||
var/list/stored = list()
|
||||
w_class = 3.0
|
||||
item_state = "electronic"
|
||||
flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
attackby(obj/item/weapon/f_card/W as obj, mob/user as mob)
|
||||
..()
|
||||
if (istype(W, /obj/item/weapon/f_card))
|
||||
if (W.fingerprints)
|
||||
return
|
||||
if (src.amount == 20)
|
||||
return
|
||||
if (W.amount + src.amount > 20)
|
||||
src.amount = 20
|
||||
W.amount = W.amount + src.amount - 20
|
||||
else
|
||||
src.amount += W.amount
|
||||
//W = null
|
||||
del(W)
|
||||
add_fingerprint(user)
|
||||
if (W)
|
||||
W.add_fingerprint(user)
|
||||
return
|
||||
|
||||
attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if (!ishuman(M))
|
||||
user << "\red [M] is not human and cannot have the fingerprints."
|
||||
flick("forensic0",src)
|
||||
return 0
|
||||
if (( !( istype(M.dna, /datum/dna) ) || M.gloves) )
|
||||
user << "\blue No fingerprints found on [M]"
|
||||
flick("forensic0",src)
|
||||
return 0
|
||||
else
|
||||
if (src.amount < 1)
|
||||
user << text("\blue Fingerprints scanned on [M]. Need more cards to print.")
|
||||
else
|
||||
src.amount--
|
||||
var/obj/item/weapon/f_card/F = new /obj/item/weapon/f_card( user.loc )
|
||||
F.amount = 1
|
||||
F.add_fingerprint(M)
|
||||
F.icon_state = "fingerprint1"
|
||||
F.name = text("FPrintC- '[M.name]'")
|
||||
|
||||
user << "\blue Done printing."
|
||||
user << "\blue [M]'s Fingerprints: [md5(M.dna.uni_identity)]"
|
||||
if ( !M.blood_DNA || !M.blood_DNA.len )
|
||||
user << "\blue No blood found on [M]"
|
||||
if(M.blood_DNA)
|
||||
del(M.blood_DNA)
|
||||
else
|
||||
user << "\blue Blood found on [M]. Analysing..."
|
||||
spawn(15)
|
||||
for(var/blood in M.blood_DNA)
|
||||
user << "\blue Blood type: [M.blood_DNA[blood]]\nDNA: [blood]"
|
||||
return
|
||||
|
||||
afterattack(atom/A as obj|turf|area, mob/user as mob)
|
||||
if(!in_range(A,user))
|
||||
return
|
||||
if(loc != user)
|
||||
return
|
||||
if(istype(A,/obj/machinery/computer/forensic_scanning)) //breaks shit.
|
||||
return
|
||||
if(istype(A,/obj/item/weapon/f_card))
|
||||
user << "The scanner displays on the screen: \"ERROR 43: Object on Excluded Object List.\""
|
||||
flick("forensic0",src)
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
//Special case for blood splaters.
|
||||
if (istype(A, /obj/effect/decal/cleanable/blood) || istype(A, /obj/effect/rune))
|
||||
if(!isnull(A.blood_DNA))
|
||||
for(var/blood in A.blood_DNA)
|
||||
user << "\blue Blood type: [A.blood_DNA[blood]]\nDNA: [blood]"
|
||||
flick("forensic2",src)
|
||||
return
|
||||
|
||||
//General
|
||||
if ((!A.fingerprints || !A.fingerprints.len) && !A.suit_fibers && !A.blood_DNA)
|
||||
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
|
||||
"\blue Unable to locate any fingerprints, materials, fibers, or blood on [A]!",\
|
||||
"You hear a faint hum of electrical equipment.")
|
||||
flick("forensic0",src)
|
||||
return 0
|
||||
|
||||
if(add_data(A))
|
||||
user << "\blue Object already in internal memory. Consolidating data..."
|
||||
flick("forensic2",src)
|
||||
return
|
||||
|
||||
|
||||
//PRINTS
|
||||
if(!A.fingerprints || !A.fingerprints.len)
|
||||
if(A.fingerprints)
|
||||
del(A.fingerprints)
|
||||
else
|
||||
user << "\blue Isolated [A.fingerprints.len] fingerprints: Data Stored: Scan with Hi-Res Forensic Scanner to retrieve."
|
||||
var/list/complete_prints = list()
|
||||
for(var/i in A.fingerprints)
|
||||
var/print = A.fingerprints[i]
|
||||
if(stringpercent(print) <= FINGERPRINT_COMPLETE)
|
||||
complete_prints += print
|
||||
if(complete_prints.len < 1)
|
||||
user << "\blue No intact prints found"
|
||||
else
|
||||
user << "\blue Found [complete_prints.len] intact prints"
|
||||
for(var/i in complete_prints)
|
||||
user << "\blue [i]"
|
||||
|
||||
//FIBERS
|
||||
if(A.suit_fibers)
|
||||
user << "\blue Fibers/Materials Data Stored: Scan with Hi-Res Forensic Scanner to retrieve."
|
||||
flick("forensic2",src)
|
||||
|
||||
//Blood
|
||||
if (A.blood_DNA)
|
||||
user << "\blue Blood found on [A]. Analysing..."
|
||||
spawn(15)
|
||||
for(var/blood in A.blood_DNA)
|
||||
user << "Blood type: \red [A.blood_DNA[blood]] \t \black DNA: \red [blood]"
|
||||
if(prob(80) || !A.fingerprints)
|
||||
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]" ,\
|
||||
"You finish scanning \the [A].",\
|
||||
"You hear a faint hum of electrical equipment.")
|
||||
flick("forensic2",src)
|
||||
return 0
|
||||
else
|
||||
user.visible_message("\The [user] scans \the [A] with \a [src], the air around [user.gender == MALE ? "him" : "her"] humming[prob(70) ? " gently." : "."]\n[user.gender == MALE ? "He" : "She"] seems to perk up slightly at the readout." ,\
|
||||
"The results of the scan pique your interest.",\
|
||||
"You hear a faint hum of electrical equipment, and someone making a thoughtful noise.")
|
||||
flick("forensic2",src)
|
||||
return 0
|
||||
return
|
||||
|
||||
proc/add_data(atom/A as mob|obj|turf|area)
|
||||
//I love associative lists.
|
||||
var/list/data_entry = stored["\ref [A]"]
|
||||
if(islist(data_entry)) //Yay, it was already stored!
|
||||
//Merge the fingerprints.
|
||||
var/list/data_prints = data_entry[1]
|
||||
for(var/print in A.fingerprints)
|
||||
var/merged_print = data_prints[print]
|
||||
if(!merged_print)
|
||||
data_prints[print] = A.fingerprints[print]
|
||||
else
|
||||
data_prints[print] = stringmerge(data_prints[print],A.fingerprints[print])
|
||||
|
||||
//Now the fibers
|
||||
var/list/fibers = data_entry[2]
|
||||
if(!fibers)
|
||||
fibers = list()
|
||||
if(A.suit_fibers && A.suit_fibers.len)
|
||||
for(var/j = 1, j <= A.suit_fibers.len, j++) //Fibers~~~
|
||||
if(!fibers.Find(A.suit_fibers[j])) //It isn't! Add!
|
||||
fibers += A.suit_fibers[j]
|
||||
var/list/blood = data_entry[3]
|
||||
if(!blood)
|
||||
blood = list()
|
||||
if(A.blood_DNA && A.blood_DNA.len)
|
||||
for(var/main_blood in A.blood_DNA)
|
||||
if(!blood[main_blood])
|
||||
blood[main_blood] = A.blood_DNA[blood]
|
||||
return 1
|
||||
var/list/sum_list[4] //Pack it back up!
|
||||
sum_list[1] = A.fingerprints ? A.fingerprints.Copy() : null
|
||||
sum_list[2] = A.suit_fibers ? A.suit_fibers.Copy() : null
|
||||
sum_list[3] = A.blood_DNA ? A.blood_DNA.Copy() : null
|
||||
sum_list[4] = "\The [A] in \the [get_area(A)]"
|
||||
stored["\ref [A]"] = sum_list
|
||||
return 0
|
||||
@@ -464,10 +464,10 @@
|
||||
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
|
||||
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
|
||||
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
<BR>"}
|
||||
user << browse(dat, text("window=mob[];size=325x500", name))
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, text("window=mob\ref[src];size=325x500"))
|
||||
onclose(user, "mob\ref[src]")
|
||||
return
|
||||
|
||||
//generates realistic-ish pulse output based on preset levels
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define STRIP_DELAY 40 //time taken (in deciseconds) to strip somebody
|
||||
/mob/living/carbon/human
|
||||
name = "unknown"
|
||||
real_name = "unknown"
|
||||
@@ -388,7 +389,11 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user as mob)
|
||||
|
||||
var/obj/item/clothing/gloves/G
|
||||
var/pickpocket = 0
|
||||
if(user:gloves)
|
||||
G = user:gloves
|
||||
pickpocket = G.pickpocket
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<B><HR><FONT size=3>[name]</FONT></B>
|
||||
@@ -411,12 +416,13 @@
|
||||
<BR>[(legcuffed ? text("<A href='?src=\ref[src];item=legcuff'>Legcuffed</A>") : text(""))]
|
||||
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
|
||||
<BR><A href='?src=\ref[src];item=splints'>Remove Splints</A>
|
||||
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
|
||||
<BR><BR><A href='?src=\ref[src];pockets=left'>Left Pocket ([l_store ? (pickpocket ? l_store.name : "Full") : "Empty"])</A>
|
||||
<BR><A href='?src=\ref[src];pockets=right'>Right Pocket ([r_store ? (pickpocket ? r_store.name : "Full") : "Empty"])</A>
|
||||
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
<BR>"}
|
||||
user << browse(dat, text("window=mob[name];size=340x480"))
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, text("window=mob\ref[src];size=340x480"))
|
||||
onclose(user, "mob\ref[src]")
|
||||
return
|
||||
|
||||
// called when something steps onto a human
|
||||
@@ -511,6 +517,43 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
var/pickpocket = 0
|
||||
if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
|
||||
if(href_list["pockets"])
|
||||
if(usr:gloves)
|
||||
var/obj/item/clothing/gloves/G = usr:gloves
|
||||
pickpocket = G.pickpocket
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store)
|
||||
var/obj/item/pocket_item = (pocket_id == slot_r_store ? src.r_store : src.l_store)
|
||||
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
|
||||
|
||||
if(pocket_item)
|
||||
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
|
||||
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1))
|
||||
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
|
||||
else
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, STRIP_DELAY))
|
||||
if(pocket_item)
|
||||
u_equip(pocket_item)
|
||||
if(pickpocket) usr.put_in_hands(pocket_item)
|
||||
else
|
||||
if(place_item)
|
||||
usr.u_equip(place_item)
|
||||
equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
show_inv(usr)
|
||||
|
||||
|
||||
|
||||
else if(!pickpocket)
|
||||
// Display a warning if the user mocks up
|
||||
src << "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>"
|
||||
|
||||
if (href_list["refresh"])
|
||||
if((machine)&&(in_range(src, usr)))
|
||||
show_inv(machine)
|
||||
@@ -522,12 +565,16 @@
|
||||
|
||||
if ((href_list["item"] && !( usr.stat ) && usr.canmove && !( usr.restrained() ) && in_range(src, usr) && ticker)) //if game hasn't started, can't make an equip_e
|
||||
var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( )
|
||||
if(usr:gloves)
|
||||
var/obj/item/clothing/gloves/G = usr:gloves
|
||||
pickpocket = G.pickpocket
|
||||
O.source = usr
|
||||
O.target = src
|
||||
O.item = usr.get_active_hand()
|
||||
O.s_loc = usr.loc
|
||||
O.t_loc = loc
|
||||
O.place = href_list["item"]
|
||||
O.pickpocket = pickpocket //Stealthy
|
||||
requests += O
|
||||
spawn( 0 )
|
||||
O.process()
|
||||
|
||||
@@ -228,13 +228,14 @@
|
||||
if(istype(used_weapon,/obj/item/weapon))
|
||||
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
|
||||
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
|
||||
organ.implants += W
|
||||
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
W.add_blood(src)
|
||||
if(ismob(W.loc))
|
||||
var/mob/living/H = W.loc
|
||||
H.drop_item()
|
||||
W.loc = src
|
||||
if(!istype(W, /obj/item/weapon/butch/meatcleaver))
|
||||
organ.implants += W
|
||||
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
W.add_blood(src)
|
||||
if(ismob(W.loc))
|
||||
var/mob/living/H = W.loc
|
||||
H.drop_item()
|
||||
W.loc = src
|
||||
|
||||
else if(istype(used_weapon,/obj/item/projectile)) //We don't want to use the actual projectile item, so we spawn some shrapnel.
|
||||
if(prob(75) && damagetype == BRUTE)
|
||||
|
||||
@@ -168,10 +168,26 @@ emp_act
|
||||
var/target_zone = get_zone_with_miss_chance(user.zone_sel.selecting, src)
|
||||
if(user == src) // Attacking yourself can't miss
|
||||
target_zone = user.zone_sel.selecting
|
||||
if(!target_zone)
|
||||
if(!target_zone && !src.stat)
|
||||
visible_message("\red <B>[user] misses [src] with \the [I]!")
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/weapon/butch/meatcleaver) && src.stat == DEAD && user.a_intent == "hurt")
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new /obj/item/weapon/reagent_containers/food/snacks/meat/human(get_turf(src.loc))
|
||||
newmeat.name = src.real_name + newmeat.name
|
||||
newmeat.subjectname = src.real_name
|
||||
newmeat.subjectjob = src.job
|
||||
newmeat.reagents.add_reagent ("nutriment", (src.nutrition / 15) / 3)
|
||||
src.reagents.trans_to (newmeat, round ((src.reagents.total_volume) / 3, 1))
|
||||
src.loc.add_blood(src)
|
||||
--src.meatleft
|
||||
user << "\red You hack off a chunk of meat from [src.name]"
|
||||
if(!src.meatleft)
|
||||
src.attack_log += "\[[time_stamp()]\] Was chopped up into meat by <b>[user]/[user.ckey]</b>"
|
||||
user.attack_log += "\[[time_stamp()]\] Chopped up <b>[src]/[src.ckey]</b> into meat</b>"
|
||||
msg_admin_attack("[user.name] ([user.ckey]) chopped up [src] ([src.ckey]) into meat (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
del(src)
|
||||
|
||||
var/datum/organ/external/affecting = get_organ(target_zone)
|
||||
if (!affecting)
|
||||
return
|
||||
|
||||
@@ -55,3 +55,4 @@
|
||||
var/xylophone = 0 //For the spoooooooky xylophone cooldown
|
||||
|
||||
var/mob/remoteview_target = null
|
||||
var/meatleft = 3 //For chef item
|
||||
@@ -278,6 +278,7 @@
|
||||
var/t_loc = null //target location
|
||||
var/obj/item/item = null
|
||||
var/place = null
|
||||
var/pickpocket = null
|
||||
|
||||
/obj/effect/equip_e/human
|
||||
name = "human"
|
||||
@@ -430,7 +431,10 @@
|
||||
if("belt")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their belt item ([target.belt]) removed by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) belt item ([target.belt])</font>")
|
||||
message = "\red <B>[source] is trying to take off the [target.belt] from [target]'s belt!</B>"
|
||||
if(!pickpocket)
|
||||
message = "\red <B>[source] is trying to take off the [target.belt] from [target]'s belt!</B>"
|
||||
else
|
||||
source << "\blue You try to take off the [target.belt] from [target]'s belt!"
|
||||
if("suit")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their suit ([target.wear_suit]) removed by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) suit ([target.wear_suit])</font>")
|
||||
@@ -481,7 +485,10 @@
|
||||
if("id")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their ID ([target.wear_id]) removed by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to remove [target.name]'s ([target.ckey]) ID ([target.wear_id])</font>")
|
||||
message = "\red <B>[source] is trying to take off [target.wear_id] from [target]'s uniform!</B>"
|
||||
if(!pickpocket)
|
||||
message = "\red <B>[source] is trying to take off [target.wear_id] from [target]'s uniform!</B>"
|
||||
else
|
||||
source << "\blue You try to take off [target.wear_id] from [target]'s uniform!"
|
||||
if("internal")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their internals toggled by [source.name] ([source.ckey])</font>")
|
||||
source.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to toggle [target.name]'s ([target.ckey]) internals</font>")
|
||||
|
||||
@@ -1,4 +1,26 @@
|
||||
|
||||
/mob/living/Life()
|
||||
..()
|
||||
if (monkeyizing) return
|
||||
if(!loc) return // Fixing a null error that occurs when the mob isn't found in the world -- TLE
|
||||
if(mind)
|
||||
if(mind in ticker.mode.implanted)
|
||||
if(implanting) return
|
||||
//world << "[src.name]"
|
||||
var/datum/mind/head = ticker.mode.implanted[mind]
|
||||
//var/list/removal
|
||||
if(!(locate(/obj/item/weapon/implant/traitor) in src.contents))
|
||||
//world << "doesn't have an implant"
|
||||
ticker.mode.remove_traitor_mind(mind, head)
|
||||
/*
|
||||
if((head in ticker.mode.implanters))
|
||||
ticker.mode.implanter[head] -= src.mind
|
||||
ticker.mode.implanted -= src.mind
|
||||
if(src.mind in ticker.mode.traitors)
|
||||
ticker.mode.traitors -= src.mind
|
||||
special_role = null
|
||||
current << "\red <FONT size = 3><B>The fog clouding your mind clears. You remember nothing from the moment you were implanted until now..(You don't remember who enslaved you)</B></FONT>"
|
||||
*/
|
||||
/mob/living/verb/succumb()
|
||||
set hidden = 1
|
||||
if ((src.health < 0 && src.health > -95.0))
|
||||
|
||||
@@ -59,6 +59,9 @@
|
||||
if(!P.nodamage)
|
||||
apply_damage((P.damage/(absorb+1)), P.damage_type, def_zone, absorb, 0, P)
|
||||
P.on_hit(src, absorb)
|
||||
if(istype(P, /obj/item/projectile/beam/lightning))
|
||||
if(src.health <= -100)
|
||||
src.dust()
|
||||
return absorb
|
||||
|
||||
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
|
||||
|
||||
@@ -35,4 +35,6 @@
|
||||
|
||||
var/tod = null // Time of death
|
||||
var/update_slimes = 1
|
||||
var/silent = null //Can't talk. Value goes down every life proc.
|
||||
var/silent = null //Can't talk. Value goes down every life proc.
|
||||
var/specialsauce = 0 //Has this person consumed enough special sauce? IF so they're a ticking time bomb of death.
|
||||
var/implanting = 0 //Used for the mind-slave implant
|
||||
@@ -16,8 +16,14 @@
|
||||
if("nuclear emergency")
|
||||
if(mind in ticker.mode:syndicates)
|
||||
ticker.mode.update_all_synd_icons()
|
||||
var/ref = "\ref[mind]"
|
||||
if(ref in ticker.mode.implanter)
|
||||
ticker.mode.update_traitor_icons_added(mind)
|
||||
if(mind in ticker.mode.implanted)
|
||||
ticker.mode.update_traitor_icons_added(mind)
|
||||
return .
|
||||
|
||||
|
||||
//This stuff needs to be merged from cloning.dm but I'm not in the mood to be shouted at for breaking all the things :< ~Carn
|
||||
/* clones
|
||||
switch(ticker.mode.name)
|
||||
|
||||
@@ -228,10 +228,10 @@ var/list/slot_equipment_priority = list( \
|
||||
<BR>[(internal ? text("<A href='?src=\ref[src];item=internal'>Remove Internal</A>") : "")]
|
||||
<BR><A href='?src=\ref[src];item=pockets'>Empty Pockets</A>
|
||||
<BR><A href='?src=\ref[user];refresh=1'>Refresh</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
<BR>"}
|
||||
user << browse(dat, text("window=mob[];size=325x500", name))
|
||||
onclose(user, "mob[name]")
|
||||
onclose(user, "mob\ref[src]")
|
||||
return
|
||||
|
||||
/mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
|
||||
|
||||
@@ -358,7 +358,9 @@
|
||||
return min(rand(20,65),rand(20,65))
|
||||
if (1000 to 10000-1)
|
||||
return min(rand(10,20),rand(10,20))*/
|
||||
if (1000000 to INFINITY)
|
||||
if (4000000 to INFINITY)
|
||||
return min(rand(80,180),rand(80,180))
|
||||
if (1000000 to 4000000)
|
||||
return min(rand(50,160),rand(50,160))
|
||||
if (200000 to 1000000)
|
||||
return min(rand(25,80),rand(25,80))
|
||||
|
||||
@@ -74,6 +74,12 @@
|
||||
projectile_type = "/obj/item/projectile/bullet/weakbullet"
|
||||
m_amt = 500
|
||||
|
||||
/obj/item/ammo_casing/shotgun/fakebeanbag
|
||||
name = "beanbag shell"
|
||||
desc = "A weak beanbag shell."
|
||||
icon_state = "bshell"
|
||||
projectile_type = "/obj/item/projectile/bullet/weakbullet/booze"
|
||||
m_amt = 12500
|
||||
|
||||
/obj/item/ammo_casing/shotgun/stunshell
|
||||
name = "stun shell"
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
origin_tech = "combat=2;materials=2"
|
||||
ammo_type = "/obj/item/ammo_casing/c38"
|
||||
|
||||
var/perfect = 0
|
||||
|
||||
|
||||
special_check(var/mob/living/carbon/human/M)
|
||||
if(caliber == initial(caliber))
|
||||
return 1
|
||||
if(prob(70 - (loaded.len * 10))) //minimum probability of 10, maximum of 60
|
||||
if(!perfect && prob(70 - (loaded.len * 10))) //minimum probability of 10, maximum of 60
|
||||
M << "<span class='danger'>[src] blows up in your face.</span>"
|
||||
M.take_organ_damage(0,20)
|
||||
M.drop_item()
|
||||
@@ -52,8 +54,14 @@
|
||||
return 1
|
||||
|
||||
attackby(var/obj/item/A as obj, mob/user as mob)
|
||||
var/obj/item/weapon/conversion_kit/CK
|
||||
..()
|
||||
if(istype(A, /obj/item/weapon/screwdriver))
|
||||
if(isscrewdriver(A) || istype(A, /obj/item/weapon/conversion_kit))
|
||||
if(istype(A, /obj/item/weapon/conversion_kit))
|
||||
CK = A
|
||||
if(!CK.open)
|
||||
user << "<span class='notice'>This [CK.name] is useless unless you open it first. </span>"
|
||||
return
|
||||
if(caliber == "38")
|
||||
user << "<span class='notice'>You begin to reinforce the barrel of [src].</span>"
|
||||
if(loaded.len)
|
||||
@@ -68,6 +76,8 @@
|
||||
caliber = "357"
|
||||
desc = "The barrel and chamber assembly seems to have been modified."
|
||||
user << "<span class='warning'>You reinforce the barrel of [src]! Now it will fire .357 rounds.</span>"
|
||||
if(CK && istype(CK))
|
||||
perfect = 1
|
||||
else
|
||||
user << "<span class='notice'>You begin to revert the modifications to [src].</span>"
|
||||
if(loaded.len)
|
||||
@@ -82,6 +92,7 @@
|
||||
caliber = "38"
|
||||
desc = initial(desc)
|
||||
user << "<span class='warning'>You remove the modifications on [src]! Now it will fire .38 rounds.</span>"
|
||||
perfect = 0
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
var/obj/item/ammo_casing/AC = loaded[1] //load next casing.
|
||||
loaded -= AC //Remove casing from loaded list.
|
||||
AC.desc += " This one is spent."
|
||||
AC.desc = "[initial(AC.desc)] This one is spent."
|
||||
|
||||
if(AC.BB)
|
||||
in_chamber = AC.BB //Load projectile into chamber.
|
||||
|
||||
@@ -94,7 +94,15 @@
|
||||
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
|
||||
if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew
|
||||
miss_modifier += -30
|
||||
def_zone = get_zone_with_miss_chance(def_zone, M, -30 + 8*distance)
|
||||
if(istype(src, /obj/item/projectile/beam/lightning)) //Lightning is quite accurate
|
||||
miss_modifier += -200
|
||||
def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier)
|
||||
var/turf/simulated/floor/f = get_turf(A.loc)
|
||||
if(f && istype(f))
|
||||
f.break_tile()
|
||||
f.hotspot_expose(1000,CELL_VOLUME)
|
||||
else
|
||||
def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 8*distance)
|
||||
|
||||
if(!def_zone)
|
||||
visible_message("\blue \The [src] misses [M] narrowly!")
|
||||
@@ -143,8 +151,9 @@
|
||||
O.bullet_act(src)
|
||||
for(var/mob/M in A)
|
||||
M.bullet_act(src, def_zone)
|
||||
density = 0
|
||||
invisibility = 101
|
||||
if(!istype(src, /obj/item/projectile/beam/lightning))
|
||||
density = 0
|
||||
invisibility = 101
|
||||
del(src)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -8,6 +8,166 @@ var/list/beam_master = list()
|
||||
// icon_states/dirs for each placed beam image
|
||||
// turfs that have that icon_state/dir
|
||||
|
||||
/obj/item/projectile/beam/lightning
|
||||
invisibility = 101
|
||||
name = "lightning"
|
||||
damage = 0
|
||||
icon = 'icons/obj/lightning.dmi'
|
||||
icon_state = "lightning"
|
||||
stun = 10
|
||||
weaken = 10
|
||||
stutter = 50
|
||||
eyeblur = 50
|
||||
var/tang = 0
|
||||
layer = 3
|
||||
var/turf/last = null
|
||||
kill_count = 6
|
||||
proc/adjustAngle(angle)
|
||||
angle = round(angle) + 45
|
||||
if(angle > 180)
|
||||
angle -= 180
|
||||
else
|
||||
angle += 180
|
||||
if(!angle)
|
||||
angle = 1
|
||||
/*if(angle < 0)
|
||||
//angle = (round(abs(get_angle(A, user))) + 45) - 90
|
||||
angle = round(angle) + 45 + 180
|
||||
else
|
||||
angle = round(angle) + 45*/
|
||||
return angle
|
||||
|
||||
process()
|
||||
var/first = 1 //So we don't make the overlay in the same tile as the firer
|
||||
var/broke = 0
|
||||
var/broken
|
||||
var/atom/curr = current
|
||||
var/Angle=round(Get_Angle(firer,curr))
|
||||
var/icon/I=new('icons/obj/zap.dmi',"lightning")
|
||||
I.Turn(Angle)
|
||||
var/DX=(32*curr.x+curr.pixel_x)-(32*firer.x+firer.pixel_x)
|
||||
var/DY=(32*curr.y+curr.pixel_y)-(32*firer.y+firer.pixel_y)
|
||||
var/N=0
|
||||
var/length=round(sqrt((DX)**2+(DY)**2))
|
||||
var/count = 0
|
||||
for(N,N<length,N+=32)
|
||||
if(count >= kill_count)
|
||||
break
|
||||
count++
|
||||
var/obj/effect/overlay/beam/X=new(loc)
|
||||
X.BeamSource=src
|
||||
if(N+32>length)
|
||||
var/icon/II=new(icon,icon_state)
|
||||
II.DrawBox(null,1,(length-N),32,32)
|
||||
II.Turn(Angle)
|
||||
X.icon=II
|
||||
else X.icon=I
|
||||
var/Pixel_x=round(sin(Angle)+32*sin(Angle)*(N+16)/32)
|
||||
var/Pixel_y=round(cos(Angle)+32*cos(Angle)*(N+16)/32)
|
||||
if(DX==0) Pixel_x=0
|
||||
if(DY==0) Pixel_y=0
|
||||
if(Pixel_x>32)
|
||||
for(var/a=0, a<=Pixel_x,a+=32)
|
||||
X.x++
|
||||
Pixel_x-=32
|
||||
if(Pixel_x<-32)
|
||||
for(var/a=0, a>=Pixel_x,a-=32)
|
||||
X.x--
|
||||
Pixel_x+=32
|
||||
if(Pixel_y>32)
|
||||
for(var/a=0, a<=Pixel_y,a+=32)
|
||||
X.y++
|
||||
Pixel_y-=32
|
||||
if(Pixel_y<-32)
|
||||
for(var/a=0, a>=Pixel_y,a-=32)
|
||||
X.y--
|
||||
Pixel_y+=32
|
||||
X.pixel_x=Pixel_x
|
||||
X.pixel_y=Pixel_y
|
||||
var/turf/TT = get_turf(X.loc)
|
||||
if(TT == firer.loc)
|
||||
continue
|
||||
if(TT.density)
|
||||
del(X)
|
||||
break
|
||||
for(var/atom/O in TT)
|
||||
if(!O.CanPass(src))
|
||||
del(X)
|
||||
broke = 1
|
||||
break
|
||||
for(var/mob/living/O in TT.contents)
|
||||
if(istype(O, /mob/living))
|
||||
if(O.density)
|
||||
del(X)
|
||||
broke = 1
|
||||
break
|
||||
if(broke)
|
||||
if(X)
|
||||
del(X)
|
||||
break
|
||||
spawn
|
||||
while(src) //Move until we hit something
|
||||
if(first)
|
||||
icon = midicon
|
||||
if((!( current ) || loc == current)) //If we pass our target
|
||||
broken = 1
|
||||
icon = endicon
|
||||
tang = adjustAngle(get_angle(original,current))
|
||||
if(tang > 180)
|
||||
tang -= 180
|
||||
else
|
||||
tang += 180
|
||||
icon_state = "[tang]"
|
||||
var/turf/simulated/floor/f = current
|
||||
if(f && istype(f))
|
||||
f.break_tile()
|
||||
f.hotspot_expose(1000,CELL_VOLUME)
|
||||
if((x == 1 || x == world.maxx || y == 1 || y == world.maxy))
|
||||
//world << "deleting"
|
||||
//del(src) //Delete if it passes the world edge
|
||||
broken = 1
|
||||
return
|
||||
if(kill_count < 1)
|
||||
//world << "deleting"
|
||||
//del(src)
|
||||
broken = 1
|
||||
kill_count--
|
||||
//world << "[x] [y]"
|
||||
if(!bumped && !isturf(original))
|
||||
if(loc == get_turf(original))
|
||||
if(!(original in permutated))
|
||||
icon = endicon
|
||||
if(!broken)
|
||||
tang = adjustAngle(get_angle(original,current))
|
||||
if(tang > 180)
|
||||
tang -= 180
|
||||
else
|
||||
tang += 180
|
||||
icon_state = "[tang]"
|
||||
Bump(original)
|
||||
first = 0
|
||||
if(broken)
|
||||
//world << "breaking"
|
||||
break
|
||||
else
|
||||
last = get_turf(src.loc)
|
||||
step_towards(src, current) //Move~
|
||||
if(src.loc != current)
|
||||
tang = adjustAngle(get_angle(src.loc,current))
|
||||
icon_state = "[tang]"
|
||||
del(src)
|
||||
return
|
||||
/*cleanup(reference) //Waits .3 seconds then removes the overlay.
|
||||
//world << "setting invisibility"
|
||||
sleep(50)
|
||||
src.invisibility = 101
|
||||
return*/
|
||||
on_hit(atom/target, blocked = 0)
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/M = target
|
||||
M.playsound_local(src, "explosion", 50, 1)
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam
|
||||
name = "laser"
|
||||
icon_state = "laser"
|
||||
|
||||
@@ -10,12 +10,32 @@
|
||||
if (..(target, blocked))
|
||||
var/mob/living/L = target
|
||||
shake_camera(L, 3, 2)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet
|
||||
damage = 10
|
||||
stun = 5
|
||||
weaken = 5
|
||||
|
||||
/obj/item/projectile/bullet/weakbullet/booze
|
||||
on_hit(var/atom/target, var/blocked = 0)
|
||||
if(..(target, blocked))
|
||||
var/mob/living/M = target
|
||||
M.dizziness += 20
|
||||
M:slurring += 20
|
||||
M.confused += 20
|
||||
M.eye_blurry += 20
|
||||
M.drowsyness += 20
|
||||
for(var/datum/reagent/ethanol/A in M.reagents.reagent_list)
|
||||
M.paralysis += 2
|
||||
M.dizziness += 10
|
||||
M:slurring += 10
|
||||
M.confused += 10
|
||||
M.eye_blurry += 10
|
||||
M.drowsyness += 10
|
||||
A.volume += 5 //Because we can
|
||||
|
||||
|
||||
/obj/item/projectile/bullet/midbullet
|
||||
damage = 20
|
||||
|
||||
@@ -362,6 +362,28 @@ datum
|
||||
M.sleeping += 1
|
||||
..()
|
||||
return
|
||||
chefspecial
|
||||
// Quiet and lethal, needs atleast 4 units in the person before they'll die
|
||||
name = "Chef's Special"
|
||||
id = "chefspecial"
|
||||
description = "An extremely toxic chemical that will surely end in death."
|
||||
reagent_state = LIQUID
|
||||
color = "#CF3600" // rgb: 207, 54, 0
|
||||
custom_metabolism = 0.39
|
||||
|
||||
on_mob_life(var/mob/living/M as mob)
|
||||
var/random = rand(150,180)
|
||||
if(!M) M = holder.my_atom
|
||||
if(!data) data = 1
|
||||
switch(data)
|
||||
if(0 to 5)
|
||||
..()
|
||||
if(data >= random)
|
||||
if(M.stat != DEAD)
|
||||
M.death(0)
|
||||
M.attack_log += "\[[time_stamp()]\]<font color='red'>Died a quick and painless death by <font color='green'>Chef Excellence's Special Sauce</font>.</font>"
|
||||
data++
|
||||
return
|
||||
|
||||
minttoxin
|
||||
name = "Mint Toxin"
|
||||
|
||||
@@ -125,6 +125,9 @@
|
||||
if("sugar")
|
||||
name = "Sugar"
|
||||
desc = "Tastey space sugar!"
|
||||
if("chefspecial")
|
||||
name = "Chef Excellence's Special Sauce"
|
||||
desc = "A potent sauce distilled from the toxin glands of 1000 Space Carp."
|
||||
else
|
||||
name = "Misc Condiment Bottle"
|
||||
if (reagents.reagent_list.len==1)
|
||||
@@ -171,4 +174,13 @@
|
||||
volume = 20
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("blackpepper", 20)
|
||||
reagents.add_reagent("blackpepper", 20)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/syndisauce
|
||||
name = "Chef Excellence's Special Sauce"
|
||||
desc = "A potent sauce distilled from the toxin glands of 1000 Space Carp with an extra touch of LSD because why not?"
|
||||
amount_per_transfer_from_this = 1
|
||||
volume = 20
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("chefspecial", 20)
|
||||
Reference in New Issue
Block a user