Massive traitor item overhaul

This commit is contained in:
ZomgPonies
2013-09-23 05:41:53 -04:00
parent 3720a8d690
commit b0aff645a3
52 changed files with 1530 additions and 647 deletions
+1
View File
@@ -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()
+6
View File
@@ -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."
-182
View File
@@ -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 &nbsp;&nbsp;No intact prints found"
else
user << "\blue &nbsp;&nbsp;Found [complete_prints.len] intact prints"
for(var/i in complete_prints)
user << "\blue &nbsp;&nbsp;&nbsp;&nbsp;[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
+3 -3
View File
@@ -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
+52 -5
View File
@@ -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>")
+22
View File
@@ -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
+3 -1
View File
@@ -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
+6
View File
@@ -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)
+2 -2
View File
@@ -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)
+3 -1
View File
@@ -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.
+12 -3
View File
@@ -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)