mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-29 00:46:13 +01:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
/obj/item/clothing/head/wig
|
||||
name = "toupée"
|
||||
desc = "You can't tell the difference, Honest!"
|
||||
icon_state= "wig"
|
||||
|
||||
/obj/item/clothing/head/bald_cap
|
||||
name = "bald cap"
|
||||
desc = "You can't tell the difference, Honest!"
|
||||
icon_state= "baldcap"
|
||||
item_state= "baldcap"
|
||||
|
||||
/obj/item/scissors
|
||||
name = "Scissors"
|
||||
desc = "Used to cut hair. Make sure you aim at the head, where the hair is."
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "scissors"
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
force = 10.0
|
||||
w_class = 1.0
|
||||
hit_type = DAMAGE_STAB
|
||||
hitsound = 'sound/effects/bloody_stab.ogg'
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
m_amt = 10000
|
||||
g_amt = 5000
|
||||
|
||||
suicide(var/mob/user as mob)
|
||||
user.visible_message("<span style=\"color:red\"><b>[user] slashes \his own throat with [src]!</b></span>")
|
||||
blood_slash(user, 25)
|
||||
user.TakeDamage("head", 150, 0)
|
||||
user.updatehealth()
|
||||
spawn(100)
|
||||
if (user)
|
||||
user.suiciding = 0
|
||||
return 1
|
||||
|
||||
/obj/item/razor_blade
|
||||
name = "Razor Blade"
|
||||
desc = "Used to cut facial hair"
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "razorblade"
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
force = 10.0
|
||||
w_class = 1.0
|
||||
hit_type = DAMAGE_CUT
|
||||
hitsound = 'sound/weapons/slashcut.ogg'
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
m_amt = 10000
|
||||
g_amt = 5000
|
||||
|
||||
suicide(var/mob/user as mob)
|
||||
user.visible_message("<span style=\"color:red\"><b>[user] slashes \his own throat with [src]!</b></span>")
|
||||
blood_slash(user, 25)
|
||||
user.TakeDamage("head", 150, 0)
|
||||
user.updatehealth()
|
||||
spawn(100)
|
||||
if (user)
|
||||
user.suiciding = 0
|
||||
return 1
|
||||
|
||||
/obj/item/dye_bottle
|
||||
name = "Hair Dye Bottle"
|
||||
desc = "Used to dye hair a different color. Seems to be made of tough, unshatterable plastic."
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "dye-e"
|
||||
flags = FPRINT | TABLEPASS
|
||||
//Default Colors
|
||||
var/customization_first_color = "#FFFFFF"
|
||||
var/empty = 1
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/hairgrowth
|
||||
name = "EZ-Hairgrowth"
|
||||
desc = "The #1 hair growth product on the market! WARNING: Some side effects may occur."
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "tonic1"
|
||||
New()
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("hairgrownium", 40)
|
||||
|
||||
on_reagent_change()
|
||||
src.icon_state = "tonic[src.reagents.total_volume ? "1" : "0"]"
|
||||
|
||||
/obj/stool/barber_chair
|
||||
name = "Barber Chair"
|
||||
desc = "Chair where hair can be cut"
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "barberchair"
|
||||
anchored = 1
|
||||
|
||||
/obj/barber_pole
|
||||
name = "Barber Pole"
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "pole"
|
||||
density = 1
|
||||
anchored = 1
|
||||
desc = "Barber poles historically were signage used to convey that the barber would perform services such as blood letting and other medical procedures, with the red representing blood, and the white representing the bandaging. In America, long after the time when blood-letting was offered, a third colour was added to bring it in line with the colours of their national flag. This one is in space."
|
||||
|
||||
///////////////////////////////////////////
|
||||
///////////Barber Chair Code///////////////
|
||||
///////////////////////////////////////////
|
||||
/obj/stool/barber_chair/MouseDrop_T(mob/M as mob, mob/user as mob)
|
||||
if (!ticker)
|
||||
boutput(user, "You can't buckle anyone in before the game starts.")
|
||||
return
|
||||
if ((!( iscarbon(M) ) || get_dist(src, user) > 1 || M.loc != src.loc || user.restrained() || usr.stat))
|
||||
return
|
||||
if (M == usr)
|
||||
user.visible_message("<span style=\"color:blue\">[M] buckles in!</span>", "<span style=\"color:blue\">You buckle yourself in.</span>")
|
||||
else
|
||||
user.visible_message("<span style=\"color:blue\">[M] is buckled in by [user].</span>", "<span style=\"color:blue\">You buckle in [M].</span>")
|
||||
M.anchored = 1
|
||||
M.buckled = src
|
||||
M.set_loc(src.loc)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/stool/barber_chair/attack_hand(mob/user as mob)
|
||||
for(var/mob/M in src.loc)
|
||||
if (M.buckled)
|
||||
if (M != user)
|
||||
user.visible_message("<span style=\"color:blue\">[M] is unbuckled by [user].</span>", "<span style=\"color:blue\">You unbuckle [M].</span>")
|
||||
else
|
||||
user.visible_message("<span style=\"color:blue\">[M] unbuckles.</span>", "<span style=\"color:blue\">You unbuckle.</span>")
|
||||
M.anchored = 0
|
||||
M.buckled = null
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/stool/barber_chair/ex_act(severity)
|
||||
for(var/mob/M in src.loc)
|
||||
if(M.buckled == src)
|
||||
M.buckled = null
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(5))
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/stool/barber_chair/blob_act(var/power)
|
||||
if(prob(power * 2.5))
|
||||
for(var/mob/M in src.loc)
|
||||
if(M.buckled == src)
|
||||
M.buckled = null
|
||||
qdel(src)
|
||||
/*
|
||||
/obj/stool/barber_chair/verb/rotate()
|
||||
set src in oview(1)
|
||||
set category = "Local"
|
||||
|
||||
src.dir = turn(src.dir, 90)
|
||||
if (src.dir == NORTH)
|
||||
src.layer = FLY_LAYER
|
||||
else
|
||||
src.layer = OBJ_LAYER
|
||||
return
|
||||
*/
|
||||
///////////////////////////////////////////////////
|
||||
//////Hair Dye Bottle Code ///////
|
||||
///////////////////////////////////////////////////
|
||||
/obj/item/dye_bottle/attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if(!istype(M,/mob/living/carbon/human)) return
|
||||
if(user.zone_sel.selecting != "head" || user.a_intent != "help")
|
||||
..()
|
||||
return
|
||||
if(src.empty)
|
||||
boutput(user, "<span style=\"color:red\">Bottle is empty!</span>")
|
||||
else //if(istype(M.buckled, /obj/stool/barber_chair))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.c_flags & COVERSEYES) || (H.wear_mask && H.wear_mask.c_flags & COVERSEYES)))
|
||||
// you can't stab someone in the eyes wearing a mask!
|
||||
boutput(user, "<span style=\"color:blue\">You're going to need to remove that mask/helmet first.</span>")
|
||||
return
|
||||
/*
|
||||
var/turf/T = M.loc
|
||||
var/turf/TM = user.loc
|
||||
boutput(user, "<span style=\"color:blue\">You begin dying [M]'s hair.</span>")
|
||||
boutput(M, "<span style=\"color:blue\">[user] begins dying your hair.</span>")
|
||||
sleep(30)
|
||||
if(M.loc == T && TM.loc == user.loc && (user.equipped() == src || istype(user, /mob/living/silicon)))
|
||||
return
|
||||
*/
|
||||
boutput(user, "<span style=\"color:blue\">You dye [M]'s hair.</span>")
|
||||
boutput(M, "<span style=\"color:blue\">[user] dyes your hair.</span>")
|
||||
M.bioHolder.mobAppearance.customization_first_color = src.customization_first_color
|
||||
M.bioHolder.mobAppearance.customization_second_color = src.customization_first_color
|
||||
M.set_face_icon_dirty()
|
||||
M.set_body_icon_dirty()
|
||||
M.update_clothing()
|
||||
src.empty = 1
|
||||
src.icon_state= "dye-e"
|
||||
//else
|
||||
// boutput(user, "<span style=\"color:red\">They need to be in a barber chair!</span>")
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////Scissors Code /////
|
||||
////////////////////////////////////////////////////
|
||||
/obj/item/scissors/attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if (src.remove_bandage(M, user))
|
||||
return
|
||||
|
||||
if(user.zone_sel.selecting != "head" || user.a_intent != "help")
|
||||
..()
|
||||
return
|
||||
|
||||
if (user == M)
|
||||
boutput(user, "<span style=\"color:red\">You can't cut your own hair!</span>")
|
||||
return
|
||||
|
||||
|
||||
if(istype(M.buckled, /obj/stool/barber_chair))
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.c_flags & COVERSEYES) || (H.wear_mask && H.wear_mask.c_flags & COVERSEYES) || (H.glasses && H.glasses.c_flags & COVERSEYES)))
|
||||
// you can't stab someone in the eyes wearing a mask!
|
||||
boutput(user, "<span style=\"color:blue\">You're going to need to remove that mask/helmet/glasses first.</span>")
|
||||
return
|
||||
|
||||
if(M.bioHolder.mobAppearance.customization_first == "None")
|
||||
boutput(user, "<span style=\"color:red\">There is nothing to cut!</span>")
|
||||
return
|
||||
|
||||
var/new_style = input(user, "Please select style", "Style") as null|anything in customization_styles
|
||||
|
||||
if (new_style)
|
||||
if(M.bioHolder.mobAppearance.customization_first == "Balding" && new_style != "None")
|
||||
boutput(user, "<span style=\"color:red\">Not enough hair!</span>")
|
||||
return
|
||||
|
||||
if(!new_style)
|
||||
return
|
||||
|
||||
var/turf/T = M.loc
|
||||
var/turf/TM = user.loc
|
||||
boutput(user, "<span style=\"color:blue\">You begin cutting [M]'s hair.</span>")
|
||||
boutput(M, "<span style=\"color:blue\">[user] begins cutting your hair.</span>")
|
||||
playsound(src.loc, "sound/items/Scissor.ogg", 100, 1)
|
||||
sleep(70)
|
||||
if(M.loc == T && TM.loc == user.loc && (user.equipped() == src || istype(user, /mob/living/silicon)))
|
||||
return
|
||||
|
||||
if (new_style == "None")
|
||||
var/obj/item/I = M.create_wig()
|
||||
I.set_loc(user.loc)
|
||||
|
||||
M.bioHolder.mobAppearance.customization_first = new_style
|
||||
boutput(M, "<span style=\"color:blue\">[user] cuts your hair.</span>")
|
||||
boutput(user, "<span style=\"color:blue\">you cut [M]'s hair.</span>")
|
||||
|
||||
M.cust_one_state = customization_styles[new_style]
|
||||
M.set_clothing_icon_dirty() // why the fuck is hair updated in clothing
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
////Razor Blade /////
|
||||
/////////////////////////////////////////////////////////
|
||||
/obj/item/razor_blade/attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if(scalpel_surgery(M,user)) return
|
||||
|
||||
if(user.zone_sel.selecting != "head" || user.a_intent != "help")
|
||||
..()
|
||||
return
|
||||
|
||||
if( istype(M, /mob/living/silicon))
|
||||
boutput(user, "<span style=\"color:red\">Shave a robot? Shave a robot!?? SHAVE A ROBOT?!?!??</span>")
|
||||
return
|
||||
|
||||
if(M.cust_two_state == "wiz")
|
||||
if (user == M)
|
||||
boutput(user, "<span style=\"color:red\">No!!! This is the worst idea you've ever had!</span>")
|
||||
return
|
||||
src.visible_message("<span style=\"color:red\"><b>[user]</b> quickly shaves off [M]'s beard!</span>")
|
||||
M.bioHolder.AddEffect("arcane_shame", timeleft = 120)
|
||||
M.bioHolder.mobAppearance.customization_second = "None"
|
||||
M.cust_two_state = "None"
|
||||
M.set_face_icon_dirty()
|
||||
M.emote("cry")
|
||||
return
|
||||
|
||||
if(istype(M.buckled, /obj/stool/barber_chair))
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.c_flags & COVERSEYES) || (H.wear_mask && H.wear_mask.c_flags & COVERSEYES) || (H.glasses && H.glasses.c_flags & COVERSEYES)))
|
||||
// you can't stab someone in the eyes wearing a mask!
|
||||
boutput(user, "<span style=\"color:blue\">You're going to need to remove that mask/helmet/glasses first.</span>")
|
||||
return
|
||||
|
||||
|
||||
if(M.bioHolder.mobAppearance.customization_second == "None")
|
||||
boutput(user, "<span style=\"color:red\">There is nothing to shave!</span>")
|
||||
return
|
||||
|
||||
var/new_style = input(user, "Please select facial style", "Facial Style") as null|anything in customization_styles
|
||||
|
||||
if (new_style)
|
||||
var/list/mustaches =list("Watson", "Chaplin", "Selleck", "Van Dyke", "Hogan")
|
||||
var/list/beards = list("Neckbeard", "Elvis", "Abe", "Chinstrap", "Hipster", "Wizard")
|
||||
var/list/full = list("Goatee", "Full Beard", "Long Beard")
|
||||
|
||||
if((new_style in full) && (!(M.bioHolder.mobAppearance.customization_second in full)))
|
||||
boutput(user, "<span style=\"color:red\">[M] doesn't have enough facial hair!</span>")
|
||||
return
|
||||
|
||||
if((new_style in beards) && (M.bioHolder.mobAppearance.customization_second in mustaches))
|
||||
boutput(user, "<span style=\"color:red\">[M] doesn't have a beard!</span>")
|
||||
return
|
||||
|
||||
if((new_style in mustaches) && (M.bioHolder.mobAppearance.customization_second in beards))
|
||||
boutput(user, "<span style=\"color:red\">[M] doesn't have a mustache!</span>")
|
||||
return
|
||||
|
||||
var/turf/T = M.loc
|
||||
var/turf/TM = user.loc
|
||||
boutput(user, "<span style=\"color:blue\">You begin shaving [M].</span>")
|
||||
boutput(M, "<span style=\"color:blue\">[user] begins shaving you.</span>")
|
||||
//playsound(src.loc, "Scissor.ogg", 100, 1)
|
||||
sleep(70)
|
||||
if(M.loc == T && TM.loc == user.loc && (user.equipped() == src || istype(user, /mob/living/silicon)))
|
||||
return
|
||||
|
||||
|
||||
M.bioHolder.mobAppearance.customization_second = new_style
|
||||
boutput(M, "<span style=\"color:blue\">[user] shaves your face</span>")
|
||||
boutput(user, "<span style=\"color:blue\">You shave [M]'s face.</span>")
|
||||
|
||||
M.cust_two_state = customization_styles[new_style]
|
||||
M.set_face_icon_dirty()
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
/////Dye Bottle Dispenser /////
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/obj/machinery/hair_dye_dispenser
|
||||
name = "Hair Dye Mixer 3000"
|
||||
desc = "Mixes hair dye for whatever color you want"
|
||||
icon = 'icons/obj/barber_shop.dmi'
|
||||
icon_state = "dyedispenser"
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
mats = 15
|
||||
|
||||
var/obj/item/dye_bottle/bottle = null
|
||||
|
||||
New()
|
||||
..()
|
||||
UnsubscribeProcess()
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
blob_act(var/power)
|
||||
if (prob(power * 1.25))
|
||||
qdel(src)
|
||||
|
||||
meteorhit()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
process()
|
||||
return
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
user.machine = src
|
||||
|
||||
var/dat = "<TT><B>Dye Bottle Dispenser Unit</B><BR><HR><BR>"
|
||||
|
||||
if(src.bottle)
|
||||
dat += {"Dye Bottle Loaded: <A href='?src=\ref[src];eject=1'>(Eject)</A><BR><BR><BR>Dye Color:<BR>"}
|
||||
|
||||
if(!src.bottle.empty)
|
||||
dat += "<A href='?src=\ref[src];emptyb=1'>Empty Dye Bottle</A><BR>"
|
||||
else
|
||||
dat += {"<A href='?src=\ref[src];fillb=1'>Fill Dye Bottle</A>"}
|
||||
else
|
||||
dat += "No Dye Bottle Loaded<BR>"
|
||||
|
||||
user << browse(dat, "window=dye_dispenser")
|
||||
onclose(user, "dye_dispenser")
|
||||
return
|
||||
|
||||
attackby(obj/item/W, mob/user as mob)
|
||||
if(istype(W, /obj/item/dye_bottle))
|
||||
if(src.bottle)
|
||||
boutput(user, "<span style=\"color:blue\">The dispenser already has a dye bottle in it.</span>")
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">You insert the dye bottle into the dispenser.</span>")
|
||||
if(W)
|
||||
user.drop_item(W)
|
||||
W.set_loc(src)
|
||||
src.bottle = W
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
Topic(href, href_list)
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
if(usr.stat || usr.restrained())
|
||||
return
|
||||
if (istype(usr, /mob/living/silicon/ai))
|
||||
boutput(usr, "<span style=\"color:red\">You are unable to dispense anything, since the controls are physical levers which don't go through any other kind of input.</span>")
|
||||
return
|
||||
|
||||
if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))))
|
||||
usr.machine = src
|
||||
|
||||
if (href_list["eject"])
|
||||
if(src.bottle)
|
||||
src.bottle.set_loc(src.loc)
|
||||
src.bottle = null
|
||||
|
||||
if(href_list["fillb"])
|
||||
if(src.bottle)
|
||||
var/new_dye = input(usr, "Please select hair color.", "Dye Color") as color
|
||||
if(new_dye)
|
||||
bottle.customization_first_color = new_dye
|
||||
bottle.empty = 0
|
||||
bottle.icon_state = "dye-f"
|
||||
src.updateDialog()
|
||||
if(href_list["emptyb"])
|
||||
if(src.bottle)
|
||||
bottle.empty = 1
|
||||
bottle.icon_state = "dye-e"
|
||||
src.updateDialog()
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
for(var/mob/M in viewers(1, src))
|
||||
if ((M.client && M.machine == src))
|
||||
src.attack_hand(M)
|
||||
else
|
||||
usr << browse(null, "window=dye_dispenser")
|
||||
return
|
||||
return
|
||||
@@ -0,0 +1,584 @@
|
||||
//Config stuff
|
||||
#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
|
||||
#define SUPPLY_STATIONZ 1 //Z-level of the Station.
|
||||
#define SUPPLY_POINTSPER 1 //Points per tick.
|
||||
#define SUPPLY_POINTDELAY 450 //Delay between ticks in milliseconds.
|
||||
#define SUPPLY_MOVETIME 1800 //Time to station is milliseconds. 1800 default
|
||||
#define SUPPLY_POINTSPERCRATE 10 //Points per crate sent back.
|
||||
|
||||
var/list/supply_requestlist = new/list()
|
||||
var/list/supply_history = new/list()
|
||||
var/supply_shuttle_can_send = 1
|
||||
var/supply_shuttle_time = 0
|
||||
var/supply_shuttle_timeleft = 0
|
||||
var/supply_shuttle_moving = 0
|
||||
var/supply_shuttle_at_station = 0
|
||||
var/door_id = "qm_dock"
|
||||
|
||||
/area/supply/spawn_point //the area supplies are spawned at and fired from
|
||||
name = "supply spawn point"
|
||||
icon_state = "shuttle3"
|
||||
luminosity = 1
|
||||
RL_Lighting = 0
|
||||
requires_power = 0
|
||||
|
||||
/area/supply/delivery_point //the area supplies are fired at
|
||||
name = "supply target point"
|
||||
icon_state = "shuttle3"
|
||||
luminosity = 1
|
||||
RL_Lighting = 0
|
||||
requires_power = 0
|
||||
|
||||
/area/supply/sell_point //the area where supplies move from the station z level
|
||||
name = "supply sell region"
|
||||
icon_state = "shuttle3"
|
||||
luminosity = 1
|
||||
RL_Lighting = 0
|
||||
requires_power = 0
|
||||
|
||||
Entered(var/atom/movable/AM)
|
||||
..()
|
||||
if(istype(AM,/obj/storage/crate))
|
||||
if(can_sell(AM))
|
||||
for(var/datum/trader/T in shippingmarket.active_traders)
|
||||
if (T.crate_tag == AM.delivery_destination)
|
||||
sell_to_trader(AM,T)
|
||||
return
|
||||
sell_crate(AM)
|
||||
|
||||
/obj/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY
|
||||
name = "Plastic flaps"
|
||||
desc = "I definitely cant get past those. no way."
|
||||
icon = 'icons/obj/stationobjs.dmi' //Change this.
|
||||
icon_state = "plasticflaps"
|
||||
density = 0
|
||||
anchored = 1
|
||||
layer = EFFECTS_LAYER_UNDER_1
|
||||
|
||||
/obj/plasticflaps/CanPass(atom/A, turf/T)
|
||||
if (istype(A, /mob/living)) // You Shall Not Pass!
|
||||
var/mob/living/M = A
|
||||
if(!M.lying) // unless you're lying down
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/plasticflaps/ex_act(severity)
|
||||
switch(severity)
|
||||
if (1)
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
if (3)
|
||||
if (prob(5))
|
||||
qdel(src)
|
||||
|
||||
/obj/marker/supplymarker
|
||||
icon_state = "X"
|
||||
icon = 'icons/misc/mark.dmi'
|
||||
name = "X"
|
||||
invisibility = 101
|
||||
anchored = 1
|
||||
opacity = 0
|
||||
|
||||
/proc/supply_ticker()
|
||||
wagesystem.shipping_budget += SUPPLY_POINTSPER
|
||||
spawn(SUPPLY_POINTDELAY) supply_ticker()
|
||||
|
||||
/proc/can_sell(var/obj/storage/crate/sellcrate)
|
||||
/*var/filterdead = 0
|
||||
if (shippingmarket.trader)
|
||||
if (shippingmarket.trader:goodsname == "corpses") filterdead = 1
|
||||
for(var/mob/living/M in sellcrate)
|
||||
if(filterdead && M.stat == 2) continue
|
||||
return 0
|
||||
for(var/atom/ATM in sellcrate)
|
||||
for(var/mob/living/N in ATM:contents)
|
||||
if(filterdead && N.stat == 2) continue
|
||||
return 0*/
|
||||
// Is this even necessary anymore?
|
||||
|
||||
return 1
|
||||
|
||||
/proc/sell_crate(var/obj/storage/crate/sell_crate)
|
||||
if (istype(sell_crate, /obj/storage/crate/biohazard/cdc))
|
||||
for (var/R in sell_crate)
|
||||
if (istype(R, /obj/item/reagent_containers) || istype(R, /mob/living/carbon/human)) //heh
|
||||
var/obj/item/reagent_containers/RC = R
|
||||
var/list/patho = RC.reagents.aggregate_pathogens()
|
||||
for (var/uid in patho)
|
||||
if (!(uid in QM_CDC.analysis_by_uid))
|
||||
var/datum/pathogen/P = patho[uid]
|
||||
var/datum/cdc_contact_analysis/D = new
|
||||
D.uid = uid
|
||||
var/sym_count = max(min(length(P.effects), 7), 2)
|
||||
D.time_factor = sym_count * rand(200, 600)
|
||||
D.cure_cost = sym_count * rand(2100, 4300)
|
||||
D.name = P.name
|
||||
var/rating = max(P.advance_speed, P.mutation_speed, P.mutativeness, P.suppression_threshold, P.maliciousness)
|
||||
var/ds = "weak"
|
||||
switch (P.stages)
|
||||
if (4)
|
||||
ds = "potent"
|
||||
if (5)
|
||||
ds = "deadly"
|
||||
var/df = "a relatively one-sided"
|
||||
switch (sym_count)
|
||||
if (3 to 4)
|
||||
df = "a somewhat colorful"
|
||||
if (5 to 6)
|
||||
df = "a rather diverse"
|
||||
if (7)
|
||||
df = "an incredibly symptomatic"
|
||||
D.desc = "It is [df] pathogen with a hazard rating of [rating]. We identify it to be a [ds] organism made up of [P.body_type.plural]. [P.suppressant.desc]"
|
||||
var/datum/pathogen/copy = unpool(/datum/pathogen)
|
||||
copy.setup(0, P, 0, null)
|
||||
D.assoc_pathogen = copy
|
||||
QM_CDC.analysis_by_uid[uid] = D
|
||||
QM_CDC.ready_to_analyze += D
|
||||
if (ishuman(RC))
|
||||
var/mob/living/carbon/human/H = RC
|
||||
H.ghostize()
|
||||
qdel(RC)
|
||||
qdel(sell_crate)
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Notification: Pathogen sample crate delivered to the CDC.")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
if(transmit_connection != null)
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
return
|
||||
|
||||
var/amount = 1
|
||||
// log account information for QM sales
|
||||
var/obj/item/card/id/scan = sell_crate.scan
|
||||
var/datum/data/record/account = sell_crate.account
|
||||
var/list/to_sell = new/list()
|
||||
for(var/obj/M in sell_crate.contents)
|
||||
amount = hasvar(M, "amount") && M:amount > 1 ? M:amount : 1
|
||||
if (isnum(to_sell.Find(M.type)))
|
||||
to_sell[M.type] += amount
|
||||
//boutput(world, "<span style=\"color:red\"><b> HEY I SHOULD BE SELLING [M.type]</b></span>")
|
||||
else
|
||||
to_sell[M.type] = amount
|
||||
//boutput(world, "<span style=\"color:red\"><b> [M.type] in the house</b></span>")
|
||||
qdel(M)
|
||||
qdel(sell_crate)
|
||||
var/duckets = 0 // fuck yeah duckets
|
||||
duckets += SUPPLY_POINTSPERCRATE
|
||||
|
||||
for(var/item_type in to_sell)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cogwerks - child types weren't inheriting their parent value properly, here is an ugly patch for the problem
|
||||
//boutput(world, "<b>PRESANITIZED SWITCH FOR [item_type]</b>") ////////////////////////////////////////////////////////
|
||||
var/sanitizer = item_type
|
||||
if(ispath(item_type, /obj/item/reagent_containers/food/snacks/ingredient/meat))
|
||||
sanitizer = /obj/item/reagent_containers/food/snacks/ingredient/meat
|
||||
if(ispath(item_type, /obj/item/reagent_containers/food/snacks/plant))
|
||||
sanitizer = /obj/item/reagent_containers/food/snacks/plant
|
||||
if(ispath(item_type, /obj/item/plant/herb))
|
||||
sanitizer = /obj/item/plant/herb
|
||||
if(ispath(item_type, /obj/item/electronics))
|
||||
sanitizer = /obj/item/electronics
|
||||
if(ispath(item_type, /obj/item/parts/robot_parts))
|
||||
sanitizer = /obj/item/parts/robot_parts
|
||||
if(ispath(item_type, /obj/item/sheet/steel))
|
||||
sanitizer = /obj/item/sheet/steel
|
||||
if(ispath(item_type, /obj/item/sheet/glass))
|
||||
sanitizer = /obj/item/sheet/glass
|
||||
//boutput(world, "[sanitizer] is our intermediary")
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////// add more ispath checks as needed, or get someone more competent to write a better workaround /////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var/datum/commodity/C = shippingmarket.commodities["[sanitizer]"]
|
||||
//boutput(world, "<b> WE ARE LOOKING FOR [item_type]")
|
||||
amount = to_sell[item_type]
|
||||
|
||||
if (C)
|
||||
//boutput(world, "<b> [C] should fetch [C.price]")
|
||||
if (C.indemand)
|
||||
//wagesystem.shipping_budget += amount * C.price * shippingmarket.demand_multiplier
|
||||
duckets += amount * C.price * shippingmarket.demand_multiplier
|
||||
//boutput(world, "<b> IN DEMAND: SELLING [amount] of [C] for [C.price] times [shippingmarket.demand_multiplier]</b>")
|
||||
else
|
||||
//wagesystem.shipping_budget += amount * C.price
|
||||
duckets += amount * C.price
|
||||
//boutput(world, "<b> NOT IN DEMAND: SELLING [amount] of [C] for [C.price]</b>")
|
||||
else
|
||||
//wagesystem.shipping_budget += amount
|
||||
duckets += amount
|
||||
//boutput(world, "<b> [C] NEVER SOLD RIGHT, FUCKIN HELL</b>")
|
||||
score_stuffshipped += amount
|
||||
if(scan && account)
|
||||
wagesystem.shipping_budget += duckets / 2
|
||||
account.fields["current_money"] += duckets / 2
|
||||
//////PDA NOTIFY/////
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Notification: [duckets] credits earned from last outgoing shipment. Splitting half of profits with [scan.registered].")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
if(transmit_connection != null)
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
//////////
|
||||
else
|
||||
wagesystem.shipping_budget += duckets
|
||||
//////PDA NOTIFY/////
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Notification: [duckets] credits earned from last outgoing shipment.")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
if(transmit_connection != null)
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
//////////
|
||||
|
||||
|
||||
////transaction is over ///
|
||||
|
||||
|
||||
/proc/sell_to_trader(var/obj/storage/crate/sellcrate,var/datum/trader/the_trader)
|
||||
//return
|
||||
|
||||
var/sellcount = 0
|
||||
var/amount = 1
|
||||
//var/sellmax = shippingmarket.trader:limit
|
||||
// log account information for QM sales // for some stupid reason this was getting a bad var bug and i have no idea why - cogwerks
|
||||
var/obj/item/card/id/scan = null
|
||||
if(sellcrate.scan)
|
||||
scan = sellcrate.scan
|
||||
var/datum/data/record/account = null
|
||||
if(sellcrate.account)
|
||||
account = sellcrate.account
|
||||
var/duckets = 0
|
||||
var/itemchecklimit = 0
|
||||
for(var/obj/M in sellcrate:contents)
|
||||
itemchecklimit++
|
||||
if (itemchecklimit > 50)
|
||||
break
|
||||
if (!the_trader)
|
||||
break
|
||||
//if (sellmax && (sellcount >= sellmax)) break
|
||||
/*if(ispath(M, /obj/item/reagent_containers/food/snacks/ingredient/meat))
|
||||
M = /obj/item/reagent_containers/food/snacks/ingredient/meat
|
||||
if(ispath(M, /obj/item/reagent_containers/food/snacks/plant))
|
||||
M = /obj/item/reagent_containers/food/snacks/plant
|
||||
if(ispath(M, /obj/item/plant/herb))
|
||||
M = /obj/item/plant/herb
|
||||
if(ispath(M, /obj/item/electronics))
|
||||
M = /obj/item/electronics
|
||||
if(ispath(M, /obj/item/parts/robot_parts))
|
||||
M = /obj/item/parts/robot_parts
|
||||
if(ispath(M, /obj/item/sheet/steel))
|
||||
M = /obj/item/sheet/steel
|
||||
if(ispath(M, /obj/item/sheet/glass))
|
||||
M = /obj/item/sheet/glass
|
||||
if(istype(M,shippingmarket.trader:tradegoods))
|
||||
amount = hasvar(M, "amount") && M:amount > 1 ? M:amount : 1
|
||||
duckets += amount * shippingmarket.trader:price
|
||||
score_stufftraded += amount
|
||||
sellcount++
|
||||
qdel(M)*/
|
||||
for(var/datum/commodity/C in the_trader.goods_buy)
|
||||
//if (M.type == C.comtype)
|
||||
if (istype(M,C.comtype))
|
||||
amount = hasvar(M, "amount") && M:amount > 1 ? M:amount : 1
|
||||
duckets += amount * C.price
|
||||
score_stufftraded += amount
|
||||
sellcount++
|
||||
qdel(M)
|
||||
|
||||
qdel(sellcrate)
|
||||
|
||||
if (sellcount)
|
||||
if(scan && account)
|
||||
wagesystem.shipping_budget += duckets / 2
|
||||
account.fields["current_money"] += duckets / 2
|
||||
//////PDA NOTIFY/////
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Deal with \"[the_trader.name]\" concluded. Net Profit: [duckets] credits. Splitting half of profits with [scan.registered].")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
if(transmit_connection != null)
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
//////////
|
||||
else
|
||||
wagesystem.shipping_budget += duckets
|
||||
//////PDA NOTIFY/////
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Deal with \"[the_trader.name]\" concluded. Net Profit: [duckets] credits.")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
if(transmit_connection != null)
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
|
||||
|
||||
|
||||
/*/proc/sell_corpses(var/obj/storage/crate/sellcrate)
|
||||
// special case sell proc for Vurdalak
|
||||
// he doesnt do this anymore it was a phase he was going through ok
|
||||
set background = 1
|
||||
var/sellcount = 0
|
||||
|
||||
var/sellmax = shippingmarket.trader:limit
|
||||
for(var/mob/living/carbon/I in sellcrate)
|
||||
if (sellmax && (sellcount >= sellmax)) break
|
||||
if (I.stat != 2)
|
||||
shippingmarket.trader = null
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Alert: \"[shippingmarket.trader:name]\" has abruptly rescinded their trade offer and left")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
return
|
||||
wagesystem.shipping_budget += shippingmarket.trader:price
|
||||
score_stufftraded += 1
|
||||
sellcount++
|
||||
if (I.mind || I.client) // if the player is waiting in the corpse, ghost them so we dont get respawn exploits
|
||||
var/mob/dead/observer/newmob = new/mob/dead/observer(I)
|
||||
if(I.client) I:client:mob = newmob
|
||||
I.mind.transfer_to(newmob)
|
||||
|
||||
spawn(0)
|
||||
qdel(I)
|
||||
qdel(sellcrate)
|
||||
if (sellcount)
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Deal with \"[shippingmarket.trader:name]\" concluded. Net Profit: [sellcount * shippingmarket.trader:price] credits")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
|
||||
shippingmarket.trader = null*/
|
||||
|
||||
// fuck it doing this with more globals
|
||||
var/crate_firing = 0
|
||||
|
||||
/proc/buy_thing(var/atom/movable/O as obj|mob)
|
||||
var/turf/spawnpoint
|
||||
for(var/turf/T in get_area_turfs(/area/supply/spawn_point))
|
||||
spawnpoint = T
|
||||
break
|
||||
|
||||
var/turf/target
|
||||
for(var/turf/T in get_area_turfs(/area/supply/delivery_point))
|
||||
target = T
|
||||
break
|
||||
|
||||
spawn(0)
|
||||
while(crate_firing)
|
||||
sleep(20)
|
||||
|
||||
if (!spawnpoint)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> No spawn turfs found! Can't deliver crate")
|
||||
return
|
||||
|
||||
if (!target)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> No target turfs found! Can't deliver crate")
|
||||
return
|
||||
|
||||
crate_firing = 1
|
||||
spawn(80)
|
||||
crate_firing = 0
|
||||
|
||||
O.set_loc(spawnpoint)
|
||||
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Shipment arriving to Cargo Bay: [O.name].")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
|
||||
for(var/obj/machinery/door/poddoor/P)
|
||||
if (P.id == door_id)
|
||||
playsound(P.loc, "sound/machines/bellalert.ogg", 50, 0)
|
||||
spawn(10)
|
||||
if (P && P.density)
|
||||
P.open()
|
||||
spawn(130)
|
||||
if (P && !P.density)
|
||||
P.close()
|
||||
|
||||
spawn(20)
|
||||
O.throw_at(target, 100, 1)
|
||||
|
||||
/proc/buy_from_trader(var/datum/trader/the_trader)
|
||||
//could be multiple possible spawn turfs
|
||||
var/turf/spawnpoint
|
||||
for(var/turf/T in get_area_turfs(/area/supply/spawn_point))
|
||||
spawnpoint = T
|
||||
break
|
||||
|
||||
//shouldn't be multiple delivery spots but it's possible
|
||||
var/turf/target
|
||||
for(var/turf/T in get_area_turfs(/area/supply/delivery_point))
|
||||
target = T
|
||||
break
|
||||
|
||||
if (!the_trader)
|
||||
return
|
||||
|
||||
the_trader.currently_selling = 1
|
||||
spawn(0)
|
||||
var/sanity = 0
|
||||
while(crate_firing && sanity < 30) // give up after 1 minute, should only take 15 seconds at most
|
||||
sleep(20)
|
||||
sanity++
|
||||
|
||||
if (sanity == 30)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> Timed out waiting to fire crate, what a bummer!")
|
||||
the_trader.currently_selling = 0
|
||||
return
|
||||
|
||||
if (!spawnpoint)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> No spawn turfs found! Can't deliver crate")
|
||||
the_trader.currently_selling = 0
|
||||
return
|
||||
|
||||
if (!target)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> No target turfs found! Can't deliver crate")
|
||||
the_trader.currently_selling = 0
|
||||
return
|
||||
|
||||
crate_firing = 1
|
||||
spawn(80)
|
||||
crate_firing = 0
|
||||
|
||||
var/atom/movable/A = new /obj/storage/crate(spawnpoint)
|
||||
A.name = "Goods Crate ([the_trader.name])"
|
||||
|
||||
/*var/putincrate = purchaseamt
|
||||
if (putincrate < 1) putincrate = 1
|
||||
if(prob(shippingmarket.trader:bullshit * 10)) // oh no! you got ripped off!
|
||||
while(putincrate > 1)
|
||||
new ourTrader.scamgoods(A)
|
||||
putincrate--
|
||||
else // a good deal
|
||||
while(putincrate > 1)
|
||||
new ourTrader.tradegoods(A)
|
||||
putincrate--*/
|
||||
|
||||
var/obj/item/paper/invoice = new /obj/item/paper(A)
|
||||
invoice.name = "Sale Invoice ([the_trader.name])"
|
||||
invoice.info = "Invoice of Sale from [the_trader.name]<br><br>"
|
||||
|
||||
var/total_price = 0
|
||||
for (var/datum/commodity/trader/C in the_trader.shopping_cart)
|
||||
if (!C.comtype || C.amount < 1) continue
|
||||
|
||||
total_price += C.price * C.amount
|
||||
invoice.info += "* [C.amount] units of [C.comname], [C.price * C.amount] credits<br>"
|
||||
var/putamount = C.amount
|
||||
while(putamount > 0)
|
||||
putamount--
|
||||
new C.comtype(A)
|
||||
invoice.info += "<br>Final Cost of Goods: [total_price] credits."
|
||||
|
||||
wagesystem.shipping_budget -= total_price
|
||||
|
||||
the_trader.wipe_cart(1) //This tells wipe_cart to not increase the amount in stock when clearing it out.
|
||||
the_trader.currently_selling = 0 //At this point the shopping cart has been processed
|
||||
|
||||
var/datum/radio_frequency/transmit_connection = radio_controller.return_frequency("1149")
|
||||
var/datum/signal/pdaSignal = get_free_signal()
|
||||
pdaSignal.data = list("address_1"="00000000", "command"="text_message", "sender_name"="CARGO-MAILBOT", "group"="cargo", "sender"="00000000", "message"="Deal with \"[the_trader.name]\" concluded. Total Cost: [total_price] credits")
|
||||
pdaSignal.transmission_method = TRANSMISSION_RADIO
|
||||
transmit_connection.post_signal(src, pdaSignal)
|
||||
|
||||
for(var/obj/machinery/door/poddoor/P)
|
||||
if (P.id == door_id)
|
||||
playsound(P.loc, "sound/machines/bellalert.ogg", 50, 0)
|
||||
spawn(10)
|
||||
if (P && P.density)
|
||||
P.open()
|
||||
spawn(130)
|
||||
if (P && !P.density)
|
||||
P.close()
|
||||
|
||||
spawn(20)
|
||||
A.throw_at(target, 100, 1)
|
||||
|
||||
/proc/process_supply_order(var/datum/supply_order/SO)
|
||||
//could be multiple possible spawn turfs
|
||||
var/turf/spawnpoint
|
||||
for(var/turf/T in get_area_turfs(/area/supply/spawn_point))
|
||||
spawnpoint = T
|
||||
break
|
||||
|
||||
//shouldn't be multiple delivery spots but it's possible
|
||||
var/turf/target
|
||||
for(var/turf/T in get_area_turfs(/area/supply/delivery_point))
|
||||
target = T
|
||||
break
|
||||
|
||||
spawn(0)
|
||||
var/sanity = 0
|
||||
while(crate_firing && sanity < 30) // give up after 1 minute, should only take 15 seconds at most
|
||||
sleep(20)
|
||||
sanity++
|
||||
|
||||
if (sanity == 30)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> Timed out waiting to fire crate, what a bummer!")
|
||||
return
|
||||
|
||||
if (!spawnpoint)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> No spawn turfs found! Can't deliver crate")
|
||||
return
|
||||
|
||||
if (!target)
|
||||
logTheThing("debug", null, null, "<b>Shipping: </b> No target turfs found! Can't deliver crate")
|
||||
return
|
||||
|
||||
crate_firing = 1
|
||||
spawn(80)
|
||||
crate_firing = 0
|
||||
|
||||
var/atom/movable/A = SO.create(spawnpoint)
|
||||
|
||||
for(var/obj/machinery/door/poddoor/P)
|
||||
if (P.id == door_id)
|
||||
playsound(P.loc, "sound/machines/bellalert.ogg", 50, 0)
|
||||
spawn(10)
|
||||
if (P && P.density)
|
||||
P.open()
|
||||
spawn(130)
|
||||
if (P && !P.density)
|
||||
P.close()
|
||||
|
||||
spawn(20)
|
||||
if (A)
|
||||
A.throw_at(target, 100, 1)
|
||||
/*
|
||||
#ifdef HALLOWEEN
|
||||
else if (halloween)
|
||||
halloween.throw_at(target, 100, 1)
|
||||
#endif
|
||||
*/
|
||||
proc/prisontothestation()
|
||||
if(turd_location == 0)
|
||||
var/area/start_location = locate(/area/shuttle/prison/prison)
|
||||
var/area/end_location = locate(/area/shuttle/prison/station)
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
for(var/turf/T in dstturfs)
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
if(istype(AM, /mob/dead))
|
||||
continue
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
turd_location = 1
|
||||
else
|
||||
if(turd_location == 1)
|
||||
var/area/start_location = locate(/area/shuttle/prison/prison)
|
||||
var/area/end_location = locate(/area/shuttle/prison/station)
|
||||
end_location.move_contents_to(start_location)
|
||||
turd_location = 0
|
||||
return
|
||||
@@ -0,0 +1,319 @@
|
||||
//NOTE:
|
||||
//This file contains the worst code ive ever written.
|
||||
//I dont fucking care. It looks pretty awesome.
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
/obj/dummy/liquid
|
||||
name = "water"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
invisibility = 101
|
||||
var/canmove = 1
|
||||
density = 0
|
||||
anchored = 1
|
||||
//
|
||||
/obj/item/reagent_containers/glass/vial
|
||||
|
||||
name = "glass test tube"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
desc = "an incredibly fragile glass test tube"
|
||||
icon_state = "vial0"
|
||||
item_state = "vial"
|
||||
throwforce = 3.0
|
||||
throw_speed = 1
|
||||
throw_range = 8
|
||||
force = 3.0
|
||||
w_class = 1.0
|
||||
|
||||
amount_per_transfer_from_this = 5
|
||||
flags = FPRINT | TABLEPASS | OPENCONTAINER
|
||||
|
||||
var/contained = null
|
||||
|
||||
New()
|
||||
var/datum/reagents/R = new/datum/reagents(30)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
|
||||
/obj/item/reagent_containers/glass/vial/green
|
||||
name = "glass test tube"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
desc = "a glass vial filled with a strange green liquid"
|
||||
icon_state = "vialgreen"
|
||||
item_state = "vialgreen"
|
||||
contained = /datum/ailment/disease/gbs
|
||||
|
||||
|
||||
/obj/item/reagent_containers/glass/blue
|
||||
name = "glass test tube"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
desc = "a glass vial filled with a shimmering blue liquid"
|
||||
icon_state = "vialblue"
|
||||
item_state = "vialblue"
|
||||
//This isn't a disease! I should make it one
|
||||
// contained = new
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////***
|
||||
/obj/item/reagent_containers/glass/vial/throw_impact(atom/hit_atom)
|
||||
..(hit_atom)
|
||||
src.shatter()
|
||||
|
||||
////////////////////////////////////////////////////////////////Generic Vial Shatter
|
||||
|
||||
/obj/item/reagent_containers/glass/vial/proc/shatter()
|
||||
var/A = src
|
||||
|
||||
var/atom/sourceloc = get_turf(src.loc)
|
||||
src = null
|
||||
qdel(A)
|
||||
var/obj/overlay/O = new /obj/overlay( sourceloc )
|
||||
var/obj/overlay/O2 = new /obj/overlay( sourceloc )
|
||||
O.name = "green liquid"
|
||||
O.density = 0
|
||||
O.anchored = 1
|
||||
O.icon = 'icons/effects/effects.dmi'
|
||||
O.icon_state = "greenshatter"
|
||||
O2.name = "broken bits of glass"
|
||||
O2.density = 0
|
||||
O2.anchored = 1
|
||||
O2.icon = 'icons/obj/objects.dmi'
|
||||
O2.icon_state = "shards"
|
||||
|
||||
if(istype(src.contained,/datum/ailment/))
|
||||
for(var/mob/living/carbon/H in view(5, sourceloc))
|
||||
H.contract_disease(src.contained,null,null,0)
|
||||
var/i
|
||||
for(i=0, i<5, i++)
|
||||
for(var/mob/living/carbon/H in view(5, sourceloc))
|
||||
H.contract_disease(src.contained,null,null,0)
|
||||
sleep(20)
|
||||
|
||||
flick("greenshatter2",O)
|
||||
O.icon_state = "nothing"
|
||||
sleep(5)
|
||||
qdel(O)
|
||||
return
|
||||
|
||||
//Generic Vial Drink
|
||||
/obj/item/reagent_containers/glass/vial/proc/drink(user)
|
||||
var/A = src
|
||||
|
||||
src = null
|
||||
qdel(A)
|
||||
if(istype(src.contained,/datum/ailment/))
|
||||
var/mob/living/M = user
|
||||
switch(pick(1,2))
|
||||
if(1)
|
||||
M.weakened += 5
|
||||
M.contract_disease(src.contained,null,null,1)
|
||||
if(2)
|
||||
spawn(200)
|
||||
M.contract_disease(src.contained,null,null,1)
|
||||
return
|
||||
|
||||
/obj/item/reagent_containers/glass/vial/blue/drink(user)
|
||||
var/A = src
|
||||
var/atom/sourceloc = get_turf(src.loc)
|
||||
src = null
|
||||
qdel(A)
|
||||
|
||||
var/obj/overlay/O = new /obj/overlay( sourceloc )
|
||||
var/obj/overlay/O2 = new /obj/overlay( sourceloc )
|
||||
|
||||
O.name = "green liquid"
|
||||
O.density = 0
|
||||
O.anchored = 1
|
||||
O.icon = 'icons/effects/effects.dmi'
|
||||
O.icon_state = "blueshatter"
|
||||
O2.name = "broken bits of glass"
|
||||
O2.density = 0
|
||||
O2.anchored = 1
|
||||
O2.icon = 'icons/obj/objects.dmi'
|
||||
O2.icon_state = "shards"
|
||||
|
||||
liquify(user)
|
||||
|
||||
sleep(20)
|
||||
flick("blueshatter2",O)
|
||||
O.icon_state = "nothing"
|
||||
sleep(5)
|
||||
qdel(O)
|
||||
|
||||
/obj/item/reagent_containers/glass/vial/blue/shatter()
|
||||
|
||||
var/A = src
|
||||
var/atom/sourceloc = get_turf(src.loc)
|
||||
src = null
|
||||
qdel(A)
|
||||
|
||||
var/obj/overlay/O = new /obj/overlay( sourceloc )
|
||||
var/obj/overlay/O2 = new /obj/overlay( sourceloc )
|
||||
|
||||
O.name = "green liquid"
|
||||
O.density = 0
|
||||
O.anchored = 1
|
||||
O.icon = 'icons/effects/effects.dmi'
|
||||
O.icon_state = "blueshatter"
|
||||
O2.name = "broken bits of glass"
|
||||
O2.density = 0
|
||||
O2.anchored = 1
|
||||
O2.icon = 'icons/obj/objects.dmi'
|
||||
O2.icon_state = "shards"
|
||||
|
||||
for(var/mob/living/carbon/human/H in view(1, sourceloc))
|
||||
liquify(H)
|
||||
|
||||
sleep(20)
|
||||
flick("blueshatter2",O)
|
||||
O.icon_state = "nothing"
|
||||
sleep(5)
|
||||
|
||||
qdel(O)
|
||||
|
||||
/mob/proc/drop_vial()
|
||||
var/obj/item/reagent_containers/glass/vial/W = src.equipped()
|
||||
if (W)
|
||||
u_equip(W)
|
||||
if (W)
|
||||
W.set_loc(src.loc)
|
||||
// W.dropped(src) Get rid of this as it would smash a vial
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
var/turf/T = get_turf(src.loc)
|
||||
T.Entered(W)
|
||||
return
|
||||
|
||||
/proc/liquify(var/mob/H, time = 150)
|
||||
|
||||
if(H.stat) return
|
||||
spawn(0)
|
||||
var/mobloc = get_turf(H.loc)
|
||||
var/obj/dummy/liquid/holder = new /obj/dummy/liquid( mobloc )
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc )
|
||||
animation.name = "water"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.icon_state = "liquify"
|
||||
animation.layer = MOB_EFFECT_LAYER
|
||||
animation.master = holder
|
||||
flick("liquify",animation)
|
||||
H.canmove = 0
|
||||
sleep(4)
|
||||
H.set_loc(holder)
|
||||
H.canmove = 1
|
||||
spawn(0)
|
||||
var/i
|
||||
for(i=0, i<10, i++)
|
||||
spawn(0)
|
||||
var/obj/effects/water/water1 = new /obj/effects/water( mobloc )
|
||||
var/direction = pick(alldirs)
|
||||
water1.name = "water"
|
||||
water1.density = 0
|
||||
water1.icon = 'icons/effects/water.dmi'
|
||||
water1.icon_state = "extinguish"
|
||||
for(i=0, i<pick(1,2,3), i++)
|
||||
sleep(5)
|
||||
step(water1,direction)
|
||||
spawn(20)
|
||||
qdel(water1)
|
||||
|
||||
sleep(time)
|
||||
H.canmove = 0
|
||||
mobloc = get_turf(H.loc)
|
||||
animation.set_loc(mobloc)
|
||||
var/b
|
||||
for(b=0, b<10, b++)
|
||||
spawn(0)
|
||||
var/turf = mobloc
|
||||
var/direction = pick(alldirs)
|
||||
var/c
|
||||
for(c=0, c<pick(1,2,3), c++)
|
||||
turf = get_step(turf,direction)
|
||||
var/obj/effects/water/water2 = new /obj/effects/water( turf )
|
||||
water2.name = "water"
|
||||
water2.icon = 'icons/effects/water.dmi'
|
||||
water2.icon_state = "extinguish"
|
||||
walk_to(water2,mobloc,-1,5)
|
||||
sleep(20)
|
||||
qdel(water2)
|
||||
|
||||
sleep(20)
|
||||
flick("reappear",animation)
|
||||
sleep(5)
|
||||
H.set_loc(mobloc)
|
||||
H.canmove = 1
|
||||
qdel(animation)
|
||||
qdel(holder)
|
||||
|
||||
|
||||
/obj/dummy/liquid/relaymove(var/mob/user, direction)
|
||||
if (!src.canmove) return
|
||||
//writing my own movement because step is broken.
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
src.y++
|
||||
if(SOUTH)
|
||||
src.y--
|
||||
if(EAST)
|
||||
src.x++
|
||||
if(WEST)
|
||||
src.x--
|
||||
if(NORTHEAST)
|
||||
src.y++
|
||||
src.x++
|
||||
if(NORTHWEST)
|
||||
src.y++
|
||||
src.x--
|
||||
if(SOUTHEAST)
|
||||
src.y--
|
||||
src.x++
|
||||
if(SOUTHWEST)
|
||||
src.y--
|
||||
src.x--
|
||||
src.canmove = 0
|
||||
spawn(20) canmove = 1
|
||||
|
||||
/obj/dummy/liquid/ex_act(blah)
|
||||
return
|
||||
/obj/dummy/liquid/bullet_act(blah,blah)
|
||||
return
|
||||
|
||||
|
||||
///atom/relaymove - change to obj to restore
|
||||
|
||||
/obj/relaymove(var/mob/user, direction) //testing something
|
||||
//if(anchored) return
|
||||
//step(src, direction)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////blue
|
||||
/*
|
||||
/obj/testtuberack
|
||||
name = "test tube rack"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "clipboard00"
|
||||
|
||||
attackby(obj/item/W, mob/user as mob)
|
||||
if (src.contents.len >= 7)
|
||||
boutput(user, "<span style=\"color:blue\">The test tube rack is full</span>")
|
||||
return
|
||||
if(istype(W, /obj/item/reagent_containers/glass/vial))
|
||||
boutput(user, "<span style=\"color:blue\">You insert the test tube into the test tube rack</span>")
|
||||
user.drop_vial()
|
||||
W.set_loc(src)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(src.contents.len > 0)
|
||||
boutput(user, "<span style=\"color:blue\">You slide a random test tube carefully out of the rack</span>")
|
||||
var/obj/item/reagent_containers/glass/vial/V = pick(src.contents)
|
||||
src.contents -= V
|
||||
V.set_loc(src.loc)
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">There are no test tubes in the rack</span>")
|
||||
return
|
||||
*/
|
||||
@@ -0,0 +1,487 @@
|
||||
// Includes:
|
||||
// - Airbridge controllers
|
||||
// - Airbridge computers
|
||||
// - Airbridge test buttons
|
||||
// - Dummy turfs
|
||||
|
||||
//air bridge controlers of the same id will automatically establish and destroy air bridges between each other if told to.
|
||||
//air bridges have a width of 3 not including the walls.
|
||||
//dont create more than 2 controlers with the same id or stuff will break. And itll be your fault.
|
||||
//Also, make sure the bridges can extend in a straight line. Or you're gonna have a really bad time
|
||||
|
||||
var/global/list/airbridge_controllers = list()
|
||||
|
||||
/* -------------------- Controller -------------------- */
|
||||
|
||||
/obj/airbridge_controler
|
||||
name = "Airbridge Controller"
|
||||
desc = "This is an invisible thing. Yet you can see it. You notice reality unraveling around you."
|
||||
icon = 'icons/misc/mark.dmi'
|
||||
icon_state = "airbr"
|
||||
invisibility = 99
|
||||
anchored = 1
|
||||
density = 0
|
||||
|
||||
var/tunnel_width = 1
|
||||
var/id = "noodles"
|
||||
var/working = 0
|
||||
var/maintaining_bridge = 0
|
||||
var/obj/airbridge_controler/linked = null
|
||||
|
||||
var/list/path = new/list()
|
||||
var/list/maintaining_turfs = new/list()
|
||||
|
||||
var/primary_controller = 0 // if 1, the bridge extends from this controller to the other one when toggled by an airbridge computer
|
||||
// ONLY SET ONE CONTROLLER TO 1 OR IT'S TOTALLY POINTLESS
|
||||
|
||||
New()
|
||||
airbridge_controllers += src
|
||||
..()
|
||||
|
||||
proc/get_link()
|
||||
for(var/obj/airbridge_controler/C in world)
|
||||
if(C.z == src.z && C.id == src.id && C != src)
|
||||
linked = C
|
||||
break
|
||||
|
||||
proc/toggle_bridge()
|
||||
if(linked == null) get_link()
|
||||
if(linked == null) return
|
||||
|
||||
if(linked.maintaining_bridge)
|
||||
return linked.remove_bridge()
|
||||
else if(maintaining_bridge)
|
||||
return linked.remove_bridge()
|
||||
else
|
||||
return establish_bridge()
|
||||
|
||||
proc/pressurize()
|
||||
if(linked == null) get_link()
|
||||
if(linked == null) return
|
||||
|
||||
if(linked.working || working) return
|
||||
if(!linked.maintaining_bridge && !maintaining_bridge) return
|
||||
|
||||
if(!maintaining_turfs.len) return
|
||||
|
||||
working = 1
|
||||
|
||||
spawn(0)
|
||||
sleep(50)
|
||||
|
||||
for(var/turf/simulated/T in maintaining_turfs)
|
||||
if(!T.air && T.density)
|
||||
continue
|
||||
T.air.toxins = 0
|
||||
T.air.toxins_archived = null
|
||||
T.air.oxygen = MOLES_O2STANDARD
|
||||
T.air.oxygen_archived = null
|
||||
T.air.carbon_dioxide = 0
|
||||
T.air.carbon_dioxide_archived = null
|
||||
T.air.nitrogen = MOLES_N2STANDARD
|
||||
T.air.nitrogen_archived = null
|
||||
T.air.fuel_burnt = 0
|
||||
T.air.trace_gases = null
|
||||
T.air.temperature = T20C
|
||||
T.air.temperature_archived = null
|
||||
sleep(-1)
|
||||
|
||||
working = 0
|
||||
|
||||
return
|
||||
|
||||
proc/get_state_string()
|
||||
if(linked == null) get_link()
|
||||
if(linked == null) return "ERROR: Connection to secondary Airbridge controller lost."
|
||||
|
||||
if(linked.working || working) return "Airbridge controller working. Please wait."
|
||||
if(linked.maintaining_bridge || maintaining_bridge) return "Airbridge established."
|
||||
if(!linked.maintaining_bridge && !maintaining_bridge) return "No active Airbridge."
|
||||
|
||||
return "Unknown State."
|
||||
|
||||
proc/is_working()
|
||||
if(linked == null) get_link()
|
||||
if(linked == null) return 0
|
||||
|
||||
if(linked.working || working) return 1
|
||||
else return 0
|
||||
|
||||
proc/establish_bridge()
|
||||
if(linked == null) get_link()
|
||||
if(linked == null) return
|
||||
|
||||
if(linked.working || working) return
|
||||
if(linked.maintaining_bridge || maintaining_bridge) return
|
||||
|
||||
working = 1
|
||||
maintaining_bridge = 1
|
||||
|
||||
spawn(0)
|
||||
path.Cut()
|
||||
|
||||
var/turf/current = src.loc
|
||||
path.Add(current)
|
||||
var/direction = get_dir(current, get_step(current,get_dir(current, linked.loc)))
|
||||
path[current] = direction
|
||||
|
||||
while(current != linked.loc)
|
||||
var/previous = current
|
||||
current = get_step(current,get_dir(current, linked.loc))
|
||||
path.Add(current)
|
||||
direction = get_dir(previous,current)
|
||||
path[current] = direction
|
||||
|
||||
for(var/turf/T in path)
|
||||
var/list/added = list()
|
||||
var/turf/curr = new/turf/simulated/shuttle/floor { RL_Ignore = 1 } (T)
|
||||
maintaining_turfs.Add(curr)
|
||||
added.Add(curr)
|
||||
|
||||
for(var/i = 1, i <= tunnel_width, i++)
|
||||
|
||||
if(i == tunnel_width)
|
||||
curr = new/turf/simulated/shuttle/wall/destroyable { RL_Ignore = 1 } ( get_steps(T, turn(path[T], 90),i) )
|
||||
maintaining_turfs.Add(curr)
|
||||
added.Add(curr)
|
||||
|
||||
curr = new/turf/simulated/shuttle/wall/destroyable { RL_Ignore = 1 } ( get_steps(T, turn(path[T], -90),i) )
|
||||
maintaining_turfs.Add(curr)
|
||||
added.Add(curr)
|
||||
|
||||
else
|
||||
curr = new/turf/simulated/shuttle/floor { RL_Ignore = 1 } ( get_steps(T, turn(path[T], 90),i) )
|
||||
maintaining_turfs.Add(curr)
|
||||
added.Add(curr)
|
||||
|
||||
curr = new/turf/simulated/shuttle/floor { RL_Ignore = 1 } ( get_steps(T, turn(path[T], -90),i) )
|
||||
maintaining_turfs.Add(curr)
|
||||
added.Add(curr)
|
||||
|
||||
//Please don't look at the following stuff or you might forget how to code properly.
|
||||
if(path.Find(T) != path.len)
|
||||
for(var/turf/A in added)
|
||||
var/obj/shuttledummy/D = null
|
||||
|
||||
if(A.density)
|
||||
D = new/obj/shuttledummy/wall(A)
|
||||
else
|
||||
D = new/obj/shuttledummy/floor(A)
|
||||
|
||||
if(added.Find(A) == added.len)
|
||||
if(D.slide(path[T]))
|
||||
D.layer = 3 // TODO LAYER
|
||||
spawn(20) qdel(D)
|
||||
else
|
||||
spawn(0)
|
||||
if(D && D.slide(path[T]))
|
||||
D.layer = 3 // TODO LAYER
|
||||
spawn(20) qdel(D)
|
||||
|
||||
playsound(T, "sound/effects/airbridge_dpl.ogg", 50, 1)
|
||||
sleep(1)
|
||||
|
||||
working = 0
|
||||
|
||||
return
|
||||
|
||||
proc/remove_bridge()
|
||||
if(linked == null) get_link()
|
||||
if(linked == null) return
|
||||
|
||||
if(linked.working || working) return
|
||||
if(!linked.maintaining_bridge && !maintaining_bridge) return
|
||||
|
||||
if(!maintaining_bridge && linked.maintaining_bridge)
|
||||
linked.remove_bridge()
|
||||
return
|
||||
|
||||
working = 1
|
||||
maintaining_bridge = 0
|
||||
playsound(src.loc, "sound/machines/warning-buzzer.ogg", 50, 1)
|
||||
|
||||
spawn(20)
|
||||
var/list/path_reverse = reverse_list(path)
|
||||
|
||||
for(var/turf/T in path_reverse)
|
||||
maintaining_turfs.Add(new/turf/space(T))
|
||||
harmless_smoke_puff(T)
|
||||
for(var/i = 1, i <= tunnel_width, i++)
|
||||
maintaining_turfs.Add(new/turf/space( get_steps(T, turn(path[T], 90),i) ) )
|
||||
//new/obj/effects/harmless_smoke(get_steps(T, turn(path[T], 90),i))
|
||||
maintaining_turfs.Add(new/turf/space( get_steps(T, turn(path[T], -90),i) ) )
|
||||
//new/obj/effects/harmless_smoke(get_steps(T, turn(path[T], -90),i))
|
||||
|
||||
playsound(T, "sound/effects/airbridge_dpl.ogg", 50, 1)
|
||||
|
||||
sleep(7)
|
||||
|
||||
maintaining_turfs.Cut()
|
||||
working = 0
|
||||
|
||||
return
|
||||
|
||||
/* -------------------- Computer -------------------- */
|
||||
|
||||
|
||||
/obj/machinery/computer/airbr
|
||||
name = "Airbridge Computer"
|
||||
desc = "Used to control the airbridge."
|
||||
var/id = "noodles"
|
||||
icon_state = "airbr0"
|
||||
|
||||
// set this var to 1 in the map editor if you want the airbridge to establish and pressurize when the round starts
|
||||
// only do it to ONE of the computers for the airbridge ID or they will both try to do it and get confused
|
||||
var/starts_established = 0
|
||||
|
||||
var/working = 0
|
||||
var/state_str = ""
|
||||
|
||||
req_access = list(access_heads)
|
||||
|
||||
var/list/links = list()
|
||||
|
||||
var/obj/airbridge_controler/primary_controller = null
|
||||
|
||||
var/emergency = 0 // 1 to automatically extend when the emergency shuttle docks
|
||||
|
||||
New()
|
||||
..()
|
||||
if (src.emergency && emergency_shuttle) // emergency_shuttle is the controller datum
|
||||
emergency_shuttle.airbridges += src
|
||||
|
||||
proc/get_links()
|
||||
if (!airbridge_controllers.len)
|
||||
return
|
||||
for (var/obj/airbridge_controler/C in airbridge_controllers)//world)
|
||||
if (C.id == src.id)
|
||||
links.Add(C)
|
||||
if (C.primary_controller)
|
||||
src.primary_controller = C
|
||||
|
||||
process()
|
||||
..()
|
||||
update_status()
|
||||
if (starts_established && links.len)
|
||||
spawn(10)
|
||||
do_initial_extend()
|
||||
return
|
||||
|
||||
proc/pick_controller()
|
||||
if (istype(src.primary_controller))
|
||||
return src.primary_controller
|
||||
var/obj/airbridge_controler/C = pick(links)
|
||||
if (istype(C))
|
||||
return C
|
||||
|
||||
proc/do_initial_extend()
|
||||
var/obj/airbridge_controler/C = src.pick_controller()
|
||||
if (!istype(C))
|
||||
return
|
||||
|
||||
C.establish_bridge()
|
||||
|
||||
var/sanity_counter = 0
|
||||
while (C.working && sanity_counter < 30)
|
||||
sanity_counter++
|
||||
sleep(20)
|
||||
|
||||
C.pressurize()
|
||||
starts_established = 0
|
||||
|
||||
proc/update_status()
|
||||
if (!links.len)
|
||||
get_links()
|
||||
|
||||
if (!links.len)
|
||||
working = 0
|
||||
starts_established = 0
|
||||
state_str = "ERROR: No controlers found."
|
||||
return
|
||||
|
||||
var/obj/airbridge_controler/C = src.pick_controller()
|
||||
if (!istype(C))
|
||||
return
|
||||
working = C.is_working()
|
||||
icon_state = "airbr[working]"
|
||||
state_str = C.get_state_string()
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
if (..(user))
|
||||
return
|
||||
|
||||
update_status()
|
||||
|
||||
var/dat = ""
|
||||
dat += "<b>Controller Status:</b><BR>"
|
||||
dat += "[state_str]<BR>"
|
||||
dat += "[working ? "Working..." : "Idle..."]<BR><BR>"
|
||||
dat += "<b>Airbridge Control:</b><BR>"
|
||||
dat += "<A href='?src=\ref[src];create=1'>Establish</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];remove=1'>Retract</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];air=1'>Pressurize</A><BR>"
|
||||
|
||||
user.machine = src
|
||||
user << browse("<TITLE>Airbridge Computer</TITLE><BR>[dat]", "window=t_computer;size=400x300")
|
||||
onclose(user, "airbr_computer")
|
||||
return
|
||||
|
||||
proc/ensure_links()
|
||||
if (!src.links.len)
|
||||
src.get_links()
|
||||
if (!src.links.len)
|
||||
src.working = 0
|
||||
src.state_str = "ERROR: No controllers found."
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
proc/establish_bridge()
|
||||
if (!src.ensure_links())
|
||||
return 0
|
||||
var/obj/airbridge_controler/C = src.pick_controller()
|
||||
if (istype(C))
|
||||
C.establish_bridge()
|
||||
return 1
|
||||
|
||||
proc/remove_bridge()
|
||||
if (!src.ensure_links())
|
||||
return 0
|
||||
var/obj/airbridge_controler/C = src.pick_controller()
|
||||
if (istype(C))
|
||||
C.remove_bridge()
|
||||
return 1
|
||||
|
||||
proc/pressurize()
|
||||
if (!src.ensure_links())
|
||||
return 0
|
||||
var/obj/airbridge_controler/C = src.pick_controller()
|
||||
if (istype(C))
|
||||
C.pressurize()
|
||||
return 1
|
||||
|
||||
Topic(href, href_list)
|
||||
if (..(href, href_list))
|
||||
return
|
||||
|
||||
if (href_list["create"])
|
||||
if (src.emergency && emergency_shuttle)
|
||||
if (emergency_shuttle.location != SHUTTLE_LOC_STATION)
|
||||
boutput(usr, "<span style=\"color:red\">The airbridge cannot be deployed while the shuttle is not in position.</span>")
|
||||
return
|
||||
if (!(src.allowed(usr, req_only_one_required)))
|
||||
boutput(usr, "<span style=\"color:red\">Access denied.</span>")
|
||||
return
|
||||
if (src.establish_bridge())
|
||||
logTheThing("station", usr, null, "extended the airbridge at [usr.loc.loc] ([showCoords(usr.x, usr.y, usr.z)])")
|
||||
|
||||
else if (href_list["remove"])
|
||||
if (!(src.allowed(usr, req_only_one_required)))
|
||||
boutput(usr, "<span style=\"color:red\">Access denied.</span>")
|
||||
return
|
||||
if (src.remove_bridge())
|
||||
logTheThing("station", usr, null, "retracted the airbridge at [usr.loc.loc] ([showCoords(usr.x, usr.y, usr.z)])")
|
||||
|
||||
else if (href_list["air"])
|
||||
if (!(src.allowed(usr, req_only_one_required)))
|
||||
boutput(usr, "<span style=\"color:red\">Access denied.</span>")
|
||||
return
|
||||
if (src.pressurize())
|
||||
logTheThing("station", usr, null, "pressurized the airbridge at [usr.loc.loc] ([showCoords(usr.x, usr.y, usr.z)])")
|
||||
|
||||
update_status()
|
||||
usr << browse(null, "window=airbr_computer")
|
||||
//src.updateUsrDialog()
|
||||
src.updateDialog()
|
||||
return
|
||||
|
||||
power_change()
|
||||
if(stat & BROKEN)
|
||||
icon_state = "airbrbr"
|
||||
light.disable()
|
||||
|
||||
else if(powered())
|
||||
icon_state = "airbr0"
|
||||
stat &= ~NOPOWER
|
||||
light.enable()
|
||||
else
|
||||
spawn(rand(0, 15))
|
||||
icon_state = "airbroff"
|
||||
stat |= NOPOWER
|
||||
light.disable()
|
||||
set_broken()
|
||||
if (stat & BROKEN) return
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, src)
|
||||
smoke.start()
|
||||
icon_state = initial(icon_state)
|
||||
icon_state = "airbrbr"
|
||||
light.disable()
|
||||
stat |= BROKEN
|
||||
|
||||
/obj/machinery/computer/airbr/emergency_shuttle
|
||||
icon = 'icons/obj/airtunnel.dmi'
|
||||
emergency = 1
|
||||
|
||||
/* -------------------- Button -------------------- */
|
||||
|
||||
/obj/machinery/airbr_test_button
|
||||
name = "Airbridge Button"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "launcherbtt"
|
||||
desc = ""
|
||||
var/id = "noodles"
|
||||
var/state = 0
|
||||
anchored = 1.0
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
for(var/obj/airbridge_controler/C in range(3, src))
|
||||
boutput(usr, "<span style=\"color:blue\">[C.toggle_bridge()]</span>")
|
||||
break
|
||||
return
|
||||
|
||||
/* -------------------- Dummy Turfs -------------------- */
|
||||
|
||||
/obj/shuttledummy
|
||||
desc = ""
|
||||
density = 0
|
||||
opacity = 1
|
||||
anchored = 1
|
||||
layer = FLOOR_EQUIP_LAYER1
|
||||
proc/slide(var/direction)
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
while(pixel_y < 32)
|
||||
pixel_y += 4
|
||||
sleep(1)
|
||||
return 1
|
||||
if(SOUTH)
|
||||
while(pixel_y > -32)
|
||||
pixel_y -= 4
|
||||
sleep(1)
|
||||
return 1
|
||||
if(EAST)
|
||||
while(pixel_x < 32)
|
||||
pixel_x += 4
|
||||
sleep(1)
|
||||
return 1
|
||||
if(WEST)
|
||||
while(pixel_x > -32)
|
||||
pixel_x -= 4
|
||||
sleep(1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/shuttledummy/wall
|
||||
name = "wall"
|
||||
icon = 'icons/turf/shuttle.dmi'
|
||||
icon_state = "wall"
|
||||
density = 1
|
||||
opacity = 1
|
||||
|
||||
/obj/shuttledummy/floor
|
||||
name = "floor"
|
||||
icon = 'icons/turf/shuttle.dmi'
|
||||
icon_state = "floor"
|
||||
density = 1
|
||||
opacity = 0
|
||||
@@ -0,0 +1,29 @@
|
||||
/obj/alien
|
||||
name = "alien thing"
|
||||
desc = "theres something alien about this"
|
||||
icon = 'alien.dmi'
|
||||
|
||||
/obj/alien/head
|
||||
name = "severed head"
|
||||
desc = "a severed head..."
|
||||
icon_state = "weeds"
|
||||
|
||||
density = 0
|
||||
anchored = 0
|
||||
|
||||
/obj/alien/skin_suit
|
||||
name = "skin"
|
||||
desc = "a persons skin, disgusting"
|
||||
icon_state = "weeds"
|
||||
|
||||
density = 0
|
||||
anchored = 0
|
||||
|
||||
/obj/alien/resin
|
||||
name = "resin"
|
||||
desc = "Looks like some kind of slimy growth."
|
||||
icon_state = "resin"
|
||||
|
||||
density = 0
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
|
||||
Better way to do this might be to make it a verb on a person and to cocoon the person in some kind of resin
|
||||
If they're next to a wall this would change their pixel and attach them to the wall, otherwise it'd cause
|
||||
Them to lie down and attach them to the floor, this could be easily done by changing the bed code.
|
||||
|
||||
This would mean having a variable affected_mob or something that we could keep the person stunned/alive while
|
||||
they're trapped
|
||||
*/
|
||||
/obj/alien/cocoon
|
||||
name = "cocoon"
|
||||
desc = "a strange... something..."
|
||||
density = 1.0
|
||||
anchored = 1.0
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "toilet"
|
||||
|
||||
var/health = 10
|
||||
|
||||
MouseDrop_T(mob/M as mob, mob/user as mob)
|
||||
if (!ticker)
|
||||
boutput(user, "You can't buckle anyone in before the game starts.")
|
||||
return
|
||||
if ((!( istype(M, /mob) ) || get_dist(src, user) > 1 || user.restrained() || usr.stat))
|
||||
return
|
||||
for(var/mob/O in viewers(user, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
boutput(O, text("<span style=\"color:blue\">[M] is absorbed by the cocoon!</span>"))
|
||||
M.anchored = 1
|
||||
M.buckled = src
|
||||
M.set_loc(src.loc)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(health <= 0)
|
||||
for(var/mob/M in src.loc)
|
||||
if (M.buckled)
|
||||
src.visible_message("<span style=\"color:blue\">[M] appears from the cocoon.</span>")
|
||||
// boutput(world, "[M] is no longer buckled to [src]")
|
||||
M.anchored = 0
|
||||
M.buckled = null
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.health <= 0)
|
||||
src.visible_message("<span style=\"color:red\"><B>[user] has destroyed the cocoon.</B></span>")
|
||||
src.death()
|
||||
return
|
||||
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
src.health -= W.force * 0.75
|
||||
if("brute")
|
||||
src.health -= W.force * 0.1
|
||||
else
|
||||
..()
|
||||
|
||||
proc/death()
|
||||
src.icon_state = "egg_destroyed" //need an icon for this
|
||||
src.density = 0
|
||||
@@ -0,0 +1,38 @@
|
||||
/obj/alien/egg
|
||||
desc = "It looks like a weird egg"
|
||||
name = "egg"
|
||||
icon_state = "egg"
|
||||
layer = MOB_LAYER
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
var/health = 25
|
||||
|
||||
New()
|
||||
spawn(900)
|
||||
if(src.health > 0)
|
||||
src.open()
|
||||
|
||||
proc/open()
|
||||
spawn(10)
|
||||
src.density = 0
|
||||
src.icon_state = "egg_hatched"
|
||||
new /obj/alien/facehugger(src.loc)
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.health <= 0)
|
||||
src.visible_message("<span style=\"color:red\"><B>[user] has destroyed the egg!</B></span>")
|
||||
src.death()
|
||||
return
|
||||
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
src.health -= W.force * 0.75
|
||||
if("brute")
|
||||
src.health -= W.force * 0.1
|
||||
else
|
||||
..()
|
||||
|
||||
proc/death()
|
||||
src.icon_state = "egg_destroyed" //need an icon for this
|
||||
src.density = 0
|
||||
@@ -0,0 +1,385 @@
|
||||
#define cycle_pause 5 //min 1
|
||||
#define viewrange 7 //min 2
|
||||
|
||||
|
||||
|
||||
|
||||
// Returns the surrounding cardinal turfs with open links
|
||||
// Including through doors openable with the ID
|
||||
// Includes spacetiles
|
||||
/turf/proc/CardinalTurfsWithAccessSpace(var/obj/item/card/id/ID)
|
||||
var/L[] = new()
|
||||
for(var/d in cardinal)
|
||||
var/turf/simulated/T = get_step(src, d)
|
||||
if((istype(T) || istype(T,/turf/space))&& !T.density)
|
||||
if(!LinkBlockedWithAccess(src, T, ID))
|
||||
L.Add(T)
|
||||
return L
|
||||
|
||||
|
||||
|
||||
/obj/alien/facehugger
|
||||
name = "alien"
|
||||
desc = "An alien, looks pretty scary!"
|
||||
icon_state = "facehugger"
|
||||
layer = MOB_LAYER
|
||||
density = 1
|
||||
anchored = 0
|
||||
|
||||
var/state = 0
|
||||
|
||||
var/list/path = null
|
||||
|
||||
var/frustration = 0
|
||||
var/mob/living/carbon/target
|
||||
var/list/path_target = null
|
||||
|
||||
var/turf/trg_idle
|
||||
var/list/path_idle = null
|
||||
|
||||
var/alive = 1 //1 alive, 0 dead
|
||||
var/health = 25
|
||||
var/maxhealth = 25
|
||||
|
||||
flags = FPRINT | TABLEPASS
|
||||
|
||||
New()
|
||||
..()
|
||||
health = maxhealth
|
||||
src.process()
|
||||
|
||||
examine()
|
||||
set src in view()
|
||||
..()
|
||||
if(!alive)
|
||||
boutput(usr, text("<span style=\"color:red\"><B>the alien is not moving</B></span>"))
|
||||
else if (src.health > 15)
|
||||
boutput(usr, text("<span style=\"color:red\"><B>the alien looks fresh, just out of the egg</B></span>"))
|
||||
else
|
||||
boutput(usr, text("<span style=\"color:red\"><B>the alien looks pretty beat up</B></span>"))
|
||||
return
|
||||
|
||||
|
||||
attack_hand(user as mob)
|
||||
return
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
src.health -= W.force * 0.75
|
||||
if("brute")
|
||||
src.health -= W.force * 0.5
|
||||
else
|
||||
if (src.health <= 0)
|
||||
src.death()
|
||||
else if (W.force)
|
||||
if(ishuman(user) || ismonkey(user))
|
||||
src.target = user
|
||||
src.state = 1
|
||||
..()
|
||||
|
||||
bullet_act(var/obj/projectile/P)
|
||||
var/damage = 0
|
||||
damage = round((P.power*P.ks_ratio), 1.0)
|
||||
|
||||
if((P.damage_type == D_KINETIC)||(P.damage_type == D_SLASHING))
|
||||
src.health -= (damage*2)
|
||||
else if(P.damage_type == D_PIERCING)
|
||||
src.health -= damage
|
||||
else if(P.damage_type == D_ENERGY)
|
||||
src.health -= damage
|
||||
else if(P.damage_type == D_BURNING)
|
||||
src.health -= damage
|
||||
else if(P.damage_type == D_RADIOACTIVE)
|
||||
src.health -= damage
|
||||
else if(P.damage_type == D_TOXIC)
|
||||
src.health += damage
|
||||
healthcheck()
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
src.death()
|
||||
if(2.0)
|
||||
src.health -= 15
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
meteorhit()
|
||||
src.death()
|
||||
return
|
||||
|
||||
blob_act(var/power)
|
||||
if(prob(25))
|
||||
src.death()
|
||||
return
|
||||
|
||||
Bumped(AM as mob|obj)
|
||||
if(ismob(AM) && (ishuman(AM) || ismonkey(AM)) )
|
||||
src.target = AM
|
||||
set_attack()
|
||||
else if(ismob(AM))
|
||||
spawn(0)
|
||||
var/turf/T = get_turf(src)
|
||||
AM:set_loc(T)
|
||||
|
||||
Bump(atom/A)
|
||||
if(ismob(A) && (ishuman(A) || ismonkey(A)))
|
||||
src.target = A
|
||||
set_attack()
|
||||
else if(ismob(A))
|
||||
src.set_loc(A:loc)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
verb/follow()
|
||||
set src in view()
|
||||
set name = "follow me"
|
||||
if(!alive) return
|
||||
if(!isalien(usr))
|
||||
boutput(usr, text("<span style=\"color:red\"><B>The alien ignores you.</B></span>"))
|
||||
return
|
||||
if(state != 2 || health < maxhealth)
|
||||
boutput(usr, text("<span style=\"color:red\"><B>The alien is too busy to follow you.</B></span>"))
|
||||
return
|
||||
boutput(usr, text("<span style=\"color:green\"><B>The alien will now try to follow you.</B></span>"))
|
||||
trg_idle = usr
|
||||
path_idle = new/list()
|
||||
return
|
||||
|
||||
verb/stop()
|
||||
set src in view()
|
||||
set name = "stop following"
|
||||
if(!alive) return
|
||||
if(!isalien(usr))
|
||||
boutput(usr, text("<span style=\"color:red\"><B>The alien ignores you.</B></span>"))
|
||||
return
|
||||
if(state != 2)
|
||||
boutput(usr, text("<span style=\"color:red\"><B>The alien is too busy to follow you.</B></span>"))
|
||||
return
|
||||
boutput(usr, text("<span style=\"color:green\"><B>The alien stops following you.</B></span>"))
|
||||
set_null()
|
||||
return
|
||||
*/
|
||||
|
||||
|
||||
|
||||
proc/call_to(var/mob/user)
|
||||
if(!alive || !isalien(user) || state != 2) return
|
||||
trg_idle = user
|
||||
path_idle = null
|
||||
return
|
||||
|
||||
proc/set_attack()
|
||||
state = 1
|
||||
path_idle = null
|
||||
trg_idle = null
|
||||
|
||||
proc/set_idle()
|
||||
state = 2
|
||||
path_target = null
|
||||
target = null
|
||||
frustration = 0
|
||||
|
||||
proc/set_null()
|
||||
state = 0
|
||||
path_target = null
|
||||
path_idle = null
|
||||
target = null
|
||||
trg_idle = null
|
||||
frustration = 0
|
||||
|
||||
proc/process()
|
||||
var/quick_move = 0
|
||||
|
||||
if (!alive)
|
||||
return
|
||||
|
||||
if (!target)
|
||||
path_target = null
|
||||
|
||||
var/last_health = INFINITY
|
||||
|
||||
for (var/mob/living/carbon/C in range(viewrange-2,src.loc))
|
||||
if (isalien(C) || C.alien_egg_flag || !can_see(src,C,viewrange))
|
||||
continue
|
||||
if(C:stunned || C:paralysis || C:weakened)
|
||||
target = C
|
||||
break
|
||||
if(C:health < last_health)
|
||||
last_health = C:health
|
||||
target = C
|
||||
|
||||
if(target)
|
||||
set_attack()
|
||||
else if(state != 2)
|
||||
set_idle()
|
||||
idle()
|
||||
|
||||
else if(target)
|
||||
var/turf/distance = get_dist(src, target)
|
||||
set_attack()
|
||||
|
||||
if(can_see(src,target,viewrange))
|
||||
// This doesn't work, it only returns whenever a human is lying down on a tile
|
||||
// TO-DO think of a way to make it so they can't go through windows
|
||||
//var/turf/trg_turf = get_turf(target)
|
||||
if(distance <= 1) //&& trg_turf.Enter(src))
|
||||
for(var/mob/O in AIviewers(world.view,src))
|
||||
O.show_message("<span style=\"color:red\"><B>[src.target] has been leapt on by the alien!</B></span>", 1, "<span style=\"color:red\">You hear someone fall</span>", 2)
|
||||
random_brute_damage(target, 10)
|
||||
target:paralysis = max(target:paralysis, 10)
|
||||
src.set_loc(target.loc)
|
||||
|
||||
if(!target.alien_egg_flag && ( ishuman(target) || ismonkey(target) ) )
|
||||
target.alien_egg_flag = 1
|
||||
var/mob/trg = target
|
||||
src.death()
|
||||
trg.contract_disease(new /datum/ailment/parasite/alien_embryo, 1)
|
||||
return
|
||||
else
|
||||
set_null()
|
||||
spawn(cycle_pause) src.process()
|
||||
return
|
||||
|
||||
step_towards(src,get_step_towards2(src , target))
|
||||
else
|
||||
if(!path_target || !path_target.len )
|
||||
|
||||
path_attack(target)
|
||||
if(!path_target)
|
||||
set_null()
|
||||
spawn(cycle_pause) src.process()
|
||||
return
|
||||
else
|
||||
var/turf/next = path_target[1]
|
||||
|
||||
if(next in range(1,src))
|
||||
path_attack(target)
|
||||
|
||||
if(!path_target || !path_target.len)
|
||||
src.frustration += 5
|
||||
else
|
||||
next = path_target[1]
|
||||
path_target -= next
|
||||
step_towards(src,next)
|
||||
quick_move = 1
|
||||
|
||||
if (get_dist(src, src.target) >= distance) src.frustration++
|
||||
else src.frustration--
|
||||
if(frustration >= 35) set_null()
|
||||
|
||||
if(quick_move)
|
||||
spawn(1)
|
||||
src.process()
|
||||
else
|
||||
spawn(cycle_pause)
|
||||
src.process()
|
||||
|
||||
proc/idle()
|
||||
var/quick_move = 0
|
||||
|
||||
if(state != 2 || !alive || target) return
|
||||
|
||||
if(locate(/obj/alien/weeds) in src.loc && health < maxhealth)
|
||||
health++
|
||||
spawn(cycle_pause) idle()
|
||||
return
|
||||
|
||||
if(!path_idle || !path_idle.len)
|
||||
|
||||
if(isalien(trg_idle))
|
||||
if(can_see(src,trg_idle,viewrange))
|
||||
step_towards(src,get_step_towards2(src , trg_idle))
|
||||
else
|
||||
path_idle(trg_idle)
|
||||
if(!path_idle)
|
||||
trg_idle = null
|
||||
set_idle()
|
||||
spawn(cycle_pause) src.idle()
|
||||
return
|
||||
else
|
||||
var/obj/alien/weeds/W = null
|
||||
if(health < maxhealth)
|
||||
var/list/the_weeds = new/list()
|
||||
|
||||
find_weeds:
|
||||
for(var/obj/alien/weeds/weed in range(viewrange,src.loc))
|
||||
if(!can_see(src,weed,viewrange)) continue
|
||||
for(var/atom/A in get_turf(weed))
|
||||
if(A.density) continue find_weeds
|
||||
the_weeds += weed
|
||||
W = pick(the_weeds)
|
||||
|
||||
if(W)
|
||||
path_idle(W)
|
||||
if(!path_idle)
|
||||
trg_idle = null
|
||||
spawn(cycle_pause) src.idle()
|
||||
return
|
||||
else
|
||||
for(var/mob/living/carbon/alien/humanoid/H in range(1,src))
|
||||
spawn(cycle_pause) src.idle()
|
||||
return
|
||||
step(src,pick(cardinal))
|
||||
|
||||
else
|
||||
|
||||
if(can_see(src,trg_idle,viewrange))
|
||||
switch(get_dist(src, trg_idle))
|
||||
if(1)
|
||||
if(istype(trg_idle,/obj/alien/weeds))
|
||||
step_towards(src,get_step_towards2(src , trg_idle))
|
||||
if(2 to INFINITY)
|
||||
step_towards(src,get_step_towards2(src , trg_idle))
|
||||
path_idle = null
|
||||
/*
|
||||
if(viewrange+1 to INFINITY)
|
||||
step_towards(src,get_step_towards2(src , trg_idle))
|
||||
if(path_idle.len) path_idle = new/list()
|
||||
quick_move = 1
|
||||
*/
|
||||
else
|
||||
var/turf/next = path_idle[1]
|
||||
if(!next in range(1,src))
|
||||
path_idle(trg_idle)
|
||||
|
||||
if(!path_idle)
|
||||
spawn(cycle_pause) src.idle()
|
||||
return
|
||||
else
|
||||
next = path_idle[1]
|
||||
path_idle -= next
|
||||
step_towards(src,next)
|
||||
quick_move = 1
|
||||
|
||||
if(quick_move)
|
||||
spawn(1)
|
||||
idle()
|
||||
else
|
||||
spawn(cycle_pause)
|
||||
idle()
|
||||
|
||||
proc/path_idle(var/atom/trg)
|
||||
path_idle = AStar(src.loc, get_turf(trg), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance)
|
||||
|
||||
proc/path_attack(var/atom/trg)
|
||||
target = trg
|
||||
path_target = AStar(src.loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance)
|
||||
|
||||
|
||||
proc/death()
|
||||
if(!alive) return
|
||||
src.alive = 0
|
||||
density = 0
|
||||
icon_state = "facehugger_l"
|
||||
set_null()
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><B>[src] curls up into a ball!</B></span>", 1)
|
||||
|
||||
proc/healthcheck()
|
||||
if (src.health <= 0)
|
||||
src.death()
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
/obj/alien/weeds
|
||||
name = "weeds"
|
||||
desc = "weird purple weeds"
|
||||
icon_state = "weeds"
|
||||
|
||||
layer = TURF_LAYER
|
||||
anchored = 1
|
||||
density = 0
|
||||
|
||||
New()
|
||||
if(istype(src.loc, /turf/space))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (!W) return
|
||||
if (!user) return
|
||||
if (istype(W, /obj/item/axe)) qdel(src)
|
||||
else if (istype(W, /obj/item/circular_saw)) qdel(src)
|
||||
else if (istype(W, /obj/item/kitchen/utensil/knife)) qdel(src)
|
||||
else if (istype(W, /obj/item/scalpel)) qdel(src)
|
||||
else if (istype(W, /obj/item/screwdriver))(qdel src)
|
||||
else if (istype(W, /obj/item/shard)) qdel(src)
|
||||
else if (istype(W, /obj/item/sword)) qdel(src)
|
||||
else if (istype(W, /obj/item/saw)) qdel(src)
|
||||
else if (istype(W, /obj/item/weldingtool)) qdel(src)
|
||||
else if (istype(W, /obj/item/wirecutters)) qdel(src)
|
||||
..()
|
||||
|
||||
proc/Life()
|
||||
|
||||
var/count = 0
|
||||
while(count < 6)
|
||||
if (!src) return
|
||||
var/Vspread
|
||||
if (prob(50)) Vspread = locate(src.x + rand(-1,1),src.y,src.z)
|
||||
else Vspread = locate(src.x,src.y + rand(-1, 1),src.z)
|
||||
var/dogrowth = 1
|
||||
if (!istype(Vspread, /turf/simulated/floor)) dogrowth = 0
|
||||
for(var/obj/O in Vspread)
|
||||
if (istype(O, /obj/window) || istype(O, /obj/forcefield) || istype(O, /obj/blob) || istype(O, /obj/spacevine) || istype(O, /obj/alien/weeds)) dogrowth = 0
|
||||
if (istype(O, /obj/machinery/door/))
|
||||
if(!O:p_open && prob(70))
|
||||
O:open()
|
||||
O:operating = -1
|
||||
else dogrowth = 0
|
||||
if (dogrowth == 1)
|
||||
var/obj/alien/weeds/B = new /obj/alien/weeds(Vspread)
|
||||
spawn(50)
|
||||
if(B)
|
||||
B.Life()
|
||||
count++
|
||||
sleep(50)
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(5))
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
/*
|
||||
/obj/alien/weeds/burn(fi_amount)
|
||||
if (fi_amount > 18000)
|
||||
spawn( 0 )
|
||||
qdel(src)
|
||||
return
|
||||
return 0
|
||||
return 1
|
||||
*/
|
||||
@@ -0,0 +1,24 @@
|
||||
/obj/item/artifact/activator_key
|
||||
// can activate any artifact simply by smacking it. very very rare
|
||||
name = "artifact activator key"
|
||||
associated_datum = /datum/artifact/activator_key
|
||||
var/universal = 1 // normally it only activates its own type, but sometimes it can do all
|
||||
var/activator = 1 // can also be a DEactivator key sometimes!
|
||||
module_research_no_diminish = 1
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
..()
|
||||
/*if (prob(10))
|
||||
src.universal = 1
|
||||
if (prob(10))
|
||||
src.activator = 0*/
|
||||
|
||||
/datum/artifact/activator_key
|
||||
associated_object = /obj/item/artifact/activator_key
|
||||
rarity_class = 4
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
automatic_activation = 1
|
||||
react_xray = list(12,80,95,8,"COMPLEX")
|
||||
examine_hint = "It kinda looks like it's supposed to be inserted into something."
|
||||
module_research = list("tools" = 20)
|
||||
module_research_insight = 5
|
||||
@@ -0,0 +1,130 @@
|
||||
/obj/item/artifact/attack_wand
|
||||
name = "artifact attack wand"
|
||||
associated_datum = /datum/artifact/attack_wand
|
||||
flags = FPRINT | CONDUCT | EXTRADELAY
|
||||
module_research_no_diminish = 1
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
|
||||
if (user.equipped() == src)
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/attack_wand/A = src.artifact
|
||||
if (!istype(A))
|
||||
return
|
||||
if (!A.activated)
|
||||
return
|
||||
var/turf/U = (istype(target, /atom/movable) ? target.loc : target)
|
||||
A.effect_click_tile(src,user,U)
|
||||
src.ArtifactFaultUsed(user)
|
||||
|
||||
/datum/artifact/attack_wand
|
||||
associated_object = /obj/item/artifact/attack_wand
|
||||
rarity_class = 3
|
||||
validtypes = list("wizard")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/force)
|
||||
react_xray = list(8,80,60,11,"COMPLEX")
|
||||
examine_hint = "It seems to have a handle you're supposed to hold it by."
|
||||
var/ready = 1
|
||||
var/cooldown = 180
|
||||
var/attack_type = null
|
||||
var/recharge_phrase = ""
|
||||
var/error_phrase = ""
|
||||
module_research = list("weapons" = 5, "energy" = 5, "tools" = 5)
|
||||
module_research_insight = 2
|
||||
|
||||
New()
|
||||
..()
|
||||
recharge_phrase = pick("crackles with static.","emits a quiet tone.","bristles with energy!","heats up.")
|
||||
error_phrase = pick("shudders briefly.","grows heavy for a moment.","emits a quiet buzz.","makes a small pop sound.")
|
||||
attack_type = pick("lightning","fire","ice","sonic")
|
||||
cooldown = rand(25,900)
|
||||
if (prob(5))
|
||||
cooldown = 0
|
||||
|
||||
effect_click_tile(var/obj/O,var/mob/living/user,var/turf/T)
|
||||
if (..())
|
||||
return
|
||||
if (!ready)
|
||||
return
|
||||
|
||||
ready = 0
|
||||
spawn(cooldown)
|
||||
if (O.loc == user)
|
||||
boutput(user, "<b>[O]</b> [recharge_phrase]")
|
||||
ready = 1
|
||||
|
||||
switch(attack_type)
|
||||
if("fire")
|
||||
playsound(T, "sound/effects/bamf.ogg", 50, 1, 0)
|
||||
fireflash(T, 2)
|
||||
|
||||
ArtifactLogs(user, T, O, "used", "creating fireball on target turf", 0) // Attack wands need special log handling (Convair880).
|
||||
|
||||
if("ice")
|
||||
playsound(T, "sound/effects/mag_iceburstlaunch.ogg", 50, 1, 0)
|
||||
for (var/turf/TT in range(T,2))
|
||||
if(locate(/obj/decal/icefloor) in TT.contents)
|
||||
continue
|
||||
var/obj/decal/icefloor/B = new /obj/decal/icefloor(TT)
|
||||
spawn(800)
|
||||
B.dispose()
|
||||
for (var/mob/living/M in range(T,2))
|
||||
if (M.bioHolder)
|
||||
if (!M.is_cold_resistant())
|
||||
new /obj/icecube(get_turf(M), M)
|
||||
|
||||
ArtifactLogs(user, M, O, "weapon", "trapping them in an ice cube", 0)
|
||||
|
||||
if("lightning")
|
||||
var/attack_amt = 0
|
||||
for (var/mob/living/M in range(T,1))
|
||||
|
||||
ArtifactLogs(user, M, O, "weapon", "zapping them with electricity", 0)
|
||||
|
||||
attack_amt = 1
|
||||
var/list/affected = DrawLine(M, user, /obj/line_obj/elec ,'icons/obj/projectiles.dmi',"WholeLghtn",1,1,"HalfStartLghtn","HalfEndLghtn",OBJ_LAYER,1,PreloadedIcon='icons/effects/LghtLine.dmi')
|
||||
for(var/obj/OB in affected)
|
||||
spawn(6)
|
||||
pool(OB)
|
||||
M.TakeDamage("chest", 0, 25)
|
||||
M.stunned += 5
|
||||
if (attack_amt)
|
||||
playsound(user, "sound/effects/elec_bigzap.ogg", 40, 1)
|
||||
else
|
||||
boutput(user, "<span style=\"color:red\"><b>[O]</b> crackles with electricity for a moment. Perhaps it couldn't find a target?</span>")
|
||||
|
||||
if("sonic")
|
||||
playsound(T, "sound/effects/screech.ogg", 100, 1, 0)
|
||||
particleMaster.SpawnSystem(new /datum/particleSystem/sonic_burst(T))
|
||||
|
||||
for (var/mob/living/M in all_hearers(world.view, T))
|
||||
if (isintangible(M))
|
||||
continue
|
||||
if (!M.ears_protected_from_sound())
|
||||
shake_camera(M, 10, 0)
|
||||
else
|
||||
continue
|
||||
|
||||
ArtifactLogs(user, M, O, "weapon", "inflicting ear damage", 0)
|
||||
|
||||
// Here used to be a C&P of what sonic powder does anyway (Convair880).
|
||||
var/datum/reagents/R = O.reagents
|
||||
|
||||
if (!R || !istype(R))
|
||||
R = new /datum/reagents(15)
|
||||
O.reagents = R
|
||||
R.my_atom = O
|
||||
else if (R && istype(R) && R.my_atom != O)
|
||||
R.my_atom = O
|
||||
|
||||
R.clear_reagents()
|
||||
if (R.maximum_volume < 15)
|
||||
R.maximum_volume = 15
|
||||
|
||||
R.add_reagent("sonicpowder_nofluff", 15, null, T0C + 200)
|
||||
R.temperature_react()
|
||||
|
||||
if (R.total_volume)
|
||||
R.clear_reagents()
|
||||
return
|
||||
@@ -0,0 +1,109 @@
|
||||
/obj/item/gun/energy/artifact
|
||||
// an energy gun, it shoots things as you might expect
|
||||
name = "artifact energy gun"
|
||||
icon = 'icons/obj/artifacts/artifactsitem.dmi'
|
||||
icon_state = "laser"
|
||||
force = 5.0
|
||||
artifact = 1
|
||||
is_syndicate = 1
|
||||
module_research_no_diminish = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
var/datum/artifact/energygun/AS = new /datum/artifact/energygun(src)
|
||||
if (forceartitype)
|
||||
AS.validtypes = list("[forceartitype]")
|
||||
src.artifact = AS
|
||||
// The other three are normal for energy gun setup, so proceed as usual i guess
|
||||
cell = null
|
||||
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
var/datum/artifact/A = src.artifact
|
||||
cell = new/obj/item/ammo/power_cell/self_charging/artifact(src,A.artitype)
|
||||
src.ArtifactDevelopFault(15)
|
||||
|
||||
current_projectile = AS.bullet
|
||||
projectiles = list(src.current_projectile)
|
||||
cell.max_charge = max(cell.max_charge, current_projectile.cost)
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
process_ammo(var/mob/user)
|
||||
if(istype(user,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.cell)
|
||||
if(R.cell.charge >= src.robocharge)
|
||||
R.cell.charge -= src.robocharge
|
||||
return 1
|
||||
return 0
|
||||
else
|
||||
if(src.current_projectile)
|
||||
if(src.cell)
|
||||
if(src.cell.use(src.current_projectile.cost))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
shoot(var/target,var/start,var/mob/user)
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/energygun/A = src.artifact
|
||||
|
||||
if (!istype(A))
|
||||
return
|
||||
|
||||
if (!A.activated)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
A.ReduceHealth(src)
|
||||
|
||||
src.ArtifactFaultUsed(user)
|
||||
return
|
||||
|
||||
/datum/artifact/energygun
|
||||
associated_object = /obj/item/gun/energy/artifact
|
||||
rarity_class = 2
|
||||
validtypes = list("ancient","eldritch","precursor")
|
||||
react_elec = list(0.02,0,5)
|
||||
react_xray = list(10,75,100,11,"CAVITY")
|
||||
var/integrity = 100
|
||||
var/integrity_loss = 5
|
||||
var/datum/projectile/artifact/bullet = null
|
||||
examine_hint = "It seems to have a handle you're supposed to hold it by."
|
||||
module_research = list("weapons" = 8, "energy" = 8)
|
||||
module_research_insight = 3
|
||||
|
||||
New()
|
||||
..()
|
||||
bullet = new/datum/projectile/artifact
|
||||
bullet.randomise()
|
||||
integrity = rand(50, 100)
|
||||
integrity_loss = rand(1, 7)
|
||||
react_xray[3] = integrity
|
||||
|
||||
proc/ReduceHealth(var/obj/item/gun/energy/artifact/O)
|
||||
var/prev_health = integrity
|
||||
integrity -= integrity_loss
|
||||
if (integrity <= 20 && prev_health > 20)
|
||||
O.visible_message("<span style=\"color:red\">[O] emits a terrible cracking noise.</span>")
|
||||
if (integrity <= 0)
|
||||
O.visible_message("<span style=\"color:red\">[O] crumbles into nothingness.</span>")
|
||||
qdel(O)
|
||||
react_xray[3] = integrity
|
||||
@@ -0,0 +1,56 @@
|
||||
/obj/item/ammo/power_cell/self_charging/artifact
|
||||
name = "artifact energy gun power cell"
|
||||
icon = 'icons/obj/artifacts/artifactsitemS.dmi'
|
||||
artifact = 1
|
||||
charge = 400.0
|
||||
max_charge = 400.0
|
||||
recharge_rate = 0.0
|
||||
module_research_no_diminish = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
//src.artifact = new /datum/artifact/energyammo(src)
|
||||
var/datum/artifact/energyammo/A = new /datum/artifact/energyammo(src)
|
||||
if (forceartitype)
|
||||
A.validtypes = list("[forceartitype]")
|
||||
src.artifact = A
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
|
||||
src.max_charge = rand(5,100)
|
||||
src.max_charge *= 10
|
||||
A.react_elec[2] = src.max_charge
|
||||
src.recharge_rate = rand(5,60)
|
||||
..()
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
/datum/artifact/energyammo
|
||||
associated_object = /obj/item/ammo/power_cell/self_charging/artifact
|
||||
rarity_class = 0
|
||||
validtypes = list("ancient","eldritch","precursor")
|
||||
automatic_activation = 1
|
||||
react_elec = list("equal",0,0)
|
||||
react_xray = list(8,80,95,11,"SEGMENTED")
|
||||
examine_hint = "It kinda looks like it's supposed to be inserted into something."
|
||||
module_research = list("energy" = 15, "weapons" = 1, "miniaturization" = 15)
|
||||
module_research_insight = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "VOLATILE REACTION DETECTED"
|
||||
@@ -0,0 +1,74 @@
|
||||
/obj/item/artifact/melee_weapon
|
||||
name = "artifact melee weapon"
|
||||
artifact = 1
|
||||
associated_datum = /datum/artifact/melee
|
||||
module_research_no_diminish = 1
|
||||
|
||||
attack(mob/M as mob, mob/user as mob)
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (A.activated)
|
||||
A.effect_melee_attack(src,user,M)
|
||||
src.ArtifactFaultUsed(user)
|
||||
src.ArtifactFaultUsed(M)
|
||||
else
|
||||
..()
|
||||
|
||||
/datum/artifact/melee
|
||||
associated_object = /obj/item/artifact/melee_weapon
|
||||
rarity_class = 2
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
react_xray = list(14,95,95,7,"DENSE")
|
||||
var/damtype = "brute"
|
||||
var/dmg_amount = 5
|
||||
var/stun_time = 0
|
||||
var/KO_time = 0
|
||||
var/deadly = 0
|
||||
var/sound/hitsound = null
|
||||
examine_hint = "It seems to have a handle you're supposed to hold it by."
|
||||
module_research = list("weapons" = 8, "miniaturization" = 8)
|
||||
module_research_insight = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
src.damtype = pick("brute", "fire", "toxin")
|
||||
src.dmg_amount = rand(3,6)
|
||||
src.dmg_amount *= rand(1,5)
|
||||
if (prob(5))
|
||||
src.dmg_amount *= rand(1,5)
|
||||
if (prob(40))
|
||||
src.stun_time = rand(3,12)
|
||||
if (prob(15))
|
||||
src.KO_time = rand(3,12)
|
||||
if (prob(1))
|
||||
src.deadly = 1
|
||||
src.hitsound = pick('sound/effects/bang.ogg','sound/effects/zhit.ogg','sound/effects/exlow.ogg','sound/effects/mag_magmisimpact.ogg','sound/effects/shieldhit2.ogg',
|
||||
'sound/effects/snap.ogg','sound/machines/mixer.ogg','sound/misc/meteorimpact.ogg','sound/weapons/ACgun2.ogg','sound/weapons/Egloves.ogg','sound/weapons/flashbang.ogg',
|
||||
'sound/weapons/grenade.ogg','sound/weapons/railgun.ogg')
|
||||
|
||||
effect_melee_attack(var/obj/O,var/mob/living/user,var/mob/living/target)
|
||||
if (..())
|
||||
return
|
||||
if (!istype(user,/mob/living/) || !istype(target,/mob/living/))
|
||||
return
|
||||
user.visible_message("<span style=\"color:red\"><b>[user.name]</b> attacks [target.name] with [O]!</span>")
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(T, hitsound, 50, 1, -1)
|
||||
if (src.deadly)
|
||||
user.visible_message("<span style=\"color:red\"><b>[target] is utterly destroyed!</b></span>")
|
||||
target.gib()
|
||||
else
|
||||
switch(damtype)
|
||||
if ("brute")
|
||||
random_brute_damage(target, dmg_amount)
|
||||
if ("fire")
|
||||
random_burn_damage(target, dmg_amount)
|
||||
if ("toxin")
|
||||
if (ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.toxloss += rand(1, dmg_amount)
|
||||
if (src.stun_time)
|
||||
target.stunned = src.stun_time
|
||||
if (src.KO_time)
|
||||
target.paralysis = src.KO_time
|
||||
@@ -0,0 +1,34 @@
|
||||
/obj/item/artifact/mining_tool
|
||||
name = "artifact mining tool"
|
||||
artifact = 1
|
||||
associated_datum = /datum/artifact/mining
|
||||
var/dig_power = 1
|
||||
var/extrahit = 0
|
||||
var/dig_sound = 'sound/effects/exlow.ogg'
|
||||
// mining.dm line 373
|
||||
module_research_no_diminish = 1
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
..()
|
||||
src.dig_power = rand(1,5)
|
||||
if (prob(33))
|
||||
src.extrahit = rand(0,4)
|
||||
src.dig_sound = pick('sound/effects/exlow.ogg','sound/effects/mag_magmisimpact.ogg','sound/effects/shieldhit2.ogg')
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
/datum/artifact/mining
|
||||
associated_object = /obj/item/artifact/mining_tool
|
||||
rarity_class = 1
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
react_xray = list(12,80,95,5,"DENSE")
|
||||
examine_hint = "It seems to have a handle you're supposed to hold it by."
|
||||
module_research = list("mining" = 10, "engineering" = 5, "miniaturization" = 10)
|
||||
module_research_insight = 3
|
||||
@@ -0,0 +1,55 @@
|
||||
/obj/item/cell/artifact
|
||||
name = "artifact power cell"
|
||||
icon = 'icons/obj/artifacts/artifactsitemS.dmi'
|
||||
maxcharge = 10000
|
||||
genrate = 50
|
||||
specialicon = 1
|
||||
artifact = 1
|
||||
module_research_no_diminish = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
//src.artifact = new /datum/artifact/powercell(src)
|
||||
var/datum/artifact/powercell/AS = new /datum/artifact/powercell(src)
|
||||
if (forceartitype)
|
||||
AS.validtypes = list("[forceartitype]")
|
||||
src.artifact = AS
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
var/datum/artifact/A = src.artifact
|
||||
src.maxcharge = rand(15,1000)
|
||||
src.maxcharge *= 100
|
||||
A.react_elec[2] = src.maxcharge
|
||||
..()
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
/datum/artifact/powercell
|
||||
associated_object = /obj/item/cell/artifact
|
||||
rarity_class = 1
|
||||
validtypes = list("ancient","martian","wizard","precursor")
|
||||
automatic_activation = 1
|
||||
react_elec = list("equal",0,10)
|
||||
react_xray = list(10,80,95,11,"SEGMENTED")
|
||||
examine_hint = "It kinda looks like it's supposed to be inserted into something."
|
||||
module_research = list("energy" = 15, "miniaturization" = 20)
|
||||
module_research_insight = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "VOLATILE REACTION DETECTED"
|
||||
@@ -0,0 +1,79 @@
|
||||
/obj/item/artifact/teleport_wand
|
||||
name = "artifact teleport wand"
|
||||
artifact = 1
|
||||
associated_datum = /datum/artifact/telewand
|
||||
flags = FPRINT | CONDUCT | EXTRADELAY
|
||||
module_research_no_diminish = 1
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/telewand/A = src.artifact
|
||||
if (!istype(A))
|
||||
return
|
||||
|
||||
var/turf/U = (istype(target, /atom/movable) ? target.loc : target)
|
||||
//var/turf/T = get_turf(target)
|
||||
if (A.activated)
|
||||
if (A.can_teleport_here(U))
|
||||
A.effect_click_tile(src,user,U)
|
||||
else
|
||||
boutput(user, "<b>[src]</b> [A.error_phrase]")
|
||||
src.ArtifactFaultUsed(user)
|
||||
|
||||
/datum/artifact/telewand
|
||||
associated_object = /obj/item/artifact/teleport_wand
|
||||
rarity_class = 3
|
||||
validtypes = list("wizard","eldritch","precursor")
|
||||
react_xray = list(10,75,90,11,"ANOMALOUS")
|
||||
var/sound/wand_sound = 'sound/effects/mag_warp.ogg'
|
||||
var/on_cooldown = 0
|
||||
var/cooldown_delay = 0
|
||||
var/particle_color = "#000000"
|
||||
var/particle_sprite = ""
|
||||
var/recharge_phrase = ""
|
||||
var/error_phrase = ""
|
||||
examine_hint = "It seems to have a handle you're supposed to hold it by."
|
||||
module_research = list("energy" = 15, "engineering" = 3, "science" = 8)
|
||||
module_research_insight = 4
|
||||
|
||||
New()
|
||||
..()
|
||||
particle_color = copytext(rgb(rand(0,255), rand(0,255), rand(0,255)),1,0)
|
||||
particle_sprite = pick("8x8circle","8x8ring","8x8triangle","8x8square","8x8bubblegrid")
|
||||
wand_sound = pick('sound/effects/mag_warp.ogg','sound/effects/mag_teleport.ogg','sound/effects/mag_phase.ogg','sound/effects/teleport.ogg','sound/effects/warp2.ogg','sound/weapons/ACgun2.ogg',
|
||||
'sound/weapons/laserultra.ogg','sound/weapons/radxbow.ogg','sound/machines/ArtifactWiz1.ogg','sound/machines/ArtifactPre1.ogg','sound/machines/ArtifactAnc1.ogg','sound/machines/engine_alert3.ogg', 'sound/voice/wizard/BlinkLoud.ogg')
|
||||
recharge_phrase = pick("crackles with static.","emits a quiet tone.","shakes violently!","heats up.")
|
||||
error_phrase = pick("shudders briefly.","grows heavy for a moment.","emits a quiet buzz.","makes a small pop sound.")
|
||||
cooldown_delay = rand(1,20) * 10
|
||||
if (prob(5))
|
||||
cooldown_delay = 0
|
||||
|
||||
effect_click_tile(var/obj/O,var/mob/living/user,var/turf/T)
|
||||
if (..())
|
||||
return
|
||||
if (on_cooldown)
|
||||
return
|
||||
|
||||
on_cooldown = 1
|
||||
spawn(cooldown_delay)
|
||||
if (O.loc == user)
|
||||
boutput(user, "<b>[O]</b> [recharge_phrase]")
|
||||
on_cooldown = 0
|
||||
|
||||
user.set_loc(T)
|
||||
|
||||
var/turf/start_loc = get_turf(user)
|
||||
playsound(start_loc, wand_sound, 50, 1, -1)
|
||||
particleMaster.SpawnSystem(new /datum/particleSystem/tele_wand(T,particle_sprite,particle_color))
|
||||
return
|
||||
|
||||
proc/can_teleport_here(var/turf/T)
|
||||
if (!istype(T,/turf/simulated/floor/))
|
||||
return 0
|
||||
if (T.density)
|
||||
return 0
|
||||
for(var/atom/X in T.contents)
|
||||
if (X.density)
|
||||
return 0
|
||||
return 1
|
||||
@@ -0,0 +1,66 @@
|
||||
/obj/item/artifact/forcewall_wand
|
||||
name = "artifact forcewall wand"
|
||||
icon = 'icons/obj/artifacts/artifactsitem.dmi'
|
||||
artifact = 1
|
||||
associated_datum = /datum/artifact/wallwand
|
||||
module_research_no_diminish = 1
|
||||
|
||||
afterattack(atom/target, mob/user , flag)
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (A.activated)
|
||||
var/turf/T = get_turf(target)
|
||||
A.effect_click_tile(src,user,T)
|
||||
src.ArtifactFaultUsed(user)
|
||||
|
||||
/datum/artifact/wallwand
|
||||
associated_object = /obj/item/artifact/forcewall_wand
|
||||
rarity_class = 2
|
||||
validtypes = list("ancient","wizard","eldritch","precursor")
|
||||
react_xray = list(10,60,92,11,"COMPLEX")
|
||||
var/wall_duration = 5
|
||||
var/wall_size = 1
|
||||
var/icon_state = "shieldsparkles"
|
||||
var/sound/wand_sound = 'sound/effects/mag_forcewall.ogg'
|
||||
examine_hint = "It seems to have a handle you're supposed to hold it by."
|
||||
module_research = list("energy" = 10, "weapons" = 3, "miniaturization" = 5, "engineering" = 3, "tools" = 3)
|
||||
module_research_insight = 3
|
||||
|
||||
New()
|
||||
..()
|
||||
src.wall_duration = rand(3,30)
|
||||
src.wall_size = rand(1,4)
|
||||
if(prob(10))
|
||||
src.wall_size += rand(3,6)
|
||||
if(prob(5))
|
||||
src.wall_duration *= rand(2,5)
|
||||
src.icon_state = pick("shieldsparkles","empdisable","greenglow","enshield","energyorb","forcewall","meteor_shield")
|
||||
src.wand_sound = pick('sound/effects/mag_forcewall.ogg','sound/effects/mag_golem.ogg','sound/effects/mag_iceburstlaunch.ogg','sound/effects/bamf.ogg','sound/weapons/ACgun2.ogg')
|
||||
|
||||
effect_click_tile(var/obj/O,var/mob/living/user,var/turf/T)
|
||||
if (..())
|
||||
return
|
||||
if (!T)
|
||||
return
|
||||
var/wallloc
|
||||
playsound(user.loc, wand_sound, 50, 1, -1)
|
||||
if (user.dir == NORTH || user.dir == SOUTH)
|
||||
for(wallloc = T.x - (src.wall_size - 1),wallloc < T.x + src.wall_size,wallloc++)
|
||||
var/obj/forcefield/wand/FW = new /obj/forcefield/wand(locate(wallloc,T.y,T.z),src.wall_duration,src.icon_state)
|
||||
FW.icon_state = src.icon_state
|
||||
else
|
||||
for(wallloc = T.y - (src.wall_size - 1),wallloc < T.y + src.wall_size,wallloc++)
|
||||
var/obj/forcefield/wand/FW = new /obj/forcefield/wand(locate(T.x,wallloc,T.z),src.wall_duration,src.icon_state)
|
||||
FW.icon_state = src.icon_state
|
||||
|
||||
/obj/forcefield/wand
|
||||
name = "force field"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
desc = "Some kind of strange energy barrier. You can't get past it."
|
||||
New(var/loc,var/duration,var/wallsprite)
|
||||
icon_state = wallsprite
|
||||
if (duration > 0)
|
||||
spawn(duration * 10)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,51 @@
|
||||
/obj/item/reagent_containers/glass/wateringcan/artifact
|
||||
name = "artifact watering can"
|
||||
icon = 'icons/obj/artifacts/artifactsitem.dmi'
|
||||
desc = "You have no idea what this thing is!"
|
||||
artifact = 1
|
||||
module_research_no_diminish = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
..()
|
||||
var/datum/artifact/watercan/AS = new /datum/artifact/watercan(src)
|
||||
if (forceartitype)
|
||||
AS.validtypes = list("[forceartitype]")
|
||||
src.artifact = AS
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
|
||||
var/capacity = rand(1,20)
|
||||
capacity *= 1000
|
||||
var/datum/reagents/R = new/datum/reagents(capacity)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("water", capacity / 2)
|
||||
R.add_reagent("saltpetre", capacity / 2)
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
examine()
|
||||
boutput(usr, "[desc]")
|
||||
return
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
/datum/artifact/watercan
|
||||
associated_object = /obj/item/reagent_containers/glass/wateringcan/artifact
|
||||
rarity_class = 1
|
||||
validtypes = list("martian","wizard","precursor")
|
||||
min_triggers = 0
|
||||
max_triggers = 0
|
||||
react_xray = list(2,90,15,11,"HOLLOW")
|
||||
module_research = list("medicine" = 5, "science" = 5, "miniaturization" = 15)
|
||||
module_research_insight = 3
|
||||
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "HIGH INTERNAL CONVECTION"
|
||||
@@ -0,0 +1,42 @@
|
||||
/obj/machinery/artifact/gravity_well_generator
|
||||
name = "artifact gravity well generator"
|
||||
associated_datum = /datum/artifact/gravity_well_generator
|
||||
|
||||
/datum/artifact/gravity_well_generator
|
||||
associated_object = /obj/machinery/artifact/gravity_well_generator
|
||||
rarity_class = 2
|
||||
validtypes = list("wizard","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch)
|
||||
activated = 0
|
||||
activ_text = "activates and begins to warp gravity around it!"
|
||||
deact_text = "shuts down, returning gravity to normal!"
|
||||
activ_sound = 'sound/effects/mag_warp.ogg'
|
||||
deact_sound = 'sound/effects/singsuck.ogg'
|
||||
react_xray = list(20,80,99,0,"ULTRADENSE")
|
||||
touch_descriptors = list("You seem to have a little difficulty taking your hand off its surface.")
|
||||
var/field_radius = 7
|
||||
var/gravity_type = 0 // push or pull?
|
||||
examine_hint = "It is covered in very conspicuous markings."
|
||||
|
||||
New()
|
||||
..()
|
||||
src.field_radius = rand(4,9) // well radius
|
||||
src.gravity_type = rand(0,1) // 0 for pull, 1 for push
|
||||
|
||||
effect_process(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
for (var/obj/V in orange(src.field_radius,O))
|
||||
if (V.anchored)
|
||||
continue
|
||||
|
||||
if (src.gravity_type)
|
||||
step_away(V,O)
|
||||
else
|
||||
step_towards(V,O)
|
||||
for (var/mob/living/M in orange(src.field_radius,O))
|
||||
if (src.gravity_type)
|
||||
step_away(M,O)
|
||||
else
|
||||
step_towards(M,O)
|
||||
@@ -0,0 +1,42 @@
|
||||
/obj/machinery/artifact/bio_damage_field_generator
|
||||
name = "artifact bio damage field generator"
|
||||
associated_datum = /datum/artifact/bio_damage_field_generator
|
||||
|
||||
/datum/artifact/bio_damage_field_generator
|
||||
associated_object = /obj/machinery/artifact/bio_damage_field_generator
|
||||
rarity_class = 3
|
||||
validtypes = list("martian","wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch)
|
||||
activated = 0
|
||||
activ_text = "begins to radiate a strange energy field!"
|
||||
deact_text = "shuts down, causing the energy field to vanish!"
|
||||
react_xray = list(12,70,90,11,"COMPLEX")
|
||||
var/field_radius = 7
|
||||
var/field_type = 0 // 0 healing, 1 harming
|
||||
var/field_strength = 2
|
||||
|
||||
New()
|
||||
..()
|
||||
src.field_radius = rand(2,9) // field radius
|
||||
src.field_type = rand(0,1)
|
||||
src.field_strength = rand(1,5)
|
||||
var/harmprob = 33
|
||||
if (src.artitype == "eldritch")
|
||||
harmprob += 42 // total of 75% chance of it being nasty
|
||||
if (prob(harmprob))
|
||||
src.field_type = 1
|
||||
|
||||
if (src.field_type && src.artitype == "eldritch")
|
||||
src.field_strength *= 2
|
||||
|
||||
effect_process(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
for (var/mob/living/carbon/M in range(O,src.field_radius))
|
||||
if (src.field_type)
|
||||
random_brute_damage(M, src.field_strength)
|
||||
boutput(M, "<span style=\"color:red\">Waves of painful energy wrack your body!</span>")
|
||||
else
|
||||
M.HealDamage("All", src.field_strength, src.field_strength)
|
||||
boutput(M, "<span style=\"color:blue\">Waves of soothing energy wash over you!</span>")
|
||||
@@ -0,0 +1,46 @@
|
||||
/obj/machinery/artifact/heater
|
||||
name = "artifact heater"
|
||||
associated_datum = /datum/artifact/heater
|
||||
|
||||
/datum/artifact/heater
|
||||
associated_object = /obj/machinery/artifact/heater
|
||||
rarity_class = 2
|
||||
validtypes = list("ancient","martian","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/cold)
|
||||
activ_text = "begins to radiate air!"
|
||||
deact_text = "stops pumping out air."
|
||||
react_xray = list(10,85,80,5,"COMPLEX")
|
||||
var/heat_target = 310
|
||||
var/heat_amount = 40000
|
||||
examine_hint = "It is covered in very conspicuous markings."
|
||||
|
||||
post_setup()
|
||||
heat_target = rand(0,620)
|
||||
if (artitype == "eldritch" && prob(66))
|
||||
if (heat_target > 310)
|
||||
heat_target *= 2
|
||||
if (heat_target < 310 && heat_target != 0)
|
||||
heat_target /= 2
|
||||
heat_amount = rand(20000,60000)
|
||||
if (heat_target > 310)
|
||||
activ_text = "begins to radiate hot air!"
|
||||
deact_text = "stops pumping out hot air."
|
||||
if (heat_target < 310)
|
||||
activ_text = "begins to radiate cold air!"
|
||||
deact_text = "stops pumping out cold air."
|
||||
|
||||
effect_process(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
var/turf/simulated/L = get_turf(O)
|
||||
if(istype(L))
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
if(env.temperature < (heat_target+T0C))
|
||||
var/transfer_moles = 0.25 * env.total_moles()
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
if(removed)
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
if(heat_capacity)
|
||||
removed.temperature = (removed.temperature*heat_capacity + heat_amount)/heat_capacity
|
||||
env.merge(removed)
|
||||
@@ -0,0 +1,73 @@
|
||||
/obj/machinery/artifact/noisy_thing
|
||||
name = "artifact noisy thing"
|
||||
associated_datum = /datum/artifact/noisy_thing
|
||||
|
||||
ArtifactDeactivated()
|
||||
return // hahaha nope
|
||||
|
||||
/datum/artifact/noisy_thing
|
||||
associated_object = /obj/machinery/artifact/noisy_thing
|
||||
rarity_class = 1
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch)
|
||||
activated = 0
|
||||
activ_text = "begins making horrible noises!"
|
||||
deact_text = "shuts down, falling silent. Thank god for that."
|
||||
react_xray = list(9,50,40,3,"TUBULAR")
|
||||
var/spamsound = 'sound/effects/screech2.ogg'
|
||||
var/harmful = 0
|
||||
var/evil = 0
|
||||
var/sound_pitch = 1
|
||||
var/times_to_play = 1
|
||||
var/list/sounds = list('sound/machines/fortune_greeting_broken.ogg','sound/machines/engine_highpower.ogg','sound/machines/engine_grump1.ogg','sound/machines/engine_alert1.ogg',
|
||||
'sound/machines/engine_alert2.ogg','sound/machines/engine_alert3.ogg','sound/machines/lavamoon_alarm1.ogg','sound/machines/lavamoon_plantalarm.ogg','sound/machines/pod_alarm.ogg',
|
||||
'sound/machines/printer_dotmatrix.ogg','sound/machines/printer_thermal.ogg','sound/machines/romhack1.ogg','sound/machines/satcrash.ogg','sound/machines/siren_generalquarters.ogg',
|
||||
'sound/machines/signal.ogg','sound/machines/ufo_move.ogg','sound/machines/modem.ogg','sound/ambience/ambimo1.ogg','sound/ambience/creaking_metal.ogg','sound/ambience/voidfx2.ogg','sound/ambience/precursorfx2.ogg')
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
..()
|
||||
src.react_heat[2] = "HIGH INTERNAL CONVECTION"
|
||||
src.spamsound = pick(sounds)
|
||||
src.sound_pitch = rand(2,20)
|
||||
src.sound_pitch /= 10
|
||||
src.times_to_play = rand(1,3)
|
||||
var/harmprob = 5
|
||||
if (src.artitype == "eldritch")
|
||||
harmprob += 20
|
||||
if (prob(harmprob))
|
||||
src.harmful = 1
|
||||
if (prob(1))
|
||||
evil = 1
|
||||
|
||||
effect_process(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
var/loops = src.times_to_play
|
||||
var/turf/T = get_turf(O)
|
||||
if (evil)
|
||||
for(var/X in src.sounds)
|
||||
playsound(T, X, 200, 1, 0, sound_pitch)
|
||||
else
|
||||
while (loops > 0)
|
||||
loops--
|
||||
playsound(T, src.spamsound, 200, 1, 0, sound_pitch)
|
||||
|
||||
if (src.harmful)
|
||||
for (var/mob/living/M in hearers(world.view, O))
|
||||
if (issilicon(M) || isintangible(M))
|
||||
continue
|
||||
if (!M.ears_protected_from_sound())
|
||||
boutput(M, "<span style=\"color:red\">The loud, horrible noises painfully batter your eardrums!</span>")
|
||||
else
|
||||
continue
|
||||
|
||||
var/weak = 0
|
||||
var/ear_damage = 2
|
||||
var/ear_tempdeaf = 4
|
||||
if (prob(10))
|
||||
weak = 2
|
||||
|
||||
M.apply_sonic_stun(weak, 0, 0, 0, 0, ear_damage, ear_tempdeaf)
|
||||
|
||||
return
|
||||
@@ -0,0 +1,51 @@
|
||||
/obj/machinery/artifact/plant_helper
|
||||
name = "artifact plant_helper"
|
||||
associated_datum = /datum/artifact/plant_helper
|
||||
|
||||
/datum/artifact/plant_helper
|
||||
associated_object = /obj/machinery/artifact/plant_helper
|
||||
rarity_class = 2
|
||||
validtypes = list("martian","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/carbon_touch)
|
||||
activated = 0
|
||||
activ_text = "begins to radiate a strange energy field!"
|
||||
deact_text = "shuts down, causing the energy field to vanish!"
|
||||
react_xray = list(9,45,85,11,"ORGANIC")
|
||||
var/field_radius = 7
|
||||
var/list/helpers = list("water") // make it a bit more modular
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "SUPERFICIAL DAMAGE DETECTED"
|
||||
src.field_radius = rand(2,9) // field radius
|
||||
if (prob(80))
|
||||
src.helpers.Add("growth")
|
||||
if (prob(60))
|
||||
src.helpers.Add("health")
|
||||
if (prob(40))
|
||||
src.helpers.Add("weedkiller")
|
||||
if (prob(20))
|
||||
src.helpers.Add("mutation")
|
||||
|
||||
effect_process(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
for (var/obj/machinery/plantpot/P in range(O,src.field_radius))
|
||||
var/datum/plant/growing = P.current
|
||||
for (var/X in src.helpers)
|
||||
if (X == "water")
|
||||
var/wateramt = P.reagents.get_reagent_amount("water")
|
||||
if(wateramt > 200)
|
||||
P.reagents.remove_reagent("water", 1)
|
||||
if(wateramt < 100)
|
||||
P.reagents.add_reagent("water", 1)
|
||||
if (X == "growth" && growing)
|
||||
P.growth++
|
||||
if (X == "health" && growing)
|
||||
P.health++
|
||||
if (X == "weedkiller" && growing)
|
||||
if (growing.growthmode == "weed")
|
||||
P.health -= 3
|
||||
if (X == "mutation" && growing)
|
||||
if (prob(8))
|
||||
P.HYPmutateplant()
|
||||
@@ -0,0 +1,72 @@
|
||||
/obj/machinery/artifact/turret
|
||||
name = "artifact turret"
|
||||
associated_datum = /datum/artifact/turret
|
||||
|
||||
/datum/artifact/turret
|
||||
associated_object = /obj/machinery/artifact/turret
|
||||
rarity_class = 3
|
||||
validtypes = list("wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch)
|
||||
activated = 0
|
||||
activ_text = "uncovers an array of guns!"
|
||||
deact_text = "retracts the guns back into itself and falls quiet!"
|
||||
react_xray = list(9,40,80,8,"SEGMENTED")
|
||||
var/cycles_without_target = 0
|
||||
var/cycles_until_shutdown = 10
|
||||
var/capricious = 0
|
||||
var/shot_range = 3
|
||||
var/datum/projectile/artifact/bullet = null
|
||||
var/mob/living/friend = null
|
||||
var/mob/living/current_target = null
|
||||
examine_hint = "It is covered in very conspicuous markings."
|
||||
|
||||
New()
|
||||
bullet = new /datum/projectile/artifact
|
||||
shot_range = rand(2,6)
|
||||
if (prob(20))
|
||||
capricious = 1
|
||||
bullet.randomise()
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (src.capricious > -1)
|
||||
if (!src.friend || src.capricious)
|
||||
src.friend = user
|
||||
|
||||
effect_process(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
if (!current_target)
|
||||
var/list/valid_targets = list()
|
||||
for (var/mob/living/M in view(shot_range,O))
|
||||
if (!target_is_valid(M,O))
|
||||
continue
|
||||
valid_targets += M
|
||||
if (valid_targets.len > 0)
|
||||
current_target = pick(valid_targets)
|
||||
T.visible_message("<b>[O]</b> turns to face [current_target]!")
|
||||
cycles_without_target = 0
|
||||
else
|
||||
cycles_without_target++
|
||||
if (cycles_without_target >= cycles_until_shutdown)
|
||||
cycles_without_target = 0
|
||||
O.ArtifactDeactivated()
|
||||
else
|
||||
if (target_is_valid(current_target,O) && istype(bullet,/datum/projectile/artifact))
|
||||
shoot_projectile_ST(O, bullet, current_target)
|
||||
else
|
||||
current_target = null
|
||||
|
||||
proc/target_is_valid(var/mob/living/M,var/obj/O)
|
||||
if (!M || !O)
|
||||
return 0
|
||||
if (M.stat == 2)
|
||||
return 0
|
||||
if (M == friend)
|
||||
return 0
|
||||
if (get_dist(M,O) > shot_range)
|
||||
return 0
|
||||
return 1
|
||||
@@ -0,0 +1,223 @@
|
||||
// base
|
||||
|
||||
/datum/artifact/bomb
|
||||
associated_object = null
|
||||
rarity_class = 0
|
||||
validtypes = list("ancient","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/cold,/datum/artifact_trigger/radiation)
|
||||
react_xray = list(12,75,30,11,"COMPLEX")
|
||||
var/explode_delay = 600
|
||||
var/dud = 0
|
||||
var/warning_initial = "begins catastrophically overloading!"
|
||||
var/warning_final = "reaches critical energy levels!"
|
||||
var/text_disarmed = "goes quiet."
|
||||
var/text_dud = "sputters and rattles a bit, then falls quiet."
|
||||
var/flascustomization_first_color = "#FF0000"
|
||||
var/sound/alarm_initial = 'sound/machines/lavamoon_plantalarm.ogg'
|
||||
var/sound/alarm_final = 'sound/machines/engine_alert1.ogg'
|
||||
examine_hint = "It is covered in very conspicuous markings."
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "VOLATILE REACTION DETECTED"
|
||||
if (artitype != "eldritch" && prob(5))
|
||||
dud = 1
|
||||
|
||||
effect_activate(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
if (explode_delay < 1)
|
||||
deploy_payload(O)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(O)
|
||||
|
||||
if (warning_initial)
|
||||
T.visible_message("<b>[O] [warning_initial]</b>")
|
||||
if (alarm_initial)
|
||||
playsound(T, alarm_initial, 50, 1, -1)
|
||||
|
||||
spawn(src.explode_delay)
|
||||
if (warning_final)
|
||||
T.visible_message("<b>[O] [warning_final]</b>")
|
||||
if (alarm_final)
|
||||
playsound(T, alarm_final, 50, 1, -1)
|
||||
animate_flash_color_fill(O,flascustomization_first_color,10,3)
|
||||
|
||||
spawn(30)
|
||||
if (src.activated)
|
||||
deploy_payload(O)
|
||||
else
|
||||
T.visible_message("<b>[O] [text_disarmed]")
|
||||
|
||||
proc/deploy_payload(var/obj/O)
|
||||
if (!O)
|
||||
return 1
|
||||
if (dud)
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<b>[O] [text_dud]")
|
||||
O.ArtifactDeactivated()
|
||||
return 1
|
||||
|
||||
// Added (Convair880).
|
||||
ArtifactLogs(usr, null, O, "detonated", null, 1)
|
||||
|
||||
return 0
|
||||
|
||||
// regular explosives
|
||||
|
||||
/obj/artifact/bomb
|
||||
name = "artifact bomb"
|
||||
associated_datum = /datum/artifact/bomb/explosive
|
||||
|
||||
/datum/artifact/bomb/explosive
|
||||
associated_object = /obj/artifact/bomb
|
||||
rarity_class = 3
|
||||
var/exp_deva = 1
|
||||
var/exp_hevy = 2
|
||||
var/exp_lite = 3
|
||||
|
||||
New()
|
||||
..()
|
||||
src.exp_deva = rand(0,3)
|
||||
src.exp_hevy = rand(3,6)
|
||||
src.exp_lite = rand(6,9)
|
||||
|
||||
deploy_payload(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
explosion(O, O.loc, src.exp_deva, src.exp_hevy, src.exp_lite, src.exp_lite * 2)
|
||||
|
||||
O.ArtifactDestroyed()
|
||||
|
||||
/obj/artifact/bomb/devastating
|
||||
name = "artifact devastating bomb"
|
||||
associated_datum = /datum/artifact/bomb/explosive/devastating
|
||||
|
||||
/datum/artifact/bomb/explosive/devastating
|
||||
associated_object = /obj/artifact/bomb/devastating
|
||||
rarity_class = 4
|
||||
|
||||
New()
|
||||
..()
|
||||
src.exp_deva *= rand(3,5)
|
||||
src.exp_hevy *= rand(4,6)
|
||||
src.exp_lite *= rand(5,7)
|
||||
src.explode_delay *= 2
|
||||
|
||||
// black hole bomb
|
||||
|
||||
/obj/artifact/bomb/blackhole
|
||||
name = "artifact black hole bomb"
|
||||
associated_datum = /datum/artifact/bomb/blackhole
|
||||
|
||||
/datum/artifact/bomb/blackhole
|
||||
associated_object = /obj/artifact/bomb/blackhole
|
||||
rarity_class = 4
|
||||
react_xray = list(12,75,30,11,"ULTRADENSE")
|
||||
warning_initial = "begins intensifying its own gravity!"
|
||||
warning_final = "begins to collapse in on itself!"
|
||||
|
||||
deploy_payload(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
playsound(T, "sound/machines/satcrash.ogg", 100, 0, 3, 0.8)
|
||||
new /obj/bhole(O.loc,rand(100,300))
|
||||
|
||||
if (O)
|
||||
O.ArtifactDestroyed()
|
||||
|
||||
// chemical bombs
|
||||
|
||||
/obj/artifact/bomb/chemical
|
||||
name = "artifact chemical bomb"
|
||||
associated_datum = /datum/artifact/bomb/chemical
|
||||
|
||||
New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(10000)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
|
||||
/datum/artifact/bomb/chemical
|
||||
explode_delay = 0
|
||||
react_xray = list(5,65,20,11,"HOLLOW")
|
||||
validtypes = list("ancient","martian","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/heat,/datum/artifact_trigger/carbon_touch)
|
||||
var/payload_type = 0 // 0 for smoke, 1 for foam
|
||||
var/recharge_delay = 600
|
||||
var/list/payload_reagents = list()
|
||||
|
||||
post_setup()
|
||||
payload_type = rand(0,1)
|
||||
var/list/potential_reagents = list()
|
||||
switch(artitype)
|
||||
if ("ancient")
|
||||
// industrial heavy machinery kinda stuff
|
||||
potential_reagents = list("nanites","liquid plasma","mercury","lithium","plasma","radium","uranium","napalm",
|
||||
"thermite","fuel","acid","silicate","lube","cryostylane","oil")
|
||||
if ("martian")
|
||||
// medicine, some poisons, some gross stuff
|
||||
potential_reagents = list("charcoal","stypic_powder","salbutamol","anti_rad","silver_sulfadiazine","synaptizine",
|
||||
"omnizine","synthflesh","cyanide","sonambutril","toxin","neurotoxin","mutagen","fake_initropidril",
|
||||
"toxic_slurry","jenkem","space_fungus","blood","vomit","gvomit","urine","meat_slurry","grease")
|
||||
if ("eldritch")
|
||||
// all the worst stuff. all of it
|
||||
potential_reagents = list("chlorine","fluorine","lithium","mercury","plasma","radium","uranium","strange_reagent",
|
||||
"napalm","thermite","infernite","foof","fuel","blackpowder","acid","amanitin","coniine","cyanide","curare",
|
||||
"formaldehyde","lipolicide","initropidril","cholesterol","itching","pacid","pancuronium","polonium",
|
||||
"sodium_thiopental","sonambutril","sulfonal","toxin","venom","neurotoxin","mutagen","wolfsbane",
|
||||
"toxic_slurry","histamine","sarin")
|
||||
else
|
||||
// absolutely everything
|
||||
potential_reagents = all_functional_reagent_ids
|
||||
|
||||
if (potential_reagents.len > 0)
|
||||
var/looper = rand(2,8)
|
||||
while (looper > 0)
|
||||
looper--
|
||||
payload_reagents += pick(potential_reagents)
|
||||
|
||||
recharge_delay = rand(200,800)
|
||||
|
||||
deploy_payload(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
|
||||
var/list/reaction_reagents = list()
|
||||
|
||||
for (var/X in payload_reagents)
|
||||
reaction_reagents += X
|
||||
|
||||
if (payload_type)
|
||||
reaction_reagents += "fluorosurfactant"
|
||||
reaction_reagents += "water"
|
||||
else
|
||||
reaction_reagents += "potassium"
|
||||
reaction_reagents += "sugar"
|
||||
reaction_reagents += "phosphorus"
|
||||
|
||||
var/amountper = 0
|
||||
if (reaction_reagents.len > 0)
|
||||
amountper = round(O.reagents.maximum_volume / reaction_reagents.len)
|
||||
else
|
||||
amountper = 20
|
||||
|
||||
for (var/X in reaction_reagents)
|
||||
O.reagents.add_reagent(X,amountper)
|
||||
|
||||
if (payload_type)
|
||||
var/turf/location = get_turf(O)
|
||||
var/datum/effects/system/foam_spread/s = new()
|
||||
s.set_up(O.reagents.total_volume, location, O.reagents, 0)
|
||||
s.start()
|
||||
else
|
||||
smoke_reaction(O.reagents, 4, get_turf(O))
|
||||
|
||||
O.reagents.clear_reagents()
|
||||
|
||||
spawn(recharge_delay)
|
||||
if (O)
|
||||
O.ArtifactDeactivated()
|
||||
@@ -0,0 +1,62 @@
|
||||
/obj/artifact/borgifier
|
||||
name = "artifact human2cyborg converter"
|
||||
associated_datum = /datum/artifact/borgifier
|
||||
|
||||
/datum/artifact/borgifier
|
||||
associated_object = /obj/artifact/borgifier
|
||||
rarity_class = 3
|
||||
validtypes = list("ancient")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch)
|
||||
activated = 0
|
||||
react_xray = list(13,60,80,6,"COMPLEX")
|
||||
touch_descriptors = list("You seem to have a little difficulty taking your hand off its surface.")
|
||||
var/converting = 0
|
||||
var/list/work_sounds = list('sound/effects/bloody_stab.ogg','sound/effects/clang.ogg','sound/effects/airbridge_dpl.ogg','sound/effects/splat.ogg','sound/misc/loudcrunch2.ogg','sound/effects/attackblob.ogg')
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (!user)
|
||||
return
|
||||
if (converting)
|
||||
return
|
||||
if (istype(user,/mob/living/carbon/human/))
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> suddenly pulls [user.name] inside and slams shut!</span>")
|
||||
user.emote("scream")
|
||||
user.set_loc(O.loc)
|
||||
converting = 1
|
||||
var/loops = rand(10,20)
|
||||
while (loops > 0)
|
||||
loops--
|
||||
random_brute_damage(user, 15)
|
||||
user.paralysis = 5
|
||||
playsound(user.loc, pick(work_sounds), 50, 1, -1)
|
||||
sleep(4)
|
||||
|
||||
var/bdna = null // For forensics (Convair880).
|
||||
var/btype = null
|
||||
if (user.bioHolder.Uid && user.bioHolder.bloodType)
|
||||
bdna = user.bioHolder.Uid
|
||||
btype = user.bioHolder.bloodType
|
||||
var/turf/T = find_loc(user)
|
||||
gibs(T, null, null, bdna, btype)
|
||||
|
||||
ArtifactLogs(user, null, O, "touched", "robotizing user", 0) // Added (Convair880).
|
||||
|
||||
if (ismonkey(user))
|
||||
user.ghostize()
|
||||
var/robopath = pick(/obj/machinery/bot/guardbot,/obj/machinery/bot/secbot,
|
||||
/obj/machinery/bot/medbot,/obj/machinery/bot/firebot,/obj/machinery/bot/cleanbot,
|
||||
/obj/machinery/bot/floorbot)
|
||||
new robopath (T)
|
||||
qdel(user)
|
||||
else
|
||||
var/mob/living/carbon/human/M = user
|
||||
M.Robotize_MK2(1)
|
||||
score_cyborgsmade += 1
|
||||
converting = 0
|
||||
else if (istype(user,/mob/living/silicon/))
|
||||
boutput(user, "<span style=\"color:red\">An imperious voice rings out in your head... \"<b>HUNT BIOLOGICALS FOR UPGRADING\"</span>")
|
||||
else
|
||||
return
|
||||
@@ -0,0 +1,73 @@
|
||||
/obj/artifact/container
|
||||
name = "artifact sealed container"
|
||||
associated_datum = /datum/artifact/container
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
..()
|
||||
|
||||
ArtifactActivated(var/mob/living/user as mob)
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (A.activated)
|
||||
return
|
||||
A.activated = 1
|
||||
playsound(src.loc, A.activ_sound, 100, 1)
|
||||
src.overlays += A.fx_image
|
||||
src.visible_message("<b>[src] seems like it has something inside it...</b>")
|
||||
switch(rand(1,4))
|
||||
if(1)
|
||||
if(prob(5))
|
||||
new/obj/item/artifact/activator_key(src)
|
||||
else
|
||||
new/obj/item/cell/artifact(src)
|
||||
new/obj/item/cell/artifact(src)
|
||||
new/obj/item/cell/artifact(src)
|
||||
if(2)
|
||||
if(prob(5))
|
||||
new/obj/critter/domestic_bee/buddy(src)
|
||||
new/obj/item/clothing/suit/bee(src)
|
||||
else
|
||||
new/obj/critter/domestic_bee_larva(src)
|
||||
new/obj/critter/domestic_bee_larva(src)
|
||||
new/obj/critter/domestic_bee_larva(src)
|
||||
new/obj/critter/domestic_bee_larva(src)
|
||||
new/obj/critter/domestic_bee_larva(src)
|
||||
if(3)
|
||||
if(prob(5))
|
||||
new/obj/item/gimmickbomb/owlclothes(src)
|
||||
new/obj/item/gimmickbomb/owlclothes(src)
|
||||
new/obj/item/gimmickbomb/owlclothes(src)
|
||||
new/obj/item/gimmickbomb/owlclothes(src)
|
||||
new/obj/item/gimmickbomb/owlclothes(src)
|
||||
else
|
||||
new/obj/item/gimmickbomb/owlclothes(src)
|
||||
if(4)
|
||||
new/obj/item/old_grenade/light_gimmick(src)
|
||||
|
||||
/datum/artifact/container
|
||||
associated_object = /obj/artifact/container
|
||||
rarity_class = 1
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch)
|
||||
activ_text = "deposits its contents on the ground."
|
||||
deact_text = "ceases functioning."
|
||||
react_xray = list(7,50,40,11,"HOLLOW")
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "HIGH INTERNAL CONVECTION"
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
for(var/obj/I in O.contents)
|
||||
I.set_loc(O.loc)
|
||||
for(var/mob/N in viewers(O, null))
|
||||
N.flash(30)
|
||||
if(N.client)
|
||||
shake_camera(N, 6, 4)
|
||||
O.visible_message("<span style=\"color:red\"><b>With a blinding light [O] vanishes, leaving its contents behind.</b></span>")
|
||||
playsound(O.loc, "sound/effects/warp2.ogg", 50, 1)
|
||||
artifact_controls.artifacts -= src
|
||||
qdel(O)
|
||||
return
|
||||
@@ -0,0 +1,53 @@
|
||||
/obj/artifact/darkness_field
|
||||
name = "artifact darkness field"
|
||||
associated_datum = /datum/artifact/darkness_field
|
||||
|
||||
/datum/artifact/darkness_field
|
||||
associated_object = /obj/artifact/darkness_field
|
||||
rarity_class = 2
|
||||
max_triggers = 3
|
||||
validtypes = list("wizard","eldritch","precursor")
|
||||
react_xray = list(15,90,90,11,"NONE")
|
||||
var/field_radius = 0
|
||||
var/field_time = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
field_radius = rand(2,8)
|
||||
if (prob(1))
|
||||
field_radius *= 2
|
||||
field_time = rand(300,1800)
|
||||
|
||||
effect_activate(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> emits a wave of absolute darkness!</span>")
|
||||
O.anchored = 1
|
||||
for(var/turf/T in circular_range(O,field_radius))
|
||||
new /obj/darkness_field(T,field_time)
|
||||
spawn(field_time)
|
||||
if (O)
|
||||
O.anchored = 0
|
||||
O.ArtifactDeactivated()
|
||||
return
|
||||
|
||||
/obj/darkness_field
|
||||
name = ""
|
||||
desc = ""
|
||||
alpha = 0
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
color = "#000000"
|
||||
blend_mode = 1
|
||||
anchored = 1
|
||||
density = 0
|
||||
opacity = 0
|
||||
layer = NOLIGHT_EFFECTS_LAYER_BASE
|
||||
mouse_opacity = 0
|
||||
|
||||
New(var/loc,var/duration)
|
||||
..()
|
||||
animate(src, time = 20, alpha = 255, easing = LINEAR_EASING)
|
||||
spawn(duration)
|
||||
animate(src, time = 20, alpha = 0, easing = LINEAR_EASING)
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,55 @@
|
||||
/obj/artifact/forcefield_generator
|
||||
name = "artifact forcefield generator"
|
||||
associated_datum = /datum/artifact/forcefield_gen
|
||||
|
||||
/datum/artifact/forcefield_gen
|
||||
associated_object = /obj/artifact/forcefield_generator
|
||||
rarity_class = 1
|
||||
validtypes = list("wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/carbon_touch,
|
||||
/datum/artifact_trigger/silicon_touch)
|
||||
activated = 0
|
||||
activ_text = "comes to life, projecting out a wall of force!"
|
||||
deact_text = "shuts down, causing the forcefield to vanish!"
|
||||
react_xray = list(13,60,95,11,"NONE")
|
||||
var/cooldown = 80
|
||||
var/field_radius = 3
|
||||
var/field_time = 80
|
||||
var/icon_state = "shieldsparkles"
|
||||
var/next_activate = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
src.icon_state = pick("shieldsparkles","empdisable","greenglow","enshield","energyorb","forcewall","meteor_shield")
|
||||
src.field_radius = rand(2,6) // forcefield radius
|
||||
src.field_time = rand(15,1500) // forcefield duration
|
||||
src.cooldown = rand(50, 1200)
|
||||
src.activ_sound = pick('sound/effects/mag_forcewall.ogg','sound/effects/mag_warp.ogg','sound/effects/MagShieldUp.ogg')
|
||||
src.deact_sound = pick('sound/effects/MagShieldDown.ogg','sound/effects/shielddown2.ogg','sound/effects/singsuck.ogg')
|
||||
|
||||
may_activate(var/obj/O)
|
||||
if (!..())
|
||||
return 0
|
||||
if (ticker.round_elapsed_ticks < next_activate)
|
||||
O.visible_message("<span style=\"color:red\">[O] emits a loud pop and lights up momentarily but nothing happens!</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
effect_activate(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
O.anchored = 1
|
||||
var/turf/Aloc = get_turf(O)
|
||||
var/list/forcefields = list()
|
||||
for (var/turf/T in range(field_radius,Aloc))
|
||||
if(get_dist(O,T) == field_radius)
|
||||
var/obj/forcefield/wand/FF = new /obj/forcefield/wand(T,0,src.icon_state)
|
||||
forcefields += FF
|
||||
spawn(field_time)
|
||||
for (var/obj/forcefield/F in forcefields)
|
||||
forcefields -= F
|
||||
qdel(F)
|
||||
next_activate = ticker.round_elapsed_ticks + cooldown
|
||||
if (O)
|
||||
O.ArtifactDeactivated()
|
||||
O.anchored = 0
|
||||
@@ -0,0 +1,54 @@
|
||||
/obj/artifact/healer_bio
|
||||
name = "artifact carbon healer"
|
||||
associated_datum = /datum/artifact/healer_bio
|
||||
|
||||
/datum/artifact/healer_bio
|
||||
associated_object = /obj/artifact/healer_bio
|
||||
rarity_class = 1
|
||||
validtypes = list("martian","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch)
|
||||
activated = 0
|
||||
activ_text = "begins to pulse softly."
|
||||
deact_text = "ceases pulsing."
|
||||
react_xray = list(11,70,90,9,"NONE")
|
||||
var/heal_amt = 20
|
||||
var/field_range = 0
|
||||
var/recharge_time = 600
|
||||
var/recharging = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
src.react_heat[2] = "SUPERFICIAL DAMAGE DETECTED"
|
||||
if(prob(20))
|
||||
src.field_range = rand(3,10) // range
|
||||
src.heal_amt = rand(5,75) // amount of healing
|
||||
src.recharge_time = rand(1,10) * 10
|
||||
if(prob(5))
|
||||
src.recharge_time = 0
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (!user)
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
if (recharging)
|
||||
boutput(user, "<span style=\"color:red\">The artifact pulses briefly, but nothing else happens.</span>")
|
||||
return
|
||||
if (recharge_time > 0)
|
||||
recharging = 1
|
||||
T.visible_message("<b>[O]</b> emits a wave of energy!")
|
||||
if(istype(user,/mob/living/carbon/))
|
||||
var/mob/living/carbon/C = user
|
||||
C.HealDamage("All", heal_amt, heal_amt)
|
||||
boutput(C, "<span style=\"color:blue\">Soothing energy saturates your body, making you feel refreshed and healthy.</span>")
|
||||
if (field_range > 0)
|
||||
for (var/mob/living/carbon/C in range(field_range,T))
|
||||
if (C == user)
|
||||
continue
|
||||
C.HealDamage("All", heal_amt, heal_amt)
|
||||
boutput(C, "<span style=\"color:blue\">Waves of soothing energy wash over you, making you feel refreshed and healthy.</span>")
|
||||
spawn(recharge_time)
|
||||
recharging = 0
|
||||
T.visible_message("<b>[O]</b> becomes energized.")
|
||||
@@ -0,0 +1,56 @@
|
||||
/obj/artifact/injector
|
||||
name = "artifact injector"
|
||||
associated_datum = /datum/artifact/injector
|
||||
|
||||
/datum/artifact/injector
|
||||
associated_object = /obj/artifact/injector
|
||||
rarity_class = 2
|
||||
validtypes = list("ancient","martian","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch,
|
||||
/datum/artifact_trigger/cold)
|
||||
activ_text = "opens up, revealing an array of strange needles!"
|
||||
deact_text = "closes itself up."
|
||||
react_xray = list(8,60,75,11,"SEGMENTED")
|
||||
var/list/injection_reagents = list()
|
||||
var/injection_amount = 10
|
||||
|
||||
post_setup()
|
||||
var/list/potential_reagents = list()
|
||||
switch(artitype)
|
||||
if ("ancient")
|
||||
// industrial heavy machinery kinda stuff
|
||||
potential_reagents = list("nanites","liquid plasma","mercury","lithium","plasma","radium","uranium","cryostylane")
|
||||
if ("martian")
|
||||
// medicine, some poisons, some gross stuff
|
||||
potential_reagents = list("charcoal","salbutamol","anti_rad","synaptizine","omnizine","synthflesh",
|
||||
"cyanide","sonambutril","toxin","neurotoxin","mutagen","fake_initropidril",
|
||||
"toxic_slurry","space_fungus","blood","urine","meat_slurry")
|
||||
if ("eldritch")
|
||||
// all the worst stuff. all of it
|
||||
potential_reagents = list("chlorine","fluorine","lithium","mercury","plasma","radium","uranium","strange_reagent",
|
||||
"amanitin","coniine","cyanide","curare",
|
||||
"formaldehyde","lipolicide","initropidril","cholesterol","itching","pancuronium","polonium",
|
||||
"sodium_thiopental","sonambutril","sulfonal","toxin","venom","neurotoxin","mutagen","wolfsbane",
|
||||
"toxic_slurry","histamine","sarin")
|
||||
else
|
||||
// absolutely everything
|
||||
potential_reagents = all_functional_reagent_ids
|
||||
|
||||
if (potential_reagents.len > 0)
|
||||
var/looper = rand(1,3)
|
||||
while (looper > 0)
|
||||
looper--
|
||||
injection_reagents += pick(potential_reagents)
|
||||
|
||||
injection_amount = rand(3,25)
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (user.reagents && injection_reagents.len > 0)
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<b>[O]</b> jabs [user] with a needle and injects something!")
|
||||
for (var/X in injection_reagents)
|
||||
ArtifactLogs(user, null, O, "touched by [user.real_name]", "injecting [X]", 0) // Added (Convair880).
|
||||
user.reagents.add_reagent(X,injection_amount)
|
||||
@@ -0,0 +1,44 @@
|
||||
/obj/artifact/lamp
|
||||
name = "artifact lamp"
|
||||
associated_datum = /datum/artifact/lamp
|
||||
var/light_brightness = 1
|
||||
var/light_R = 1
|
||||
var/light_G = 1
|
||||
var/light_B = 1
|
||||
var/datum/light/light
|
||||
|
||||
New()
|
||||
..()
|
||||
light_brightness = max(0.5, (rand(5, 20) / 10))
|
||||
light_R = rand(25,100) / 100
|
||||
light_G = rand(25,100) / 100
|
||||
light_B = rand(25,100) / 100
|
||||
light = new /datum/light/point
|
||||
light.set_brightness(light_brightness)
|
||||
light.set_color(light_R, light_G, light_B)
|
||||
light.attach(src)
|
||||
|
||||
/datum/artifact/lamp
|
||||
associated_object = /obj/artifact/lamp
|
||||
rarity_class = 1
|
||||
validtypes = list("martian","wizard","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch,
|
||||
/datum/artifact_trigger/cold)
|
||||
activ_text = "begins to emit a steady light!"
|
||||
deact_text = "goes dark and quiet."
|
||||
react_xray = list(10,90,90,11,"NONE")
|
||||
|
||||
effect_activate(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
var/obj/artifact/lamp/L = O
|
||||
if (L.light)
|
||||
L.light.enable()
|
||||
|
||||
effect_deactivate(var/obj/O)
|
||||
if (..())
|
||||
return
|
||||
var/obj/artifact/lamp/L = O
|
||||
if (L.light)
|
||||
L.light.disable()
|
||||
@@ -0,0 +1,45 @@
|
||||
/obj/artifact/power_giver
|
||||
name = "artifact power giver"
|
||||
associated_datum = /datum/artifact/power_giver
|
||||
|
||||
/datum/artifact/power_giver
|
||||
associated_object = /obj/artifact/power_giver
|
||||
rarity_class = 3
|
||||
validtypes = list("martian","wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch,
|
||||
/datum/artifact_trigger/cold)
|
||||
activ_text = "begins glowing with an eerie light!"
|
||||
deact_text = "falls dark and quiet."
|
||||
react_xray = list(10,90,80,10,"NONE")
|
||||
var/power_granted = null
|
||||
var/power_time = 0
|
||||
var/recharge_time = 300
|
||||
var/ready = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
power_granted = pick("blind","mute","clumsy","fat","dwarf","fire_resist","cold_resist","resist_electric",
|
||||
"psy_resist","glowy","hulk","xray","horns","stinky","monkey","mattereater","jumpy","telepathy","empath",
|
||||
"immolate","eyebeams","melt")
|
||||
power_time = rand(30,180)
|
||||
if (prob(5))
|
||||
power_time = 0
|
||||
recharge_time = rand(100,600)
|
||||
if (prob(5))
|
||||
recharge_time = 0
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (!istype(user,/mob/living/carbon/))
|
||||
return
|
||||
if (user.bioHolder && ready)
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<b>[O]</b> envelops [user] in a strange light!")
|
||||
user.bioHolder.AddEffect(power_granted,0,power_time)
|
||||
if (recharge_time > 0)
|
||||
ready = 0
|
||||
spawn(recharge_time)
|
||||
T.visible_message("<b>[O]</b> begins to glow again.")
|
||||
ready = 1
|
||||
@@ -0,0 +1,39 @@
|
||||
/obj/artifact/prison
|
||||
name = "artifact imprisoner"
|
||||
associated_datum = /datum/artifact/prison
|
||||
|
||||
/datum/artifact/prison
|
||||
associated_object = /obj/artifact/prison
|
||||
rarity_class = 2
|
||||
min_triggers = 2
|
||||
max_triggers = 2
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch)
|
||||
react_xray = list(15,90,90,11,"HOLLOW")
|
||||
touch_descriptors = list("You seem to have a little difficulty taking your hand off its surface.")
|
||||
var/mob/living/prisoner = null
|
||||
var/imprison_time = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
imprison_time = rand(50,1200)
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (!user)
|
||||
return
|
||||
if (prisoner)
|
||||
return
|
||||
if (istype(user,/mob/living/))
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> suddenly pulls [user.name] inside and slams shut!</span>")
|
||||
user.set_loc(O)
|
||||
prisoner = user
|
||||
spawn(imprison_time)
|
||||
for(var/obj/I in O.contents)
|
||||
I.set_loc(get_turf(O))
|
||||
prisoner.set_loc(get_turf(O))
|
||||
prisoner = null
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> releases [user.name] and shuts down!</span>")
|
||||
O.ArtifactDeactivated()
|
||||
return
|
||||
@@ -0,0 +1,31 @@
|
||||
/obj/artifact/teleport_recaller
|
||||
name = "artifact recaller"
|
||||
associated_datum = /datum/artifact/recaller
|
||||
|
||||
/datum/artifact/recaller
|
||||
associated_object = /obj/artifact/teleport_recaller
|
||||
rarity_class = 2
|
||||
validtypes = list("wizard","eldritch","precursor")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch)
|
||||
activated = 0
|
||||
react_xray = list(15,75,90,3,"ANOMALOUS")
|
||||
var/recall_delay = 10
|
||||
|
||||
New()
|
||||
..()
|
||||
src.recall_delay = rand(2,600) // how long *10 it takes for the recall to happen
|
||||
src.recall_delay *= 10
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (!user)
|
||||
return
|
||||
|
||||
spawn(src.recall_delay)
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> is suddenly pulled through space!</span>")
|
||||
playsound(user.loc, "sound/effects/mag_warp.ogg", 50, 1, -1)
|
||||
var/turf/T = get_turf(O)
|
||||
if (T)
|
||||
user.set_loc(T)
|
||||
@@ -0,0 +1,92 @@
|
||||
/obj/artifact/wish_granter
|
||||
name = "artifact wish granter"
|
||||
associated_datum = /datum/artifact/wish_granter
|
||||
|
||||
/datum/artifact/wish_granter
|
||||
associated_object = /obj/artifact/wish_granter
|
||||
rarity_class = 4
|
||||
validtypes = list("wizard","eldritch")
|
||||
validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/cold)
|
||||
activ_text = "begins glowing with an enticing light!"
|
||||
deact_text = "falls dark and quiet."
|
||||
react_xray = list(666,666,666,11,"NONE")
|
||||
var/list/wish_granted = list()
|
||||
var/evil = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
if (prob(50))
|
||||
evil = 1
|
||||
|
||||
effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (!istype(user,/mob/living/))
|
||||
return
|
||||
if (user.key in wish_granted)
|
||||
boutput(user, "<b>[O]</b> is silent.")
|
||||
return
|
||||
boutput(user, "<b>[O]</b> resonates, \"<big>I SHALL GRANT YOU ONE WISH...</big>\"")
|
||||
|
||||
var/list/wishes = list("I wish to become rich!","I wish for great power!")
|
||||
|
||||
var/wish = input("Make a wish?","[O]") as null|anything in wishes
|
||||
if (!wish)
|
||||
boutput(user, "You say nothing.")
|
||||
boutput(user, "<b>[O]</b> resonates, \"<big>YOU MAY RETURN LATER...</big>\"")
|
||||
return
|
||||
|
||||
wish_granted += user.key
|
||||
user.say(wish)
|
||||
sleep(5)
|
||||
boutput(user, "<b>[O]</b> resonates, \"<big>SO BE IT...</big>\"")
|
||||
playsound(O, "sound/effects/gong_rumble.ogg", 40, 1)
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> begins to charge up...</span>")
|
||||
sleep(30)
|
||||
if (prob(2))
|
||||
evil = !evil
|
||||
|
||||
if (evil)
|
||||
switch(wish)
|
||||
if("I wish to become rich!")
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> envelops [user] in a golden light!</span>")
|
||||
playsound(user, "sound/weapons/flashbang.ogg", 50, 1)
|
||||
for(var/mob/N in viewers(user, null))
|
||||
N.flash(30)
|
||||
if(N.client)
|
||||
shake_camera(N, 6, 4)
|
||||
user.desc = "A statue of someone very wealthy"
|
||||
user.become_gold_statue()
|
||||
|
||||
if("I wish for great power!")
|
||||
O.visible_message("<span style=\"color:red\"><b>[O] discharges a massive bolt of electricity!</b></span>")
|
||||
playsound(user, "sound/effects/elec_bigzap.ogg", 40, 1)
|
||||
var/list/affected = DrawLine(O,user,/obj/line_obj/elec,'icons/obj/projectiles.dmi',"WholeLghtn",1,1,"HalfStartLghtn","HalfEndLghtn",OBJ_LAYER,1,PreloadedIcon='icons/effects/LghtLine.dmi')
|
||||
for(var/obj/OB in affected)
|
||||
spawn(6)
|
||||
pool(OB)
|
||||
user.elecgib()
|
||||
else
|
||||
switch(wish)
|
||||
if("I wish to become rich!")
|
||||
O.visible_message("<span style=\"color:red\">A ton of money falls out of thin air! Woah!</span>")
|
||||
for(var/turf/T in range(user,3))
|
||||
if (T.density)
|
||||
continue
|
||||
new /obj/item/spacecash/million(T)
|
||||
|
||||
if("I wish for great power!")
|
||||
O.visible_message("<span style=\"color:red\"><b>[O]</b> envelops [user] in a brilliant light!</span>")
|
||||
if (ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if (H.bioHolder)
|
||||
H.bioHolder.RandomEffect("good")
|
||||
H.bioHolder.RandomEffect("good")
|
||||
H.bioHolder.RandomEffect("good")
|
||||
else if (istype(user,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if (istype(R.cell))
|
||||
R.cell.genrate = 100
|
||||
R.cell.maxcharge = 1000000
|
||||
R.cell.charge = R.cell.maxcharge
|
||||
@@ -0,0 +1,175 @@
|
||||
// MASTER DATUMS
|
||||
|
||||
/datum/artifact/
|
||||
var/associated_object = null
|
||||
var/rarity_class = 0
|
||||
|
||||
var/datum/artifact_origin/artitype = null
|
||||
var/list/validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
// During setup, artitype will be set from a pick() from within the validtypes list.
|
||||
// Keep it to only the five here or shit will probably get a bit weird. This allows us to exclude things that don't make
|
||||
// any sense such as martian robot builders or ancient robot plant seeds.
|
||||
|
||||
var/internal_name = null
|
||||
var/image/fx_image = null
|
||||
//var/image/effects_overlay = null
|
||||
var/obj/holder = null
|
||||
// These are automatically handled. They're used to make the artifact glow different colors.
|
||||
|
||||
var/activated = 0 // Is the artifact currently switched on?
|
||||
var/automatic_activation = 0 // Does the artifact switch itself on on spawn?
|
||||
var/activ_sound = null // What noise the artifact makes when it activates
|
||||
var/activ_text = null // What message the artifact transmits when it activates
|
||||
var/deact_sound = null // Guess.
|
||||
var/deact_text = null // No really, have a wild guess.
|
||||
var/scramblechance = 10 // how likely this artifact is to look like a type it isnt
|
||||
|
||||
var/list/faults = list() // Automatically handled
|
||||
var/list/fault_types = list() // this is set up based on the artifact's origin type
|
||||
|
||||
var/list/triggers = list()
|
||||
var/validtriggers = list(/datum/artifact_trigger/force,/datum/artifact_trigger/electric,/datum/artifact_trigger/heat,
|
||||
/datum/artifact_trigger/radiation,/datum/artifact_trigger/carbon_touch,/datum/artifact_trigger/silicon_touch)
|
||||
var/min_triggers = 1
|
||||
var/max_triggers = 1
|
||||
var/hint_text = "emits a faint noise."
|
||||
var/examine_hint = null
|
||||
|
||||
// These are used for module research
|
||||
var/list/module_research = list()
|
||||
var/module_research_insight = 1 // insight level into the origin of the artifact
|
||||
|
||||
var/health = 100
|
||||
// This is mostly used in the stimulus procs that deal with damaging the artifact and whatnot.
|
||||
// Once it hits 0 or below, the artifact is destroyed.
|
||||
|
||||
// these below are holders for data that will come back from the various artifact sensor test apparatus
|
||||
var/list/react_mpct = list(0,0)
|
||||
// Impact Pad - returns Vibration Amplitude, Vibration Frequency
|
||||
// react_mpct should be set up in the ArtifactSetup proc
|
||||
var/list/react_elec = list(0.1,0,0)
|
||||
// Electrobox - returns Returned Current, Circuit Capacity, Circuit Interference
|
||||
// react_elec should be set up in the item's New proc (NOT the datum's!)
|
||||
var/list/react_heat = list(1,"NONE")
|
||||
// Heat Plate - returns Artifact Temp, Heat Response, Cold Response, Details
|
||||
// react_heat - set up first var in ArtifactSetup, the rest in the individual datums
|
||||
var/list/react_xray = list(10,100,100,11,"NONE")
|
||||
// X-ray - returns Density, Structural Consistency, Structural Integrity, Response, Special Features
|
||||
// react_xray should be set as a variable on the artifact datum
|
||||
var/list/touch_descriptors = list()
|
||||
|
||||
proc/post_setup()
|
||||
return
|
||||
|
||||
proc/may_activate(var/obj/O)
|
||||
if (!O)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// Added log entry calls here. See artifactprocs.dm for the proc (Convair880).
|
||||
proc/effect_activate(var/obj/O)
|
||||
if (!O)
|
||||
return 1
|
||||
O.add_fingerprint(usr)
|
||||
ArtifactLogs(usr, null, O, "activated", null, istype(src, /datum/artifact/bomb/) ? 1 : 0)
|
||||
return 0
|
||||
|
||||
proc/effect_deactivate(var/obj/O)
|
||||
if (!O)
|
||||
return 1
|
||||
O.add_fingerprint(usr)
|
||||
ArtifactLogs(usr, null, O, "deactivated", null, 0)
|
||||
return 0
|
||||
|
||||
proc/effect_process(var/obj/O)
|
||||
if (!O)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/effect_touch(var/obj/O,var/mob/living/user)
|
||||
if (!O || !user)
|
||||
return 1
|
||||
O.add_fingerprint(user)
|
||||
return 0
|
||||
|
||||
proc/effect_melee_attack(var/obj/O,var/mob/living/user,var/mob/living/target)
|
||||
if (!O || !user || !target)
|
||||
return 1
|
||||
O.add_fingerprint(user)
|
||||
ArtifactLogs(user, target, O, "weapon", null, 0)
|
||||
return 0
|
||||
|
||||
proc/effect_click_tile(var/obj/O,var/mob/living/user,var/turf/T)
|
||||
if (!O || !user || !T)
|
||||
return 1
|
||||
O.add_fingerprint(user)
|
||||
if (!istype(O, /obj/item/artifact/attack_wand)) // Special log handling required there.
|
||||
ArtifactLogs(user, T, O, "used", "triggering its effect on target turf", 0)
|
||||
return 0
|
||||
|
||||
proc/get_trigger_by_string(var/string)
|
||||
if (!istext(string))
|
||||
return null
|
||||
for (var/datum/artifact_trigger/AT in src.triggers)
|
||||
if (AT.stimulus_required == string)
|
||||
return AT
|
||||
return null
|
||||
|
||||
proc/get_trigger_by_path(var/path)
|
||||
if (!ispath(path))
|
||||
return null
|
||||
for (var/datum/artifact_trigger/AT in src.triggers)
|
||||
if (AT.type == path)
|
||||
return AT
|
||||
return null
|
||||
|
||||
// SPECIFIC DATUMS
|
||||
|
||||
/datum/artifact/art
|
||||
validtypes = list("ancient","martian","wizard","eldritch","precursor")
|
||||
activated = 0
|
||||
min_triggers = 0
|
||||
max_triggers = 0
|
||||
react_xray = list(10,100,100,11,"NONE")
|
||||
|
||||
// DATUMS USED BY ARTIFACTS
|
||||
|
||||
/datum/projectile/artifact
|
||||
name = "energy bolt"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "u_laser"
|
||||
power = 75
|
||||
cost = 25
|
||||
dissipation_rate = 0
|
||||
dissipation_delay = 50
|
||||
ks_ratio = 1.0
|
||||
sname = "energy bolt"
|
||||
shot_sound = 'sound/weapons/Taser.ogg'
|
||||
shot_number = 1
|
||||
damage_type = D_PIERCING
|
||||
hit_ground_chance = 90
|
||||
window_pass = 0
|
||||
|
||||
on_hit(atom/hit)
|
||||
return
|
||||
|
||||
proc/randomise()
|
||||
icon_state = pick("spark","laser","ibeam","u_laser","phaser_heavy","phaser_light","phaser_med","phaser_ultra","blue_spark","disrupt","disrupt_lethal","radbolt","crescent",
|
||||
"goo","40mmgatling","elecorb","purple_orb","triple")
|
||||
src.shot_sound = pick('sound/weapons/Taser.ogg','sound/weapons/flaregun.ogg','sound/weapons/Laser.ogg','sound/weapons/laserheavy.ogg','sound/weapons/laserlight.ogg','sound/weapons/lasermed.ogg','sound/weapons/laserultra.ogg','sound/weapons/grenade.ogg','sound/weapons/rocket.ogg','sound/weapons/snipershot.ogg','sound/weapons/TaserOLD.ogg','sound/weapons/ACgun1.ogg','sound/weapons/ACgun2.ogg')
|
||||
var/namep1 = pick("neutrino","meson","photon","quark","disruptor","atomic","zero point","tachyon","plasma","quantum","neutron","baryon","hadron","electron","positron")
|
||||
var/namep2 = pick("bolt","ray","beam","wave","burst","blast","torpedo","missile","bomb","shard","stream","string")
|
||||
src.name = "[namep1] [namep2]"
|
||||
// Now randomise the damage type, power, energy cost and other fun stuff
|
||||
|
||||
src.damage_type = pick(D_KINETIC,D_PIERCING,D_SLASHING,D_ENERGY,D_BURNING,D_RADIOACTIVE,D_TOXIC)
|
||||
src.power = rand(2,50)
|
||||
src.dissipation_rate = rand(1,power)
|
||||
src.dissipation_delay = rand(1,10)
|
||||
src.ks_ratio = pick(0, 1, prob(10); (rand(0, 10000) / 10000))
|
||||
|
||||
src.cost = rand(50,150)
|
||||
if (prob(20))
|
||||
src.window_pass = 1
|
||||
// Rare chance of the gun firing several shots in a burst
|
||||
shot_number = pick(1, prob(25); 2, prob(5); 3, prob(1); 4)
|
||||
@@ -0,0 +1,436 @@
|
||||
// Artifact Infrastructure Procs
|
||||
|
||||
/obj/landmark/artifact
|
||||
name = "artifact spawner"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "x3"
|
||||
anchored = 1.0
|
||||
var/spawnchance = 100 // prob chance out of 100 to spawn artifact at game start
|
||||
var/spawnpath = null // if you want a landmark to spawn a specific artifact rather than a random one
|
||||
|
||||
/obj/landmark/artifact/seed
|
||||
name = "artifact seed spawner"
|
||||
spawnpath = /obj/item/seed/alien
|
||||
|
||||
/obj/landmark/artifact/cannabis_seed
|
||||
name = "cannabis seed spawner"
|
||||
spawnpath = /obj/item/seed/cannabis
|
||||
// not actually an artifact but eh seeds are behaving oddly
|
||||
|
||||
/proc/Artifact_Spawn(var/atom/T,var/forceartitype)
|
||||
if (!T)
|
||||
return
|
||||
if (!istype(T,/turf/) && !istype(T,/obj/))
|
||||
return
|
||||
|
||||
var/rarityroll = 1
|
||||
|
||||
switch(rand(1,100))
|
||||
if (63 to 88)
|
||||
rarityroll = 2
|
||||
// 1 in 25
|
||||
if (89 to 99)
|
||||
rarityroll = 3
|
||||
// 1 in 10
|
||||
if (100)
|
||||
rarityroll = 4
|
||||
// 1 in 100
|
||||
else
|
||||
rarityroll = 1
|
||||
// 1 in 62
|
||||
|
||||
var/list/selection_pool = list()
|
||||
|
||||
for (var/datum/artifact/A in artifact_controls.artifact_types)
|
||||
if (A.rarity_class != rarityroll)
|
||||
continue
|
||||
if (istext(forceartitype) && !forceartitype in A.validtypes)
|
||||
continue
|
||||
selection_pool += A
|
||||
|
||||
if (selection_pool.len < 1)
|
||||
return
|
||||
|
||||
var/datum/artifact/picked = pick(selection_pool)
|
||||
if (!istype(picked,/datum/artifact/))
|
||||
return
|
||||
|
||||
if (istext(forceartitype))
|
||||
new picked.associated_object(T,forceartitype)
|
||||
else
|
||||
new picked.associated_object(T)
|
||||
|
||||
/obj/proc/ArtifactSanityCheck()
|
||||
// This proc is called in any other proc or thing that uses the new artifact shit. If there was an improper artifact variable
|
||||
// involved when trying to do the new shit, it would probably spew errors fucking everywhere and generally be horrible so if
|
||||
// the sanity check detects that an artifact doesn't have the proper shit set up it'll just wipe out the artifact and stop
|
||||
// the rest of the proc from occurring.
|
||||
// This proc should be called in an if statement at the start of every artifact proc, since it returns 0 or 1.
|
||||
if (!src.artifact)
|
||||
return 0
|
||||
// if the artifact var isn't set at all, it's probably not an artifact so don't bother continuing
|
||||
if (!istype(src.artifact,/datum/artifact/))
|
||||
logTheThing("debug", null, null, "<b>I Said No/Artifact:</b> Invalid artifact variable in [src.type] at [showCoords(src.x, src.y, src.z)]")
|
||||
qdel(src) // wipes itself out since if it's processing it'd be calling procs it can't use again and again
|
||||
return 0 // uh oh, we've got a poorly set up artifact and now we need to stop the proc that called it!
|
||||
else
|
||||
return 1 // give the all clear
|
||||
|
||||
/obj/proc/ArtifactSetup()
|
||||
// This proc gets called in every artifact's New() proc, after src.artifact is turned from a 1 into its appropriate datum.
|
||||
//It scrambles the name and appearance of the artifact so we can't tell what it is on sight or cursory examination.
|
||||
// Could potentially go in /obj/New(), but...
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
A.holder = src
|
||||
|
||||
var/datum/artifact_origin/AO = artifact_controls.get_origin_from_string(pick(A.validtypes))
|
||||
if (!istype(AO,/datum/artifact_origin/))
|
||||
qdel(src)
|
||||
return
|
||||
A.artitype = AO
|
||||
// Refers to the artifact datum's list of origins it's allowed to be from and selects one at random. This way we can avoid
|
||||
// stuff that doesn't make sense like ancient robot plant seeds or eldritch healing devices
|
||||
|
||||
var/datum/artifact_origin/appearance = artifact_controls.get_origin_from_string(AO.name)
|
||||
if (prob(A.scramblechance))
|
||||
appearance = null
|
||||
// rare-ish chance of an artifact appearing to be a different origin, just to throw things off
|
||||
|
||||
if (!istype(appearance,/datum/artifact_origin/))
|
||||
var/list/all_origin_names = list()
|
||||
for (var/datum/artifact_origin/O in artifact_controls.artifact_origins)
|
||||
all_origin_names += O.name
|
||||
appearance = artifact_controls.get_origin_from_string(pick(all_origin_names))
|
||||
|
||||
var/name1 = pick(appearance.adjectives)
|
||||
var/name2 = "thingy"
|
||||
if (istype(src,/obj/item/))
|
||||
name2 = pick(appearance.nouns_small)
|
||||
else
|
||||
name2 = pick(appearance.nouns_large)
|
||||
|
||||
src.name = "[name1] [name2]"
|
||||
src:real_name = "[name1] [name2]"
|
||||
desc = "You have no idea what this thing is!"
|
||||
A.touch_descriptors |= appearance.touch_descriptors
|
||||
|
||||
src.icon_state = appearance.name + "-[rand(1,appearance.max_sprites)]"
|
||||
if (istype(src,/obj/item/))
|
||||
var/obj/item/I = src
|
||||
I.item_state = appearance.name
|
||||
|
||||
A.fx_image = image(src.icon, src.icon_state + "fx")
|
||||
A.fx_image.color = rgb(rand(AO.fx_red_min,AO.fx_red_max),rand(AO.fx_green_min,AO.fx_green_max),rand(AO.fx_blue_min,AO.fx_blue_max))
|
||||
|
||||
A.react_mpct[1] = AO.impact_reaction_one
|
||||
A.react_mpct[2] = AO.impact_reaction_two
|
||||
A.react_heat[1] = AO.heat_reaction_one
|
||||
A.activ_sound = pick(AO.activation_sounds)
|
||||
A.fault_types |= AO.fault_types
|
||||
A.internal_name = AO.generate_name()
|
||||
|
||||
ArtifactDevelopFault(10)
|
||||
|
||||
if (A.automatic_activation)
|
||||
src.ArtifactActivated()
|
||||
else
|
||||
var/list/valid_triggers = A.validtriggers
|
||||
var/trigger_amount = rand(A.min_triggers,A.max_triggers)
|
||||
var/selection = null
|
||||
while (trigger_amount > 0)
|
||||
trigger_amount--
|
||||
selection = pick(valid_triggers)
|
||||
if (ispath(selection))
|
||||
var/datum/artifact_trigger/AT = new selection
|
||||
A.triggers += AT
|
||||
valid_triggers -= selection
|
||||
|
||||
artifact_controls.artifacts += src
|
||||
A.post_setup()
|
||||
|
||||
/obj/proc/ArtifactActivated()
|
||||
if (!src)
|
||||
return
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return 1
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (A.activated)
|
||||
return 1
|
||||
if (A.triggers.len < 1 && !A.automatic_activation)
|
||||
return 1 // can't activate these ones at all by design
|
||||
if (!A.may_activate(src))
|
||||
return 1
|
||||
if (A.activ_sound)
|
||||
playsound(src.loc, A.activ_sound, 100, 1)
|
||||
if (A.activ_text)
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<b>[src] [A.activ_text]</b>")
|
||||
A.activated = 1
|
||||
src.overlays += A.fx_image
|
||||
A.effect_activate(src)
|
||||
|
||||
/obj/proc/ArtifactDeactivated()
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (A.deact_sound)
|
||||
playsound(src.loc, A.deact_sound, 100, 1)
|
||||
if (A.deact_text)
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<b>[src] [A.deact_text]</b>")
|
||||
A.activated = 0
|
||||
src.overlays = null
|
||||
A.effect_deactivate(src)
|
||||
|
||||
/obj/proc/Artifact_attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/cargotele)) // Re-added (Convair880).
|
||||
var/obj/item/cargotele/CT = W
|
||||
CT.cargoteleport(src, user)
|
||||
return
|
||||
|
||||
if (istype(user,/mob/living/silicon/robot))
|
||||
src.ArtifactStimulus("silitouch", 1)
|
||||
|
||||
if (istype(W,/obj/item/artifact/activator_key))
|
||||
var/obj/item/artifact/activator_key/ACT = W
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
if (!W.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
var/datum/artifact/K = ACT.artifact
|
||||
|
||||
if (K.activated)
|
||||
if (ACT.universal || A.artitype == K.artitype)
|
||||
if (ACT.activator && !A.activated)
|
||||
src.ArtifactActivated()
|
||||
else if (!ACT.activator && A.activated)
|
||||
src.ArtifactDeactivated()
|
||||
else
|
||||
..()
|
||||
|
||||
if (istype(W,/obj/item/weldingtool))
|
||||
var/obj/item/weldingtool/WELD = W
|
||||
if (WELD.welding)
|
||||
WELD.eyecheck(user)
|
||||
src.ArtifactStimulus("heat", 800)
|
||||
playsound(src.loc, "sound/items/Welder.ogg", 100, 1)
|
||||
src.visible_message("<span style=\"color:red\">[user.name] burns the artifact with [WELD]!</span>")
|
||||
return 0
|
||||
|
||||
if (istype(W,/obj/item/zippo))
|
||||
var/obj/item/zippo/ZIP = W
|
||||
if (ZIP.lit)
|
||||
src.ArtifactStimulus("heat", 400)
|
||||
src.visible_message("<span style=\"color:red\">[user.name] burns the artifact with [ZIP]!</span>")
|
||||
return 0
|
||||
|
||||
if(istype(W,/obj/item/baton))
|
||||
var/obj/item/baton/BAT = W
|
||||
if (BAT.can_stun(1, 1, user) == 1)
|
||||
src.ArtifactStimulus("force", BAT.force)
|
||||
src.ArtifactStimulus("elec", 1500)
|
||||
playsound(src.loc, "sound/weapons/Egloves.ogg", 100, 1)
|
||||
src.visible_message("<span style=\"color:red\">[user.name] beats the artifact with [BAT]!</span>")
|
||||
BAT.process_charges(-1, user)
|
||||
return 0
|
||||
|
||||
if (W.force)
|
||||
src.ArtifactStimulus("force", W.force)
|
||||
return 1
|
||||
|
||||
/obj/proc/ArtifactFaultUsed(var/mob/user)
|
||||
// This is for a tool/item artifact that you can use. If it has a fault, whoever is using it is basically rolling the dice
|
||||
// every time the thing is used (a check to see if rand(1,faultcount) hits 1 most of the time) and if they're unlucky, the
|
||||
// thing will deliver it's payload onto them.
|
||||
// There's also no reason this can't be used whoever the artifact is being used *ON*, also!
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
|
||||
var/datum/artifact/A = src.artifact
|
||||
|
||||
if (!A.faults.len)
|
||||
return // no faults, so dont waste any more time
|
||||
if (!A.activated)
|
||||
return // doesn't make a lot of sense for an inert artifact to go haywire
|
||||
var/halt = 0
|
||||
for (var/datum/artifact_fault/F in A.faults)
|
||||
if (prob(F.trigger_prob))
|
||||
if (F.halt_loop)
|
||||
halt = 1
|
||||
F.deploy(src,user)
|
||||
if (halt)
|
||||
break
|
||||
|
||||
/obj/proc/ArtifactStimulus(var/stimtype, var/strength = 0)
|
||||
// This is what will be used for most of the testing equipment stuff. Stimtype is what kind of stimulus the artifact is being
|
||||
// exposed to (such as brute force, high temperatures, electricity, etc) and strength is how powerful the stimulus is. This
|
||||
// one here is intended as a master proc with individual items calling back to this one and then rolling their own version of
|
||||
// it alongside this. This one mainly deals with accidentally damaging an artifact due to hitting it with a poor choice of
|
||||
// stimulus, such as hitting crystals with brute force and so forth.
|
||||
if (!stimtype)
|
||||
return
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
var/datum/artifact/A = src.artifact
|
||||
|
||||
// Possible stimuli = force, elec, radiate, heat
|
||||
switch(A.artitype)
|
||||
if("martian") // biotech, so anything that'd probably kill a living thing works on them too
|
||||
if(stimtype == "force")
|
||||
if (strength >= 30)
|
||||
T.visible_message("<span style=\"color:red\">[src] bruises from the impact!</span>")
|
||||
playsound(src.loc, "sound/effects/attackblob.ogg", 100, 1)
|
||||
ArtifactDevelopFault(33)
|
||||
src.ArtifactTakeDamage(strength / 1.5)
|
||||
if(stimtype == "elec")
|
||||
if (strength >= 3000) // max you can get from the electrobox is 5000
|
||||
if (prob(10))
|
||||
T.visible_message("<span style=\"color:red\">[src] seems to quiver in pain!</span>")
|
||||
src.ArtifactTakeDamage(strength / 1000)
|
||||
if(stimtype == "radiate")
|
||||
if (strength >= 6)
|
||||
ArtifactDevelopFault(50)
|
||||
if (strength >= 9)
|
||||
ArtifactDevelopFault(75)
|
||||
src.ArtifactTakeDamage(strength * 1.25)
|
||||
if("wizard") // these are big crystals, thus you probably shouldn't smack them around too hard!
|
||||
if(stimtype == "force")
|
||||
if (strength >= 20)
|
||||
T.visible_message("<span style=\"color:red\">[src] cracks and splinters!</span>")
|
||||
playsound(src.loc, "sound/misc/glass_step.ogg", 100, 1)
|
||||
ArtifactDevelopFault(80)
|
||||
src.ArtifactTakeDamage(strength * 1.5)
|
||||
|
||||
if (!src || !A)
|
||||
return
|
||||
|
||||
if (!A.activated)
|
||||
for (var/datum/artifact_trigger/AT in A.triggers)
|
||||
if (A.activated)
|
||||
break
|
||||
if (AT.stimulus_required == stimtype)
|
||||
if (AT.do_amount_check)
|
||||
if (AT.stimulus_type == ">=" && strength >= AT.stimulus_amount)
|
||||
src.ArtifactActivated()
|
||||
else if (AT.stimulus_type == "<=" && strength <= AT.stimulus_amount)
|
||||
src.ArtifactActivated()
|
||||
else if (AT.stimulus_type == "==" && strength == AT.stimulus_amount)
|
||||
src.ArtifactActivated()
|
||||
else
|
||||
if (istext(A.hint_text))
|
||||
if (strength >= AT.stimulus_amount - AT.hint_range && strength <= AT.stimulus_amount + AT.hint_range)
|
||||
if (prob(AT.hint_prob))
|
||||
T.visible_message("<b>[src]</b> [A.hint_text]")
|
||||
else
|
||||
src.ArtifactActivated()
|
||||
|
||||
/obj/proc/ArtifactTouched(mob/user as mob)
|
||||
if (istype(user,/mob/living/silicon/ai))
|
||||
return
|
||||
if (istype(user,/mob/dead/))
|
||||
return
|
||||
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istype(A,/datum/artifact/))
|
||||
if (istype(user,/mob/living/carbon/))
|
||||
src.ArtifactStimulus("carbtouch", 1)
|
||||
if (istype(user,/mob/living/silicon/))
|
||||
src.ArtifactStimulus("silitouch", 1)
|
||||
src.ArtifactStimulus("force", 1)
|
||||
user.visible_message("<b>[user.name]</b> touches [src].")
|
||||
if (istype(src.artifact,/datum/artifact))
|
||||
if (A.touch_descriptors.len > 0)
|
||||
boutput(user, "[pick(A.touch_descriptors)]")
|
||||
else
|
||||
boutput(user, "You can't really tell how it feels.")
|
||||
if (A.activated)
|
||||
A.effect_touch(src,user)
|
||||
return
|
||||
|
||||
/obj/proc/ArtifactTakeDamage(var/dmg_amount)
|
||||
if (!src.ArtifactSanityCheck() || !isnum(dmg_amount))
|
||||
return
|
||||
|
||||
var/datum/artifact/A = src.artifact
|
||||
|
||||
A.health -= dmg_amount
|
||||
A.health = max(0,min(A.health,100))
|
||||
|
||||
if (A.health <= 0)
|
||||
src.ArtifactDestroyed()
|
||||
return
|
||||
|
||||
/obj/proc/ArtifactDestroyed()
|
||||
// Call this rather than straight Del() on an artifact if you want to destroy it. This way, artifacts can have their own
|
||||
// version of this for ones that will deliver a payload if broken.
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
|
||||
var/datum/artifact/A = src.artifact
|
||||
|
||||
ArtifactLogs(usr, null, src, "destroyed", null, 0)
|
||||
|
||||
artifact_controls.artifacts -= src
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (istype(T,/turf/))
|
||||
switch(A.artitype)
|
||||
if("ancient")
|
||||
T.visible_message("<span style=\"color:red\"><B>[src] sparks and sputters violently before falling apart!</B></span>")
|
||||
if("martian")
|
||||
T.visible_message("<span style=\"color:red\"><B>[src] bursts open, and rapidly liquefies!</B></span>")
|
||||
if("wizard")
|
||||
T.visible_message("<span style=\"color:red\"><B>[src] shatters and disintegrates!</B></span>")
|
||||
if("eldritch")
|
||||
T.visible_message("<span style=\"color:red\"><B>[src] warps in on itself and vanishes!</B></span>")
|
||||
if("precursor")
|
||||
T.visible_message("<span style=\"color:red\"><B>[src] implodes, crushing itself into dust!</B></span>")
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/proc/ArtifactDevelopFault(var/faultprob)
|
||||
// This proc is used for randomly giving an artifact a fault. It's usually used in the New() proc of an artifact so that
|
||||
// newly spawned artifacts have a chance of being faulty by default, though this can also be called whenever an artifact is
|
||||
// damaged or otherwise poorly handled, so you could potentially turn a good artifact into a dangerous piece of shit if you
|
||||
// abuse it too much.
|
||||
// I'm probably going to change this one up to use a list of fault datum rather than some kind of variable, that way multiple
|
||||
// faults can be on one artifact.
|
||||
if (!isnum(faultprob))
|
||||
return
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
|
||||
if (A.artitype == "eldritch")
|
||||
faultprob *= 2 // eldritch artifacts fucking hate you and are twice as likely to go faulty
|
||||
faultprob = max(0,min(faultprob,100))
|
||||
|
||||
if (prob(faultprob) && A.fault_types.len)
|
||||
var/new_fault = pick(A.fault_types)
|
||||
if (ispath(new_fault))
|
||||
var/datum/artifact_fault/F = new new_fault(A)
|
||||
F.holder = A
|
||||
A.faults += F
|
||||
|
||||
// Added. Very little related to artifacts was logged (Convair880).
|
||||
/proc/ArtifactLogs(var/mob/user, var/mob/target, var/obj/O, var/type_of_action, var/special_addendum, var/trigger_alert = 0)
|
||||
if (!O || !istype(O.artifact, /datum/artifact) || !type_of_action)
|
||||
return
|
||||
|
||||
var/datum/artifact/A = O.artifact
|
||||
|
||||
if ((target && ismob(target)) && type_of_action == "weapon")
|
||||
logTheThing("combat", user, target, "attacks %target% with an active artifact ([A.type])[special_addendum ? ", [special_addendum]" : ""] at [log_loc(target)].")
|
||||
else
|
||||
logTheThing(type_of_action == "detonated" ? "bombing" : "station", user, target, "an artifact ([A.type]) was [type_of_action] [special_addendum ? "([special_addendum])" : ""] at [target && isturf(target) ? "[log_loc(target)]" : "[log_loc(O)]"].[type_of_action == "detonated" ? " Last touched by: [O.fingerprintslast ? "[O.fingerprintslast]" : "*null*"]" : ""]")
|
||||
|
||||
if (trigger_alert)
|
||||
message_admins("An artifact ([A.type]) was [type_of_action] [special_addendum ? "([special_addendum])" : ""] at [log_loc(O)]. Last touched by: [O.fingerprintslast ? "[O.fingerprintslast]" : "*null*"]")
|
||||
|
||||
return
|
||||
@@ -0,0 +1,331 @@
|
||||
/obj/artifact
|
||||
// a totally inert piece of shit that does nothing (alien art)
|
||||
// might as well use it as the category header for non-machinery artifacts just to be efficient
|
||||
name = "artifact large art piece"
|
||||
icon = 'icons/obj/artifacts/artifacts.dmi'
|
||||
icon_state = "wizard-1" // it's technically pointless to set this but it makes it easier to find in the dreammaker tree
|
||||
opacity = 0
|
||||
density = 1
|
||||
anchored = 0
|
||||
artifact = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
var/associated_datum = /datum/artifact/art
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
var/datum/artifact/AS = new src.associated_datum(src)
|
||||
if (forceartitype) AS.validtypes = list("[forceartitype]")
|
||||
src.artifact = AS
|
||||
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.ArtifactTouched(user)
|
||||
return
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
meteorhit(obj/O as obj)
|
||||
src.ArtifactStimulus("force", 60)
|
||||
..()
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
src.ArtifactStimulus("force", 200)
|
||||
src.ArtifactStimulus("heat", 500)
|
||||
if(2.0)
|
||||
src.ArtifactStimulus("force", 75)
|
||||
src.ArtifactStimulus("heat", 450)
|
||||
if(3.0)
|
||||
src.ArtifactStimulus("force", 25)
|
||||
src.ArtifactStimulus("heat", 380)
|
||||
return
|
||||
|
||||
reagent_act(reagent_id,volume)
|
||||
if (..())
|
||||
return
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
src.ArtifactStimulus(reagent_id, volume)
|
||||
switch(reagent_id)
|
||||
if("radium","porktonium")
|
||||
src.ArtifactStimulus("radiate", round(volume / 10))
|
||||
if("polonium","strange_reagent")
|
||||
src.ArtifactStimulus("radiate", round(volume / 5))
|
||||
if("uranium")
|
||||
src.ArtifactStimulus("radiate", round(volume / 2))
|
||||
if("dna_mutagen","mutagen","omega_mutagen")
|
||||
if (A.artitype == "martian")
|
||||
ArtifactDevelopFault(80)
|
||||
if("napalm","dbreath","el_diablo")
|
||||
src.ArtifactStimulus("heat", 310 + (volume * 5))
|
||||
if("infernite","foof","ghostchilijuice")
|
||||
src.ArtifactStimulus("heat", 310 + (volume * 10))
|
||||
if("cryostylane")
|
||||
src.ArtifactStimulus("heat", 310 - (volume * 10))
|
||||
if("acid")
|
||||
src.ArtifactTakeDamage(volume * 2)
|
||||
if("pacid")
|
||||
src.ArtifactTakeDamage(volume * 10)
|
||||
if("george_melonium")
|
||||
var/random_stimulus = pick("heat","force","radiate","elec")
|
||||
var/random_strength = 0
|
||||
switch(random_stimulus)
|
||||
if ("heat")
|
||||
random_strength = rand(200,400)
|
||||
if ("elec")
|
||||
random_strength = rand(5,5000)
|
||||
if ("force")
|
||||
random_strength = rand(3,30)
|
||||
if ("radiate")
|
||||
random_strength = rand(1,10)
|
||||
src.ArtifactStimulus(random_stimulus,random_strength)
|
||||
return
|
||||
|
||||
emp_act()
|
||||
src.ArtifactStimulus("elec", 800)
|
||||
src.ArtifactStimulus("radiate", 3)
|
||||
|
||||
blob_act(var/power)
|
||||
src.ArtifactStimulus("force", power)
|
||||
src.ArtifactStimulus("carbtouch", 1)
|
||||
|
||||
bullet_act(var/obj/projectile/P)
|
||||
if(src.material) src.material.triggerOnAttacked(src, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter))
|
||||
for(var/atom/A in src)
|
||||
if(A.material)
|
||||
A.material.triggerOnAttacked(A, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter))
|
||||
|
||||
switch (P.proj_data.damage_type)
|
||||
if(D_KINETIC,D_PIERCING,D_SLASHING)
|
||||
src.ArtifactStimulus("force", P.power)
|
||||
for (var/obj/machinery/networked/test_apparatus/impact_pad/I in src.loc.contents)
|
||||
I.impactpad_senseforce_shot(src, P)
|
||||
if(D_ENERGY)
|
||||
src.ArtifactStimulus("elec", P.power * 10)
|
||||
if(D_BURNING)
|
||||
src.ArtifactStimulus("heat", 310 + (P.power * 5))
|
||||
if(D_RADIOACTIVE)
|
||||
src.ArtifactStimulus("radiate", P.power)
|
||||
..()
|
||||
|
||||
Bumped(M as mob|obj)
|
||||
if (istype(M,/obj/item/))
|
||||
var/obj/item/ITM = M
|
||||
src.ArtifactStimulus("force", ITM.throwforce)
|
||||
for (var/obj/machinery/networked/test_apparatus/impact_pad/I in src.loc.contents)
|
||||
I.impactpad_senseforce(src, ITM)
|
||||
..()
|
||||
|
||||
/obj/machinery/artifact
|
||||
name = "artifact large art piece"
|
||||
icon = 'icons/obj/artifacts/artifacts.dmi'
|
||||
icon_state = "wizard-1" // it's technically pointless to set this but it makes it easier to find in the dreammaker tree
|
||||
opacity = 0
|
||||
density = 1
|
||||
anchored = 0
|
||||
artifact = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
var/associated_datum = /datum/artifact/art
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
..()
|
||||
var/datum/artifact/AS = new src.associated_datum(src)
|
||||
if (forceartitype)
|
||||
AS.validtypes = list("[forceartitype]")
|
||||
src.artifact = AS
|
||||
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
process()
|
||||
..()
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
|
||||
if (A.activated)
|
||||
A.effect_process(src)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.ArtifactTouched(user)
|
||||
return
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
meteorhit(obj/O as obj)
|
||||
src.ArtifactStimulus("force", 60)
|
||||
..()
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
src.ArtifactStimulus("force", 200)
|
||||
src.ArtifactStimulus("heat", 500)
|
||||
if(2.0)
|
||||
src.ArtifactStimulus("force", 75)
|
||||
src.ArtifactStimulus("heat", 450)
|
||||
if(3.0)
|
||||
src.ArtifactStimulus("force", 25)
|
||||
src.ArtifactStimulus("heat", 380)
|
||||
return
|
||||
|
||||
reagent_act(reagent_id,volume)
|
||||
if (..())
|
||||
return
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
src.ArtifactStimulus(reagent_id, volume)
|
||||
switch(reagent_id)
|
||||
if("radium","porktonium")
|
||||
src.ArtifactStimulus("radiate", round(volume / 10))
|
||||
if("polonium","strange_reagent")
|
||||
src.ArtifactStimulus("radiate", round(volume / 5))
|
||||
if("uranium")
|
||||
src.ArtifactStimulus("radiate", round(volume / 2))
|
||||
if("dna_mutagen","mutagen","omega_mutagen")
|
||||
if (A.artitype == "martian")
|
||||
ArtifactDevelopFault(80)
|
||||
if("napalm","dbreath","el_diablo")
|
||||
src.ArtifactStimulus("heat", 310 + (volume * 5))
|
||||
if("infernite","foof","ghostchilijuice")
|
||||
src.ArtifactStimulus("heat", 310 + (volume * 10))
|
||||
if("cryostylane")
|
||||
src.ArtifactStimulus("heat", 310 - (volume * 10))
|
||||
if("acid")
|
||||
src.ArtifactTakeDamage(volume * 2)
|
||||
if("pacid")
|
||||
src.ArtifactTakeDamage(volume * 10)
|
||||
if("george_melonium")
|
||||
var/random_stimulus = pick("heat","force","radiate","elec")
|
||||
var/random_strength = 0
|
||||
switch(random_stimulus)
|
||||
if ("heat")
|
||||
random_strength = rand(200,400)
|
||||
if ("elec")
|
||||
random_strength = rand(5,5000)
|
||||
if ("force")
|
||||
random_strength = rand(3,30)
|
||||
if ("radiate")
|
||||
random_strength = rand(1,10)
|
||||
src.ArtifactStimulus(random_stimulus,random_strength)
|
||||
return
|
||||
|
||||
emp_act()
|
||||
src.ArtifactStimulus("elec", 800)
|
||||
src.ArtifactStimulus("radiate", 3)
|
||||
|
||||
blob_act(var/power)
|
||||
src.ArtifactStimulus("force", power)
|
||||
src.ArtifactStimulus("carbtouch", 1)
|
||||
|
||||
bullet_act(var/obj/projectile/P)
|
||||
switch (P.proj_data.damage_type)
|
||||
if(D_KINETIC,D_PIERCING,D_SLASHING)
|
||||
src.ArtifactStimulus("force", P.power)
|
||||
if (istype(src.loc,/turf/))
|
||||
for (var/obj/machinery/networked/test_apparatus/impact_pad/I in src.loc.contents)
|
||||
I.impactpad_senseforce_shot(src, P)
|
||||
if(D_ENERGY)
|
||||
src.ArtifactStimulus("elec", P.power * 10)
|
||||
if(D_BURNING)
|
||||
src.ArtifactStimulus("heat", P.power * 5)
|
||||
if(D_RADIOACTIVE)
|
||||
src.ArtifactStimulus("radiate", P.power)
|
||||
..()
|
||||
|
||||
Bumped(M as mob|obj)
|
||||
if (istype(M,/obj/item/))
|
||||
var/obj/item/ITM = M
|
||||
src.ArtifactStimulus("force", ITM.throwforce)
|
||||
for (var/obj/machinery/networked/test_apparatus/impact_pad/I in src.loc.contents)
|
||||
I.impactpad_senseforce(src, ITM)
|
||||
..()
|
||||
|
||||
/obj/item/artifact
|
||||
name = "artifact small art piece"
|
||||
icon = 'icons/obj/artifacts/artifactsitem.dmi'
|
||||
icon_state = "wizard-1"
|
||||
artifact = 1
|
||||
mat_changename = 0
|
||||
mat_changedesc = 0
|
||||
var/associated_datum = /datum/artifact/art
|
||||
|
||||
New(var/loc, var/forceartitype)
|
||||
var/datum/artifact/AS = new src.associated_datum(src)
|
||||
if (forceartitype)
|
||||
AS.validtypes = list("[forceartitype]")
|
||||
src.artifact = AS
|
||||
|
||||
spawn(0)
|
||||
src.ArtifactSetup()
|
||||
|
||||
examine()
|
||||
set src in oview()
|
||||
boutput(usr, "You have no idea what this thing is!")
|
||||
if (!src.ArtifactSanityCheck())
|
||||
return
|
||||
var/datum/artifact/A = src.artifact
|
||||
if (istext(A.examine_hint))
|
||||
boutput(usr, "[A.examine_hint]")
|
||||
|
||||
UpdateName()
|
||||
src.name = "[name_prefix(null, 1)][src.real_name][name_suffix(null, 1)]"
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.Artifact_attackby(W,user))
|
||||
..()
|
||||
|
||||
/obj/artifact_spawner
|
||||
// pretty much entirely for debugging/gimmick use
|
||||
New(var/loc,var/forceartitype = null,var/cinematic = 0)
|
||||
var/turf/T = get_turf(src)
|
||||
if (cinematic)
|
||||
T.visible_message("<span style=\"color:red\"><b>An artifact suddenly warps into existance!</b></span>")
|
||||
playsound(T,"sound/effects/teleport.ogg",50,1)
|
||||
var/obj/decal/teleport_swirl/swirl = unpool(/obj/decal/teleport_swirl)
|
||||
swirl.set_loc(T)
|
||||
spawn(15)
|
||||
pool(swirl)
|
||||
Artifact_Spawn(T,forceartitype)
|
||||
qdel(src)
|
||||
return
|
||||
@@ -0,0 +1,154 @@
|
||||
// FAULTS
|
||||
|
||||
/datum/artifact_fault
|
||||
// these are booby traps, self-defense mechanisms, hardware faults or just other nasty shit that can fuck you up when you
|
||||
// use the artifact for anything
|
||||
var/trigger_prob = 0
|
||||
var/tmp/datum/artifact/holder = null
|
||||
var/halt_loop = 0
|
||||
|
||||
proc/deploy(var/obj/O,var/mob/living/user)
|
||||
if (!O || !user)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/artifact_fault/burn
|
||||
// sets the victim on fire
|
||||
trigger_prob = 8
|
||||
var/burn_amount = 40
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(user)
|
||||
T.visible_message("<span style=\"color:red\">The [O.name] suddenly bursts into flames!</span>")
|
||||
user.update_burning(40)
|
||||
playsound(T, "sound/effects/bamf.ogg", 100, 1)
|
||||
|
||||
/datum/artifact_fault/irradiate
|
||||
// irradiates the victim
|
||||
trigger_prob = 8
|
||||
var/rads_amount = 20
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
boutput(user, "<span style=\"color:red\">You feel strange.</span>")
|
||||
user.irradiate(src.rads_amount)
|
||||
|
||||
/datum/artifact_fault/shutdown
|
||||
// deactivates the artifact
|
||||
trigger_prob = 10
|
||||
halt_loop = 1
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<span style=\"color:red\">The [O.name] suddenly deactivates!</span>")
|
||||
playsound(T, "sound/effects/shielddown2.ogg", 100, 1)
|
||||
O.ArtifactDeactivated()
|
||||
|
||||
/datum/artifact_fault/warp
|
||||
// warps the user off somewhere random
|
||||
trigger_prob = 15
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<span style=\"color:red\">The [O.name] warps [user.name] away!</span>")
|
||||
playsound(T, "sound/effects/mag_warp.ogg", 100, 1)
|
||||
user.set_loc(pick(wormholeturfs))
|
||||
|
||||
/datum/artifact_fault/murder
|
||||
// gibs the user
|
||||
trigger_prob = 1
|
||||
halt_loop = 1
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (istype(src,/obj/item/))
|
||||
var/obj/item/I = src
|
||||
if (I.loc == user)
|
||||
user.u_equip(I)
|
||||
I.dropped()
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<span style=\"color:red\"><b>The [O.name] utterly annihilates [user.name]!</b></span>")
|
||||
playsound(T, "sound/effects/elec_bigzap.ogg", 100, 1)
|
||||
user.elecgib()
|
||||
|
||||
/datum/artifact_fault/explode
|
||||
// causes an explosion and destroys the artifact
|
||||
trigger_prob = 1
|
||||
halt_loop = 1
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<span style=\"color:red\">The [O.name] suddenly explodes!</span>")
|
||||
if (istype(src,/obj/item/))
|
||||
var/obj/item/I = src
|
||||
user.u_equip(I)
|
||||
I.dropped()
|
||||
explosion(O, T, 1, 2, 4, 8)
|
||||
O.ArtifactDestroyed()
|
||||
|
||||
/datum/artifact_fault/zap
|
||||
// electrocutes the user
|
||||
trigger_prob = 6
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
T.visible_message("<span style=\"color:red\"><b>[user.name]</b> is shocked by a surge of energy from [O.name]!</span>")
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, user)
|
||||
s.start()
|
||||
user.stunned += 15
|
||||
user.weakened += 15
|
||||
user.stuttering += 30
|
||||
|
||||
/datum/artifact_fault/messager
|
||||
trigger_prob = 30
|
||||
var/text_style = null
|
||||
var/list/messages = list()
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
if (messages.len < 1)
|
||||
return
|
||||
switch(text_style)
|
||||
if ("small")
|
||||
boutput(user, "<small>[pick(messages)]</small>")
|
||||
if ("big")
|
||||
boutput(user, "<big>[pick(messages)]</big>")
|
||||
if ("red")
|
||||
boutput(user, "<span style=\"color:red\">[pick(messages)]</span>")
|
||||
if ("blue")
|
||||
boutput(user, "<span style=\"color:blue\">[pick(messages)]</span>")
|
||||
else
|
||||
boutput(user, "[pick(messages)]")
|
||||
|
||||
/datum/artifact_fault/messager/creepy_whispers
|
||||
text_style = "small"
|
||||
messages = list("its your fault","theyre going to get you","no escape","youre going to die here","no hope",
|
||||
"die","stop","give up","no","theyre watching you","theres nothing you can do","you have failed","run","i see you",
|
||||
"surrender","its hopeless","you are in hell","its all lies","hate","there is only despair","your heart will stop",
|
||||
"they will all forget you","they have abandoned you","please stop","no one will mourn you")
|
||||
|
||||
/datum/artifact_fault/poison
|
||||
trigger_prob = 8
|
||||
var/poison_type = "toxin"
|
||||
var/poison_amount = 10
|
||||
|
||||
deploy(var/obj/O,var/mob/living/user)
|
||||
if (..())
|
||||
return
|
||||
boutput(user, "<span style=\"color:red\">The [O.name] stings you!</span>")
|
||||
if (user.reagents)
|
||||
user.reagents.add_reagent(poison_type,poison_amount)
|
||||
@@ -0,0 +1,73 @@
|
||||
// TRIGGERS
|
||||
|
||||
/datum/artifact_trigger
|
||||
var/stimulus_required = null
|
||||
var/do_amount_check = 1
|
||||
var/stimulus_amount = null
|
||||
var/stimulus_type = ">="
|
||||
var/hint_range = 0
|
||||
var/hint_prob = 33
|
||||
|
||||
/datum/artifact_trigger/carbon_touch
|
||||
// touched by a carbon lifeform
|
||||
stimulus_required = "carbtouch"
|
||||
do_amount_check = 0
|
||||
|
||||
/datum/artifact_trigger/silicon_touch
|
||||
// touched by a silicon lifeform
|
||||
stimulus_required = "silitouch"
|
||||
do_amount_check = 0
|
||||
|
||||
/datum/artifact_trigger/force
|
||||
stimulus_required = "force"
|
||||
hint_range = 20
|
||||
hint_prob = 75
|
||||
|
||||
New()
|
||||
stimulus_amount = rand(3,30)
|
||||
|
||||
/datum/artifact_trigger/heat
|
||||
stimulus_required = "heat"
|
||||
hint_range = 20
|
||||
|
||||
New()
|
||||
stimulus_amount = rand(320,400)
|
||||
|
||||
/datum/artifact_trigger/cold
|
||||
stimulus_required = "heat"
|
||||
stimulus_type = "<="
|
||||
hint_range = 20
|
||||
|
||||
New()
|
||||
stimulus_amount = rand(200,300)
|
||||
|
||||
/datum/artifact_trigger/radiation
|
||||
stimulus_required = "radiate"
|
||||
hint_range = 2
|
||||
hint_prob = 75
|
||||
|
||||
New()
|
||||
stimulus_type = pick(">=","<=")
|
||||
stimulus_amount = rand(1,10)
|
||||
|
||||
/datum/artifact_trigger/electric
|
||||
stimulus_required = "elec"
|
||||
hint_range = 500
|
||||
hint_prob = 66
|
||||
|
||||
New()
|
||||
stimulus_type = pick(">=","<=")
|
||||
stimulus_amount = rand(5,5000)
|
||||
|
||||
/datum/artifact_trigger/reagent
|
||||
stimulus_required = "reagent"
|
||||
// can just use the above var as the required reagent field really
|
||||
stimulus_type = ">="
|
||||
hint_range = 50
|
||||
hint_prob = 100
|
||||
|
||||
New()
|
||||
stimulus_amount = rand(10,100)
|
||||
|
||||
/datum/artifact_trigger/reagent/blood
|
||||
stimulus_required = "blood"
|
||||
+1203
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
/obj/construction_frame
|
||||
icon = 'icons/obj/construction_frame.dmi'
|
||||
anchored = 0
|
||||
density = 1
|
||||
proc/updateicon()
|
||||
|
||||
/obj/item/circuit // not to be confused with /obj/item/circuitboard (i'll merge these someday okay)
|
||||
name = "circuit board"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
|
||||
smes
|
||||
name = "SMES control circuit"
|
||||
icon_state = "smes"
|
||||
|
||||
/obj/construction_frame/smes
|
||||
name = "SMES frame"
|
||||
desc = "An unfinished SMES."
|
||||
icon_state = "smes0"
|
||||
|
||||
var/obj/item/coil/large/coil
|
||||
var/obj/item/circuit/circuitboard
|
||||
var/circuit_secured = 0
|
||||
var/wired = 0
|
||||
|
||||
updateicon()
|
||||
if (!coil)
|
||||
icon_state = "smes0"
|
||||
else if (!circuitboard)
|
||||
icon_state = "smes2"
|
||||
else if (!wired)
|
||||
icon_state = "smes3"
|
||||
else
|
||||
icon_state = "smes4"
|
||||
|
||||
attackby(obj/item/W, mob/user)
|
||||
if (!coil)
|
||||
if (istype(W, /obj/item/coil/large))
|
||||
playsound(src.loc, "sound/items/Deconstruct.ogg", 50, 1)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
coil = W
|
||||
boutput(user, "<span style=\"color:blue\">You insert the coil.</span>")
|
||||
else if (!circuitboard)
|
||||
if (istype(W, /obj/item/circuit/smes))
|
||||
playsound(src.loc, "sound/items/Deconstruct.ogg", 50, 1)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
circuitboard = W
|
||||
circuit_secured = 0
|
||||
boutput(user, "<span style=\"color:blue\">You insert the control circuitry.</span>")
|
||||
else if (!circuit_secured)
|
||||
if (istype(W, /obj/item/screwdriver))
|
||||
playsound(src.loc, "sound/items/Screwdriver.ogg", 50, 1)
|
||||
circuit_secured = 1
|
||||
boutput(user, "<span style=\"color:blue\">You secure the control circuitry.</span>")
|
||||
else if (!wired)
|
||||
if (istype(W, /obj/item/cable_coil))
|
||||
var/obj/item/cable_coil/coil = W
|
||||
if (coil.amount >= 5)
|
||||
playsound(src.loc, "sound/items/Deconstruct.ogg", 50, 1)
|
||||
coil.amount -= 5
|
||||
if (!coil.amount)
|
||||
qdel(coil)
|
||||
wired = 1
|
||||
boutput(user, "<span style=\"color:blue\">You wire up the circuitry.</span>")
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">You're going to need more cable for this.</span>")
|
||||
else
|
||||
if (istype(W, /obj/item/sheet))
|
||||
var/obj/item/sheet/sheet = W
|
||||
if (!sheet.material)
|
||||
boutput(user, "<span style=\"color:blue\">This kind of sheets wont work!</span>")
|
||||
return
|
||||
if (sheet.amount >= 3)
|
||||
playsound(src.loc, "sound/items/Deconstruct.ogg", 50, 1)
|
||||
sheet.amount -= 3
|
||||
if (!sheet.amount)
|
||||
qdel(sheet)
|
||||
boutput(user, "<span style=\"color:blue\">You add the outer shell.</span>")
|
||||
var/obj/machinery/power/smes/smes = new(src.loc)
|
||||
smes.setMaterial(sheet.material)
|
||||
qdel(src)
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">You're going to need more sheets for this.</span>")
|
||||
|
||||
src.updateicon()
|
||||
@@ -0,0 +1,106 @@
|
||||
/obj/critter/alien/larva
|
||||
name = "alien larva"
|
||||
icon_state = "larva" // icon_state = "larva_l" - dead
|
||||
dead_state = "larva_l"
|
||||
health = 10
|
||||
aggressive = 0
|
||||
defensive = 1
|
||||
var/amount_grown = 0
|
||||
desc = "You know, it'd be kind of cute if it wasn't trying to eat you."
|
||||
|
||||
process() //overriding default sleeping behavior
|
||||
if (!src.alive) // and completely ruining their ability to die by not including some very important bits I guess
|
||||
return 0
|
||||
check_health()
|
||||
|
||||
src.amount_grown++
|
||||
|
||||
if(amount_grown >= 100)
|
||||
new /obj/critter/alien/humanoid( src.loc )
|
||||
|
||||
qdel(src)
|
||||
|
||||
else
|
||||
ai_think()
|
||||
|
||||
/obj/critter/alien/humanoid
|
||||
density = 1
|
||||
|
||||
/obj/critter/alien
|
||||
name = "Alien"
|
||||
desc = "An alien."
|
||||
icon_state = "alien"
|
||||
density = 1
|
||||
anchored = 0
|
||||
health = 40
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
firevuln = 1
|
||||
brutevuln = 1
|
||||
atcritter = 1
|
||||
|
||||
seek_target()
|
||||
if (!src.alive) return
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (iscarbon(C) && !src.atkcarbon) continue
|
||||
//if(isalien(C)) continue
|
||||
if (istype(C, /mob/living/silicon/) && !src.atksilicon) continue
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> charges at [C:name]!</span>")
|
||||
src.task = "chasing"
|
||||
return
|
||||
else
|
||||
continue
|
||||
|
||||
if(!src.atcritter) return
|
||||
for (var/obj/critter/C in view(src.seekrange,src))
|
||||
if (!C.alive) continue
|
||||
if (C.health < 0) continue
|
||||
if (!istype(C, /obj/critter/alien)) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> lunges at [C.name]!</span>")
|
||||
|
||||
src.task = "chasing"
|
||||
return
|
||||
|
||||
else continue
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
if(istype(M,/obj/critter))
|
||||
var/obj/critter/C = M
|
||||
src.visible_message("<span class='combat'><B>[src]</B> claws [src.target]!</span>")
|
||||
playsound(C.loc, "punch", 25, 1, -1)
|
||||
C.health -= 10
|
||||
if(C.health <= 0)
|
||||
C.CritterDeath()
|
||||
spawn(15)
|
||||
src.attacking = 0
|
||||
return
|
||||
|
||||
src.visible_message("<span class='combat'><B>[src]</B> claws at [src.target]!</span>")
|
||||
random_brute_damage(src.target, rand(5,10))
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> jumps at [M]!</span>")
|
||||
if(iscarbon(M))
|
||||
if (prob(60)) M.stunned += rand(1,5)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
@@ -0,0 +1,418 @@
|
||||
/////// cogwerks spooky automaton thing that kinda just sits there being weird and ominous
|
||||
|
||||
var/global/the_automaton = null
|
||||
|
||||
#define AUTOMATON_MAX_KEYS 7
|
||||
/obj/critter/automaton
|
||||
name = "automaton"
|
||||
desc = "What is this thing? A toy? A machine? What is it doing? Why does it seem to be watching you?"
|
||||
icon_state = "automaton"
|
||||
health = 1000 // what kind of jerk would kill it
|
||||
anchored = 1
|
||||
aggressive = 0
|
||||
defensive = 0
|
||||
wanderer = 0
|
||||
opensdoors = 0
|
||||
atkcarbon = 0
|
||||
atksilicon = 0
|
||||
firevuln = 0.5
|
||||
brutevuln = 1
|
||||
generic = 0
|
||||
var/atom/admiring_target = null
|
||||
var/keycount = 0
|
||||
var/vacation = 0
|
||||
var/pied = 0
|
||||
var/saw_moon_bee = 0
|
||||
var/sun_spin = 0
|
||||
var/spin_lock = null // for making sure the sun keeps spinning in the direction it's already going
|
||||
var/got_cheget_key = 0 // Don't keep handing me this you fuck
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn (10)
|
||||
if (!the_automaton)
|
||||
the_automaton = src
|
||||
|
||||
disposing()
|
||||
if (the_automaton == src)
|
||||
the_automaton = null
|
||||
..()
|
||||
|
||||
Del()
|
||||
if (the_automaton == src)
|
||||
the_automaton = null
|
||||
..()
|
||||
|
||||
angry
|
||||
aggressive = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> smashes [src.target]!</span>")
|
||||
random_brute_damage(src.target, rand(5,15))
|
||||
playsound(src.loc, "sound/misc/automaton_spaz.ogg", 50, 1)
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
process()
|
||||
if(!..())
|
||||
return 0
|
||||
if (!alive)
|
||||
return
|
||||
if (prob(6))
|
||||
playsound(src.loc, "sound/misc/automaton_tickhum.ogg", 60, 1)
|
||||
if (!src.muted)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] emits [pick("a soft", "a quiet", "a curious", "an odd", "an ominous", "a strange", "a forboding", "a peculiar", "a faint")] [pick("ticking", "tocking", "humming", "droning", "clicking")] sound.</span>")
|
||||
if (prob(6))
|
||||
playsound(src.loc, "sound/misc/automaton_ratchet.ogg", 60, 1)
|
||||
if (!src.muted)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] emits [pick("a peculiar", "a worried", "a suspicious", "a reassuring", "a gentle", "a perturbed", "a calm", "an annoyed", "an unusual")] [pick("ratcheting", "rattling", "clacking", "whirring")] noise.</span>")
|
||||
if (prob(5))
|
||||
playsound(src.loc, "sound/misc/automaton_spaz.ogg", 50, 1)
|
||||
spin()
|
||||
|
||||
if ((src.aggressive || prob(6)) && locate(/obj/critter/domestic_bee) in view(7,src))
|
||||
for (var/obj/critter/domestic_bee/moonbeeMaybe in view(7, src))
|
||||
if (moonbeeMaybe.desc == "A moon bee. It's like a regular space bee, but it has a peculiar gleam in its eyes...") //Because bee names are customizable, but desc isn't!
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> [pick("points at", "stares at", "gesticulates at", "madly gestures towards")] [moonbeeMaybe]!</span>")
|
||||
if (!saw_moon_bee)
|
||||
saw_moon_bee = 1
|
||||
|
||||
if (saw_moon_bee == 1 && keycount == INFINITY && !aggressive)
|
||||
|
||||
ending_event()
|
||||
|
||||
|
||||
if (moonbeeMaybe.alive && prob(75))
|
||||
if (!moonbeeMaybe.muted)
|
||||
moonbeeMaybe.visible_message("<span style=\"color:red\"><b>[moonbeeMaybe]</b> buzzes [pick("grumpily","in a confused manner", "excitedly")] at [src]!</span>")
|
||||
|
||||
return
|
||||
|
||||
else if (moonbeeMaybe.desc == "A sun bee. It's like a regular space bee, but it has a look of fiery passion. Passion for doing bee stuff.") //Oh, it's the sun bee
|
||||
if (src.aggressive)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> sees [moonbeeMaybe] and seems to calm down. Phew!</span>")
|
||||
src.aggressive = 0
|
||||
src.attacking = 0
|
||||
src.atkcarbon = 0
|
||||
src.atksilicon = 0
|
||||
saw_moon_bee = 2
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> [pick("points at", "stares at", "gesticulates at", "madly gestures towards")] [moonbeeMaybe]!</span>")
|
||||
|
||||
if (moonbeeMaybe.alive && prob(75))
|
||||
if (!moonbeeMaybe.muted)
|
||||
moonbeeMaybe.visible_message("<span style=\"color:red\"><b>[moonbeeMaybe]</b> buzzes [pick("grumpily","in a confused manner", "excitedly")] at [src]!</span>")
|
||||
|
||||
return
|
||||
|
||||
if (prob(5)) // adapted chunk of peeker code
|
||||
var/list/mobsnearby = list()
|
||||
for (var/mob/M in view(7,src))
|
||||
mobsnearby.Add("[M.name]")
|
||||
var/mob/M1 = null
|
||||
if (mobsnearby.len > 0) // somehow this returned a blank list once wtf
|
||||
M1 = pick(mobsnearby)
|
||||
if (M1 && prob(50)) // do we see anyone
|
||||
if (!src.muted)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> stares at [M1].</span>")
|
||||
else
|
||||
var/area/current_loc = get_area(src)
|
||||
switch (current_loc.type)
|
||||
if (/area/solarium)
|
||||
|
||||
src.dir = 4
|
||||
if (!src.muted)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> stares into the sun.</span>")
|
||||
if (/area/station/engine/core)
|
||||
if (!admiring_target)
|
||||
for (var/obj/machinery/power/generatorTemp/G in range(7, src))
|
||||
admiring_target = G
|
||||
break
|
||||
var/obj/machinery/power/generatorTemp/G = admiring_target
|
||||
if (istype(G) && G.lastgenlev >= 26)
|
||||
src.dir = get_dir(src, G)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> [pick("stares","gazes","glares","looks")] [pick("alluringly", "enticingly", "lovingly", "fanatically", "zealously", "warmly", "obediently", "calmly")] at the [G.name].</span>")
|
||||
|
||||
|
||||
proc/spin()
|
||||
if (!src.muted)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> [pick("turns", "pivots", "twitches", "spins")].</span>")
|
||||
src.dir = pick(alldirs)
|
||||
|
||||
proc/inserted_key()
|
||||
switch (keycount)
|
||||
if (2)
|
||||
for (var/mob/M in range(5))
|
||||
M.flash(30)
|
||||
random_events.force_event("Solar Flare","Solarium Event (2 keys)")
|
||||
if (4)
|
||||
for (var/mob/M in range(5))
|
||||
M.flash(30)
|
||||
random_events.force_event("Radiation Storm","Solarium Event (4 keys)")
|
||||
if (6)
|
||||
for (var/mob/M in range(5))
|
||||
M.flash(30)
|
||||
random_events.force_event("Solar Flare","Solarium Event (6 keys)")
|
||||
|
||||
attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
if (!alive)
|
||||
return ..()
|
||||
if (aggressive)
|
||||
return ..()
|
||||
if (istype(W, /obj/item/device/key))
|
||||
if (keycount >= AUTOMATON_MAX_KEYS)
|
||||
boutput(user, "<span style=\"color:red\"><b>[src]</b> ignores you. Perhaps the time for that has passed?</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span style=\"color:red\">[user] hands [W] to [src]!</span>", "You hand [W] to [src].")
|
||||
|
||||
if (istype(W, /obj/item/device/key/skull) && W.icon_state == "bloodyskull")
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a while, then hands it back. It doesn't seem to want it in the state it's in.</span>")
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/reagent_containers/food/snacks/pizza) && W.name == "cheese keyzza") // vOv
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a while, then hands it back.</span>")
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/key/cheget)) //I don' like yer new-fangled mumbo-jumbo
|
||||
user.u_equip(W)
|
||||
W.dropped(user)
|
||||
W.loc = src
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> takes \the [W] and studies it intently for a moment.</span>")
|
||||
sleep(30)
|
||||
if (!got_cheget_key)
|
||||
got_cheget_key = 1
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> clacks angrily and throws \the [W] at [user]!</span>")
|
||||
playsound(src.loc, "sound/misc/automaton_spaz.ogg", 60, 1)
|
||||
W.loc = src.loc
|
||||
W.throw_at(user, 20, 2)
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> makes a loud ratcheting noise and crumples up \the [W]!</span>")
|
||||
playsound(src.loc, "sound/effects/thunk.ogg", 60, 1)
|
||||
new /obj/item/raw_material/scrap_metal(src.loc)
|
||||
qdel(W)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/key/filing_cabinet))
|
||||
boutput(user, "<span style=\"color:red\"><B>[src]</B> ignores you. This may be related to their lack of circular key holes.")
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/key/hospital))
|
||||
user.visible_message("<span style=\"color:red\"><b>[src]</b> studies [src]'s open hand for a moment, then looks disappointed.</span>", "<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, then hands it back. Maybe it's not yet time?</span>")
|
||||
return
|
||||
|
||||
//Normal keys below
|
||||
if (dd_hasprefix(ckey(W.name), "iridium"))
|
||||
if (keycount < (AUTOMATON_MAX_KEYS-1))
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, then hands it back. Maybe it's not yet time?</span>")
|
||||
else
|
||||
keycount = AUTOMATON_MAX_KEYS
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, before secreting it away into a central key hole in its chest.</span>")
|
||||
playsound(src.loc, "sound/effects/thunk.ogg", 60, 1)
|
||||
playsound(src.loc, "sound/effects/gong_rumble.ogg", 60, 1)
|
||||
qdel(W)
|
||||
sleep(5)
|
||||
playsound(src.loc, "sound/misc/automaton_spaz.ogg", 60, 1)
|
||||
sleep(8)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> twitches before locking into a pose of contemplation. Its hand held before it, as if reading from a text.</span>")
|
||||
|
||||
else if (dd_hasprefix(ckey(W.name), "lead"))
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, then hands it back. Maybe the material is off?</span>")
|
||||
return
|
||||
|
||||
else if (dd_hasprefix(ckey(W.name), "solar"))
|
||||
keycount = AUTOMATON_MAX_KEYS
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, before secreting it away into a central key hole in its chest.</span>")
|
||||
playsound(src.loc, "sound/effects/thunk.ogg", 60, 1)
|
||||
playsound(src.loc, "sound/effects/gong_rumble.ogg", 60, 1)
|
||||
qdel(W)
|
||||
sleep(5)
|
||||
playsound(src.loc, "sound/misc/automaton_spaz.ogg", 60, 1)
|
||||
sleep(8)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> makes a curious sign in the air. Huh.</span>")
|
||||
|
||||
for (var/mob/M in range(5))
|
||||
M.flash(30)
|
||||
|
||||
//var/obj/overlay/the_sun = locate("the_sun")
|
||||
//if (istype(the_sun))
|
||||
if (the_sun)
|
||||
var/obj/Sun = the_sun
|
||||
Sun.icon_state = "sun"
|
||||
Sun.desc = "Hey, it looks better again!"
|
||||
|
||||
sleep(8)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> tips over.</span>")
|
||||
src.health = 0
|
||||
src.CritterDeath() // rip
|
||||
|
||||
|
||||
else
|
||||
keycount = min(keycount+1, AUTOMATON_MAX_KEYS-1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, before secreting it away into one of many key holes in its chest.</span>")
|
||||
playsound(src.loc, "sound/effects/thunk.ogg", 60, 1)
|
||||
playsound(src.loc, "sound/effects/gong_rumble.ogg", 60, 1)
|
||||
qdel (W)
|
||||
sleep(5)
|
||||
inserted_key()
|
||||
|
||||
playsound(src.loc, "sound/misc/automaton_spaz.ogg", 60, 1)
|
||||
else if (istype(W, /obj/item/reagent_containers/food/snacks/pie/lime) && keycount < AUTOMATON_MAX_KEYS)
|
||||
user.visible_message("<span style=\"color:red\">[user] hands [W] to [src]!</span>", "You hand [W] to [src].")
|
||||
|
||||
if (keycount < (AUTOMATON_MAX_KEYS-1) && !pied)
|
||||
keycount++
|
||||
inserted_key()
|
||||
pied = 1
|
||||
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> studies [W] intently for a moment, before secreting it away into a pie-shaped hole in its chest. How did you not notice that before?</span>")
|
||||
playsound(src.loc, "sound/effects/gong_rumble.ogg", 50, 1)
|
||||
qdel (W)
|
||||
|
||||
else if (istype(W, /obj/item/skull))
|
||||
if (keycount != AUTOMATON_MAX_KEYS)
|
||||
user.visible_message("<span style=\"color:red\"><b>[src]</b> ignores [user]. Perhaps it's not time for that?</span>",\
|
||||
"<span style=\"color:red\"><b>[src]</b> ignores you. Perhaps it's not time for that?</span>")
|
||||
return
|
||||
|
||||
if (!istype(W, /obj/item/skull/crystal) || W.icon_state != "skull_crystal")
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> holds [W] out for a moment, staring into its empty face, then hands it back </span>")
|
||||
return
|
||||
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> holds [W] out, staring into its empty eye sockets.<br>Alas, poor Yorick?</span>")
|
||||
qdel(W)
|
||||
//todo: good ending???? egg ending????
|
||||
|
||||
else if (istype(W, /obj/item/iomoon_key))
|
||||
user.visible_message("<span style=\"color:red\"><b>[src]</b> totally ignores [user]. Maybe this is the wrong puzzle for [W] or something, sheesh.</span>",\
|
||||
"<span style=\"color:red\">Okay, no. Good thought, but this is totally the wrong puzzle for that.</span>")
|
||||
|
||||
else if (istype(W, /obj/item/alchemy/stone))
|
||||
src.visible_message("<span style=\"color:red\">[src] studies [W] intently. It looks impressed, but hands [W] back. Perhaps it's not the right time for this yet?</span>")
|
||||
|
||||
else if (istype(W, /obj/item/onyxphoto))
|
||||
if (!W:used)
|
||||
src.visible_message("<span style=\"color:blue\"><b>[src]</b> studies [W] intently, then hands it back after a short pause.</span>")
|
||||
|
||||
W:used = 1
|
||||
W.name = "empty photo"
|
||||
W.desc = "The key seems to be gone from the photo."
|
||||
if (keycount < (AUTOMATON_MAX_KEYS-1))
|
||||
keycount++
|
||||
inserted_key()
|
||||
playsound(src.loc, "sound/effects/gong_rumble.ogg", 60, 1)
|
||||
else
|
||||
boutput(user, "<span style=\"color:red\">[src] no longer seems interested in [W].</span>")
|
||||
|
||||
|
||||
else if (istype(W, /obj/item/space_thing)) // if I'm gunna make a weird widget it may as well have some interaction with the automaton
|
||||
var/obj/item/space_thing/ST = W
|
||||
if (ST.icon_state == "thing")
|
||||
src.visible_message("<span style=\"color:red\">[src] studies [ST] for a moment. It rotates it, and then hands it back.</span>")
|
||||
ST.icon_state = "thing2"
|
||||
//var/obj/overlay/the_sun = locate("the_sun")
|
||||
//if (istype(the_sun))
|
||||
if (the_sun)
|
||||
if (!src.spin_lock)
|
||||
src.spin_lock = pick("L", "R")
|
||||
DEBUG("<B>HAINE DEBUG:</b> spin set to [src.spin_lock]")
|
||||
var/final_spin = 1000 - min(src.sun_spin, 999)
|
||||
DEBUG("<B>HAINE DEBUG:</b> final spin set to [final_spin]")
|
||||
animate_spin(the_sun, src.spin_lock, final_spin, -1)
|
||||
if (src.sun_spin >= 990)
|
||||
src.sun_spin += 1
|
||||
DEBUG("<B>HAINE DEBUG:</b> spin now [src.sun_spin]")
|
||||
else if (src.sun_spin >= 900)
|
||||
src.sun_spin += 10
|
||||
DEBUG("<B>HAINE DEBUG:</b> spin now [src.sun_spin]")
|
||||
else
|
||||
src.sun_spin += 100
|
||||
DEBUG("<B>HAINE DEBUG:</b> spin now [src.sun_spin]")
|
||||
else
|
||||
user.visible_message("<span style=\"color:red\">[src] studies [ST] for a moment. It hands it back.</span>")
|
||||
|
||||
else if (istype(W, /obj/item/book_kinginyellow))
|
||||
if (keycount < AUTOMATON_MAX_KEYS || derelict_mode)
|
||||
user.visible_message("<span style=\"color:red\"><b>[src]</b> ignores [user]'s attempts to hand over the book, even if \he waves it right in its face and get all obnoxious about it. Maybe this isn't the right time?</span>",\
|
||||
"<span style=\"color:red\"><b>[src]</b> ignores your attempts to hand over the book, even if you wave it right in its face and get all obnoxious about it. Maybe this isn't the right time?</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span style=\"color:red\">[user] hands [W] to [src]!</span>", "You hand [W] to [src].")
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> appears to read from [W].</span>")
|
||||
user.drop_item()
|
||||
W.set_loc(src)
|
||||
sleep(10)
|
||||
playsound(src.loc, 'sound/weapons/genhit3.ogg', 50, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] frantically tears [W] to pieces! What!</b></span>")
|
||||
if (narrator_mode)
|
||||
playsound(src.loc, 'sound/vox/ghost.ogg', 60, 1)
|
||||
else
|
||||
playsound(src.loc, 'sound/effects/ghost.ogg', 60, 1)
|
||||
spawn(0)
|
||||
var/i = rand(4,8)
|
||||
while (i-- > 0)
|
||||
var/obj/item/paper/tornpaper = new /obj/item/paper(src.loc)
|
||||
tornpaper.name = "torn page"
|
||||
tornpaper.info = "A page torn from a book. Most of the text is illegible."
|
||||
sleep(3)
|
||||
tornpaper.combust()
|
||||
keycount = INFINITY
|
||||
world << sound('sound/effects/gong_rumble.ogg')
|
||||
//var/obj/overlay/the_sun = locate("the_sun")
|
||||
//if (istype(the_sun))
|
||||
if (the_sun)
|
||||
var/obj/Sun = the_sun
|
||||
Sun.icon_state = "sun_ripple"
|
||||
Sun.desc = "Uhhh...."
|
||||
|
||||
if (W)
|
||||
for (var/mob/living/carbon/C in hearers(src.seekrange,src))
|
||||
W:readers += C
|
||||
|
||||
if (saw_moon_bee == 1)
|
||||
ending_event()
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
proc/ending_event()
|
||||
if (saw_moon_bee == 2)
|
||||
return
|
||||
|
||||
saw_moon_bee = 2
|
||||
var/turf/target_turf = locate(src.x - 1, src.y, src.z)
|
||||
var/obj/decal/teleport_swirl/swirl = unpool(/obj/decal/teleport_swirl)
|
||||
swirl.set_loc(target_turf)
|
||||
swirl.pixel_y = 10
|
||||
playsound(target_turf, "sound/effects/teleport.ogg", 50, 1)
|
||||
spawn(15)
|
||||
swirl.pixel_y = 0
|
||||
pool(swirl)
|
||||
|
||||
src.visible_message("<span style=\"color:red\">[src.name] seems to tense up and freeze.</span>")
|
||||
playsound(src.loc, "sound/machines/glitch1.ogg", 50, 1)
|
||||
alive = 0
|
||||
|
||||
it_is_okay_to_do_the_endgame_thing = 1
|
||||
if(!src.vacation)
|
||||
new /obj/the_server_ingame_whoa(target_turf)
|
||||
else
|
||||
new /obj/item/sticker/gold_star(target_turf)
|
||||
src.visible_message("<span style=\"color:red\">[src.name] looks very annoyed. It just wanted to relax!</span>")
|
||||
|
||||
|
||||
|
||||
#undef AUTOMATON_MAX_KEYS
|
||||
|
||||
alohamaton
|
||||
icon_state = "alohamaton"
|
||||
vacation = 1
|
||||
|
||||
/obj/item/paper/postcard
|
||||
name = "postcard"
|
||||
info = "<font face='Comic Sans MS' color='#F75AA4' size=5><b>Wish you were here!</b></font>"
|
||||
icon_state = "postcard"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,421 @@
|
||||
/obj/critter/bear
|
||||
name = "space bear"
|
||||
desc = "WOORGHHH"
|
||||
icon_state = "abear"
|
||||
health = 60
|
||||
aggressive = 1
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
butcherable = 1
|
||||
var/loveometer = 0
|
||||
|
||||
var/left_arm_stage = 0
|
||||
var/right_arm_stage = 0
|
||||
var/obj/item/parts/human_parts/arm/left/bear/left_arm
|
||||
var/obj/item/parts/human_parts/arm/right/bear/right_arm
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/leather
|
||||
max_skins = 2
|
||||
|
||||
New()
|
||||
..()
|
||||
src.left_arm = new /obj/item/parts/human_parts/arm/left/bear(src)
|
||||
src.right_arm = new /obj/item/parts/human_parts/arm/right/bear(src)
|
||||
|
||||
on_revive()
|
||||
if (!src.left_arm)
|
||||
src.left_arm = new /obj/item/parts/human_parts/arm/left/bear(src)
|
||||
src.left_arm_stage = 0
|
||||
src.visible_message("<span style=\"color:red\">[src]'s left arm regrows!</span>")
|
||||
if (!src.right_arm)
|
||||
src.right_arm = new /obj/item/parts/human_parts/arm/right/bear(src)
|
||||
src.right_arm_stage = 0
|
||||
src.visible_message("<span style=\"color:red\">[src]'s right arm regrows!</span>")
|
||||
..()
|
||||
|
||||
CritterDeath()
|
||||
if (!alive)
|
||||
return
|
||||
..()
|
||||
src.update_dead_icon()
|
||||
|
||||
proc/update_dead_icon()
|
||||
if (src.alive)
|
||||
return
|
||||
. = initial(icon_state)
|
||||
if (!src.left_arm)
|
||||
. += "-l"
|
||||
if (!src.right_arm)
|
||||
. += "-r"
|
||||
. += "-dead"
|
||||
icon_state = .
|
||||
|
||||
attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
if (!src.alive)
|
||||
// TODO: tie this into surgery()
|
||||
if (istype(W, /obj/item/scalpel))
|
||||
if (user.zone_sel.selecting == "l_arm")
|
||||
if (src.left_arm_stage == 0)
|
||||
user.visible_message("<span class='combat'>[user] slices through the skin and flesh of [src]'s left arm with [W].</span>", "<span style=\"color:red\">You slice through the skin and flesh of [src]'s left arm with [W].</span>")
|
||||
src.left_arm_stage++
|
||||
else if (src.left_arm_stage == 2)
|
||||
user.visible_message("<span class='combat'>[user] cuts through the remaining strips of skin holding [src]'s left arm on with [W].</span>", "<span style=\"color:red\">You cut through the remaining strips of skin holding [src]'s left arm on with [W].</span>")
|
||||
src.left_arm_stage++
|
||||
|
||||
var/turf/location = get_turf(src)
|
||||
if (location)
|
||||
src.left_arm.set_loc(location)
|
||||
src.left_arm = null
|
||||
src.update_dead_icon()
|
||||
|
||||
else if (user.zone_sel.selecting == "r_arm")
|
||||
if (src.right_arm_stage == 0)
|
||||
user.visible_message("<span class='combat'>[user] slices through the skin and flesh of [src]'s right arm with [W].</span>", "<span style=\"color:red\">You slice through the skin and flesh of [src]'s right arm with [W].</span>")
|
||||
src.right_arm_stage++
|
||||
else if (src.right_arm_stage == 2)
|
||||
user.visible_message("<span class='combat'>[user] cuts through the remaining strips of skin holding [src]'s right arm on with [W].</span>", "<span style=\"color:red\">You cut through the remaining strips of skin holding [src]'s right arm on with [W].</span>")
|
||||
src.right_arm_stage++
|
||||
|
||||
var/turf/location = get_turf(src)
|
||||
if (location)
|
||||
src.right_arm.set_loc(location)
|
||||
src.right_arm = null
|
||||
src.update_dead_icon()
|
||||
|
||||
else if (istype(W, /obj/item/circular_saw))
|
||||
if (user.zone_sel.selecting == "l_arm")
|
||||
if (src.left_arm_stage == 1)
|
||||
user.visible_message("<span class='combat'>[user] saws through the bone of [src]'s left arm with [W].</span>", "<span style=\"color:red\">You saw through the bone of [src]'s left arm with [W].</span>")
|
||||
src.left_arm_stage++
|
||||
else if (user.zone_sel.selecting == "r_arm")
|
||||
if (src.right_arm_stage == 1)
|
||||
user.visible_message("<span class='combat'>[user] saws through the bone of [src]'s right arm with [W].</span>", "<span style=\"color:red\">You saw through the bone of [src]'s right arm with [W].</span>")
|
||||
src.right_arm_stage++
|
||||
else
|
||||
..()
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
CritterAttack(mob/M)
|
||||
if(ismob(M))
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> claws at [src.target]!</span>")
|
||||
if(ishuman(target))
|
||||
random_brute_damage(src.target, rand(6,18))
|
||||
else if (isrobot(target))
|
||||
target:compborg_take_critter_damage(null, rand(4,8))
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> mauls [M]!</span>")
|
||||
playsound(src.loc, pick("sound/voice/MEraaargh.ogg"), 40, 0)
|
||||
M.weakened += rand(2,4)
|
||||
M.stunned += rand(1,3)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
|
||||
obj/critter/bear/care
|
||||
name = "space carebear"
|
||||
desc = "I love you!"
|
||||
icon_state = "carebear"
|
||||
|
||||
New()
|
||||
..()
|
||||
src.name = pick("Lovealot Bear", "Stuffums", "World Destroyer", "Pookie", "Colonel Sanders", "Hugbeast", "Lovely Bear", "HUG ME", "Empathy Bear", "Steve", "Mr. Pants")
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> snuggles [M]!</span>")
|
||||
playsound(src.loc, pick("sound/misc/babynoise.ogg"), 50, 0)
|
||||
M.weakened += rand(2,4)
|
||||
M.stunned += rand(1,3)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
|
||||
/obj/critter/yeti
|
||||
name = "space yeti"
|
||||
desc = "Well-known as the single most aggressive, dangerous and hungry thing in the universe."
|
||||
icon_state = "yeti"
|
||||
density = 1
|
||||
health = 75
|
||||
aggressive = 1
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
firevuln = 3
|
||||
brutevuln = 1
|
||||
angertext = "starts chasing" // comes between critter name and target name
|
||||
butcherable = 1
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/leather
|
||||
max_skins = 2
|
||||
|
||||
New()
|
||||
..()
|
||||
src.seek_target()
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (src.target)
|
||||
src.task = "chasing"
|
||||
break
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C)) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/)) src.attack = 1
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> [src.angertext] [src.target]!</span>")
|
||||
playsound(src.loc, pick("sound/voice/YetiGrowl.ogg"), 40, 0)
|
||||
src.task = "chasing"
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> punches out [M]!</span>")
|
||||
playsound(src.loc, "sound/effects/bang.ogg", 40, 1, -1)
|
||||
M.stunned = 10
|
||||
M.weakened = 10
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> devours [M] in one bite!</span>")
|
||||
logTheThing("combat", M, null, "was devoured by [src] at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880).
|
||||
playsound(src.loc, "sound/items/eatfood.ogg", 30, 1, -2)
|
||||
M.death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
M.transforming = 1
|
||||
M.canmove = 0
|
||||
M.icon = null
|
||||
M.invisibility = 101
|
||||
if(ishuman(M))
|
||||
animation = new(src.loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
if (M.client)
|
||||
var/mob/dead/observer/newmob
|
||||
newmob = new/mob/dead/observer(M)
|
||||
M.client:mob = newmob
|
||||
M.mind.transfer_to(newmob)
|
||||
qdel(M)
|
||||
src.task = "thinking"
|
||||
src.seek_target()
|
||||
src.attacking = 0
|
||||
playsound(src.loc, pick("sound/misc/burp_alien.ogg"), 50, 0)
|
||||
|
||||
sleeping = 1
|
||||
|
||||
/obj/critter/shark
|
||||
name = "space shark"
|
||||
desc = "This is the third most terrifying thing you've ever laid eyes on."
|
||||
icon = 'icons/misc/banshark.dmi'
|
||||
icon_state = "banshark1"
|
||||
density = 1
|
||||
health = 75
|
||||
aggressive = 1
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
firevuln = 3
|
||||
brutevuln = 1
|
||||
angertext = "swims after" // comes between critter name and target name
|
||||
generic = 0
|
||||
var/recentsound = 0
|
||||
butcherable = 1
|
||||
|
||||
CritterDeath()
|
||||
..()
|
||||
src.reagents.add_reagent("shark_dna", 50, null)
|
||||
return
|
||||
|
||||
New()
|
||||
..()
|
||||
src.seek_target()
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (src.target)
|
||||
src.task = "chasing"
|
||||
break
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C)) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/)) src.attack = 1
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> [src.angertext] [src.target]!</span>")
|
||||
if(!recentsound)
|
||||
playsound(src.loc, pick("sound/misc/jaws.ogg"), 50, 0)
|
||||
recentsound = 1
|
||||
spawn(600) recentsound = 0
|
||||
src.task = "chasing"
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> bashes into [M]!</span>")
|
||||
playsound(src.loc, "sound/effects/bang.ogg", 50, 1, -1)
|
||||
M.stunned = 10
|
||||
M.weakened = 10
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> gibs [M] in one bite!</span>")
|
||||
logTheThing("combat", M, null, "was gibbed by [src] at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880).
|
||||
playsound(src.loc, "sound/items/eatfood.ogg", 30, 1, -2)
|
||||
M.gib()
|
||||
src.task = "thinking"
|
||||
src.seek_target()
|
||||
src.attacking = 0
|
||||
spawn(30) playsound(src.loc, pick("sound/misc/burp_alien.ogg"), 50, 0)
|
||||
|
||||
sleeping = 1
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/shark
|
||||
name = "shark egg"
|
||||
critter_type = /obj/critter/shark
|
||||
warm_count = 50
|
||||
|
||||
/obj/critter/bat
|
||||
name = "bat"
|
||||
desc = "skreee!"
|
||||
icon_state = "bat"
|
||||
density = 1
|
||||
health = 5
|
||||
aggressive = 0
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 0
|
||||
atksilicon = 0
|
||||
firevuln = 1
|
||||
brutevuln = 1
|
||||
|
||||
CritterDeath()
|
||||
..()
|
||||
src.reagents.add_reagent("woolofbat", 50, null)
|
||||
return
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> bites [src.target]!</span>")
|
||||
random_brute_damage(src.target, 1)
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
Move()
|
||||
if(prob(15))
|
||||
playsound(src.loc, "rustle", 10, 1)
|
||||
..()
|
||||
|
||||
/obj/critter/bat/doctor
|
||||
name = "Dr. Acula"
|
||||
desc = "If you ask nicely he might even write you a preskreeeption!"
|
||||
icon_state = "batdoctor"
|
||||
health = 30
|
||||
generic = 0
|
||||
|
||||
// A slightly scarier (but still cute) bat for vampires
|
||||
|
||||
/obj/critter/bat/buff
|
||||
name = "angry bat"
|
||||
desc = "It doesn't look too happy!"
|
||||
icon_state = "scarybat"
|
||||
health = 25
|
||||
aggressive = 1
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
brutevuln = 0.7
|
||||
opensdoors = 0
|
||||
seekrange = 5
|
||||
density = 1 // so lasers can hit them
|
||||
angertext = "screeches at"
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (src.target)
|
||||
src.task = "chasing"
|
||||
break
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (iscarbon(C) && !src.atkcarbon) continue
|
||||
if (istype(C, /mob/living/silicon/) && !src.atksilicon) continue
|
||||
if (C.health < 0) continue
|
||||
if (C in src.friends) continue
|
||||
if (isvampire(C)) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> [src.angertext] [C.name]!</span>")
|
||||
src.task = "chasing"
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> hits [M]!</span>")
|
||||
if (prob(30)) M.weakened += rand(1,2)
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> bites and claws at [src.target]!</span>")
|
||||
random_brute_damage(src.target, rand(3,5))
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/bat
|
||||
name = "bat egg"
|
||||
critter_type = /obj/critter/bat
|
||||
|
||||
/obj/critter/lion
|
||||
name = "lion"
|
||||
desc = "Oh christ"
|
||||
icon_state = "lion"
|
||||
density = 1
|
||||
health = 20
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
atcritter = 1
|
||||
firevuln = 0.5
|
||||
brutevuln = 0.5
|
||||
butcherable = 1
|
||||
death_text = "%src% gives up the ghost!"
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
M.visible_message("<span class='combat'><b>[src]</b> savagely bites [src.target]!</span>")
|
||||
random_brute_damage(M, rand(8,16))
|
||||
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><b>[src]</b> lunges upon [M]!</span>")
|
||||
if(iscarbon(M))
|
||||
if(prob(50)) M.stunned += rand(2,4)
|
||||
random_brute_damage(M, rand(4,8))
|
||||
@@ -0,0 +1,878 @@
|
||||
// p much straight up copied from secbot code =I
|
||||
|
||||
/obj/critter/
|
||||
name = "critter"
|
||||
desc = "you shouldnt be able to see this"
|
||||
icon = 'icons/misc/critter.dmi'
|
||||
var/living_state = null
|
||||
var/dead_state = null
|
||||
layer = 5.0
|
||||
density = 1
|
||||
anchored = 0
|
||||
flags = FPRINT | CONDUCT | USEDELAY
|
||||
var/is_template = 0
|
||||
var/alive = 1
|
||||
var/health = 10
|
||||
|
||||
// "sleeping" is a special state that sleeps for 10 cycles, wakes up, sleeps again unless someone is found
|
||||
// "hibernating" is another special state where it does nothing unless explicitly woken up
|
||||
var/task = "thinking"
|
||||
|
||||
var/list/followed_path = null
|
||||
var/followed_path_retries = 0
|
||||
var/followed_path_retry_target = null
|
||||
var/follow_path_blindly = 0
|
||||
|
||||
var/report_state = 0
|
||||
var/quality_name = null
|
||||
var/mobile = 1
|
||||
var/aggressive = 0
|
||||
var/defensive = 0
|
||||
var/wanderer = 1
|
||||
var/opensdoors = 0
|
||||
var/frustration = 0
|
||||
var/last_found = null
|
||||
var/target = null
|
||||
var/oldtarget_name = null
|
||||
var/target_lastloc = null
|
||||
var/atkcarbon = 0
|
||||
var/atksilicon = 0
|
||||
var/atcritter = 0
|
||||
var/atkintangible = 0
|
||||
var/attack = 0
|
||||
var/attacking = 0
|
||||
var/steps = 0
|
||||
var/firevuln = 1
|
||||
var/brutevuln = 1
|
||||
var/miscvuln = 0.2
|
||||
var/attack_range = 1 // how many tiles away it will attack from
|
||||
var/seekrange = 7 // how many tiles away it will look for a target
|
||||
var/list/friends = list() // used for tracking hydro-grown monsters's creator
|
||||
var/attacker = null // used for defensive tracking
|
||||
var/angertext = "charges at" // comes between critter name and target name
|
||||
var/pet_text = "pets"
|
||||
var/death_text = "%src% dies!"
|
||||
var/hitsound = null
|
||||
var/flying = 0
|
||||
//flags = OPENCONTAINER
|
||||
var/sleeping = 0 //countdown, when hits 0 does a wake check
|
||||
var/sleep_check = 10 //countdown, when hits 0 does a sleep check
|
||||
var/hibernate_check = 2
|
||||
var/sleeping_icon_state = null
|
||||
var/mob/living/wrangler = null
|
||||
|
||||
var/butcherable = 0
|
||||
var/meat_type = /obj/item/reagent_containers/food/snacks/ingredient/meat/mysterymeat
|
||||
var/name_the_meat = 1
|
||||
|
||||
var/generic = 1 // if yes, critter can be randomized a bit
|
||||
var/max_quality = 100
|
||||
var/min_quality = -100
|
||||
|
||||
var/can_revive = 1 // resurrectable with strange reagent
|
||||
|
||||
var/skinresult = null //type path of hide/leather item from skinning
|
||||
var/max_skins = 1 //How many skins you can get at most from this critter. It's 1 to the max amound defined here. random.
|
||||
var/muted = 0 // shut UP
|
||||
|
||||
var/chases_food = 0
|
||||
var/health_gain_from_food = 0
|
||||
var/obj/item/reagent_containers/food/snacks/food_target = null
|
||||
var/eat_text = "nibbles at"
|
||||
var/feed_text = null
|
||||
|
||||
var/area/registered_area = null //the area this critter is registered in
|
||||
|
||||
proc/tokenized_message(var/message, var/target)
|
||||
if (!message || !length(message))
|
||||
return
|
||||
var/msg = dd_replacetext(message, "%src%", "<b>[src]</b>")
|
||||
msg = dd_replacetext(msg, "%target%", "[target]")
|
||||
src.visible_message("<span style=\"color:red\">[msg]</span>")
|
||||
|
||||
proc/report_spawn()
|
||||
if (!report_state)
|
||||
report_state = 1
|
||||
if (src in gauntlet_controller.gauntlet)
|
||||
gauntlet_controller.increaseCritters(src)
|
||||
if (src in colosseum_controller.colosseum)
|
||||
colosseum_controller.increaseCritters(src)
|
||||
|
||||
proc/report_death()
|
||||
if (report_state == 1)
|
||||
report_state = 0
|
||||
if (src in gauntlet_controller.gauntlet)
|
||||
gauntlet_controller.decreaseCritters(src)
|
||||
if (src in colosseum_controller.colosseum)
|
||||
colosseum_controller.decreaseCritters(src)
|
||||
|
||||
serialize(var/savefile/F, var/path, var/datum/sandbox/sandbox)
|
||||
..()
|
||||
F["[path].aggressive"] << src.aggressive
|
||||
F["[path].atkcarbon"] << src.atkcarbon
|
||||
F["[path].atksilicon"] << src.atksilicon
|
||||
F["[path].health"] << src.health
|
||||
F["[path].opensdoors"] << src.opensdoors
|
||||
F["[path].wanderer"] << src.wanderer
|
||||
F["[path].mobile"] << src.mobile
|
||||
F["[path].brutevuln"] << src.brutevuln
|
||||
F["[path].firevuln"] << src.firevuln
|
||||
|
||||
deserialize(var/savefile/F, var/path, var/datum/sandbox/sandbox)
|
||||
. = ..()
|
||||
F["[path].aggressive"] >> src.aggressive
|
||||
F["[path].atkcarbon"] >> src.atkcarbon
|
||||
F["[path].atksilicon"] >> src.atksilicon
|
||||
F["[path].health"] >> src.health
|
||||
F["[path].opensdoors"] >> src.opensdoors
|
||||
F["[path].wanderer"] >> src.wanderer
|
||||
F["[path].mobile"] >> src.mobile
|
||||
F["[path].brutevuln"] >> src.brutevuln
|
||||
F["[path].firevuln"] >> src.firevuln
|
||||
|
||||
clone()
|
||||
var/obj/critter/C = ..()
|
||||
C.mobile = mobile
|
||||
C.aggressive = aggressive
|
||||
C.defensive = defensive
|
||||
C.atkcarbon = atkcarbon
|
||||
C.atksilicon = atksilicon
|
||||
C.health = health
|
||||
C.wanderer = wanderer
|
||||
C.brutevuln = brutevuln
|
||||
C.firevuln = firevuln
|
||||
return C
|
||||
|
||||
proc/wake_from_hibernation()
|
||||
if(task != "hibernating") return
|
||||
//DEBUG("[src] woke from hibernation at [showCoords(src.x, src.y, src.z)] in [registered_area ? registered_area.name : "nowhere"] due to [usr ? usr : "some mysterious fucking reason"]")
|
||||
//Ok, now we look to see if we should get murdlin'
|
||||
task = "sleeping"
|
||||
hibernate_check = 20 //20 sleep_checks
|
||||
do_wake_check(1)
|
||||
|
||||
if(registered_area)
|
||||
registered_area.registered_critters -= src
|
||||
registered_area = null
|
||||
|
||||
anchored = initial(anchored)
|
||||
//critters |= src //Resume processing this critter
|
||||
|
||||
|
||||
proc/hibernate()
|
||||
registered_area = get_area(src)
|
||||
hibernate_check = 20 //Reset this counter in case of failure
|
||||
if(registered_area)
|
||||
task = "hibernating"
|
||||
registered_area.registered_critters |= src
|
||||
anchored = 1
|
||||
//DEBUG("[src] started hibernating at [showCoords(src.x, src.y, src.z)] in [registered_area ? registered_area.name : "nowhere"].")
|
||||
//critters -= src //Stop processing this critter
|
||||
|
||||
|
||||
HasProximity(atom/movable/AM as mob|obj)
|
||||
if(task == "hibernating" && istype(AM, /mob))
|
||||
var/mob/M = AM
|
||||
if(M.client) wake_from_hibernation()
|
||||
|
||||
..()
|
||||
|
||||
set_loc(var/atom/newloc)
|
||||
..()
|
||||
wake_from_hibernation() //Critters hibernate lightly enough to wake up when moved
|
||||
|
||||
proc/on_revive()
|
||||
return
|
||||
|
||||
proc/on_sleep()
|
||||
|
||||
proc/on_wake()
|
||||
var/area/A = get_area(src)
|
||||
if(A) A.wake_critters() //HLEP!
|
||||
|
||||
proc/on_grump()
|
||||
|
||||
attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
..()
|
||||
if (!src.alive)
|
||||
if (src.skinresult && max_skins)
|
||||
if (istype(W, /obj/item/circular_saw) || istype(W, /obj/item/kitchen/utensil/knife) || istype(W, /obj/item/scalpel) || istype(W, /obj/item/raw_material/shard) || istype(W, /obj/item/sword) || istype(W, /obj/item/saw) || istype(W, /obj/item/wirecutters))
|
||||
|
||||
for(var/i, i<rand(1, max_skins), i++)
|
||||
new src.skinresult (src.loc)
|
||||
|
||||
src.skinresult = null
|
||||
|
||||
user.visible_message("<span style=\"color:red\">[user] skins [src].</span>","You skin [src].")
|
||||
|
||||
if (src.butcherable && (istype(W, /obj/item/kitchen/utensil/knife) || istype(W, /obj/item/knife_butcher)))
|
||||
user.visible_message("<span style=\"color:red\">[user] butchers [src].[src.butcherable == 2 ? "<b>WHAT A MONSTER</b>" : null]","You butcher [src].</span>")
|
||||
|
||||
var/i = rand(2,4)
|
||||
var/transfer = src.reagents.total_volume / i
|
||||
|
||||
while (i-- > 0)
|
||||
var/obj/item/reagent_containers/food/newmeat = new meat_type
|
||||
newmeat.set_loc(src.loc)
|
||||
src.reagents.trans_to(newmeat, transfer)
|
||||
if (name_the_meat)
|
||||
newmeat.name = "[src.name] meat"
|
||||
newmeat.real_name = newmeat.name
|
||||
qdel (src)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
if (src.health_gain_from_food && (istype(W, /obj/item/reagent_containers/food/snacks) || istype(W, /obj/item/seed)))
|
||||
user.visible_message("<b>[user]</b> feeds [W] to [src]!","You feed [W] to [src].")
|
||||
if (src.feed_text)
|
||||
src.visible_message("[src] [src.feed_text]")
|
||||
src.health += src.health_gain_from_food
|
||||
qdel(W)
|
||||
return
|
||||
|
||||
var/attack_force = 0
|
||||
var/damage_type = "brute"
|
||||
if (istype(W, /obj/item/artifact/melee_weapon))
|
||||
var/datum/artifact/melee/ME = W.artifact
|
||||
attack_force = ME.dmg_amount
|
||||
damage_type = ME.damtype
|
||||
else
|
||||
attack_force = W.force
|
||||
damage_type = W.damtype
|
||||
|
||||
if (!attack_force)
|
||||
return
|
||||
|
||||
if (src.sleeping)
|
||||
sleeping = 0
|
||||
on_wake()
|
||||
|
||||
switch(damage_type)
|
||||
if("fire")
|
||||
src.health -= attack_force * src.firevuln
|
||||
if("brute")
|
||||
src.health -= attack_force * src.brutevuln
|
||||
else
|
||||
src.health -= attack_force * src.miscvuln
|
||||
if (hitsound)
|
||||
playsound(src, hitsound, 50, 1)
|
||||
if (src.alive && src.health <= 0) src.CritterDeath()
|
||||
if (src.alive)
|
||||
on_damaged(user)
|
||||
if (src.defensive)
|
||||
if (src.target == user && src.task == "attacking")
|
||||
if (prob(50 - attack_force))
|
||||
return
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> flinches!</span>")
|
||||
src.target = user
|
||||
src.oldtarget_name = user.name
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> [src.angertext] [user.name]!</span>")
|
||||
src.task = "chasing"
|
||||
on_grump()
|
||||
|
||||
proc/on_damaged(mob/user)
|
||||
if(registered_area) //In case some butt fiddles with a hibernating critter
|
||||
registered_area.wake_critters()
|
||||
return
|
||||
|
||||
proc/on_pet()
|
||||
if(registered_area) //In case some nice person fiddles with a hibernating critter
|
||||
registered_area.wake_critters()
|
||||
return
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
..()
|
||||
if (!src.alive)
|
||||
..()
|
||||
return
|
||||
|
||||
if (src.sleeping)
|
||||
sleeping = 0
|
||||
on_wake()
|
||||
|
||||
if (user.a_intent == INTENT_HARM)
|
||||
src.health -= rand(1,2) * src.brutevuln
|
||||
src.visible_message("<span style=\"color:red\"><b>[user]</b> punches [src]!</span>")
|
||||
playsound(src.loc, pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg'), 100, 1)
|
||||
if (hitsound)
|
||||
playsound(src, hitsound, 50, 1)
|
||||
if (src.alive && src.health <= 0) src.CritterDeath()
|
||||
if (src.alive)
|
||||
on_damaged(user)
|
||||
if (src.defensive)
|
||||
if (src.target == user && src.task == "attacking")
|
||||
if (prob(50))
|
||||
return
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> flinches!</span>")
|
||||
src.target = user
|
||||
src.oldtarget_name = user.name
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> [src.angertext] [user.name]!</span>")
|
||||
src.task = "chasing"
|
||||
on_grump()
|
||||
else
|
||||
var/pet_verb = islist(src.pet_text) ? pick(src.pet_text) : src.pet_text
|
||||
src.visible_message("<span style=\"color:blue\"><b>[user]</b> [pet_verb] [src]!</span>", 1)
|
||||
on_pet()
|
||||
|
||||
proc/patrol_step()
|
||||
if (!mobile)
|
||||
return
|
||||
var/turf/moveto = locate(src.x + rand(-1,1),src.y + rand(-1, 1),src.z)
|
||||
if(isturf(moveto) && !moveto.density) step_towards(src, moveto)
|
||||
if(src.aggressive) seek_target()
|
||||
steps += 1
|
||||
if (steps == rand(5,20)) src.task = "thinking"
|
||||
|
||||
Bump(M as mob|obj)
|
||||
spawn(0)
|
||||
if (istype(M, /obj/machinery/door/))
|
||||
var/obj/machinery/door/D = M
|
||||
D.Bumped(src) // Doesn't call that automatically for some inexplicable reason.
|
||||
else if ((istype(M, /mob/living/)) && (!src.anchored))
|
||||
src.set_loc(M:loc)
|
||||
src.frustration = 0
|
||||
return
|
||||
return
|
||||
|
||||
bullet_act(var/obj/projectile/P)
|
||||
var/damage = 0
|
||||
damage = round((P.power*P.proj_data.ks_ratio), 1.0)
|
||||
|
||||
if (src.sleeping)
|
||||
sleeping = 0
|
||||
on_wake()
|
||||
|
||||
if(src.material) src.material.triggerOnAttacked(src, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter) )
|
||||
for(var/atom/A in src)
|
||||
if(A.material)
|
||||
A.material.triggerOnAttacked(A, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter) )
|
||||
|
||||
switch(P.proj_data.damage_type)
|
||||
if(D_KINETIC,D_PIERCING,D_SLASHING)
|
||||
src.health -= (damage*brutevuln)
|
||||
if(D_ENERGY)
|
||||
src.health -= damage
|
||||
if(D_BURNING)
|
||||
src.health -= (damage*firevuln)
|
||||
if(D_RADIOACTIVE)
|
||||
src.health -= 1
|
||||
if(D_TOXIC)
|
||||
src.health -= 1
|
||||
|
||||
on_damaged(usr)
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
|
||||
ex_act(severity)
|
||||
if (src.sleeping)
|
||||
sleeping = 0
|
||||
on_wake()
|
||||
|
||||
on_damaged()
|
||||
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
src.health -= 200
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
return
|
||||
if(2.0)
|
||||
src.health -= 75
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
return
|
||||
else
|
||||
src.health -= 25
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
return
|
||||
return
|
||||
|
||||
meteorhit()
|
||||
src.health -= 150 // no more instakill
|
||||
on_damaged()
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
return
|
||||
|
||||
proc/check_health()
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
|
||||
blob_act(var/power)
|
||||
src.health -= power
|
||||
on_damaged()
|
||||
if (src.health <= 0)
|
||||
src.CritterDeath()
|
||||
return
|
||||
|
||||
proc/follow_path()
|
||||
if (!mobile)
|
||||
task = "thinking"
|
||||
return
|
||||
if (src.loc == followed_path_retry_target)
|
||||
logTheThing("debug", null, null, "<B>Marquesas/Critter Astar:</b> Critter arrived at target location.")
|
||||
task = "thinking"
|
||||
followed_path = null
|
||||
followed_path_retries = 0
|
||||
followed_path_retry_target = null
|
||||
else if (!followed_path)
|
||||
logTheThing("debug", null, null, "<B>Marquesas/Critter Astar:</b> Critter following empty path.")
|
||||
task = "thinking"
|
||||
else if (!followed_path.len)
|
||||
logTheThing("debug", null, null, "<B>Marquesas/Critter Astar:</b> Critter path ran out.")
|
||||
task = "thinking"
|
||||
else
|
||||
var/turf/nextturf = followed_path[1]
|
||||
var/retry = 0
|
||||
if (nextturf.density)
|
||||
retry = 1
|
||||
if (!retry)
|
||||
for (var/obj/O in nextturf)
|
||||
if (O.density)
|
||||
retry = 1
|
||||
break
|
||||
if (retry)
|
||||
if (!followed_path_retry_target)
|
||||
task = "thinking"
|
||||
else if (followed_path_retries > 10)
|
||||
logTheThing("debug", null, null, "<B>Marquesas/Critter Astar:</b> Critter out of retries.")
|
||||
task = "thinking"
|
||||
else
|
||||
logTheThing("debug", null, null, "<B>Marquesas/Critter Astar:</b> Hit a wall, retrying.")
|
||||
followed_path = findPath(src.loc, followed_path_retry_target)
|
||||
return
|
||||
else
|
||||
set_loc(nextturf)
|
||||
followed_path -= nextturf
|
||||
if (!follow_path_blindly)
|
||||
seek_target()
|
||||
|
||||
proc/do_wake_check(var/force = 0)
|
||||
if(!force && sleeping-- > 0) return
|
||||
|
||||
var/waking = 0
|
||||
for(var/mob/M in range(10, src))
|
||||
if(M.client)
|
||||
waking = 1
|
||||
break
|
||||
if (!waking)
|
||||
if (get_area(src) == colosseum_controller.colosseum)
|
||||
waking = 1
|
||||
|
||||
if(waking)
|
||||
hibernate_check = 20
|
||||
sleeping = 0
|
||||
task = "thinking"
|
||||
on_wake()
|
||||
if (sleeping_icon_state)
|
||||
src.icon_state = initial(src.icon_state)
|
||||
return 1
|
||||
else
|
||||
sleeping = 10
|
||||
if(--hibernate_check <= 0)
|
||||
src.hibernate()
|
||||
return 0
|
||||
|
||||
proc/do_sleep_check(var/force = 0)
|
||||
if(!force && sleep_check-- > 0) return
|
||||
|
||||
var/stay_awake = 0
|
||||
for(var/mob/M in range(10, src))
|
||||
if(M.client)
|
||||
stay_awake = 1
|
||||
break
|
||||
|
||||
if(!stay_awake)
|
||||
sleeping = 10
|
||||
on_sleep()
|
||||
if (sleeping_icon_state)
|
||||
src.icon_state = sleeping_icon_state
|
||||
task = "sleeping"
|
||||
return 0
|
||||
else
|
||||
sleep_check = 10
|
||||
|
||||
proc/process()
|
||||
if (is_template || task == "hibernating")
|
||||
return 0
|
||||
if (!src.alive) return 0
|
||||
|
||||
if(sleeping > 0)
|
||||
sleeping--
|
||||
return 0
|
||||
|
||||
check_health()
|
||||
|
||||
if(task == "following path")
|
||||
follow_path()
|
||||
spawn(10)
|
||||
follow_path()
|
||||
else if(task == "sleeping")
|
||||
do_wake_check()
|
||||
else
|
||||
do_sleep_check()
|
||||
|
||||
return ai_think()
|
||||
|
||||
proc/ai_think()
|
||||
switch(task)
|
||||
if ("thinking")
|
||||
src.attack = 0
|
||||
src.target = null
|
||||
|
||||
walk_to(src,0)
|
||||
|
||||
if (src.aggressive) seek_target()
|
||||
if (src.wanderer && src.mobile && !src.target) src.task = "wandering"
|
||||
if ("chasing")
|
||||
if (src.frustration >= 8)
|
||||
src.target = null
|
||||
src.last_found = world.time
|
||||
src.frustration = 0
|
||||
src.task = "thinking"
|
||||
if (mobile)
|
||||
walk_to(src,0)
|
||||
if (target)
|
||||
if (get_dist(src, src.target) <= src.attack_range)
|
||||
var/mob/living/carbon/M = src.target
|
||||
if (M)
|
||||
ChaseAttack(M)
|
||||
src.task = "attacking"
|
||||
src.anchored = 1
|
||||
src.target_lastloc = M.loc
|
||||
else
|
||||
if (mobile)
|
||||
var/turf/olddist = get_dist(src, src.target)
|
||||
walk_to(src, src.target,1,4)
|
||||
if ((get_dist(src, src.target)) >= (olddist))
|
||||
src.frustration++
|
||||
else
|
||||
src.frustration = 0
|
||||
else
|
||||
if (get_dist(src, src.target) > attack_range)
|
||||
src.frustration++
|
||||
else
|
||||
src.frustration = 0
|
||||
else src.task = "thinking"
|
||||
|
||||
if ("chasing food")
|
||||
if (!src.chases_food || src.food_target == null)
|
||||
src.task = "thinking"
|
||||
else if (get_dist(src, src.food_target) <= src.attack_range)
|
||||
src.task = "eating"
|
||||
else
|
||||
walk_to(src, src.food_target,1,4)
|
||||
|
||||
if ("eating")
|
||||
if (get_dist(src, src.food_target) > src.attack_range)
|
||||
src.task = "chasing food"
|
||||
else
|
||||
src.visible_message("<b>[src]</b> [src.eat_text] [src.food_target].")
|
||||
playsound(src.loc,"sound/items/eatfood.ogg", rand(10,50), 1)
|
||||
if (food_target.reagents.total_volume > 0 && src.reagents.total_volume < 30)
|
||||
food_target.reagents.trans_to(src, 5)
|
||||
src.food_target.amount--
|
||||
spawn(rand(20,30))
|
||||
if (src.food_target != null && src.food_target.amount <= 0)
|
||||
qdel(src.food_target)
|
||||
src.task = "thinking"
|
||||
src.food_target = null
|
||||
src.health += src.health_gain_from_food
|
||||
|
||||
if ("attacking")
|
||||
// see if he got away
|
||||
if ((get_dist(src, src.target) > src.attack_range) || ((src.target:loc != src.target_lastloc)))
|
||||
src.anchored = initial(src.anchored)
|
||||
src.task = "chasing"
|
||||
else
|
||||
if (get_dist(src, src.target) <= src.attack_range)
|
||||
var/mob/living/carbon/M = src.target
|
||||
if (!src.attacking) CritterAttack(src.target)
|
||||
if (!src.aggressive)
|
||||
src.task = "thinking"
|
||||
src.target = null
|
||||
src.anchored = initial(src.anchored)
|
||||
src.last_found = world.time
|
||||
src.frustration = 0
|
||||
src.attacking = 0
|
||||
else
|
||||
if(M!=null)
|
||||
if (M.health < 0)
|
||||
src.task = "thinking"
|
||||
src.target = null
|
||||
src.anchored = initial(src.anchored)
|
||||
src.last_found = world.time
|
||||
src.frustration = 0
|
||||
src.attacking = 0
|
||||
else
|
||||
src.anchored = initial(src.anchored)
|
||||
src.attacking = 0
|
||||
src.task = "chasing"
|
||||
if ("wandering")
|
||||
patrol_step()
|
||||
return 1
|
||||
|
||||
|
||||
New()
|
||||
if(!src.reagents) src.create_reagents(100)
|
||||
critters += src
|
||||
report_spawn()
|
||||
if(generic)
|
||||
src.quality = rand(min_quality,max_quality)
|
||||
var/nickname = getCritterQuality(src.quality)
|
||||
if(nickname)
|
||||
src.quality_name = nickname
|
||||
src.name = "[nickname] [src.name]"
|
||||
..()
|
||||
|
||||
proc/seek_target()
|
||||
src.anchored = initial(src.anchored)
|
||||
if (src.target)
|
||||
src.task = "chasing"
|
||||
return
|
||||
|
||||
if (src.chases_food)
|
||||
var/list/visible = new()
|
||||
for (var/obj/item/reagent_containers/food/snacks/S in view(src.seekrange,src))
|
||||
visible.Add(S)
|
||||
if (src.food_target && visible.Find(src.food_target))
|
||||
src.task = "chasing food"
|
||||
return
|
||||
else
|
||||
src.task = "thinking"
|
||||
if (visible.len)
|
||||
src.food_target = visible[1]
|
||||
src.task = "chasing food"
|
||||
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
//if (src.target)
|
||||
// src.task = "chasing"
|
||||
// break
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (iscarbon(C) && !src.atkcarbon) continue
|
||||
if (istype(C, /mob/living/silicon/) && !src.atksilicon) continue
|
||||
if (istype(C, /mob/living/intangible/) && !src.atkintangible) continue
|
||||
if (C.health < 0) continue
|
||||
if(!filter_target(C)) continue
|
||||
if (C in src.friends) continue
|
||||
if (ishuman(C))
|
||||
if (C:bioHolder && C:bioHolder.HasEffect("revenant"))
|
||||
continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> [src.angertext] [C.name]!</span>")
|
||||
src.task = "chasing"
|
||||
on_grump()
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
proc/filter_target(var/mob/living/M) //Better to have specialized filters in it's own proc rather than overriding the main seek_target thing imo
|
||||
return 1
|
||||
|
||||
proc/CritterDeath()
|
||||
if (!src.alive) return
|
||||
if (!dead_state)
|
||||
src.icon_state = "[initial(src.icon_state)]-dead"
|
||||
else
|
||||
src.icon_state = dead_state
|
||||
src.alive = 0
|
||||
src.anchored = 0
|
||||
src.density = 0
|
||||
walk_to(src,0)
|
||||
report_death()
|
||||
src.tokenized_message(death_text)
|
||||
|
||||
proc/ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> leaps at [src.target]!</span>")
|
||||
//playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1, -1)
|
||||
|
||||
proc/CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> bites [src.target]!</span>")
|
||||
random_brute_damage(src.target, 1)
|
||||
spawn(25)
|
||||
src.attacking = 0
|
||||
|
||||
proc/getCritterQuality(var/quality)
|
||||
switch(quality)
|
||||
if(-INFINITY to -100)
|
||||
return "abysmal"
|
||||
if(-100 to -99)
|
||||
return "worst"
|
||||
if(-98 to -91)
|
||||
return pick("shameful", "hideous", "grotesque", "vile", "misshapen", "garbage", "illegal", "dreadful", "god-awful")
|
||||
if(-90 to -75)
|
||||
return pick("ugly", "grody", "stinky", "awful", "diseased", "filthy", "lousy", "overweight", "broken", "unfortunate", "unacceptable", "sad", "slipshod", "crappy", "faulty", "fraudulent")
|
||||
if(-74 to -50)
|
||||
return pick("shabby", "mangy", "dented", "dusty", "sub-par", "slightly less nice", "weird", "crummy", "busted", "funky", "bad news", "deficient", "cruddy", "icky", "not good")
|
||||
if(-49 to 50)
|
||||
return ""
|
||||
if(51 to 64)
|
||||
return pick("nice", "cute", "healthy", "buff", "strong")
|
||||
if(65 to 74)
|
||||
return pick("suave", "buff", "robust", "handsome", "fine", "slightly nicer", "pretty good")
|
||||
if(75 to 85)
|
||||
return pick("high-class", "great", "burly", "superb", "excellent", "admirable")
|
||||
if(86 to 90)
|
||||
return pick("majestic", "fantastic", "high-quality", "marvelous", "deluxe")
|
||||
if(91 to 94)
|
||||
return pick("show-quality", "finest", "superb")
|
||||
if(95 to 97)
|
||||
return "champion"
|
||||
if(98 to 99)
|
||||
src.material = getCachedMaterial("gold")
|
||||
if (src.material)
|
||||
src.material.owner = src
|
||||
src.material.triggerOnAdd(src)
|
||||
return "best"
|
||||
if(100 to INFINITY)
|
||||
src.material = getCachedMaterial("gold")
|
||||
if (src.material)
|
||||
src.material.owner = src
|
||||
src.material.triggerOnAdd(src)
|
||||
return "mystical"
|
||||
else
|
||||
return "odd"
|
||||
return
|
||||
|
||||
proc/Shoot(var/target, var/start, var/user, var/bullet = 0)
|
||||
if(target == start)
|
||||
return
|
||||
// playsound(user, "mp5gunshot.ogg", 100, 1)
|
||||
/* if(bullet == 0)
|
||||
A = new /obj/bullet/mpbullet( user:loc )
|
||||
else if(bullet == 1)
|
||||
playsound(user, "sound/weapons/shotgunshot.ogg", 100, 1)
|
||||
A = new /obj/bullet/slug( user:loc )
|
||||
else if(bullet == 2)
|
||||
playsound(user, "fivegunshot.ogg", 100, 1)
|
||||
A = new /obj/bullet/medbullet( user:loc )*/
|
||||
if (!isturf(target))
|
||||
return
|
||||
// FUCK YOU WHOEVER IS USING THIS
|
||||
// FUCK YOU
|
||||
shoot_projectile_ST(src, new/datum/projectile/bullet/revolver_38(), target)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter
|
||||
name = "egg"
|
||||
desc = "Looks like this could hatch into something."
|
||||
icon_state = "critter_egg"
|
||||
var/critter_name = null
|
||||
var/hatched = 0
|
||||
var/critter_type = null
|
||||
var/warm_count = 10 // how many times you gotta warm it before it hatches
|
||||
var/critter_reagent = null
|
||||
rand_pos = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
var/amt_to_mod = round(src.warm_count / 10, 1)
|
||||
src.warm_count += rand(-amt_to_mod,amt_to_mod)
|
||||
src.color = random_saturated_hex_color(1)
|
||||
if (src.reagents && src.critter_reagent)
|
||||
src.reagents.add_reagent(src.critter_reagent, 10)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if (src.anchored)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/pen))
|
||||
var/t = input(user, "Enter new name", src.name, src.critter_name) as null|text
|
||||
logTheThing("debug", user, null, "names a critter egg \"[t]\"")
|
||||
if (!t)
|
||||
return
|
||||
t = strip_html(dd_replacetext(t, "'",""))
|
||||
t = copytext(t, 1, 65)
|
||||
if (!t)
|
||||
return
|
||||
if (!in_range(src, usr) && src.loc != usr)
|
||||
return
|
||||
|
||||
src.critter_name = t
|
||||
|
||||
else if ((istype(W, /obj/item/weldingtool) && W:welding) || (istype(W, /obj/item/clothing/head/cakehat) && W:on) || istype(W, /obj/item/device/igniter) || ((istype(W, /obj/item/zippo) || istype(W, /obj/item/match) || istype(W, /obj/item/device/candle)) && W:lit) || W.burning || W.hit_type == DAMAGE_BURN) // jesus motherfucking christ
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> warms [src] with [W].</span>",\
|
||||
"<span style=\"color:red\">You warm [src] with [W].</span>")
|
||||
src.warm_count -= 2
|
||||
src.warm_count = max(src.warm_count, 0)
|
||||
src.hatch_check(0, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
attack_self(mob/user as mob)
|
||||
if (src.anchored)
|
||||
return
|
||||
user.visible_message("[user] warms [src] with [his_or_her(user)] hands.",\
|
||||
"You warm [src] with your hands.")
|
||||
src.warm_count --
|
||||
src.warm_count = max(src.warm_count, 0)
|
||||
src.hatch_check(0, user)
|
||||
|
||||
throw_impact(var/turf/T)
|
||||
//..() <- Fuck off mom, I'm 25 and I do what I want =I
|
||||
src.hatch_check(1, null, T)
|
||||
|
||||
proc/hatch_check(var/shouldThrow = 0, var/mob/user, var/turf/T)
|
||||
if (hatched || anchored)
|
||||
return
|
||||
if (src.warm_count <= 0 || shouldThrow)
|
||||
if (shouldThrow && T)
|
||||
new /obj/decal/cleanable/eggsplat(T)
|
||||
src.set_loc(T)
|
||||
else
|
||||
src.anchored = 1
|
||||
src.layer = initial(src.layer)
|
||||
if (user)
|
||||
user.u_equip(src)
|
||||
src.set_loc(get_turf(src))
|
||||
|
||||
spawn(0)
|
||||
if (shouldThrow && T)
|
||||
src.visible_message("<span style=\"color:red\">[src] splats onto the floor messily!</span>")
|
||||
playsound(T, "sound/effects/splat.ogg", 100, 1)
|
||||
else
|
||||
var/hatch_wiggle_counter = rand(3,8)
|
||||
while (hatch_wiggle_counter-- > 0)
|
||||
src.pixel_x++
|
||||
sleep(2)
|
||||
src.pixel_x--
|
||||
sleep(10)
|
||||
src.visible_message("[src] hatches!")
|
||||
|
||||
if (!ispath(critter_type))
|
||||
if (istext(critter_type))
|
||||
critter_type = text2path(critter_type)
|
||||
else
|
||||
logTheThing("debug", null, null, "EGG: [src] has invalid critter path!")
|
||||
src.visible_message("Looks like there wasn't anything inside of [src]!")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/obj/critter/newCritter = new critter_type(T ? T : get_turf(src))
|
||||
|
||||
if (critter_name)
|
||||
newCritter.name = critter_name
|
||||
|
||||
if (shouldThrow && T)
|
||||
newCritter.throw_at(get_edge_target_turf(src, src.dir), 2, 1)
|
||||
|
||||
sleep(1)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
return
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,96 @@
|
||||
/obj/critter/gunbot
|
||||
name = "Robot"
|
||||
desc = "A Security Robot, something seems a bit off."
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "syndibot"
|
||||
density = 1
|
||||
health = 50
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 0
|
||||
atcritter = 1
|
||||
firevuln = 0.5
|
||||
brutevuln = 1
|
||||
is_syndicate = 1
|
||||
mats = 8
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (!src.alive) break
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> fires at [src.target]!</span>")
|
||||
|
||||
|
||||
playsound(src.loc, "sound/weapons/Gunshot.ogg", 50, 1)
|
||||
var/tturf = get_turf(target)
|
||||
spawn(1)
|
||||
Shoot(tturf, src.loc, src)
|
||||
spawn(4)
|
||||
Shoot(tturf, src.loc, src)
|
||||
spawn(6)
|
||||
Shoot(tturf, src.loc, src)
|
||||
|
||||
src.attack = 0
|
||||
return
|
||||
else continue
|
||||
|
||||
if(!src.atcritter) return
|
||||
for (var/obj/critter/C in view(src.seekrange,src))
|
||||
if (!C.alive) break
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (!istype(C, /obj/critter/gunbot)) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> fires at [src.target]!</span>")
|
||||
|
||||
playsound(src.loc, "sound/weapons/Gunshot.ogg", 50, 1)
|
||||
var/tturf = get_turf(target)
|
||||
spawn(1)
|
||||
Shoot(tturf, src.loc, src)
|
||||
spawn(4)
|
||||
Shoot(tturf, src.loc, src)
|
||||
spawn(6)
|
||||
Shoot(tturf, src.loc, src)
|
||||
|
||||
src.attack = 0
|
||||
return
|
||||
else continue
|
||||
task = "thinking"
|
||||
|
||||
CritterDeath()
|
||||
if (!src.alive) return
|
||||
..()
|
||||
if (get_area(src) != colosseum_controller.colosseum)
|
||||
var/turf/Ts = get_turf(src)
|
||||
var/obj/item/drop1 = pick(/obj/item/electronics/battery,/obj/item/electronics/board,/obj/item/electronics/buzzer,/obj/item/electronics/frame,/obj/item/electronics/resistor,/obj/item/electronics/screen,/obj/item/electronics/relay, /obj/item/parts/robot_parts/arm/left, /obj/item/parts/robot_parts/arm/right)
|
||||
var/obj/item/drop2 = pick(/obj/item/electronics/battery,/obj/item/electronics/board,/obj/item/electronics/buzzer,/obj/item/electronics/frame,/obj/item/electronics/resistor,/obj/item/electronics/screen,/obj/item/electronics/relay, /obj/item/parts/robot_parts/arm/left, /obj/item/parts/robot_parts/arm/right)
|
||||
|
||||
new /obj/decal/cleanable/robot_debris(Ts)
|
||||
new drop1(Ts)
|
||||
new /obj/decal/cleanable/robot_debris(Ts)
|
||||
new drop2(Ts)
|
||||
new /obj/decal/cleanable/robot_debris(Ts)
|
||||
|
||||
spawn()
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
@@ -0,0 +1,62 @@
|
||||
/obj/critter/headspider
|
||||
name = "headspider"
|
||||
desc = "Oh my god!"
|
||||
icon_state = "headspider"
|
||||
density = 1
|
||||
anchored = 0
|
||||
aggressive = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 0
|
||||
opensdoors = 1
|
||||
health = 80
|
||||
|
||||
var/datum/abilityHolder/changeling/changeling = null
|
||||
var/datum/mind/owner = null
|
||||
|
||||
examine()
|
||||
set src in view()
|
||||
..()
|
||||
if(!alive)
|
||||
boutput(usr, text("<span style=\"color:red\"><B>the disgusting creature is not moving</B></span>"))
|
||||
else if (src.health > 40)
|
||||
boutput(usr, text("<span style=\"color:red\"><B>the spindly-legged head looks healthy and strong</B></span>"))
|
||||
else
|
||||
boutput(usr, text("<span style=\"color:red\"><B>the ugly thing is missing several limbs</B></span>"))
|
||||
return
|
||||
|
||||
filter_target(var/mob/living/C)
|
||||
//Don't want a dead mob, don't want a mob with the same mind as the owner
|
||||
return C.stat != 2 && (!owner || C.mind != owner)
|
||||
|
||||
ChaseAttack(var/mob/M)
|
||||
if(attacking) return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
src.visible_message("<font color='#FF0000'><B>\The [src]</B> leaps on [H.name]!</font>")
|
||||
H.weakened += rand(3,5)
|
||||
|
||||
CritterAttack(var/mob/M)
|
||||
if(attacking) return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
src.set_loc(H.loc)
|
||||
random_brute_damage(H, 10)
|
||||
src.set_loc(H.loc)
|
||||
src.visible_message("<font color='#FF0000'><B>\The [src]</B> crawls down [H.name]'s throat!</font>")
|
||||
H.paralysis = max(H.paralysis, 10)
|
||||
attacking = 1
|
||||
|
||||
var/datum/ailment_data/parasite/HS = new /datum/ailment_data/parasite
|
||||
HS.master = get_disease_from_path(/datum/ailment/parasite/headspider)
|
||||
HS.affected_mob = H
|
||||
HS.source = owner
|
||||
var/datum/ailment/parasite/headspider/HSD = HS.master
|
||||
HSD.changeling = changeling
|
||||
H.ailments += HS
|
||||
|
||||
if(owner)
|
||||
logTheThing("combat", owner.current ? owner.current : owner, H, "'s headspider enters %target% at [log_loc(src)].")
|
||||
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
@@ -0,0 +1,312 @@
|
||||
/obj/item/clothing/head/tinfoil_hat
|
||||
name = "tinfoil hat"
|
||||
desc = "Protects the wearer from mindcontrol and, apparently, weak martian psychic blasts which do not involve the liquification of brains."
|
||||
icon_state = "tinfoil"
|
||||
item_state = "tinfoil"
|
||||
|
||||
/obj/critter/martian
|
||||
name = "martian"
|
||||
desc = "Genocidal monsters from Mars."
|
||||
icon_state = "martian"
|
||||
density = 1
|
||||
health = 20
|
||||
aggressive = 0
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
firevuln = 1.5
|
||||
brutevuln = 1
|
||||
butcherable = 1
|
||||
flying = 1
|
||||
|
||||
on_damaged(mob/user)
|
||||
if (src.alive && src.defensive && prob(10))
|
||||
MartianPsyblast(user)
|
||||
if (!(src in gauntlet_controller.gauntlet))
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> teleports away!</span>")
|
||||
CritterTeleport(8, 1, 0)
|
||||
|
||||
on_pet()
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<b>[src]</b> screeches, 'KXBQUB IJFDQVW??'", 1)
|
||||
|
||||
|
||||
proc/MartianPsyblast(mob/target as mob)
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<b>[src]</b> screeches, 'GBVQW UVQWIBJZ PKDDR!!!'", 1)
|
||||
if (!ishuman(target))
|
||||
return
|
||||
playsound(target.loc, "sound/effects/ghost2.ogg", 100, 1)
|
||||
var/mob/living/carbon/human/H = target
|
||||
if (istype(H.head, /obj/item/clothing/head/tinfoil_hat))
|
||||
boutput(H, "<span style=\"color:blue\">Your tinfoil hat protects you from the psyblast!</span>")
|
||||
else
|
||||
boutput(H, "<span style=\"color:red\">You are blasted by psychic energy!</span>")
|
||||
H.paralysis += 5
|
||||
H.stuttering += 60
|
||||
H.take_brain_damage(20)
|
||||
H.TakeDamage("head", 0, 5)
|
||||
|
||||
proc/CritterTeleport(var/telerange, var/dospark, var/dosmoke)
|
||||
if (!src.alive) return
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/T in orange(src, telerange))
|
||||
if(istype(T, /turf/space) || T.density) continue
|
||||
randomturfs.Add(T)
|
||||
src.set_loc(pick(randomturfs))
|
||||
if (dospark)
|
||||
spawn()
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if (dosmoke)
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(10, 0, src.loc)
|
||||
smoke.start()
|
||||
src.task = "thinking"
|
||||
|
||||
/obj/critter/martian/soldier
|
||||
name = "martian soldier"
|
||||
icon_state = "martianS"
|
||||
health = 35
|
||||
aggressive = 1
|
||||
seekrange = 7
|
||||
|
||||
dead
|
||||
icon_state = "martianS-dead"
|
||||
health = 0
|
||||
New()
|
||||
..()
|
||||
CritterDeath()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (!src.alive) break
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> shoots at [C.name]!</span>")
|
||||
playsound(src.loc, "sound/weapons/lasermed.ogg", 100, 1)
|
||||
if (prob(66))
|
||||
C.TakeDamage("chest", 0, rand(3,5))
|
||||
spawn()
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(3, 1, C)
|
||||
s.start()
|
||||
else boutput(target, "<span style=\"color:red\">The shot missed!</span>")
|
||||
src.attack = 0
|
||||
sleeping = 1
|
||||
return
|
||||
else
|
||||
continue
|
||||
task = "thinking"
|
||||
|
||||
/obj/critter/martian/psychic
|
||||
name = "martian mutant"
|
||||
icon_state = "martianP"
|
||||
health = 10
|
||||
aggressive = 1
|
||||
seekrange = 4
|
||||
var/gib_delay = 55
|
||||
var/do_stun = 1
|
||||
var/max_gib_distance = 6
|
||||
var/gib_counter = 0
|
||||
|
||||
dead
|
||||
icon_state = "martianP-dead"
|
||||
health = 0
|
||||
New()
|
||||
..()
|
||||
CritterDeath()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (!src.alive) break
|
||||
if (C.health < 0) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> stares at [C.name]!</span>")
|
||||
playsound(src.loc, "sound/weapons/phaseroverload.ogg", 100, 1)
|
||||
boutput(C, "<span style=\"color:red\">You feel a horrible pain in your head!</span>")
|
||||
gib_counter = 0
|
||||
if (do_stun)
|
||||
C.stunned += rand(1,2)
|
||||
spawn(0)
|
||||
for (var/i = 0, i <= round(gib_delay / 10), i++)
|
||||
if ((get_dist(src, C) <= max_gib_distance) && src.alive)
|
||||
if (gib_counter == gib_delay)
|
||||
C.visible_message("<span style=\"color:red\"><b>[C.name]'s</b> head explodes!</span>")
|
||||
logTheThing("combat", C, null, "was gibbed by [src] at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880).
|
||||
C.gib()
|
||||
else
|
||||
C.show_message("<span style=\"color:red\">You no longer feel the [name]'s psychic glare.</span>")
|
||||
break
|
||||
if (gib_delay - gib_counter >= 10)
|
||||
gib_delay += 10
|
||||
sleep(10)
|
||||
else
|
||||
var/slp = gib_delay - gib_counter
|
||||
gib_delay = gib_counter
|
||||
sleep(slp)
|
||||
src.attack = 0
|
||||
sleeping = 7
|
||||
return
|
||||
else continue
|
||||
|
||||
src.task = "thinking"
|
||||
|
||||
/obj/critter/martian/psychic/weak
|
||||
name = "martian mutant initiate"
|
||||
gib_delay = 55
|
||||
do_stun = 0
|
||||
seekrange = 3
|
||||
max_gib_distance = 4
|
||||
|
||||
/obj/critter/martian/warrior
|
||||
name = "martian warrior"
|
||||
icon_state = "martianW"
|
||||
health = 35
|
||||
aggressive = 1
|
||||
seekrange = 7
|
||||
|
||||
dead
|
||||
icon_state = "martianW-dead"
|
||||
health = 0
|
||||
New()
|
||||
..()
|
||||
CritterDeath()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><B>[src]</B> grabs at [M]!</span>", 1)
|
||||
if (prob(33)) M.weakened += rand(2,4)
|
||||
spawn(25)
|
||||
if (get_dist(src, M) <= 1)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> starts strangling [M]!</span>")
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
if (prob(95))
|
||||
if (prob(10))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> wraps its tentacles around [M]'s neck!</span>")
|
||||
M.take_oxygen_deprivation(2)
|
||||
M.weakened += 1
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]'s</B> grip slips!</span>")
|
||||
M.stunned = 0
|
||||
sleeping = 1
|
||||
spawn(10)
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><b>[src]</b> screeches, 'KBWKB WVYPGD!!'</span>", 1)
|
||||
src.task = "thinking"
|
||||
src.attacking = 0
|
||||
|
||||
/obj/critter/martian/sapper
|
||||
name = "martian sapper"
|
||||
icon_state = "martianSP"
|
||||
health = 10
|
||||
aggressive = 0
|
||||
defensive = 0
|
||||
atkcarbon = 0
|
||||
atksilicon = 0
|
||||
task = "wandering"
|
||||
|
||||
ai_think()
|
||||
switch(task)
|
||||
if("thinking")
|
||||
var/obj/machinery/martianbomb/B = new(src.loc)
|
||||
B.icon_state = "mbomb-timing"
|
||||
B.active = 1
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> plants a bomb and teleports away!</span>")
|
||||
qdel(src)
|
||||
else
|
||||
patrol_step()
|
||||
sleeping = 1
|
||||
|
||||
/obj/machinery/martianbomb
|
||||
name = "martian bomb"
|
||||
desc = "You'd best destroy this thing fast."
|
||||
icon = 'icons/misc/critter.dmi'
|
||||
icon_state = "mbomb-off"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/health = 100
|
||||
var/active = 0
|
||||
var/timeleft = 300
|
||||
|
||||
process()
|
||||
if (src.active)
|
||||
src.icon_state = "mbomb-timing"
|
||||
src.timeleft -= 1
|
||||
if (src.timeleft <= 30) src.icon_state = "mbomb-det"
|
||||
if (src.timeleft == 0)
|
||||
explosion_new(src, src.loc, 62)
|
||||
qdel (src)
|
||||
//proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
|
||||
else
|
||||
src.icon_state = "mbomb-off"
|
||||
|
||||
ex_act(severity)
|
||||
if(severity)
|
||||
src.visible_message("<span style=\"color:blue\"><B>[src]</B> crumbles away into dust!</span>")
|
||||
qdel (src)
|
||||
return
|
||||
|
||||
bullet_act(var/obj/projectile/P)
|
||||
var/damage = 0
|
||||
damage = round((P.power*P.proj_data.ks_ratio), 1.0)
|
||||
|
||||
if(src.material) src.material.triggerOnAttacked(src, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter))
|
||||
for(var/atom/A in src)
|
||||
if(A.material)
|
||||
A.material.triggerOnAttacked(A, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter))
|
||||
|
||||
if(P.proj_data.damage_type == D_KINETIC)
|
||||
if(damage >= 20)
|
||||
src.health -= damage
|
||||
else
|
||||
damage = 0
|
||||
else if(P.proj_data.damage_type == D_PIERCING)
|
||||
src.health -= (damage*2)
|
||||
else if(P.proj_data.damage_type == D_ENERGY)
|
||||
src.health -= damage
|
||||
else
|
||||
damage = 0
|
||||
|
||||
if(damage >= 15)
|
||||
if (src.active && src.timeleft > 10)
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><B>[src]</B> begins buzzing loudly!</span>", 1)
|
||||
src.timeleft = 10
|
||||
|
||||
if (src.health <= 0)
|
||||
src.visible_message("<span style=\"color:blue\"><B>[src]</B> crumbles away into dust!</span>")
|
||||
qdel (src)
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
..()
|
||||
src.health -= W.force
|
||||
if (src.active && src.timeleft > 10)
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><B>[src]</B> begins buzzing loudly!</span>", 1)
|
||||
src.timeleft = 10
|
||||
if (src.health <= 0)
|
||||
src.visible_message("<span style=\"color:blue\"><B>[src]</B> crumbles away into dust!</span>")
|
||||
qdel (src)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,143 @@
|
||||
/obj/critter/maneater
|
||||
name = "man-eating plant"
|
||||
desc = "It looks hungry..."
|
||||
icon_state = "maneater"
|
||||
density = 1
|
||||
health = 30
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 1
|
||||
atksilicon = 0
|
||||
firevuln = 2
|
||||
brutevuln = 0.5
|
||||
butcherable = 1
|
||||
name_the_meat = 0
|
||||
meat_type = /obj/item/reagent_containers/food/snacks/salad
|
||||
generic = 0 // get this using the plant quality
|
||||
|
||||
New()
|
||||
..()
|
||||
playsound(src.loc, pick("sound/voice/MEilive.ogg"), 45, 0)
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (iscarbon(C) && !src.atkcarbon) continue
|
||||
if (istype(C, /mob/living/silicon/) && !src.atksilicon) continue
|
||||
if (C.job == "Botanist") continue
|
||||
if (C.health < 0) continue
|
||||
if (C in src.friends) continue
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> charges at [C.name]!</span>")
|
||||
playsound(src.loc, pick('sound/voice/MEhunger.ogg', 'sound/voice/MEraaargh.ogg', 'sound/voice/MEruncoward.ogg', 'sound/voice/MEbewarecoward.ogg'), 40, 0)
|
||||
src.task = "chasing"
|
||||
break
|
||||
else continue
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> slams into [M]!</span>")
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1, -1)
|
||||
M.stunned += rand(1,4)
|
||||
M.weakened += rand(1,4)
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> starts trying to eat [M]!</span>")
|
||||
spawn(70)
|
||||
if (get_dist(src, M) <= 1 && ((M:loc == target_lastloc)) && src.alive) // added a health check so dead maneaters stop eating people - cogwerks
|
||||
if(iscarbon(M))
|
||||
src.visible_message("<span class='combat'><B>[src]</B> ravenously wolfs down [M]!</span>")
|
||||
logTheThing("combat", M, null, "was devoured by [src] at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880).
|
||||
playsound(src.loc, "sound/items/eatfood.ogg", 30, 1, -2)
|
||||
M.death(1)
|
||||
var/atom/movable/overlay/animation = null
|
||||
M.transforming = 1
|
||||
M.canmove = 0
|
||||
M.icon = null
|
||||
M.invisibility = 101
|
||||
if(ishuman(M))
|
||||
animation = new(src.loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
if (M.client)
|
||||
M.ghostize()
|
||||
qdel(M)
|
||||
|
||||
sleeping = 2
|
||||
src.target = null
|
||||
src.task = "thinking"
|
||||
playsound(src.loc, pick("sound/misc/burp_alien.ogg"), 50, 0)
|
||||
else
|
||||
if(src.alive) // don't gnash teeth if dead
|
||||
src.visible_message("<span class='combat'><B>[src]</B> gnashes its teeth in fustration!</span>")
|
||||
src.attacking = 0
|
||||
|
||||
/obj/critter/killertomato
|
||||
name = "killer tomato"
|
||||
desc = "Today, Space Station 13 - tomorrow, THE WORLD!"
|
||||
icon_state = "ktomato"
|
||||
density = 1
|
||||
health = 15
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
firevuln = 2
|
||||
brutevuln = 2
|
||||
butcherable = 1
|
||||
name_the_meat = 0
|
||||
death_text = "%src% messily splatters into a puddle of tomato sauce!"
|
||||
meat_type = /obj/item/reagent_containers/food/snacks/plant/tomato/explosive
|
||||
generic = 0
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (iscarbon(C) && !src.atkcarbon) continue
|
||||
if (istype(C, /mob/living/silicon/) && !src.atksilicon) continue
|
||||
if (C.health < 0) continue
|
||||
if (C in src.friends) continue
|
||||
if (C.name == src.attacker) src.attack = 1
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span class='combat'><b>[src]</b> charges at [C:name]!</span>")
|
||||
playsound(src.loc, pick('sound/voice/MEhunger.ogg', 'sound/voice/MEraaargh.ogg', 'sound/voice/MEruncoward.ogg', 'sound/voice/MEbewarecoward.ogg'), 40, 0)
|
||||
src.task = "chasing"
|
||||
break
|
||||
else
|
||||
continue
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
src.visible_message("<span class='combat'><B>[src]</B> viciously lunges at [M]!</span>")
|
||||
if (prob(20)) M.stunned += rand(1,3)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
src.visible_message("<span class='combat'><B>[src]</B> bites [src.target]!</span>")
|
||||
random_brute_damage(src.target, rand(1,2))
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
CritterDeath()
|
||||
..()
|
||||
playsound(src.loc, "sound/effects/splat.ogg", 100, 1)
|
||||
var/obj/decal/cleanable/blood/B = new(src.loc)
|
||||
B.name = "ruined tomato"
|
||||
qdel (src)
|
||||
@@ -0,0 +1,405 @@
|
||||
|
||||
/obj/critter/nicespider
|
||||
name = "bumblespider"
|
||||
desc = "It seems pretty friendly. D'aww."
|
||||
icon_state = "bumblespider"
|
||||
health = 30
|
||||
aggressive = 1
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 0
|
||||
atksilicon = 0
|
||||
density = 0
|
||||
sleeping_icon_state = "bumblespider-sleep"
|
||||
var/venom1 = "venom"
|
||||
var/spazzing = 0
|
||||
|
||||
CritterAttack(mob/M)
|
||||
src.attacking = 1
|
||||
M.visible_message("<span style=\"color:red\"><b>[src]</b> nibbles [src.target]!</span>")
|
||||
random_brute_damage(M, rand(2,4))
|
||||
if(iscarbon(M) && M.reagents)
|
||||
M.reagents.add_reagent("[venom1]", 3)
|
||||
if(prob(15))
|
||||
spiderspaz(src.target)
|
||||
|
||||
spawn(10)
|
||||
src.attacking = 0
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if (src.alive)
|
||||
if (user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><b>[user]</b> [pick("pets","hugs","snuggles","cuddles")] [src]!</span>")
|
||||
if (prob(15))
|
||||
for (var/mob/O in hearers(src, null))
|
||||
O.show_message("[src] coos[prob(50) ? " happily!" : ""]!",2)
|
||||
playsound(src.loc, "sound/misc/babynoise.ogg", 40, 0)
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
return
|
||||
|
||||
proc/spiderspaz(mob/M) //todo: centralize this fucking mess of spiders into one base type
|
||||
if (spazzing)
|
||||
return
|
||||
|
||||
spazzing = 10
|
||||
playsound(src.loc, "rustle", 50, 0)
|
||||
spawn(0)
|
||||
while(spazzing-- > 0 && src.alive)
|
||||
src.set_loc(M.loc)
|
||||
src.pixel_x = rand(-2,2) * 2
|
||||
src.pixel_y = rand(-2,2) * 2
|
||||
src.dir = pick(alldirs)
|
||||
if(prob(30))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> bites [src.target]!</span>")
|
||||
playsound(src.loc, "rustle", 50, 1)
|
||||
random_brute_damage(src.target, rand(1,2))
|
||||
M.reagents.add_reagent("[venom1]", 2)
|
||||
sleep(4)
|
||||
src.pixel_x = 0
|
||||
src.pixel_y = 0
|
||||
if(spazzing < 0)
|
||||
spazzing = 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/nicespider
|
||||
name = "bumblespider egg"
|
||||
critter_type = /obj/critter/nicespider
|
||||
|
||||
/obj/critter/spider
|
||||
name = "space spider"
|
||||
desc = "A big ol' spider, from space. In space. A space spider."
|
||||
density = 1
|
||||
health = 50
|
||||
aggressive = 0
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
firevuln = 0.65
|
||||
brutevuln = 0.45
|
||||
angertext = "scuttles towards"
|
||||
butcherable = 1
|
||||
var/spazzing = 0
|
||||
var/feeding = 0
|
||||
var/venom1 = "venom" // making these modular so i don't have to rewrite this gigantic goddamn section for all the subtypes
|
||||
var/venom2 = "spiders"
|
||||
var/babyspider = 0
|
||||
var/adultpath = null
|
||||
var/bitesound = 'sound/weapons/handcuffs.ogg'
|
||||
var/stepsound = null
|
||||
var/deathsound = 'sound/effects/snap.ogg'
|
||||
death_text = "%src% crumples up into a ball!"
|
||||
var/encase_in_web = 1 // do they encase people in web or ice?
|
||||
var/reacting = 1 // when they inject their venom, does it react immediately or not?
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/spidersilk
|
||||
max_skins = 4
|
||||
|
||||
New()
|
||||
..()
|
||||
if (!icon_state && !babyspider)
|
||||
icon_state = pick("big_spide", "big_spide-red", "big_spide-green", "big_spide-blue")
|
||||
src.dead_state = "[src.icon_state]-dead"
|
||||
|
||||
CritterDeath()
|
||||
if(!src.alive) return
|
||||
..()
|
||||
playsound(src.loc, src.deathsound, 50, 0)
|
||||
src.reagents.add_reagent(venom1, 50, null)
|
||||
src.reagents.add_reagent(venom2, 50, null)
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
if (src.target)
|
||||
src.task = "chasing"
|
||||
return
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
//if (C.stat || C.health < 0) continue
|
||||
if (C.bioHolder.HasEffect("husk")) continue
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.task = "chasing"
|
||||
playsound(src.loc, "sound/effects/cat_hiss.ogg", 50, 1)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> hisses!</span>")
|
||||
break
|
||||
|
||||
Move()
|
||||
if (src.stepsound)
|
||||
if(prob(30))
|
||||
playsound(src.loc, src.stepsound, 50, 0)
|
||||
..()
|
||||
|
||||
CritterAttack(mob/M)
|
||||
if(ismob(M))
|
||||
src.attacking = 1
|
||||
if (prob(20))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> dives on [M]!</span>")
|
||||
playsound(src.loc, "sound/weapons/thudswoosh.ogg", 50, 0)
|
||||
M.weakened += rand(2,4)
|
||||
M.stunned += rand(1,3)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
src.spiderspaz(src.target)
|
||||
if(!M.stat) M.emote("scream") // don't scream while dead/asleep // why?
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> bites [src.target]!</span>")
|
||||
playsound(src.loc, src.bitesound, 50, 1)
|
||||
if(ishuman(M))
|
||||
random_brute_damage(src.target, rand(1,2))
|
||||
src.reagents.add_reagent("[venom1]", 2) // doing this instead of directly adding reagents to M should give people the correct messages
|
||||
src.reagents.add_reagent("[venom2]", 2)
|
||||
if (src.reacting)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
else
|
||||
src.reagents.trans_to(M, 4)
|
||||
else if(issilicon(M))
|
||||
switch(rand(1,4))
|
||||
if(1)
|
||||
M:compborg_take_critter_damage("r_arm", rand(2,4))
|
||||
if(2)
|
||||
M:compborg_take_critter_damage("l_arm", rand(2,4))
|
||||
if(3)
|
||||
M:compborg_take_critter_damage("r_leg", rand(2,4))
|
||||
if(4)
|
||||
M:compborg_take_critter_damage("l_leg", rand(2,4))
|
||||
if(ishuman(M))
|
||||
if(M.stat == 1) // kill KOd people faster
|
||||
src.set_loc(M.loc)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> jumps onto [src.target]!</span>")
|
||||
sleep(5)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> sinks its fangs into [src.target]!</span>")
|
||||
playsound(src.loc, "sound/misc/fuse.ogg", 50, 1)
|
||||
src.reagents.add_reagent("[venom1]", 5) // doing this instead of directly adding reagents to M should give people the correct messages
|
||||
src.reagents.add_reagent("[venom2]", 5)
|
||||
if (src.reacting)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
else
|
||||
src.reagents.trans_to(M, 10)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
|
||||
if(M.stat == 2 && !feeding) // drain corpses into husks
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/T = M
|
||||
feeding = 1
|
||||
src.spiderspaz(src.target)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> starts draining the fluids out of [T]!</span>")
|
||||
src.set_loc(T.loc)
|
||||
sleep(20)
|
||||
playsound(src.loc, "sound/misc/pourdrink.ogg", 50, 1)
|
||||
sleep(50)
|
||||
if(src.target && T.stat && src.loc == T.loc) // check to see if the target is still passed out and under the spider
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> drains [T] dry!</span>")
|
||||
T.death(0)
|
||||
T.real_name = "Unknown"
|
||||
T.bioHolder.AddEffect("husk")
|
||||
sleep(2)
|
||||
playsound(src.loc, "sound/misc/fuse.ogg", 50, 1)
|
||||
src.set_loc(get_step(src, pick(alldirs))) // get the fuck out of the way of the ice cube
|
||||
sleep(2)
|
||||
var/obj/icecube/cube = new /obj/icecube(get_turf(M), M)
|
||||
M.set_loc(cube)
|
||||
if (src.encase_in_web)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> encases [src.target] in web!</span>")
|
||||
cube.name = "bundle of web"
|
||||
cube.desc = "A big wad of web. Someone seems to be stuck inside it."
|
||||
cube.icon_state = "web2"
|
||||
cube.steam_on_death = 0
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> encases [src.target] in ice!</span>")
|
||||
|
||||
feeding = 0
|
||||
if (babyspider) // dawww
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> grows up!</span>")
|
||||
var/adult = text2path(src.adultpath)
|
||||
new adult(src.loc)
|
||||
qdel(src)
|
||||
else
|
||||
feeding = 0
|
||||
|
||||
spawn(20)
|
||||
src.attacking = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
playsound(src.loc, "sound/effects/cat_hiss.ogg", 50, 1)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> hisses!</span>")
|
||||
if (prob(30))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> dives on [M]!</span>")
|
||||
playsound(src.loc, pick("sound/weapons/thudswoosh.ogg"), 50, 0)
|
||||
M.weakened += rand(2,4)
|
||||
M.stunned += rand(1,3)
|
||||
random_brute_damage(M, rand(2,5))
|
||||
src.spiderspaz(src.target)
|
||||
if(!M.stat) M.emote("scream") // don't scream while dead or KOd
|
||||
else src.visible_message("<span style=\"color:red\"><B>[src]</B> dives at [M], but misses!</span>")
|
||||
|
||||
on_pet()
|
||||
playsound(src.loc, 'sound/misc/babynoise.ogg', 50, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] coos!</b></span>", 1)
|
||||
|
||||
proc/spiderspaz(mob/M)
|
||||
if (spazzing)
|
||||
return
|
||||
|
||||
spazzing = 10
|
||||
if (src.stepsound)
|
||||
playsound(src.loc, src.stepsound, 50, 0)
|
||||
spawn(0)
|
||||
while(spazzing-- > 0 && src.alive)
|
||||
src.set_loc(M.loc)
|
||||
src.pixel_x = rand(-2,2) * 2
|
||||
src.pixel_y = rand(-2,2) * 2
|
||||
src.dir = pick(alldirs)
|
||||
if(prob(30))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> bites [src.target]!</span>")
|
||||
playsound(src.loc, src.bitesound, 50, 1)
|
||||
if(ishuman(M))
|
||||
random_brute_damage(src.target, rand(1,2))
|
||||
src.reagents.add_reagent("[venom1]", 2) // doing this instead of directly adding reagents to M should give people the correct messages
|
||||
src.reagents.add_reagent("[venom2]", 2)
|
||||
if (src.reacting)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
else
|
||||
src.reagents.trans_to(M, 4)
|
||||
else if(issilicon(M))
|
||||
switch(rand(1,4))
|
||||
if(1)
|
||||
M:compborg_take_critter_damage("r_arm", rand(2,4))
|
||||
if(2)
|
||||
M:compborg_take_critter_damage("l_arm", rand(2,4))
|
||||
if(3)
|
||||
M:compborg_take_critter_damage("r_leg", rand(2,4))
|
||||
if(4)
|
||||
M:compborg_take_critter_damage("l_leg", rand(2,4))
|
||||
sleep(4)
|
||||
src.pixel_x = 0
|
||||
src.pixel_y = 0
|
||||
if(spazzing < 0)
|
||||
spazzing = 0
|
||||
|
||||
/obj/critter/spider/baby
|
||||
name = "li'l space spider"
|
||||
desc = "A li'l tiny spider, from space. In space. A space spider."
|
||||
icon_state = "lil_spide"
|
||||
density = 0
|
||||
health = 1
|
||||
venom1 = "toxin"
|
||||
venom2 = "black_goop"
|
||||
babyspider = 1
|
||||
max_skins = 1
|
||||
adultpath = "/obj/critter/spider"
|
||||
|
||||
// don't ask
|
||||
proc/streak(var/list/directions)
|
||||
spawn (0)
|
||||
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
|
||||
sleep(3)
|
||||
if (step_to(src, get_step(src, pick(directions)), 0))
|
||||
break
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/spider
|
||||
name = "spider egg"
|
||||
critter_type = /obj/critter/spider/baby
|
||||
critter_reagent = "spiders"
|
||||
|
||||
/obj/critter/spider/ice
|
||||
name = "ice spider"
|
||||
desc = "It seems to be adapted to a frozen climate."
|
||||
icon_state = "icespider"
|
||||
density = 1
|
||||
health = 20
|
||||
aggressive = 1
|
||||
firevuln = 1.5
|
||||
brutevuln = 0.5
|
||||
hitsound = 'sound/effects/crystalhit.ogg'
|
||||
venom1 = "toxin"
|
||||
venom2 = "cryostylane"
|
||||
babyspider = 0
|
||||
bitesound = 'sound/effects/crystalhit.ogg'
|
||||
stepsound = 'sound/misc/glass_step.ogg'
|
||||
deathsound = 'sound/effects/crystalshatter.ogg'
|
||||
encase_in_web = 0
|
||||
max_skins = 4
|
||||
reacting = 0
|
||||
|
||||
/// subtypes
|
||||
|
||||
/obj/critter/spider/ice/baby
|
||||
name = "baby ice spider"
|
||||
desc = "Dawww."
|
||||
icon_state = "babyicespider"
|
||||
density = 0
|
||||
health = 1
|
||||
venom1 = "toxin"
|
||||
venom2 = "cryostylane"
|
||||
babyspider = 1
|
||||
max_skins = 1
|
||||
adultpath = "/obj/critter/spider/ice"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/icespider
|
||||
name = "ice spider egg"
|
||||
critter_type = /obj/critter/spider/ice/baby
|
||||
warm_count = 25
|
||||
critter_reagent = "spidereggs"
|
||||
|
||||
/obj/critter/spider/ice/queen
|
||||
name = "queen ice spider"
|
||||
desc = "AHHHHHHH"
|
||||
icon_state = "gianticespider"
|
||||
density = 1
|
||||
health = 100
|
||||
venom1 = "morphine"
|
||||
venom2 = "spidereggs"
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/spidersilk
|
||||
max_skins = 8
|
||||
|
||||
/obj/critter/spider/ice/nice
|
||||
name = "nice spider"
|
||||
desc = "Aww, hi there!"
|
||||
aggressive = 0
|
||||
defensive = 0
|
||||
atkcarbon = 0
|
||||
atksilicon = 0
|
||||
venom1 = "hugs"
|
||||
venom2 = "glitter_harmless"
|
||||
|
||||
/obj/critter/spider/ice/queen/nice
|
||||
name = "queen nice spider"
|
||||
desc = "AWWWWWWW!"
|
||||
icon_state = "gianticespider"
|
||||
aggressive = 0
|
||||
defensive = 0
|
||||
atkcarbon = 0
|
||||
atksilicon = 0
|
||||
venom1 = "hugs"
|
||||
venom2 = "glitter_harmless"
|
||||
|
||||
/obj/critter/spider/spacerachnid // you get to be in here TOO
|
||||
name = "spacerachnid"
|
||||
desc = "A rather large spider."
|
||||
icon_state = "spider"
|
||||
density = 1
|
||||
health = 10
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
atcritter = 1
|
||||
firevuln = 0.65
|
||||
brutevuln = 0.45
|
||||
venom1 = "venom"
|
||||
venom2 = "venom"
|
||||
death_text = "%src% is squashed!"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/spacerachnid
|
||||
name = "spacerachnid egg"
|
||||
critter_type = /obj/critter/spider/spacerachnid
|
||||
critter_reagent = "spiders"
|
||||
@@ -0,0 +1,419 @@
|
||||
/////////// cogwerks - hideous wendigo beast
|
||||
|
||||
/obj/critter/wendigo
|
||||
name = "wendigo"
|
||||
desc = "Oh god."
|
||||
icon_state = "wendigo"
|
||||
invisibility = 16
|
||||
health = 60
|
||||
firevuln = 1
|
||||
brutevuln = 0.5
|
||||
aggressive = 1
|
||||
defensive = 1
|
||||
wanderer = 1
|
||||
opensdoors = 0
|
||||
seekrange = 6
|
||||
density = 0
|
||||
butcherable = 1
|
||||
can_revive = 1
|
||||
var/boredom_countdown = 0
|
||||
var/spazzing = 0
|
||||
var/frenzied = 0
|
||||
var/king = 0
|
||||
|
||||
var/left_arm_stage = 0
|
||||
var/right_arm_stage = 0
|
||||
var/obj/item/parts/human_parts/arm/left/wendigo/left_arm
|
||||
var/obj/item/parts/human_parts/arm/right/wendigo/right_arm
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/wendigohide
|
||||
|
||||
New()
|
||||
src.left_arm = new /obj/item/parts/human_parts/arm/left/wendigo(src)
|
||||
src.right_arm = new /obj/item/parts/human_parts/arm/right/wendigo(src)
|
||||
..()
|
||||
|
||||
on_revive()
|
||||
if (!src.left_arm)
|
||||
src.left_arm = new /obj/item/parts/human_parts/arm/left/wendigo(src)
|
||||
src.left_arm_stage = 0
|
||||
src.visible_message("<span style=\"color:red\">[src]'s left arm regrows!</span>")
|
||||
if (!src.right_arm)
|
||||
src.right_arm = new /obj/item/parts/human_parts/arm/right/wendigo(src)
|
||||
src.right_arm_stage = 0
|
||||
src.visible_message("<span style=\"color:red\">[src]'s right arm regrows!</span>")
|
||||
..()
|
||||
|
||||
CritterDeath()
|
||||
if (src.alive)
|
||||
playsound(src.loc, "sound/misc/wendigo_cry.ogg", 60, 1)
|
||||
src.visible_message("<b>[src]</b> dies!")
|
||||
src.alive = 0
|
||||
walk_to(src,0)
|
||||
src.update_dead_icon()
|
||||
anchored = 0
|
||||
density = 0
|
||||
layer = initial(layer)
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
if (src.target)
|
||||
src.task = "chasing"
|
||||
return
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if (!istype(C,/mob/living/silicon/robot/) && !istype(C,/mob/living/carbon/human/)) continue
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
//if (C.stat || C.health < 0) continue
|
||||
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(!king && iswerewolf(H))
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] backs away in fear!</b></span>")
|
||||
step_away(src, H, 15)
|
||||
src.dir = get_dir(src, H)
|
||||
continue
|
||||
|
||||
src.boredom_countdown = rand(2,5)
|
||||
if(king)
|
||||
boredom_countdown = rand(0,1) // king wendigos are pretty much grump elementals
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.task = "chasing"
|
||||
src.appear()
|
||||
if(king)
|
||||
playsound(src.loc, "sound/misc/wendigo_roar.ogg", 75, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] roars!</b></span>", 1)
|
||||
break
|
||||
|
||||
proc/update_dead_icon()
|
||||
if (src.alive)
|
||||
return
|
||||
. = "wendigo"
|
||||
if (!src.left_arm)
|
||||
. += "-l"
|
||||
if (!src.right_arm)
|
||||
. += "-r"
|
||||
. += "-dead"
|
||||
icon_state = .
|
||||
|
||||
attackby(obj/item/W as obj, mob/living/user as mob)
|
||||
if (!src.alive)
|
||||
// TODO: tie this into surgery()
|
||||
if (istype(W, /obj/item/scalpel))
|
||||
if (user.zone_sel.selecting == "l_arm")
|
||||
if (src.left_arm_stage == 0)
|
||||
user.visible_message("<span style=\"color:red\">[user] slices through the skin and flesh of [src]'s left arm with [W].</span>", "<span style=\"color:red\">You slice through the skin and flesh of [src]'s left arm with [W].</span>")
|
||||
src.left_arm_stage++
|
||||
else if (src.left_arm_stage == 2)
|
||||
user.visible_message("<span style=\"color:red\">[user] cuts through the remaining strips of skin holding [src]'s left arm on with [W].</span>", "<span style=\"color:red\">You cut through the remaining strips of skin holding [src]'s left arm on with [W].</span>")
|
||||
src.left_arm_stage++
|
||||
|
||||
src.left_arm.quality = (src.quality + 150) / 350.0
|
||||
var/nickname = "king"
|
||||
if (src.quality < 200)
|
||||
nickname = src.quality_name
|
||||
if (nickname)
|
||||
src.left_arm.name = "[nickname] [initial(src.left_arm.name)]"
|
||||
|
||||
var/turf/location = get_turf(src)
|
||||
if (location)
|
||||
src.left_arm.set_loc(location)
|
||||
src.left_arm = null
|
||||
src.update_dead_icon()
|
||||
|
||||
else if (user.zone_sel.selecting == "r_arm")
|
||||
if (src.right_arm_stage == 0)
|
||||
user.visible_message("<span style=\"color:red\">[user] slices through the skin and flesh of [src]'s right arm with [W].</span>", "<span style=\"color:red\">You slice through the skin and flesh of [src]'s right arm with [W].</span>")
|
||||
src.right_arm_stage++
|
||||
else if (src.right_arm_stage == 2)
|
||||
user.visible_message("<span style=\"color:red\">[user] cuts through the remaining strips of skin holding [src]'s right arm on with [W].</span>", "<span style=\"color:red\">You cut through the remaining strips of skin holding [src]'s right arm on with [W].</span>")
|
||||
src.right_arm_stage++
|
||||
|
||||
src.right_arm.quality = (src.quality + 100) / 350.0
|
||||
var/nickname = "king"
|
||||
if (src.quality < 200)
|
||||
nickname = src.quality_name
|
||||
if (nickname)
|
||||
src.right_arm.name = "[nickname] [initial(src.right_arm.name)]"
|
||||
|
||||
var/turf/location = get_turf(src)
|
||||
if (location)
|
||||
src.right_arm.set_loc(location)
|
||||
src.right_arm = null
|
||||
src.update_dead_icon()
|
||||
|
||||
else if (istype(W, /obj/item/circular_saw))
|
||||
if (user.zone_sel.selecting == "l_arm")
|
||||
if (src.left_arm_stage == 1)
|
||||
user.visible_message("<span style=\"color:red\">[user] saws through the bone of [src]'s left arm with [W].</span>", "<span style=\"color:red\">You saw through the bone of [src]'s left arm with [W].</span>")
|
||||
src.left_arm_stage++
|
||||
else if (user.zone_sel.selecting == "r_arm")
|
||||
if (src.right_arm_stage == 1)
|
||||
user.visible_message("<span style=\"color:red\">[user] saws through the bone of [src]'s right arm with [W].</span>", "<span style=\"color:red\">You saw through the bone of [src]'s right arm with [W].</span>")
|
||||
src.right_arm_stage++
|
||||
else
|
||||
..()
|
||||
return
|
||||
var/attack_force = 0
|
||||
var/damage_type = "brute"
|
||||
if (istype(W, /obj/item/artifact/melee_weapon))
|
||||
var/datum/artifact/melee/ME = W.artifact
|
||||
attack_force = ME.dmg_amount
|
||||
damage_type = ME.damtype
|
||||
else
|
||||
attack_force = W.force
|
||||
damage_type = W.damtype
|
||||
switch(damage_type)
|
||||
if("fire")
|
||||
src.health -= attack_force * src.firevuln
|
||||
if("brute")
|
||||
src.health -= attack_force * src.brutevuln
|
||||
else
|
||||
src.health -= attack_force * src.miscvuln
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><b>[user]</b> hits [src] with [W]!</span>", 1)
|
||||
if(prob(30))
|
||||
playsound(src.loc, "sound/misc/wendigo_cry.ogg", 60, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] cries!</b></span>", 1)
|
||||
if(prob(25) && alive) // crowds shouldn't be able to beat the fuck out of a confused wendigo with impunity, fuck that
|
||||
src.target = user
|
||||
src.oldtarget_name = user.name
|
||||
src.task = "chasing"
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 60, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> slams into [src.target]!</span>")
|
||||
target:weakened += 2
|
||||
frenzy(src.target)
|
||||
|
||||
if (src.alive && src.health <= 0) src.CritterDeath()
|
||||
|
||||
//src.boredom_countdown = rand(5,10)
|
||||
src.target = user
|
||||
src.oldtarget_name = user.name
|
||||
src.task = "chasing"
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
|
||||
if (!src.alive)
|
||||
..()
|
||||
return
|
||||
if (user.a_intent == INTENT_HARM)
|
||||
src.health -= rand(1,2) * src.brutevuln
|
||||
on_damaged(src)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
O.show_message("<span style=\"color:red\"><b>[user]</b> punches [src]!</span>", 1)
|
||||
playsound(src.loc, "punch", 50, 1)
|
||||
if(prob(30))
|
||||
playsound(src.loc, "sound/misc/wendigo_cry.ogg", 60, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] cries!</b></span>", 1)
|
||||
if(prob(20) && alive) // crowd beatdown fix
|
||||
src.target = user
|
||||
src.oldtarget_name = user.name
|
||||
src.task = "chasing"
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> slams into [src.target]!</span>")
|
||||
target:weakened += 20
|
||||
frenzy(src.target)
|
||||
if (src.alive && src.health <= 0) src.CritterDeath()
|
||||
|
||||
//src.boredom_countdown = rand(5,10)
|
||||
src.target = user
|
||||
src.oldtarget_name = user.name
|
||||
src.task = "chasing"
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><b>[user]</b> pets [src]!</span>", 1)
|
||||
playsound(src.loc, "sound/misc/wendigo_laugh.ogg", 60, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] laughs!</b></span>", 1)
|
||||
|
||||
on_sleep()
|
||||
..()
|
||||
src.disappear()
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
if(prob(10))
|
||||
playsound(src.loc, "sound/misc/wendigo_scream.ogg", 75, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] howls!</b></span>", 1)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> tackles [M]!</span>")
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1, -1)
|
||||
if(ismob(M))
|
||||
M.stunned += rand(1,2)
|
||||
M.weakened += rand(1,2)
|
||||
|
||||
CritterAttack(mob/M) // nominating this for scariest goddamn critter 2013
|
||||
src.attacking = 1
|
||||
var/attack_delay = rand(10,30) // needs to attack more often, changed from 30
|
||||
|
||||
if (istype(M,/mob/living/silicon/robot/))
|
||||
var/mob/living/silicon/robot/BORG = M
|
||||
if (!BORG.part_head)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> sniffs at [BORG.name].</span>")
|
||||
sleep(15)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> throws a tantrum and smashes [BORG.name] to pieces!</span>")
|
||||
playsound(src.loc, "sound/misc/wendigo_scream.ogg", 75, 1)
|
||||
playsound(src.loc, "sound/effects/wbreak.wav", 70, 1)
|
||||
BORG.gib()
|
||||
src.target = null
|
||||
src.boredom_countdown = 0
|
||||
else
|
||||
if (BORG.part_head.ropart_get_damage_percentage() >= 85)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> grabs [BORG.name]'s head and wrenches it right off!</span>")
|
||||
playsound(src.loc, "sound/misc/wendigo_laugh.ogg", 70, 1)
|
||||
playsound(src.loc, "sound/effects/wbreak.wav", 70, 1)
|
||||
BORG.compborg_lose_limb(BORG.part_head)
|
||||
sleep(15)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> ravenously eats the mangled brain remnants out of the decapitated head!</span>")
|
||||
playsound(src.loc, "sound/misc/wendigo_maul.ogg", 80, 1)
|
||||
new /obj/decal/cleanable/blood(src.loc)
|
||||
src.target = null
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> pounds on [BORG.name]'s head furiously!</span>")
|
||||
playsound(src.loc, "sound/effects/zhit.ogg", 50, 1)
|
||||
BORG.part_head.ropart_take_damage(rand(20,40),0)
|
||||
if (prob(33)) playsound(src.loc, "sound/misc/wendigo_scream.ogg", 75, 1)
|
||||
attack_delay = 5
|
||||
else
|
||||
if (boredom_countdown-- > 0)
|
||||
if(prob(70))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> [pick("bites", "nibbles", "chews on", "gnaws on")] [src.target]!</span>")
|
||||
playsound(src.loc, "sound/effects/bloody_stab.ogg", 50, 1)
|
||||
playsound(src.loc, "sound/items/eatfood.ogg", 50, 1)
|
||||
random_brute_damage(target, 10)
|
||||
take_bleeding_damage(target, null, 5, DAMAGE_STAB, 1, get_turf(target))
|
||||
if(prob(40))
|
||||
playsound(src.loc, "sound/misc/wendigo_laugh.ogg", 70, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] laughs!</b></span>", 1)
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> [pick("slashes", "swipes", "claws", "tears")] a chunk out of [src.target]!</span>")
|
||||
playsound(src.loc, "sound/effects/bloody_stab.ogg", 50, 1)
|
||||
random_brute_damage(target, 20)
|
||||
take_bleeding_damage(target, null, 10, DAMAGE_CUT, 0, get_turf(target))
|
||||
playsound(src.loc, "sound/effects/splat.ogg", 50, 1)
|
||||
playsound(src.loc, "sound/misc/wendigo_scream.ogg", 75, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] howls!</b></span>", 1)
|
||||
if(!M.stat) M.emote("scream") // don't scream while dead/asleep
|
||||
|
||||
else // flip the fuck out
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> slams into [src.target]!</span>")
|
||||
target:weakened += 3
|
||||
frenzy(src.target)
|
||||
|
||||
if (M.stat == 2) // devour corpses
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] devours [src.target]! Holy shit!</b></span>")
|
||||
playsound(src.loc, "sound/effects/fleshbr1.ogg", 50, 1)
|
||||
M.ghostize()
|
||||
new /obj/decal/skeleton(M.loc)
|
||||
M.gib()
|
||||
src.target = null
|
||||
|
||||
spawn(attack_delay)
|
||||
src.attacking = 0
|
||||
|
||||
proc/appear()
|
||||
if (!invisibility)
|
||||
return
|
||||
src.icon_state = "wendigo_appear"
|
||||
src.invisibility = 0
|
||||
density = 1
|
||||
spawn(12)
|
||||
if(king)
|
||||
src.icon_state = "wendigoking"
|
||||
else
|
||||
src.icon_state = "wendigo"
|
||||
playsound(src.loc, "sound/misc/wendigo_scream.ogg", 85, 1)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> howls!</span>")
|
||||
return
|
||||
|
||||
proc/disappear()
|
||||
if (invisibility)
|
||||
return
|
||||
|
||||
src.icon_state = "wendigo_melt"
|
||||
density = 0
|
||||
spawn(12)
|
||||
src.invisibility = 16
|
||||
if(king)
|
||||
src.icon_state = "wendigoking"
|
||||
else
|
||||
src.icon_state = "wendigo"
|
||||
return
|
||||
|
||||
proc/spaz()
|
||||
if (spazzing)
|
||||
return
|
||||
|
||||
spazzing = 25
|
||||
spawn(0)
|
||||
while(spazzing-- > 0)
|
||||
src.pixel_x = rand(-2,2) * 2
|
||||
src.pixel_y = rand(-2,2) * 2
|
||||
src.dir = pick(alldirs)
|
||||
sleep(4)
|
||||
src.pixel_x = 0
|
||||
src.pixel_y = 0
|
||||
if(spazzing < 0)
|
||||
spazzing = 0
|
||||
|
||||
|
||||
// go crazy and make a huge goddamn mess
|
||||
proc/frenzy(mob/M)
|
||||
if (src.frenzied)
|
||||
return
|
||||
|
||||
spawn(0)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] goes [pick("into a frenzy", "into a bloodlust", "berserk", "hog wild", "crazy")]!</b></span>")
|
||||
playsound(src.loc, "sound/misc/wendigo_maul.ogg", 80, 1)
|
||||
if(king)
|
||||
playsound(src.loc, "sound/misc/wendigo_roar.ogg", 80, 1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] roars!</b></span>")
|
||||
spawn(1)
|
||||
if(!spazzing) src.spaz()
|
||||
src.set_loc(M.loc)
|
||||
src.frenzied = 20
|
||||
while(src.target && src.frenzied && src.alive && src.loc == M.loc )
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] [pick("mauls", "claws", "slashes", "tears at", "lacerates", "mangles")] [src.target]!</b></span>")
|
||||
random_brute_damage(target, 10)
|
||||
take_bleeding_damage(target, null, 5, DAMAGE_CUT, 0, get_turf(target))
|
||||
if(prob(33)) // don't make quite so much mess
|
||||
bleed(target, 5, 5, get_step(src.loc, pick(alldirs)), 1)
|
||||
if(king && prob(33))
|
||||
bleed(target, 5, 5, get_step(src.loc, pick(alldirs)), 1)
|
||||
sleep(4)
|
||||
src.frenzied--
|
||||
src.frenzied = 0
|
||||
|
||||
////////////////
|
||||
//////king wendigo, why not
|
||||
///////////////
|
||||
|
||||
/obj/critter/wendigo/king
|
||||
name = "wendigo king"
|
||||
desc = "You should run."
|
||||
health = 500
|
||||
icon_state = "wendigoking"
|
||||
king = 1
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/kingwendigohide
|
||||
|
||||
New()
|
||||
..()
|
||||
quality = 200 // for the limbs
|
||||
|
||||
CritterDeath()
|
||||
playsound(src.loc, "sound/misc/wendigo_roar.ogg", 75, 1)
|
||||
playsound(src.loc, "sound/misc/wendigo_cry.ogg", 75, 1)
|
||||
src.visible_message("<b>[src]</b> collapses in a heap!")
|
||||
src.alive = 0
|
||||
walk_to(src,0)
|
||||
icon_state = "wendigoking-dead"
|
||||
density = 0
|
||||
|
||||
////////////////
|
||||
////// e-egg?
|
||||
///////////////
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/ingredient/egg/critter/wendigo
|
||||
name = "wendigo egg"
|
||||
desc = "They lay eggs?!"
|
||||
critter_type = /obj/critter/wendigo
|
||||
warm_count = 100
|
||||
critter_reagent = "ice"
|
||||
@@ -0,0 +1,308 @@
|
||||
/obj/critter/zombie
|
||||
name = "Zombie"
|
||||
desc = "BraaAAAinnsSSs..."
|
||||
icon_state = "zombie"
|
||||
density = 1
|
||||
health = 20
|
||||
aggressive = 1
|
||||
defensive = 0
|
||||
wanderer = 1
|
||||
opensdoors = 1
|
||||
atkcarbon = 1
|
||||
atksilicon = 1
|
||||
atcritter = 1
|
||||
firevuln = 0.25
|
||||
brutevuln = 0.5
|
||||
butcherable = 1
|
||||
|
||||
var/punch_damage_max = 9
|
||||
var/punch_damage_min = 3
|
||||
var/hulk = 0 //A zombie hulk? Oh god.
|
||||
var/eats_brains = 1
|
||||
|
||||
skinresult = /obj/item/material_piece/cloth/leather
|
||||
max_skins = 2
|
||||
|
||||
New()
|
||||
..()
|
||||
playsound(src.loc, pick('sound/voice/Zgroan1.ogg', 'sound/voice/Zgroan2.ogg', 'sound/voice/Zgroan3.ogg', 'sound/voice/Zgroan4.ogg'), 25, 0)
|
||||
|
||||
seek_target()
|
||||
src.anchored = 0
|
||||
for (var/mob/living/C in hearers(src.seekrange,src))
|
||||
if ((C.name == src.oldtarget_name) && (world.time < src.last_found + 100)) continue
|
||||
if (iscarbon(C) && !src.atkcarbon) continue
|
||||
if (istype(C, /mob/living/silicon/) && !src.atksilicon) continue
|
||||
if (C.health < 0) continue
|
||||
if (istype(C,/mob/living/carbon/human))
|
||||
if (C:mutantrace && istype(C:mutantrace, /datum/mutantrace/zombie)) continue
|
||||
if (istype(C:head, /obj/item/clothing/head/void_crown)) continue
|
||||
|
||||
if (iscarbon(C) && src.atkcarbon) src.attack = 1
|
||||
if (istype(C, /mob/living/silicon/) && src.atksilicon) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> lunges at [C.name]!</span>")
|
||||
playsound(src.loc, pick('sound/voice/Zgroan1.ogg', 'sound/voice/Zgroan2.ogg', 'sound/voice/Zgroan3.ogg', 'sound/voice/Zgroan4.ogg'), 25, 0)
|
||||
src.task = "chasing"
|
||||
return
|
||||
else
|
||||
continue
|
||||
|
||||
|
||||
if(!src.atcritter) return
|
||||
for (var/obj/critter/C in view(src.seekrange,src))
|
||||
if (!C.alive) continue
|
||||
if (C.health < 0) continue
|
||||
if (!istype(C, /obj/critter/zombie)) src.attack = 1
|
||||
|
||||
if (src.attack)
|
||||
src.target = C
|
||||
src.oldtarget_name = C.name
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> lunges at [C.name]!</span>")
|
||||
playsound(src.loc, pick('sound/voice/Zgroan1.ogg', 'sound/voice/Zgroan2.ogg', 'sound/voice/Zgroan3.ogg', 'sound/voice/Zgroan4.ogg'), 25, 0)
|
||||
src.task = "chasing"
|
||||
return
|
||||
|
||||
else continue
|
||||
|
||||
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
if(iscarbon(M) && prob(15))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> slams into [src.target]!</span>")
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1, -1)
|
||||
random_brute_damage(M, rand(0,3))
|
||||
M.stunned += rand(0,4)
|
||||
M.weakened += rand(1,4)
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> tries to knock down [src.target] but misses!</span>")
|
||||
|
||||
CritterAttack(mob/living/M)
|
||||
src.attacking = 1
|
||||
if(istype(M,/obj/critter))
|
||||
var/obj/critter/C = M
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> punches [src.target]!</span>")
|
||||
playsound(C.loc, "punch", 25, 1, -1)
|
||||
C.health -= 4
|
||||
if(C.health <= 0)
|
||||
C.CritterDeath()
|
||||
spawn(25)
|
||||
src.attacking = 0
|
||||
return
|
||||
|
||||
if (M.health > 40 && !M.weakened)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> punches [src.target]!</span>")
|
||||
playsound(M.loc, "punch", 25, 1, -1)
|
||||
|
||||
var/to_deal = rand(punch_damage_min,punch_damage_max)
|
||||
random_brute_damage(M, to_deal)
|
||||
if(iscarbon(M))
|
||||
if(to_deal > (((punch_damage_max-punch_damage_min)/2)+punch_damage_min) && prob(50))
|
||||
src.visible_message("<span style=\"color:red\"><B>[src] knocks down [M]!</B></span>")
|
||||
M:weakened += 8
|
||||
// if(prob(4) && eats_brains) //Give the gift of being a zombie (unless we eat them too fast)
|
||||
// M.contract_disease(/datum/ailment/disease/necrotic_degeneration, null, null, 1) // path, name, strain, bypass resist
|
||||
if(src.hulk) //TANK!
|
||||
spawn(0)
|
||||
M:paralysis += 1
|
||||
step_away(M,src,15)
|
||||
spawn(3) step_away(M,src,15)
|
||||
spawn(25)
|
||||
src.attacking = 0
|
||||
else
|
||||
if(istype(M,/mob/living/carbon/human) && src.eats_brains) //These only make human zombies anyway!
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> starts trying to eat [M]'s brain!</span>")
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> attacks [src.target]!</span>")
|
||||
playsound(src.loc, "sound/weapons/genhit1.ogg", 50, 1, -1)
|
||||
random_brute_damage(src.target, rand(punch_damage_min,punch_damage_max))
|
||||
spawn(25)
|
||||
src.attacking = 0
|
||||
return
|
||||
spawn(60)
|
||||
if (get_dist(src, M) <= 1 && ((M:loc == target_lastloc)))
|
||||
if(iscarbon(M))
|
||||
logTheThing("combat", M, null, "was zombified by [src] at [log_loc(src)].") // Some logging for instakill critters would be nice (Convair880).
|
||||
M.death(1)
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> slurps up [M]'s brain!</span>")
|
||||
playsound(src.loc, "sound/items/eatfood.ogg", 30, 1, -2)
|
||||
M.canmove = 0
|
||||
M.icon = null
|
||||
M.invisibility = 101
|
||||
M:death()
|
||||
var/obj/critter/zombie/P = new(M.loc)
|
||||
///this little bit of code prevents multiple zombies from the same victim
|
||||
if (M == null)
|
||||
qdel(P)
|
||||
return
|
||||
src.visible_message("<span style=\"color:red\">[M]'s corpse reanimates!</span>")
|
||||
//Zombie is all dressed up and no place to go
|
||||
var/stealthy = 0 //High enough and people won't even see it's undead right away.
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
//Uniform
|
||||
if(H.w_uniform)
|
||||
if (istype(H.w_uniform, /obj/item/clothing/under))
|
||||
P.overlays += image("icon" = 'icons/mob/jumpsuits/worn_js.dmi', "icon_state" = H.w_uniform.icon_state, "layer" = FLOAT_LAYER)
|
||||
stealthy += 4
|
||||
//Suit
|
||||
if(H.wear_suit)
|
||||
if (istype(H.wear_suit, /obj/item/clothing/suit))
|
||||
P.overlays += image("icon" = 'icons/mob/overcoats/worn_suit.dmi', "icon_state" = H.wear_suit.icon_state, "layer" = FLOAT_LAYER)
|
||||
stealthy += 2
|
||||
//Back
|
||||
if(H.back)
|
||||
var/t1 = H.back.icon_state
|
||||
P.overlays += image("icon" = 'icons/mob/back.dmi', "icon_state" = t1, "layer" = FLOAT_LAYER)
|
||||
//Mask
|
||||
if (H.wear_mask)
|
||||
if (istype(H.wear_mask, /obj/item/clothing/mask))
|
||||
var/t1 = H.wear_mask.icon_state
|
||||
P.overlays += image("icon" = 'icons/mob/mask.dmi', "icon_state" = t1, "layer" = FLOAT_LAYER)
|
||||
if (H.wear_mask.c_flags & COVERSEYES)
|
||||
stealthy += 2
|
||||
//Shoes
|
||||
if (H.shoes)
|
||||
if (istype(H.shoes))
|
||||
var/t1 = H.shoes.icon_state
|
||||
P.overlays += image("icon" = 'icons/mob/feet.dmi', "icon_state" = t1, "layer" = FLOAT_LAYER)
|
||||
stealthy++
|
||||
//Gloves. Zombie boxers??
|
||||
if (H.gloves)
|
||||
if (istype(H.gloves))
|
||||
var/t1 = H.gloves.item_state
|
||||
P.overlays += image("icon" = 'icons/mob/hands.dmi', "icon_state" = t1, "layer" = FLOAT_LAYER)
|
||||
stealthy++
|
||||
//Head
|
||||
if (H.head)
|
||||
var/t1 = H.head.icon_state
|
||||
var/icon/head_icon = icon('icons/mob/head.dmi', "[t1]")
|
||||
if (istype(H.head, /obj/item/clothing/head/butt))
|
||||
var/obj/item/clothing/head/butt/B = H.head
|
||||
if (B.s_tone >= 0)
|
||||
head_icon.Blend(rgb(B.s_tone, B.s_tone, B.s_tone), ICON_ADD)
|
||||
else
|
||||
head_icon.Blend(rgb(-B.s_tone, -B.s_tone, -B.s_tone), ICON_SUBTRACT)
|
||||
P.overlays += image("icon" = head_icon, "layer" = FLOAT_LAYER)
|
||||
if (H.head.c_flags & COVERSEYES)
|
||||
stealthy += 2
|
||||
if (H.head.c_flags & COVERSMOUTH)
|
||||
stealthy += 2
|
||||
|
||||
//Oh no, a tank!
|
||||
if(H.bioHolder.HasEffect("hulk"))
|
||||
P.hulk = 1
|
||||
P.punch_damage_max += 4
|
||||
|
||||
P.health = src.health
|
||||
if(stealthy >= 10)
|
||||
P.name = M.real_name
|
||||
else
|
||||
P.name += " [M.real_name]"
|
||||
|
||||
var/atom/movable/overlay/animation = null
|
||||
if(ishuman(M))
|
||||
animation = new(src.loc)
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = src
|
||||
if (M.client)
|
||||
var/mob/dead/observer/newmob
|
||||
newmob = new/mob/dead/observer(M)
|
||||
M.client:mob = newmob
|
||||
M.mind.transfer_to(newmob)
|
||||
qdel(M)
|
||||
qdel(animation)
|
||||
sleeping = 2
|
||||
spawn(20) playsound(src.loc, pick("sound/misc/burp_alien.ogg"), 50, 0)
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><B>[src]</B> gnashes its teeth in fustration!</span>")
|
||||
src.attacking = 0
|
||||
|
||||
CritterDeath()
|
||||
src.alive = 0
|
||||
playsound(src.loc, "sound/effects/splat.ogg", 100, 1)
|
||||
var/obj/decal/cleanable/blood/gibs/gib = null
|
||||
gib = new /obj/decal/cleanable/blood/gibs(src.loc)
|
||||
if (prob(30))
|
||||
gib.icon_state = "gibup1"
|
||||
gib.streak(list(NORTH, NORTHEAST, NORTHWEST))
|
||||
qdel (src)
|
||||
|
||||
/obj/critter/zombie/scientist
|
||||
name = "Shambling Scientist"
|
||||
desc = "Physician, heal thyself! Welp, so much for that."
|
||||
icon_state = "scizombie"
|
||||
health = 10
|
||||
firevuln = 0.15
|
||||
generic = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
if(!attacking)
|
||||
src.CritterAttack(M)
|
||||
return
|
||||
|
||||
/obj/critter/zombie/security
|
||||
name = "Undead Guard"
|
||||
desc = "Eh, couldn't be any worse than regular security."
|
||||
icon_state = "seczombie"
|
||||
health = 18
|
||||
brutevuln = 0.6
|
||||
generic = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
if(!attacking)
|
||||
src.CritterAttack(M)
|
||||
return
|
||||
|
||||
CritterDeath()
|
||||
src.alive = 0
|
||||
playsound(src.loc, "sound/effects/splat.ogg", 100, 1)
|
||||
gibs(src.loc)
|
||||
qdel (src)
|
||||
|
||||
/obj/critter/zombie/h7
|
||||
name = "Biosuit Shambler"
|
||||
desc = "This does not reassure one about biosuit reliability."
|
||||
icon_state = "suitzombie"
|
||||
health = 10
|
||||
brutevuln = 0.6
|
||||
atcritter = 0
|
||||
eats_brains = 0
|
||||
generic = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
if(!attacking)
|
||||
src.CritterAttack(M)
|
||||
return
|
||||
|
||||
CritterDeath()
|
||||
src.alive = 0
|
||||
src.visible_message("<span style=\"color:red\">Black mist flows from the broken suit!</span>")
|
||||
playsound(src.loc, "sound/machines/hiss.ogg", 50, 1)
|
||||
|
||||
harmless_smoke_puff(src.loc)
|
||||
|
||||
new /obj/critter/aberration(src.loc)
|
||||
new /obj/item/clothing/suit/bio_suit(src.loc)
|
||||
new /obj/item/clothing/gloves/latex(src.loc)
|
||||
new /obj/item/clothing/head/bio_hood(src.loc)
|
||||
qdel (src)
|
||||
|
||||
//It's like the jam mansion is back!
|
||||
/obj/critter/zombie/hogan
|
||||
name = "Zombie Hogan"
|
||||
desc = "Hulkamania is shambling wiilllldd in space!"
|
||||
icon_state = "hoganzombie"
|
||||
health = 25
|
||||
firevuln = 0.15
|
||||
hulk = 1
|
||||
generic = 0
|
||||
|
||||
ChaseAttack(mob/M)
|
||||
if(!attacking)
|
||||
src.CritterAttack(M)
|
||||
return
|
||||
@@ -0,0 +1,217 @@
|
||||
/obj/datacore
|
||||
name = "datacore"
|
||||
var/list/medical = list( )
|
||||
var/list/general = list( )
|
||||
var/list/security = list( )
|
||||
var/list/bank = list ( )
|
||||
var/list/fines = list ( )
|
||||
var/list/tickets = list ( )
|
||||
var/obj/machinery/networked/mainframe/mainframe = null
|
||||
|
||||
/obj/datacore/proc/addManifest(var/mob/living/carbon/human/H as mob)
|
||||
if (!H || !H.mind)
|
||||
return
|
||||
|
||||
var/datum/data/record/G = new /datum/data/record( )
|
||||
var/datum/data/record/M = new /datum/data/record( )
|
||||
var/datum/data/record/S = new /datum/data/record( )
|
||||
var/datum/data/record/B = new /datum/data/record( )
|
||||
|
||||
if (H.mind.assigned_role)
|
||||
G.fields["rank"] = H.mind.assigned_role
|
||||
else
|
||||
G.fields["rank"] = "Unassigned"
|
||||
|
||||
G.fields["name"] = H.real_name
|
||||
G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6))
|
||||
M.fields["name"] = G.fields["name"]
|
||||
M.fields["id"] = G.fields["id"]
|
||||
S.fields["name"] = G.fields["name"]
|
||||
S.fields["id"] = G.fields["id"]
|
||||
|
||||
B.fields["name"] = G.fields["name"]
|
||||
B.fields["id"] = G.fields["id"]
|
||||
|
||||
if (H.gender == FEMALE)
|
||||
G.fields["sex"] = "Female"
|
||||
else
|
||||
G.fields["sex"] = "Male"
|
||||
|
||||
G.fields["age"] ="[H.bioHolder.age]"
|
||||
G.fields["fingerprint"] = "[md5(H.bioHolder.Uid)]"
|
||||
G.fields["dna"] = H.bioHolder.Uid
|
||||
G.fields["p_stat"] = "Active"
|
||||
G.fields["m_stat"] = "Stable"
|
||||
spawn(10)
|
||||
G.fields["file_photo"] = H.build_flat_icon()
|
||||
|
||||
M.fields["bioHolder.bloodType"] = "[H.bioHolder.bloodType]"
|
||||
M.fields["mi_dis"] = "None"
|
||||
M.fields["mi_dis_d"] = "No minor disabilities have been declared."
|
||||
M.fields["ma_dis"] = "None"
|
||||
M.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
|
||||
M.fields["alg"] = "None"
|
||||
M.fields["alg_d"] = "No allergies have been detected in this patient."
|
||||
M.fields["cdi"] = "None"
|
||||
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
|
||||
|
||||
M.fields["h_imp"] = "No health implant detected."
|
||||
|
||||
M.fields["notes"] = "No notes."
|
||||
|
||||
M.fields["dnasample"] = create_new_dna_sample_file(H)
|
||||
|
||||
var/traitStr = ""
|
||||
if(H.traitHolder)
|
||||
for(var/X in H.traitHolder.traits)
|
||||
var/obj/trait/T = getTraitById(X)
|
||||
if(length(traitStr)) traitStr += " | [T.cleanName]"
|
||||
else traitStr = T.name
|
||||
|
||||
M.fields["traits"] = traitStr
|
||||
|
||||
S.fields["criminal"] = "None"
|
||||
S.fields["mi_crim"] = "None"
|
||||
S.fields["mi_crim_d"] = "No minor crime convictions."
|
||||
S.fields["ma_crim"] = "None"
|
||||
S.fields["ma_crim_d"] = "No major crime convictions."
|
||||
S.fields["notes"] = "No notes."
|
||||
|
||||
B.fields["job"] = H.job
|
||||
B.fields["current_money"] = 100.0
|
||||
B.fields["notes"] = "No notes."
|
||||
|
||||
// If it exists for a job give them the correct wage
|
||||
var/wageMult = 1
|
||||
if(H.traitHolder.hasTrait("unionized"))
|
||||
wageMult = 1.5
|
||||
|
||||
if(wagesystem.jobs[H.job])
|
||||
B.fields["wage"] = round(wagesystem.jobs[H.job] * wageMult)
|
||||
// Otherwise give them a default wage
|
||||
else
|
||||
var/datum/job/J = find_job_in_controller_by_string(G.fields["rank"])
|
||||
if (J && J.wages)
|
||||
B.fields["wage"] = round(J.wages * wageMult)
|
||||
else
|
||||
B.fields["wage"] = 0
|
||||
|
||||
src.general += G
|
||||
src.medical += M
|
||||
src.security += S
|
||||
src.bank += B
|
||||
|
||||
//Add email group
|
||||
if ("[H.mind.assigned_role]" in job_mailgroup_list)
|
||||
var/mailgroup = job_mailgroup_list["[H.mind.assigned_role]"]
|
||||
if (!mailgroup)
|
||||
return
|
||||
|
||||
var/username = format_username(H.real_name)
|
||||
if (!src.mainframe || !src.mainframe.hd || !(src.mainframe.hd in src.mainframe))
|
||||
for (var/obj/machinery/networked/mainframe/newMainframe in machines)
|
||||
if (newMainframe.z != 1 || newMainframe.stat)
|
||||
continue
|
||||
|
||||
if (newMainframe.hd)
|
||||
src.mainframe = newMainframe
|
||||
break
|
||||
|
||||
if (src.mainframe)
|
||||
for (var/datum/computer/folder/folder in src.mainframe.hd.root.contents)
|
||||
if (ckey(folder.name) == "etc")
|
||||
for (var/datum/computer/folder/folder2 in folder.contents)
|
||||
if (ckey(folder2.name) == "mail")
|
||||
for (var/datum/computer/file/record/groups in folder2.contents)
|
||||
if (ckey(groups.name) != "groups")
|
||||
continue
|
||||
|
||||
if (!groups.fields)
|
||||
break
|
||||
|
||||
for (var/mailgroupEntry in groups.fields)
|
||||
if (dd_hasprefix(mailgroupEntry, "[mailgroup]:"))
|
||||
groups.fields -= mailgroupEntry
|
||||
groups.fields += "[mailgroupEntry][username],"
|
||||
break
|
||||
|
||||
groups.fields += "[mailgroup]:[username],"
|
||||
break
|
||||
|
||||
break
|
||||
|
||||
break
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
/datum/ticket
|
||||
var/name = "ticket"
|
||||
var/target = null
|
||||
var/reason = null
|
||||
var/issuer = null
|
||||
var/issuer_job = null
|
||||
var/text = null
|
||||
var/target_byond_key = null
|
||||
var/issuer_byond_key = null
|
||||
|
||||
New()
|
||||
spawn(10)
|
||||
statlog_ticket(src, usr)
|
||||
|
||||
/datum/fine
|
||||
var/ID = null
|
||||
var/name = "fine"
|
||||
var/target = null
|
||||
var/reason = null
|
||||
var/amount = 0
|
||||
var/issuer = null
|
||||
var/issuer_job = null
|
||||
var/approver = null
|
||||
var/approver_job = null
|
||||
var/paid_amount = 0
|
||||
var/paid = 0
|
||||
var/datum/data/record/bank_record = null
|
||||
var/target_byond_key = null
|
||||
var/issuer_byond_key = null
|
||||
var/approver_byond_key = null
|
||||
|
||||
New()
|
||||
generate_ID()
|
||||
spawn(10)
|
||||
for(var/datum/data/record/B in data_core.bank) //gross
|
||||
if(B.fields["name"] == target)
|
||||
bank_record = B
|
||||
break
|
||||
if(!bank_record) qdel(src)
|
||||
statlog_fine(src, usr)
|
||||
|
||||
/datum/fine/proc/approve(var/approved_by,var/their_job)
|
||||
if(approver || paid) return
|
||||
if(!(their_job in list("Captain","Head of Security","Head of Personnel"))) return
|
||||
|
||||
approver = approved_by
|
||||
approver_job = their_job
|
||||
approver_byond_key = get_byond_key(approver)
|
||||
|
||||
if(bank_record.fields["current_money"] >= amount)
|
||||
bank_record.fields["current_money"] -= amount
|
||||
paid = 1
|
||||
paid_amount = amount
|
||||
else
|
||||
paid_amount += bank_record.fields["current_money"]
|
||||
bank_record.fields["current_money"] = 0
|
||||
spawn(300) process_payment()
|
||||
|
||||
/datum/fine/proc/process_payment()
|
||||
if(bank_record.fields["current_money"] >= (amount-paid_amount))
|
||||
bank_record.fields["current_money"] -= (amount-paid_amount)
|
||||
paid = 1
|
||||
paid_amount = amount
|
||||
else
|
||||
paid_amount += bank_record.fields["current_money"]
|
||||
bank_record.fields["current_money"] = 0
|
||||
spawn(300) process_payment()
|
||||
|
||||
/datum/fine/proc/generate_ID()
|
||||
if(!ID) ID = (data_core.fines.len + 1)
|
||||
@@ -0,0 +1,177 @@
|
||||
/obj/particle_maker
|
||||
name = "Particle Effect Maker"
|
||||
desc = "A thing for making nice particles with. It's an admin tool so if you see it ingame please adminhelp about it!"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "holo_console1"
|
||||
var/datum/particle_maker_var_holder/P = null
|
||||
|
||||
New()
|
||||
P = new /datum/particle_maker_var_holder
|
||||
|
||||
proc/Run()
|
||||
set background = 1
|
||||
src.visible_message("<b>[src]</b> beginning particle emission.")
|
||||
for(var/i=0, i < P.particle_amount, i++)
|
||||
SpawnNew()
|
||||
sleep(P.particle_delay)
|
||||
src.visible_message("<b>[src]</b> particle emission finished.")
|
||||
return
|
||||
|
||||
proc/SpawnNew()
|
||||
if(!istype(src))
|
||||
return
|
||||
|
||||
var/obj/particle/par = unpool(/obj/particle)
|
||||
|
||||
if(!istype(par))
|
||||
return
|
||||
|
||||
spawn(P.particle_lifespan)
|
||||
if (par)
|
||||
par.alpha = 255
|
||||
par.blend_mode = 0
|
||||
par.color = null
|
||||
par.pixel_x = 0
|
||||
par.pixel_y = 0
|
||||
par.transform = null
|
||||
par.override_state = null
|
||||
animate(par)
|
||||
pool(par)
|
||||
|
||||
par.set_loc(get_turf(src.loc))
|
||||
par.blend_mode = P.particle_blend_mode
|
||||
par.color = P.particle_color
|
||||
par.icon = P.particle_icon
|
||||
par.icon_state = P.particle_icon_state
|
||||
|
||||
par.pixel_x = P.initial_pixel_x + rand((0 - P.initial_pixel_x_variance),P.initial_pixel_x_variance)
|
||||
par.pixel_y = P.initial_pixel_y + rand((0 - P.initial_pixel_y_variance),P.initial_pixel_y_variance)
|
||||
var/x_destination = P.destination_pixel_x + rand((0 - P.destination_pixel_x_variance),P.destination_pixel_x_variance)
|
||||
var/y_destination = P.destination_pixel_y + rand((0 - P.destination_pixel_y_variance),P.destination_pixel_y_variance)
|
||||
|
||||
var/alpha_initial = P.initial_alpha + rand((0 - P.initial_alpha_variance),P.initial_alpha_variance)
|
||||
var/alpha_destination = P.destination_alpha + rand((0 - P.destination_alpha_variance),P.destination_alpha_variance)
|
||||
par.alpha = max(0,min(alpha_initial,255))
|
||||
var/end_alpha = max(0,min(alpha_destination,255))
|
||||
|
||||
var/matrix/M = turn(matrix(), rand(P.destination_turn_min, P.destination_turn_max))
|
||||
M.Scale(rand(P.destination_scale_min,P.destination_scale_max))
|
||||
|
||||
animate(par, color = P.particle_destination_color, time = P.animation_time, loop = P.animation_loops, transform = M, pixel_x = x_destination, pixel_y = y_destination, alpha = end_alpha, easing = P.easing)
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
Run()
|
||||
|
||||
verb/change_easing()
|
||||
set src in view(1)
|
||||
|
||||
var/ptype = input("Choose easing type","Particles") as null|anything in easing_types
|
||||
if (ptype)
|
||||
P.easing = easing_types[ptype]
|
||||
|
||||
verb/change_blend()
|
||||
set src in view(1)
|
||||
|
||||
var/ptype = input("Choose blend type","Particles") as null|anything in blend_types
|
||||
if (ptype)
|
||||
P.particle_blend_mode = blend_types[ptype]
|
||||
|
||||
/datum/particle_maker_var_holder
|
||||
var/particle_color = "#FF0000"
|
||||
var/particle_icon = 'icons/effects/particles.dmi'
|
||||
var/particle_icon_state = "8x8circle"
|
||||
var/particle_blend_mode = BLEND_ADD
|
||||
var/particle_delay = 1
|
||||
var/particle_amount = 20
|
||||
var/particle_lifespan = 35
|
||||
var/initial_alpha = 255
|
||||
var/initial_alpha_variance = 0
|
||||
var/initial_pixel_x = 0
|
||||
var/initial_pixel_y = 0
|
||||
var/initial_pixel_x_variance = 0
|
||||
var/initial_pixel_y_variance = 0
|
||||
var/destination_turn_max = 180
|
||||
var/destination_turn_min = -180
|
||||
var/destination_scale_min = 0.5
|
||||
var/destination_scale_max = 0.5
|
||||
var/destination_alpha = 100
|
||||
var/destination_alpha_variance = 0
|
||||
var/animation_time = 10
|
||||
var/animation_loops = 1
|
||||
var/destination_pixel_x = 0
|
||||
var/destination_pixel_y = 0
|
||||
var/destination_pixel_x_variance = 0
|
||||
var/destination_pixel_y_variance = 0
|
||||
var/particle_destination_color = "#0000FF"
|
||||
var/easing = LINEAR_EASING
|
||||
|
||||
/obj/jumpsuit_maker_experiment
|
||||
name = "jumpsuit making thing"
|
||||
desc = "this is an admin thing ok just ignore it"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "holo_console1"
|
||||
var/list/components = list("jumpsuit", "overalls", "jacket", "jacket_heavy", "vest", "shirt", "sleeves", "pants",
|
||||
"zipper", "belt", "stripe_sides", "stripe_shoulder", "stripe_belt", "stripe_captain", "trim_feet", "trim_hands",
|
||||
"decal_medic")
|
||||
var/list/current_pieces = list()
|
||||
var/list/current_colors = list()
|
||||
var/list/current_alphas = list()
|
||||
|
||||
attack_hand(var/mob/user as mob)
|
||||
var/dat = "<B>[src.name]</B><HR>"
|
||||
dat += "<B>Current Jumpsuit:</B><BR>"
|
||||
var/list_counter = 0
|
||||
if (current_pieces.len > 0)
|
||||
for (var/X as anything in current_pieces)
|
||||
list_counter++
|
||||
dat += "<b>Piece:</b> [X], <b>Color:</b> [current_colors[list_counter]], <b>Alpha:</b> [current_alphas[list_counter]]<br>"
|
||||
dat += "<HR>"
|
||||
if (current_pieces.len > 0)
|
||||
dat += "<A href='?src=\ref[src];dispense=1'>Dispense Jumpsuit</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];add=1'>Add New Element</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];wipe=1'>Erase All Elements</A><BR>"
|
||||
|
||||
user << browse(dat, "window=jumpsuitmaker;size=575x450")
|
||||
onclose(user, "jumpsuitmaker")
|
||||
return
|
||||
|
||||
Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if (href_list["dispense"])
|
||||
var/obj/item/clothing/under/experimental/E = new /obj/item/clothing/under/experimental(src.loc)
|
||||
E.component_images = src.current_pieces
|
||||
E.component_colors = src.current_colors
|
||||
E.component_alphas = src.current_alphas
|
||||
E.update_images()
|
||||
|
||||
else if (href_list["add"])
|
||||
src.current_pieces += input("Select Piece","Jumpsuit Maker") as anything in src.components
|
||||
src.current_colors += input("Select Color","Jumpsuit Maker") as color
|
||||
var/new_alpha = input("Input Alpha","Jumpsuit Maker") as num
|
||||
new_alpha = max(0,min(255,new_alpha))
|
||||
src.current_alphas += new_alpha
|
||||
|
||||
else if (href_list["wipe"])
|
||||
src.current_pieces = list()
|
||||
src.current_colors = list()
|
||||
src.current_alphas = list()
|
||||
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/circular_range_tester
|
||||
name = "circle tester"
|
||||
desc = "IGNORE ME!!!"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "holo_console1"
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
var/user_input = input("What size?","Circle Tester") as num
|
||||
if (user_input <= 0 || user_input > 30)
|
||||
alert("fuck you nerd","what are you doing")
|
||||
return
|
||||
for(var/turf/T in circular_range(get_turf(src),user_input))
|
||||
animate_flash_color_fill(T,"#FF0000",1,5)
|
||||
+1993
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,303 @@
|
||||
|
||||
/obj/poolwater
|
||||
name = "water"
|
||||
density = 0
|
||||
anchored = 1
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "poolwater"
|
||||
layer = EFFECTS_LAYER_UNDER_3
|
||||
mouse_opacity = 0
|
||||
New()
|
||||
var/datum/reagents/R = new/datum/reagents(10)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
R.add_reagent("cleaner",5)
|
||||
R.add_reagent("water",5)
|
||||
HasEntered(atom/A)
|
||||
reagents.reaction(A, TOUCH, 2)
|
||||
return
|
||||
|
||||
/obj/tree1
|
||||
name = "Tree"
|
||||
desc = "It's a tree."
|
||||
icon = 'icons/effects/96x96.dmi' // changed from worlds.dmi
|
||||
icon_state = "tree" // changed from 0.0
|
||||
anchored = 1
|
||||
layer = EFFECTS_LAYER_UNDER_3
|
||||
pixel_x = -20
|
||||
density = 1
|
||||
opacity = 0 // this causes some of the super ugly lighting issues too
|
||||
|
||||
// what the hell is all this and why wasn't it just using a big icon? the lighting system gets all fucked up with this stuff
|
||||
|
||||
/*
|
||||
New()
|
||||
var/image/tile10 = image('icons/misc/worlds.dmi',null,"1,0",10)
|
||||
tile10.pixel_x = 32
|
||||
|
||||
var/image/tile01 = image('icons/misc/worlds.dmi',null,"0,1",10)
|
||||
tile01.pixel_y = 32
|
||||
|
||||
var/image/tile11 = image('icons/misc/worlds.dmi',null,"1,1",10)
|
||||
tile11.pixel_y = 32
|
||||
tile11.pixel_x = 32
|
||||
|
||||
overlays += tile10
|
||||
overlays += tile01
|
||||
overlays += tile11
|
||||
|
||||
var/image/tile20 = image('icons/misc/worlds.dmi',null,"2,0",10)
|
||||
tile20.pixel_x = 64
|
||||
|
||||
var/image/tile02 = image('icons/misc/worlds.dmi',null,"0,2",10)
|
||||
tile02.pixel_y = 64
|
||||
|
||||
var/image/tile22 = image('icons/misc/worlds.dmi',null,"2,2",10)
|
||||
tile22.pixel_y = 64
|
||||
tile22.pixel_x = 64
|
||||
|
||||
var/image/tile21 = image('icons/misc/worlds.dmi',null,"2,1",10)
|
||||
tile21.pixel_y = 32
|
||||
tile21.pixel_x = 64
|
||||
|
||||
var/image/tile12 = image('icons/misc/worlds.dmi',null,"1,2",10)
|
||||
tile12.pixel_y = 64
|
||||
tile12.pixel_x = 32
|
||||
|
||||
overlays += tile20
|
||||
overlays += tile02
|
||||
overlays += tile22
|
||||
overlays += tile21
|
||||
overlays += tile12 */
|
||||
|
||||
|
||||
/obj/river
|
||||
name = "River"
|
||||
desc = "Its a river."
|
||||
icon = 'icons/misc/worlds.dmi'
|
||||
icon_state = "river"
|
||||
anchored = 1
|
||||
|
||||
/obj/stone
|
||||
name = "Stone"
|
||||
desc = "Its a stone."
|
||||
icon = 'icons/misc/worlds.dmi'
|
||||
icon_state = "stone"
|
||||
anchored = 1
|
||||
density=1
|
||||
|
||||
/obj/shrub
|
||||
name = "shrub"
|
||||
icon = 'icons/misc/worlds.dmi'
|
||||
icon_state = "shrub"
|
||||
anchored = 1
|
||||
density = 0
|
||||
layer = EFFECTS_LAYER_UNDER_1
|
||||
var/destroyed = 0
|
||||
|
||||
/obj/shrub/captainshrub
|
||||
name = "\improper Captain's bonsai tree"
|
||||
icon = 'icons/misc/worlds.dmi'
|
||||
icon_state = "shrub"
|
||||
desc = "The Captain's most prized possession. Don't touch it. Don't even look at it."
|
||||
anchored = 1
|
||||
density = 1
|
||||
layer = EFFECTS_LAYER_UNDER_1
|
||||
dir = EAST
|
||||
|
||||
// Added ex_act and meteorhit handling here (Convair880).
|
||||
proc/update_icon()
|
||||
if (!src) return
|
||||
src.dir = NORTHEAST
|
||||
src.destroyed = 1
|
||||
src.density = 0
|
||||
src.desc = "The scattered remains of a once-beautiful bonsai tree."
|
||||
playsound(src, "sound/effects/attackblob.ogg", 100, 0)
|
||||
return
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (!W) return
|
||||
if (!user) return
|
||||
if (src.destroyed) return
|
||||
if ((user.mind && user.mind.assigned_role == "Captain") && istype(W, /obj/item/wirecutters))
|
||||
boutput(user, "<span style=\"color:blue\">You carefully and lovingly sculpt your bonsai tree.</span>")
|
||||
if ((user.mind && user.mind.assigned_role == "Captain") && (!(istype(W, /obj/item/wirecutters))))
|
||||
boutput(user, "<span style=\"color:red\">Why would you ever destroy your precious bonsai tree?</span>")
|
||||
else if(istype(W, /obj/item/) && (user.mind && user.mind.assigned_role != "Captain"))
|
||||
src.update_icon()
|
||||
boutput(user, "<span style=\"color:red\">I don't think the Captain is going to be too happy about this...</span>")
|
||||
src.visible_message(text("<b><span style=\"color:red\">[] ravages the [] with the [].</span></b>", user, src, W), 1)
|
||||
return
|
||||
|
||||
meteorhit(obj/O as obj)
|
||||
src.visible_message("<b><span style=\"color:red\">The meteor smashes right through [src]!</span></b>")
|
||||
src.update_icon()
|
||||
return
|
||||
|
||||
ex_act(severity)
|
||||
src.visible_message("<b><span style=\"color:red\">[src] is ripped to pieces by the blast!</span></b>")
|
||||
src.update_icon()
|
||||
return
|
||||
|
||||
/obj/grassplug
|
||||
name = "grass"
|
||||
icon = 'icons/misc/worlds.dmi'
|
||||
icon_state = "grassplug"
|
||||
anchored = 1
|
||||
|
||||
/obj/window_blinds
|
||||
name = "blinds"
|
||||
icon = 'icons/obj/decoration.dmi'
|
||||
icon_state = "blindsH-o"
|
||||
anchored = 1
|
||||
density = 0
|
||||
opacity = 0
|
||||
layer = 30.1 // just above windows
|
||||
var/base_state = "blindsH"
|
||||
var/open = 1
|
||||
var/id = null
|
||||
var/obj/blind_switch/mySwitch = null
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.toggle()
|
||||
src.toggle_group()
|
||||
|
||||
attackby(obj/item/W, mob/user)
|
||||
src.toggle()
|
||||
src.toggle_group()
|
||||
|
||||
proc/toggle(var/force_state as null|num)
|
||||
if (!isnull(force_state))
|
||||
src.open = force_state
|
||||
else
|
||||
src.open = !(src.open)
|
||||
src.update_icon()
|
||||
|
||||
proc/toggle_group()
|
||||
if (istype(src.mySwitch))
|
||||
src.mySwitch.toggle()
|
||||
|
||||
proc/update_icon()
|
||||
if (src.open)
|
||||
src.icon_state = "[src.base_state]-c"
|
||||
src.opacity = 1
|
||||
else
|
||||
src.icon_state = "[src.base_state]-o"
|
||||
src.opacity = 0
|
||||
|
||||
left
|
||||
icon_state = "blindsH-L-o"
|
||||
base_state = "blindsH-L"
|
||||
middle
|
||||
icon_state = "blindsH-M-o"
|
||||
base_state = "blindsH-M"
|
||||
right
|
||||
icon_state = "blindsH-R-o"
|
||||
base_state = "blindsH-R"
|
||||
|
||||
vertical
|
||||
icon_state = "blindsV-o"
|
||||
base_state = "blindsV"
|
||||
|
||||
left
|
||||
icon_state = "blindsV-L-o"
|
||||
base_state = "blindsV-L"
|
||||
middle
|
||||
icon_state = "blindsV-M-o"
|
||||
base_state = "blindsV-M"
|
||||
right
|
||||
icon_state = "blindsV-R-o"
|
||||
base_state = "blindsV-R"
|
||||
|
||||
cog2
|
||||
icon_state = "blinds_cog2-o"
|
||||
base_state = "blinds_cog2"
|
||||
|
||||
left
|
||||
icon_state = "blinds_cog2-L-o"
|
||||
base_state = "blinds_cog2-L"
|
||||
middle
|
||||
icon_state = "blinds_cog2-M-o"
|
||||
base_state = "blinds_cog2-M"
|
||||
right
|
||||
icon_state = "blinds_cog2-R-o"
|
||||
base_state = "blinds_cog2-R"
|
||||
|
||||
/obj/blind_switch
|
||||
name = "blind switch"
|
||||
desc = "A switch for opening the blinds."
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "light1"
|
||||
anchored = 1
|
||||
density = 0
|
||||
var/on = 0
|
||||
var/id = null
|
||||
var/list/myBlinds = list()
|
||||
|
||||
New()
|
||||
..()
|
||||
if (!src.name || src.name in list("N blind switch", "E blind switch", "S blind switch", "W blind switch"))//== "N light switch" || name == "E light switch" || name == "S light switch" || name == "W light switch")
|
||||
src.name = "blind switch"
|
||||
spawn(5)
|
||||
src.locate_blinds()
|
||||
|
||||
proc/locate_blinds()
|
||||
for (var/obj/window_blinds/blind in world)
|
||||
if (blind.id == src.id)
|
||||
if (!(blind in src.myBlinds))
|
||||
src.myBlinds += blind
|
||||
blind.mySwitch = src
|
||||
|
||||
proc/toggle()
|
||||
src.on = !(src.on)
|
||||
src.icon_state = "light[!(src.on)]"
|
||||
if (!islist(myBlinds) || !myBlinds.len)
|
||||
return
|
||||
for (var/obj/window_blinds/blind in myBlinds)
|
||||
blind.toggle(src.on)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.toggle()
|
||||
|
||||
attackby(obj/item/W, mob/user)
|
||||
src.toggle()
|
||||
|
||||
/obj/blind_switch/north
|
||||
name = "N blind switch"
|
||||
pixel_y = 24
|
||||
|
||||
/obj/blind_switch/east
|
||||
name = "E blind switch"
|
||||
pixel_x = 24
|
||||
|
||||
/obj/blind_switch/south
|
||||
name = "S blind switch"
|
||||
pixel_y = -24
|
||||
|
||||
/obj/blind_switch/west
|
||||
name = "W blind switch"
|
||||
pixel_x = -24
|
||||
|
||||
/obj/blind_switch/area
|
||||
locate_blinds()
|
||||
var/area/A = get_area(src)
|
||||
for (var/obj/window_blinds/blind in A)
|
||||
if (!(blind in src.myBlinds))
|
||||
src.myBlinds += blind
|
||||
blind.mySwitch = src
|
||||
|
||||
/obj/blind_switch/area/north
|
||||
name = "N blind switch"
|
||||
pixel_y = 24
|
||||
|
||||
/obj/blind_switch/area/east
|
||||
name = "E blind switch"
|
||||
pixel_x = 24
|
||||
|
||||
/obj/blind_switch/area/south
|
||||
name = "S blind switch"
|
||||
pixel_y = -24
|
||||
|
||||
/obj/blind_switch/area/west
|
||||
name = "W blind switch"
|
||||
pixel_x = -24
|
||||
@@ -0,0 +1,326 @@
|
||||
/obj/displaycase
|
||||
name = "Display Case"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "glassbox1"
|
||||
desc = "A display case for antique possessions."
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/health = 30
|
||||
var/occupied = 1
|
||||
var/destroyed = 0
|
||||
|
||||
/obj/displaycase/ex_act(severity)
|
||||
switch(severity)
|
||||
if (1)
|
||||
new /obj/item/raw_material/shard/glass( src.loc )
|
||||
if (occupied)
|
||||
new /obj/item/captaingun( src.loc )
|
||||
occupied = 0
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
src.health -= 15
|
||||
src.healthcheck()
|
||||
if (3)
|
||||
if (prob(50))
|
||||
src.health -= 5
|
||||
src.healthcheck()
|
||||
|
||||
/obj/displaycase/bullet_act(var/obj/projectile/P)
|
||||
var/damage = 0
|
||||
damage = round((P.power*P.proj_data.ks_ratio), 1.0)
|
||||
if (damage < 1)
|
||||
return
|
||||
|
||||
if(src.material) src.material.triggerOnAttacked(src, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter) )
|
||||
for(var/atom/A in src)
|
||||
if(A.material)
|
||||
A.material.triggerOnAttacked(A, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter))
|
||||
|
||||
switch(P.proj_data.damage_type)
|
||||
if(D_KINETIC)
|
||||
src.health -= (damage*2)
|
||||
if(D_PIERCING)
|
||||
src.health -= (damage/2)
|
||||
if(D_ENERGY)
|
||||
src.health -= (damage/4)
|
||||
|
||||
src.healthcheck()
|
||||
return
|
||||
|
||||
|
||||
/obj/displaycase/blob_act(var/power)
|
||||
if (prob(50))
|
||||
new /obj/item/raw_material/shard/glass( src.loc )
|
||||
if (occupied)
|
||||
new /obj/item/captaingun( src.loc )
|
||||
occupied = 0
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/displaycase/meteorhit(obj/O as obj)
|
||||
new /obj/item/raw_material/shard/glass( src.loc )
|
||||
new /obj/item/captaingun( src.loc )
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/displaycase/proc/healthcheck()
|
||||
if (src.health <= 0)
|
||||
if (!( src.destroyed ))
|
||||
src.density = 0
|
||||
src.destroyed = 1
|
||||
new /obj/item/raw_material/shard/glass( src.loc )
|
||||
playsound(src, "shatter", 70, 1)
|
||||
update_icon()
|
||||
else
|
||||
playsound(src.loc, "sound/effects/Glasshit.ogg", 75, 1)
|
||||
return
|
||||
|
||||
/obj/displaycase/proc/update_icon()
|
||||
if(src.destroyed)
|
||||
src.icon_state = "glassboxb[src.occupied]"
|
||||
else
|
||||
src.icon_state = "glassbox[src.occupied]"
|
||||
return
|
||||
|
||||
|
||||
/obj/displaycase/attackby(obj/item/W as obj, mob/user as mob)
|
||||
src.health -= W.force
|
||||
src.healthcheck()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/displaycase/attack_hand(mob/user as mob)
|
||||
if (src.destroyed && src.occupied)
|
||||
new /obj/item/captaingun( src.loc )
|
||||
boutput(user, "<b>You deactivate the hover field built into the case.</b>")
|
||||
src.occupied = 0
|
||||
src.add_fingerprint(user)
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
user.visible_message("<span style=\"color:red\">[user] kicks the display case.</span>")
|
||||
src.health -= 2
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
// Added a little mini-quest here. Gun can be repaired, and the player will be rewarded for using
|
||||
// high-quality materials, which will make the weapon more powerful (Convair880).
|
||||
/obj/item/captaingun
|
||||
name = "antique laser gun"
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "caplaser"
|
||||
inhand_image_icon = 'icons/mob/inhand/hand_weapons.dmi'
|
||||
item_state = "gun"
|
||||
force = 1.0
|
||||
flags = FPRINT | TABLEPASS | CONDUCT | ONBELT
|
||||
var/stability = 10
|
||||
|
||||
var/repair_stage = 0
|
||||
var/quality_counter = 0 // Simply the sum of all material.quality values of every component.
|
||||
var/q_threshold1 = 100 // Decent quality.
|
||||
var/q_threshold2 = 200 // Superb quality.
|
||||
|
||||
var/datum/projectile/our_projectile = null
|
||||
var/datum/projectile/our_projectile2 = null // Reserved for top-notch replacement parts.
|
||||
var/list/our_projectiles = null
|
||||
var/obj/item/ammo/power_cell/our_cell = null
|
||||
|
||||
New()
|
||||
src.stability = rand(6,20)
|
||||
..()
|
||||
return
|
||||
|
||||
examine()
|
||||
set src in usr
|
||||
if (usr.mind && usr.mind.assigned_role == "Captain")
|
||||
boutput(usr, "It's your laser gun! It's really just for show and made of plastic but man it looks cool. Everybody thinks you're awesome, and you know it.")
|
||||
else
|
||||
boutput(usr, "On closer inspection, it looks like it's just a display model...? What a cheapskate. Fuck our captain.")
|
||||
|
||||
if (src.repair_stage > 0)
|
||||
switch (src.repair_stage)
|
||||
if (1)
|
||||
boutput(usr, "<br><span style=\"color:blue\">The maintenance panel is open, revealing a largely empty circuit board.</span>")
|
||||
if (2)
|
||||
boutput(usr, "<br><span style=\"color:blue\">The wiring has been replaced, but there's still an empty spot in the circuit board.</span>")
|
||||
if (3)
|
||||
boutput(usr, "<br><span style=\"color:blue\">A new coil has been inserted, but not secured yet.</span>")
|
||||
if (4)
|
||||
boutput(usr, "<br><span style=\"color:blue\">The coil has been soldered into place, but there's nothing to focus the laser beam.</span>")
|
||||
if (5)
|
||||
boutput(usr, "<br><span style=\"color:blue\">A lens has been installed, but the control circuits aren't set up yet.</span>")
|
||||
if (6)
|
||||
boutput(usr, "<br><span style=\"color:blue\">The gun appears to be missing a power cell.</span>")
|
||||
if (7)
|
||||
boutput(usr, "<br><span style=\"color:blue\">Power cell installed. The maintenance panel is open.</span>")
|
||||
return
|
||||
|
||||
attack()
|
||||
..()
|
||||
src.stability--
|
||||
src.healthcheck(usr)
|
||||
return
|
||||
|
||||
proc/healthcheck(mob/user as mob)
|
||||
if (!src) return
|
||||
if (src.stability <= 0)
|
||||
if (user && ismob(user))
|
||||
boutput(user, "<span style=\"color:red\">The laser gun snaps in half!</span>")
|
||||
user.u_equip(src)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/*
|
||||
0 Screwdriver
|
||||
1 Cable coil
|
||||
2 Small coil
|
||||
3 Soldering iron
|
||||
4 Lens
|
||||
5 Multitool
|
||||
6 Power cell
|
||||
7 Screwdriver
|
||||
*/
|
||||
attackby(obj/item/O as obj, mob/user as mob)
|
||||
if (istype(O, /obj/item/screwdriver))
|
||||
if (src.repair_stage == 0)
|
||||
user.show_text("You open the maintenance panel.", "blue")
|
||||
src.repair_stage = 1
|
||||
|
||||
else if (src.repair_stage == 7)
|
||||
user.visible_message("<span style=\"color:blue\">[user] finishes repairing the [src.name].</span>", "<span style=\"color:blue\">You close the maintenance panel and power up the gun.</span>")
|
||||
|
||||
src.generate_properties(user) // Type of projectile(s) based on material quality.
|
||||
var/obj/item/gun/energy/laser_gun/antique/L = new /obj/item/gun/energy/laser_gun/antique(get_turf(user))
|
||||
L.current_projectile = new src.our_projectile
|
||||
if (!isnull(src.our_projectile2))
|
||||
src.our_projectiles = list(new src.our_projectile, new src.our_projectile2)
|
||||
L.projectiles = src.our_projectiles
|
||||
src.our_cell.set_loc(L)
|
||||
L.cell = src.our_cell
|
||||
|
||||
// The man with the golden gun.
|
||||
if (src.quality_counter >= src.q_threshold2)
|
||||
L.material = getCachedMaterial("gold")
|
||||
if (L.material)
|
||||
L.material.owner = L
|
||||
L.material.triggerOnAdd(L)
|
||||
L.name = "show-piece antique laser gun"
|
||||
user.unlock_medal("Tinkerer", 1)
|
||||
|
||||
user.u_equip(src)
|
||||
user.put_in_hand_or_drop(L)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
else if (istype(O, /obj/item/cable_coil))
|
||||
if (src.repair_stage == 1)
|
||||
var/obj/item/cable_coil/C = O
|
||||
if (C.amount >= 10)
|
||||
user.show_text("You begin to rewire the gun's circuit board...", "blue")
|
||||
if (do_after(user, 35))
|
||||
user.show_text("You rewire the circuit board.", "blue")
|
||||
src.repair_stage = 2
|
||||
if (C.material)
|
||||
src.quality_counter += C.material.quality
|
||||
else
|
||||
user.show_text("You were interrupted!", "red")
|
||||
return
|
||||
else
|
||||
user.show_text("You need more wire than that.", "red")
|
||||
return
|
||||
|
||||
else if (istype(O, /obj/item/coil/small))
|
||||
if (src.repair_stage == 2)
|
||||
user.show_text("You begin to install the coil...", "blue")
|
||||
if (do_after(user, 35))
|
||||
user.show_text("You install the coil.", "blue")
|
||||
src.repair_stage = 3
|
||||
if (O.material)
|
||||
src.quality_counter += O.material.quality
|
||||
user.u_equip(O)
|
||||
qdel(O)
|
||||
else
|
||||
user.show_text("You were interrupted!", "red")
|
||||
return
|
||||
|
||||
else if (istype(O, /obj/item/electronics/soldering))
|
||||
if (src.repair_stage == 3)
|
||||
user.show_text("You begin to solder the coil into place...", "blue")
|
||||
if (do_after(user, 35))
|
||||
user.show_text("You solder the coil into place.", "blue")
|
||||
src.repair_stage = 4
|
||||
else
|
||||
user.show_text("You were interrupted!", "red")
|
||||
return
|
||||
|
||||
else if (istype(O, /obj/item/lens))
|
||||
if (src.repair_stage == 4)
|
||||
user.show_text("You begin to install the lens...", "blue")
|
||||
if (do_after(user, 35))
|
||||
user.show_text("You install the lens.", "blue")
|
||||
src.repair_stage = 5
|
||||
if (O.material)
|
||||
src.quality_counter += O.material.quality
|
||||
user.u_equip(O)
|
||||
qdel(O)
|
||||
else
|
||||
user.show_text("You were interrupted!", "red")
|
||||
return
|
||||
|
||||
else if (istype(O, /obj/item/device/multitool))
|
||||
if (src.repair_stage == 5)
|
||||
user.show_text("You initialize the control board.", "blue")
|
||||
src.repair_stage = 6
|
||||
|
||||
else if (istype(O, /obj/item/ammo/power_cell))
|
||||
if (src.repair_stage == 6)
|
||||
var/obj/item/ammo/power_cell/P = O
|
||||
user.show_text("You begin to install the power cell...", "blue")
|
||||
if (do_after(user, 35))
|
||||
user.show_text("You install the power cell.", "blue")
|
||||
src.repair_stage = 7
|
||||
user.u_equip(P)
|
||||
P.set_loc(src)
|
||||
src.our_cell = P
|
||||
if (P.material)
|
||||
src.quality_counter += P.material.quality
|
||||
else
|
||||
user.show_text("You were interrupted!", "red")
|
||||
return
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
return
|
||||
|
||||
// Basically determines how powerful the gun will be, based on the quality of the materials used.
|
||||
// Code for the energy gun itself can be found in energy.dm.
|
||||
//
|
||||
// Why isn't there a crappy version (less than 0 quality) here? I don't want to punish the player
|
||||
// for investing a bit of time of effort. After all, scanning and mass-producing energy guns is
|
||||
// much less of a hassle.
|
||||
proc/generate_properties(var/mob/user)
|
||||
if (!src) return
|
||||
|
||||
// Nothing special, just a plain old laser.
|
||||
if (src.quality_counter < src.q_threshold1)
|
||||
src.our_projectile = /datum/projectile/laser
|
||||
if (user && ismob(user))
|
||||
user.show_text("The [src.name] looks a little worn, but appears to work alright.", "blue")
|
||||
|
||||
// Player put some effort into it, so let's give him something a little more powerful.
|
||||
else if (src.quality_counter >= src.q_threshold1 && src.quality_counter < src.q_threshold2)
|
||||
if (user && ismob(user))
|
||||
user.show_text("The [src.name] seems to work better than expected thanks to above-average replacment parts.", "blue")
|
||||
src.our_projectile = /datum/projectile/laser/old
|
||||
|
||||
// Now we're talking about top-notch stuff.
|
||||
else if (src.quality_counter >= src.q_threshold2)
|
||||
if (user && ismob(user))
|
||||
user.show_text("The [src.name]'s high-quality replacement parts fit together perfectly, increasing the gun's output.", "blue")
|
||||
src.our_projectile = /datum/projectile/laser/old
|
||||
src.our_projectile2 = /datum/projectile/laser/old_burst
|
||||
|
||||
//DEBUG("[src.name]'s quality_counter: [quality_counter]")
|
||||
return
|
||||
@@ -0,0 +1,19 @@
|
||||
/* This is an attempt to make some easily reusable "particle" type effects, to stop the code
|
||||
constantly having to be rewritten. An item like the jetpack that uses the ion_trail_follow system, just has one
|
||||
defined, then set up when it is created with New(). Then this same system can just be reused each time
|
||||
it needs to create more trails.A beaker could have a steam_trail_follow system set up, then the steam
|
||||
would spawn and follow the beaker, even if it is carried or thrown.
|
||||
*/
|
||||
#define TOUCH 1
|
||||
#define INGEST 2
|
||||
|
||||
/obj/effects
|
||||
name = "effects"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
mouse_opacity = 0
|
||||
flags = TABLEPASS
|
||||
desc = null
|
||||
|
||||
pooled()
|
||||
..()
|
||||
color = initial(color)
|
||||
@@ -0,0 +1,40 @@
|
||||
/////////////////////////////////////////////
|
||||
// Bad smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effects/bad_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effects/bad_smoke/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/M in get_turf(src))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.c_flags & MASKINTERNALS))
|
||||
else
|
||||
M.drop_item()
|
||||
if (prob(25))
|
||||
M.stunned += 1
|
||||
M.take_oxygen_deprivation(1)
|
||||
M.emote("cough")
|
||||
return
|
||||
|
||||
/obj/effects/bad_smoke/HasEntered(mob/living/carbon/M as mob )
|
||||
..()
|
||||
if(iscarbon(M))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.c_flags & MASKINTERNALS))
|
||||
return
|
||||
else
|
||||
M.drop_item()
|
||||
if (prob(25))
|
||||
M.stunned += 1
|
||||
M.take_oxygen_deprivation(1)
|
||||
M.emote("cough")
|
||||
return
|
||||
@@ -0,0 +1,54 @@
|
||||
// fart cloud for toxic farts
|
||||
|
||||
/obj/effects/fart_cloud
|
||||
name = "fart cloud"
|
||||
icon_state = "mustard"
|
||||
opacity = 1
|
||||
anchored = 0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6
|
||||
var/mob/living/fartowner = null
|
||||
|
||||
proc/Life()
|
||||
amount--
|
||||
for(var/mob/living/carbon/human/H in range(get_turf(src),1))
|
||||
if (H == src.fartowner)
|
||||
continue
|
||||
if (prob(20))
|
||||
boutput(H, "<span style=\"color:red\">Oh god! The <i>smell</i>!!!</span>")
|
||||
H.reagents.add_reagent("jenkem",0.1)
|
||||
sleep(15)
|
||||
if(amount < 1)
|
||||
dispose()
|
||||
return
|
||||
else
|
||||
src.Life()
|
||||
|
||||
/obj/effects/fart_cloud/New(loc,var/mob/living/owner)
|
||||
..()
|
||||
if (owner)
|
||||
fartowner = owner
|
||||
amount = rand(3,8)
|
||||
spawn(0)
|
||||
src.Life()
|
||||
return
|
||||
|
||||
/obj/effects/fart_cloud/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/human/R in get_turf(src))
|
||||
if (R.internal != null && usr.wear_mask && (R.wear_mask.c_flags & MASKINTERNALS))
|
||||
continue
|
||||
if (R == src.fartowner)
|
||||
continue
|
||||
R.reagents.add_reagent("jenkem",1)
|
||||
return
|
||||
|
||||
/obj/effects/fart_cloud/HasEntered(mob/living/carbon/human/R as mob )
|
||||
..()
|
||||
if (istype(R, /mob/living/carbon/human))
|
||||
if (R.internal != null && usr.wear_mask && (R.wear_mask.c_flags & MASKINTERNALS))
|
||||
return
|
||||
if (R == src.fartowner)
|
||||
return
|
||||
R.reagents.add_reagent("jenkem",1)
|
||||
return
|
||||
@@ -0,0 +1,169 @@
|
||||
// Foam
|
||||
// Similar to smoke, but spreads out more
|
||||
// metal foams leave behind a foamed metal wall
|
||||
|
||||
/obj/effects/foam
|
||||
name = "foam"
|
||||
icon_state = "foam"
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
density = 0
|
||||
layer = OBJ_LAYER + 0.9
|
||||
mouse_opacity = 0
|
||||
var/foamcolor
|
||||
var/amount = 3
|
||||
var/expand = 1
|
||||
animate_movement = 0
|
||||
var/metal = 0
|
||||
|
||||
/*
|
||||
/obj/effects/foam/New(loc, var/ismetal=0)
|
||||
..(loc)
|
||||
|
||||
*/
|
||||
|
||||
/obj/effects/foam/pooled()
|
||||
..()
|
||||
name = "foam"
|
||||
icon_state = "foam"
|
||||
opacity = 0
|
||||
foamcolor = null
|
||||
expand = 0
|
||||
amount = 0
|
||||
metal = 0
|
||||
animate_movement = 0
|
||||
if(reagents)
|
||||
reagents.clear_reagents()
|
||||
|
||||
/obj/effects/foam/unpooled()
|
||||
..()
|
||||
amount = 3
|
||||
expand = 1
|
||||
|
||||
/obj/effects/foam/proc/set_up(loc, var/ismetal)
|
||||
src.set_loc(loc)
|
||||
expand = 1
|
||||
if(ismetal == 1)
|
||||
icon_state = "mfoam"
|
||||
else
|
||||
icon_state = "foam"
|
||||
if(reagents)
|
||||
src.overlays.len = 0
|
||||
icon_state = "foam"
|
||||
src.foamcolor = src.reagents.get_master_color()
|
||||
var/icon/I = new /icon('icons/effects/effects.dmi',"foam_overlay")
|
||||
I.Blend(src.foamcolor, ICON_ADD)
|
||||
src.overlays += I
|
||||
metal = ismetal
|
||||
playsound(src, "sound/effects/bubbles2.ogg", 80, 1, -3)
|
||||
|
||||
spawn(3 + metal*3)
|
||||
process()
|
||||
spawn(120)
|
||||
expand = 0 // stop expanding
|
||||
sleep(30)
|
||||
|
||||
if(metal)
|
||||
var/obj/foamedmetal/M = new(src.loc)
|
||||
M.metal = metal
|
||||
M.updateicon()
|
||||
|
||||
if(metal)
|
||||
flick("mfoam-disolve", src)
|
||||
else
|
||||
flick("foam-disolve", src)
|
||||
sleep(5)
|
||||
die()
|
||||
return
|
||||
|
||||
// on delete, transfer any reagents to the floor & surrounding tiles
|
||||
/obj/effects/foam/proc/die()
|
||||
expand = 0
|
||||
if(!metal && reagents)
|
||||
reagents.handle_reactions()
|
||||
for(var/atom/A in oview(1,src))
|
||||
if(A == src)
|
||||
continue
|
||||
if(istype(A,/mob/living))
|
||||
var/mob/living/L = A
|
||||
logTheThing("combat", L, null, "is hit by chemical foam [log_reagents(src)] at [log_loc(src)].")
|
||||
reagents.reaction(A, TOUCH, 5)
|
||||
pool(src)
|
||||
|
||||
/obj/effects/foam/proc/process()
|
||||
if(--amount < 0)
|
||||
return
|
||||
|
||||
|
||||
while(expand) // keep trying to expand while true
|
||||
|
||||
for(var/direction in cardinal)
|
||||
var/turf/T = get_step(src,direction)
|
||||
if(!T)
|
||||
continue
|
||||
|
||||
if(!T.Enter(src))
|
||||
continue
|
||||
|
||||
//if(istype(T, /turf/space))
|
||||
// continue
|
||||
|
||||
var/obj/effects/foam/F = locate() in T
|
||||
if(F)
|
||||
continue
|
||||
|
||||
F = unpool(/obj/effects/foam)
|
||||
F.set_up(T, metal)
|
||||
F.amount = amount
|
||||
if(!metal)
|
||||
F.overlays.len = 0
|
||||
F.create_reagents(15)
|
||||
|
||||
//This very slight tweak is to make it so some reactions that require different ratios
|
||||
//can still work in foam.
|
||||
for(var/reagent_id in src.reagents.reagent_list)
|
||||
var/datum/reagent/current_reagent = src.reagents.reagent_list[reagent_id]
|
||||
if(current_reagent)
|
||||
F.reagents.add_reagent(reagent_id,min(current_reagent.volume, 3), current_reagent.data, src.reagents.total_temperature)
|
||||
|
||||
F.icon_state = "foam"
|
||||
F.foamcolor = src.reagents.get_master_color()
|
||||
var/icon/I = new /icon('icons/effects/effects.dmi',"foam_overlay")
|
||||
I.Blend(F.foamcolor, ICON_ADD)
|
||||
F.overlays += I
|
||||
|
||||
sleep(15)
|
||||
|
||||
// foam disolves when heated
|
||||
// except metal foams
|
||||
/obj/effects/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(!metal && prob(max(0, exposed_temperature - 475)))
|
||||
flick("foam-disolve", src)
|
||||
|
||||
spawn(5)
|
||||
die()
|
||||
expand = 0
|
||||
|
||||
|
||||
/obj/effects/foam/HasEntered(var/atom/movable/AM)
|
||||
if (metal)
|
||||
return
|
||||
|
||||
if (ishuman(AM))
|
||||
var/mob/living/carbon/human/M = AM
|
||||
if (!M.can_slip())
|
||||
return
|
||||
|
||||
for(var/reagent_id in src.reagents.reagent_list)
|
||||
var/amount = M.reagents.get_reagent_amount(reagent_id)
|
||||
if(amount < 25)
|
||||
M.reagents.add_reagent(reagent_id, min(round(amount / 2),15))
|
||||
logTheThing("combat", M, null, "is hit by chemical foam [log_reagents(src)] at [log_loc(src)].")
|
||||
reagents.reaction(M, TOUCH, 5)
|
||||
|
||||
if(!istype(src.loc, /turf/space))
|
||||
M.pulling = null
|
||||
M.show_text("You slip on the foam!", "red")
|
||||
playsound(src.loc, "sound/misc/slip.ogg", 50, 1, -3)
|
||||
M.stunned = 2
|
||||
M.weakened = 2
|
||||
@@ -0,0 +1,36 @@
|
||||
/obj/effects/harmless_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
pooled()
|
||||
..()
|
||||
|
||||
/*
|
||||
/obj/effects/harmless_smoke/New()
|
||||
..()
|
||||
spawn (100)
|
||||
pool(src)
|
||||
return
|
||||
*/
|
||||
/obj/effects/harmless_smoke/proc/kill(var/time)
|
||||
spawn(time)
|
||||
pool(src)
|
||||
|
||||
/obj/effects/harmless_smoke/Move()
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
proc/harmless_smoke_puff(var/turf/location, var/duration = 100)
|
||||
if(!istype(location)) return
|
||||
var/obj/effects/harmless_smoke/smoke = unpool(/obj/effects/harmless_smoke)
|
||||
smoke.set_loc(location)
|
||||
smoke.kill(100)
|
||||
@@ -0,0 +1,17 @@
|
||||
/////////////////////////////////////////////
|
||||
//////// Attach an Ion trail to any object, that spawns when it moves (like for the jetpack)
|
||||
/// just pass in the object to attach it to in set_up
|
||||
/// Then do start() to start it and stop() to stop it, obviously
|
||||
/// and don't call start() in a loop that will be repeated otherwise it'll get spammed!
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effects/ion_trails
|
||||
name = "ion trails"
|
||||
icon_state = "ion_trails"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effects/ion_trails/pooled(var/poolname)
|
||||
icon_state = "blank"
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
..()
|
||||
@@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////
|
||||
// Mustard Gas
|
||||
/////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/effects/mustard_gas
|
||||
name = "mustard gas"
|
||||
icon_state = "mustard"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
|
||||
/obj/effects/mustard_gas/New()
|
||||
..()
|
||||
spawn (100)
|
||||
dispose()
|
||||
return
|
||||
|
||||
/obj/effects/mustard_gas/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/human/R in get_turf(src))
|
||||
if (R.internal != null && R.wear_mask && (R.wear_mask.c_flags & MASKINTERNALS))
|
||||
else
|
||||
R.TakeDamage("chest", 0, 10)
|
||||
R.losebreath = max(5, R.losebreath)
|
||||
R.emote("scream")
|
||||
if (prob(25))
|
||||
R.stunned += 1
|
||||
R.updatehealth()
|
||||
return
|
||||
|
||||
/obj/effects/mustard_gas/HasEntered(mob/living/carbon/human/R as mob )
|
||||
..()
|
||||
if (istype(R, /mob/living/carbon/human))
|
||||
if (R.internal != null && R.wear_mask && (R.wear_mask.c_flags & MASKINTERNALS))
|
||||
return
|
||||
R.losebreath = max(5, R.losebreath)
|
||||
R.TakeDamage("chest", 0, 10)
|
||||
R.emote("scream")
|
||||
if (prob(25))
|
||||
R.stunned += 1
|
||||
R.updatehealth()
|
||||
return
|
||||
@@ -0,0 +1,8 @@
|
||||
/obj/effects/smoke
|
||||
name = "smoke"
|
||||
icon = 'icons/effects/water.dmi'
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 8.0
|
||||
@@ -0,0 +1,35 @@
|
||||
/////////////////////////////////////////////
|
||||
//SPARK SYSTEM (like steam system)
|
||||
// The attach(atom/atom) proc is optional, and can be called to attach the effect
|
||||
// to something, like the RCD, so then you can just call start() and the sparks
|
||||
// will always spawn at the items location.
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effects/sparks
|
||||
name = "sparks"
|
||||
icon_state = "sparks"
|
||||
var/amount = 6.0
|
||||
anchored = 1.0
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/effects/sparks/unpooled(var/poolname)
|
||||
..(poolname)
|
||||
spawn(5)
|
||||
playsound(src.loc, "sparks", 100, 1)
|
||||
var/turf/T = src.loc
|
||||
if (istype(T, /turf))
|
||||
T.hotspot_expose(1000,100)
|
||||
return
|
||||
|
||||
/obj/effects/sparks/disposing()
|
||||
var/turf/T = get_turf(src)
|
||||
if (istype(T, /turf))
|
||||
T.hotspot_expose(1000,100)
|
||||
..()
|
||||
|
||||
/obj/effects/sparks/Move()
|
||||
..()
|
||||
var/turf/T = src.loc
|
||||
if (istype(T, /turf))
|
||||
T.hotspot_expose(1000,100)
|
||||
return
|
||||
@@ -0,0 +1,8 @@
|
||||
/obj/effects/spray
|
||||
name = "spray"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "extinguish"
|
||||
flags = TABLEPASS
|
||||
mouse_opacity = 0
|
||||
anchored = 1
|
||||
var/original_dir = NORTH
|
||||
@@ -0,0 +1,5 @@
|
||||
/obj/effects/steam
|
||||
name = "steam"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "extinguish"
|
||||
density = 0
|
||||
@@ -0,0 +1,52 @@
|
||||
/obj/effects/water
|
||||
name = "water"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "extinguish"
|
||||
var/life = 15.0
|
||||
flags = TABLEPASS
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/effects/water/pooled(var/poolname)
|
||||
life = initial(life)
|
||||
..()
|
||||
|
||||
/obj/effects/water/Move(turf/newloc)
|
||||
//var/turf/T = src.loc
|
||||
//if (istype(T, /turf))
|
||||
// T.firelevel = 0 //TODO: FIX
|
||||
if (--src.life < 1)
|
||||
//SN src = null
|
||||
if (!disposed)
|
||||
pool(src)
|
||||
return 0
|
||||
if(newloc.density)
|
||||
if (!disposed)
|
||||
pool(src)
|
||||
return 0
|
||||
.=..()
|
||||
|
||||
/obj/effects/water/proc/spray_at(var/turf/target, var/datum/reagents/R)
|
||||
if (!target || !R)
|
||||
pool(src)
|
||||
return
|
||||
|
||||
src.reagents = R
|
||||
R.my_atom = src
|
||||
src.reagents.trans_to(src,1)
|
||||
var/turf/T
|
||||
for(var/b=0, b<5, b++)
|
||||
T = get_turf(src)
|
||||
step_towards(src,target)
|
||||
if(!src.reagents)
|
||||
break
|
||||
src.reagents.reaction(T)
|
||||
for(var/atom/atm in T)
|
||||
src.reagents.reaction(atm)
|
||||
if(src.loc == target)
|
||||
break
|
||||
sleep(2)
|
||||
if (disposed)
|
||||
break
|
||||
|
||||
if (!disposed)
|
||||
pool(src)
|
||||
@@ -0,0 +1,239 @@
|
||||
/turf/simulated/wall/false_wall
|
||||
name = "wall"
|
||||
icon = 'icons/obj/doors/Doorf.dmi'
|
||||
icon_state = "door1"
|
||||
blocks_air = 0
|
||||
var/operating = null
|
||||
var/visible = 1
|
||||
var/floorname
|
||||
var/floorintact
|
||||
var/floorhealth
|
||||
var/floorburnt
|
||||
var/icon/flooricon
|
||||
var/flooricon_state
|
||||
var/const/delay = 15
|
||||
var/const/prob_opens = 25
|
||||
var/list/known_by = list()
|
||||
var/can_be_auto = 1
|
||||
var/mod = null
|
||||
|
||||
temp
|
||||
var/was_rwall = 0
|
||||
|
||||
reinforced
|
||||
icon_state = "rdoor1"
|
||||
mod = "R"
|
||||
|
||||
hive
|
||||
name = "strange hive wall"
|
||||
desc = "Looking more closely, these are actually really squat octagons, not hexagons! What!!"
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
icon_state = "hive"
|
||||
can_be_auto = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
//Hide the wires or whatever THE FUCK
|
||||
src.levelupdate()
|
||||
src.blocks_air = 1
|
||||
src.find_icon_state()
|
||||
spawn(10)
|
||||
// so that if it's getting created by the map it works, and if it isn't this will just return
|
||||
src.setFloorUnderlay('icons/turf/floors.dmi', "plating", 0, 100, 0, "plating")
|
||||
|
||||
proc/setFloorUnderlay(FloorIcon, FloorIcon_State, Floor_Intact, Floor_Health, Floor_Burnt, Floor_Name)
|
||||
if(src.underlays.len)
|
||||
//only one underlay
|
||||
return 0
|
||||
if(!(FloorIcon || FloorIcon_State))
|
||||
return 0
|
||||
if(!Floor_Health)
|
||||
Floor_Health = 150
|
||||
if(!Floor_Burnt)
|
||||
Floor_Burnt = 0
|
||||
if(!Floor_Intact)
|
||||
Floor_Intact = 1
|
||||
if(!Floor_Name)
|
||||
Floor_Name = "floor"
|
||||
underlays += image(FloorIcon, FloorIcon_State)
|
||||
src.flooricon = FloorIcon
|
||||
src.flooricon_state = FloorIcon_State
|
||||
src.floorintact = Floor_Intact
|
||||
src.floorhealth = Floor_Health
|
||||
src.floorburnt = Floor_Burnt
|
||||
src.floorname = Floor_Name
|
||||
return 1
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
var/known = (user in known_by)
|
||||
if (src.density)
|
||||
//door is closed
|
||||
if (known)
|
||||
if (open())
|
||||
boutput(user, "<span style=\"color:blue\">The wall slides open.</span>")
|
||||
else if (prob(prob_opens))
|
||||
//it's hard to open
|
||||
if (open())
|
||||
boutput(user, "<span style=\"color:blue\">The wall slides open!</span>")
|
||||
known_by += user
|
||||
else
|
||||
return ..()
|
||||
else
|
||||
if (close())
|
||||
boutput(user, "<span style=\"color:blue\">The wall slides shut.</span>")
|
||||
return
|
||||
|
||||
attackby(obj/item/screwdriver/S as obj, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
var/known = (user in known_by)
|
||||
if (istype(S, /obj/item/screwdriver))
|
||||
//try to disassemble the false wall
|
||||
if (!src.density || prob(prob_opens))
|
||||
//without this, you can detect a false wall just by going down the line with screwdrivers
|
||||
//if it's already open, you can disassemble it no problem
|
||||
if (src.density && !known) //if it was closed, let them know that they did something
|
||||
boutput(user, "<span style=\"color:blue\">It was a false wall!</span>")
|
||||
//disassemble it
|
||||
boutput(user, "<span style=\"color:blue\">Now dismantling false wall.</span>")
|
||||
var/floorname1 = src.floorname
|
||||
var/floorintact1 = src.floorintact
|
||||
var/floorburnt1 = src.floorburnt
|
||||
var/icon/flooricon1 = src.flooricon
|
||||
var/flooricon_state1 = src.flooricon_state
|
||||
src.density = 0
|
||||
src.RL_SetOpacity(0)
|
||||
src.update_nearby_tiles()
|
||||
var/turf/simulated/floor/F = src.ReplaceWithFloor()
|
||||
F.name = floorname1
|
||||
F.icon = flooricon1
|
||||
F.icon_state = flooricon_state1
|
||||
F.intact = floorintact1
|
||||
F.burnt = floorburnt1
|
||||
|
||||
//a false wall turns into a sheet of metal and displaced girders
|
||||
var/atom/A = new /obj/item/sheet(F)
|
||||
var/atom/B = new /obj/structure/girder/displaced(F)
|
||||
if(src.material)
|
||||
A.setMaterial(src.material)
|
||||
B.setMaterial(src.material)
|
||||
else
|
||||
var/datum/material/M = getCachedMaterial("steel")
|
||||
A.setMaterial(M)
|
||||
B.setMaterial(M)
|
||||
F.levelupdate()
|
||||
logTheThing("station", user, null, "dismantles a False Wall in [user.loc.loc] ([showCoords(user.x, user.y, user.z)])")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
// grabsmash
|
||||
else if (istype(S, /obj/item/grab/))
|
||||
var/obj/item/grab/G = S
|
||||
if (!grab_smash(G, user))
|
||||
return ..(S, user)
|
||||
else return
|
||||
else
|
||||
return src.attack_hand(user)
|
||||
|
||||
proc/open()
|
||||
if (src.operating)
|
||||
return 0
|
||||
src.operating = 1
|
||||
src.name = "false wall"
|
||||
animate(src, time = delay, pixel_x = 25, easing = BACK_EASING)
|
||||
spawn(delay)
|
||||
//we want to return 1 without waiting for the animation to finish - the textual cue seems sloppy if it waits
|
||||
//actually do the opening things
|
||||
src.density = 0
|
||||
src.blocks_air = 0
|
||||
src.pathable = 1
|
||||
src.update_air_properties()
|
||||
src.RL_SetOpacity(0)
|
||||
if(!floorintact)
|
||||
src.intact = 0
|
||||
src.levelupdate()
|
||||
if(checkForMultipleDoors())
|
||||
update_nearby_tiles()
|
||||
src.operating = 0
|
||||
return 1
|
||||
|
||||
proc/close()
|
||||
if (src.operating)
|
||||
return 0
|
||||
src.operating = 1
|
||||
src.name = "wall"
|
||||
animate(src, time = delay, pixel_x = 0, easing = BACK_EASING)
|
||||
src.density = 1
|
||||
src.blocks_air = 1
|
||||
src.pathable = 0
|
||||
src.update_air_properties()
|
||||
if (src.visible)
|
||||
src.RL_SetOpacity(1)
|
||||
src.intact = 1
|
||||
update_nearby_tiles()
|
||||
spawn(delay)
|
||||
//we want to return 1 without waiting for the animation to finish - the textual cue seems sloppy if it waits
|
||||
src.operating = 0
|
||||
return 1
|
||||
|
||||
proc/find_icon_state()
|
||||
if (!map_setting)
|
||||
return
|
||||
|
||||
//var/wall_path = /turf/simulated/wall/auto
|
||||
var/r_wall_path = /turf/simulated/wall/auto/reinforced
|
||||
if (map_setting == "COG2")
|
||||
icon = 'icons/turf/walls_supernorn.dmi'
|
||||
//wall_path = /turf/simulated/wall/auto/supernorn
|
||||
r_wall_path = /turf/simulated/wall/auto/reinforced/supernorn
|
||||
else if (map_setting == "DESTINY")
|
||||
icon = 'icons/turf/walls_destiny.dmi'
|
||||
//wall_path = /turf/simulated/wall/auto/gannets
|
||||
r_wall_path = /turf/simulated/wall/auto/reinforced/gannets
|
||||
else
|
||||
icon = 'icons/turf/walls_auto.dmi'
|
||||
|
||||
var/dirs = 0
|
||||
for (var/dir in cardinal)
|
||||
var/turf/T = get_step(src, dir)
|
||||
if (istype(T, /turf/simulated/wall/auto))
|
||||
// neither of us are reinforced
|
||||
if (!istype(T, r_wall_path) && !istype(src, /turf/simulated/wall/false_wall/reinforced))
|
||||
dirs |= dir
|
||||
// both of us are reinforced
|
||||
else if (istype(T, r_wall_path) && istype(src, /turf/simulated/wall/false_wall/reinforced))
|
||||
dirs |= dir
|
||||
src.icon_state = "[mod][num2text(dirs)]"
|
||||
return src.icon_state
|
||||
|
||||
get_desc()
|
||||
if (!src.density)
|
||||
return "It's a false wall. It's open."
|
||||
|
||||
//Temp false walls turn back to regular walls when closed.
|
||||
temp/New()
|
||||
..()
|
||||
spawn(11)
|
||||
src.open()
|
||||
|
||||
temp/close()
|
||||
if (src.operating)
|
||||
return 0
|
||||
src.operating = 1
|
||||
src.name = "wall"
|
||||
animate(src, time = delay, pixel_x = 0, easing = BACK_EASING)
|
||||
src.icon_state = "door1"
|
||||
src.density = 1
|
||||
src.blocks_air = 1
|
||||
src.pathable = 0
|
||||
src.update_air_properties()
|
||||
if (src.visible)
|
||||
src.opacity = 0
|
||||
src.RL_SetOpacity(1)
|
||||
src.intact = 1
|
||||
update_nearby_tiles()
|
||||
if(src.was_rwall)
|
||||
src.ReplaceWithRWall()
|
||||
else
|
||||
src.ReplaceWithWall()
|
||||
return 1
|
||||
@@ -0,0 +1,84 @@
|
||||
// wall formed by metal foams
|
||||
// dense and opaque, but easy to break
|
||||
|
||||
/obj/foamedmetal
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "metalfoam"
|
||||
density = 1
|
||||
opacity = 0 // changed in New()
|
||||
anchored = 1
|
||||
name = "foamed metal"
|
||||
desc = "A lightweight foamed metal wall."
|
||||
flags = FPRINT | CONDUCT | USEDELAY
|
||||
var/metal = 1 // 1=aluminium, 2=iron
|
||||
|
||||
New()
|
||||
..()
|
||||
|
||||
if(istype(loc, /turf/space))
|
||||
loc:ReplaceWithMetalFoam(metal)
|
||||
|
||||
update_nearby_tiles(1)
|
||||
spawn(1)
|
||||
RL_SetOpacity(1)
|
||||
|
||||
disposing()
|
||||
RL_SetOpacity(0)
|
||||
density = 0
|
||||
update_nearby_tiles(1)
|
||||
..()
|
||||
|
||||
proc/updateicon()
|
||||
if(metal == 1)
|
||||
icon_state = "metalfoam"
|
||||
else
|
||||
icon_state = "ironfoam"
|
||||
|
||||
|
||||
ex_act(severity)
|
||||
dispose()
|
||||
|
||||
blob_act(var/power)
|
||||
dispose()
|
||||
|
||||
bullet_act()
|
||||
if(metal==1 || prob(50))
|
||||
dispose()
|
||||
|
||||
attack_hand(var/mob/user)
|
||||
if (user.bioHolder.HasEffect("hulk") || (prob(75 - metal*25)))
|
||||
user.visible_message("<span style=\"color:red\">[user] smashes through the foamed metal.</span>")
|
||||
dispose()
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">You hit the metal foam but bounce off it.</span>")
|
||||
return
|
||||
|
||||
|
||||
attackby(var/obj/item/I, var/mob/user)
|
||||
|
||||
if (istype(I, /obj/item/grab))
|
||||
var/obj/item/grab/G = I
|
||||
G.affecting.set_loc(src.loc)
|
||||
src.visible_message("<span style=\"color:red\">[G.assailant] smashes [G.affecting] through the foamed metal wall.</span>")
|
||||
I.dispose()
|
||||
dispose()
|
||||
return
|
||||
|
||||
if(prob(I.force*20 - metal*25))
|
||||
user.visible_message( "<span style=\"color:red\">[user] smashes through the foamed metal.</span>", "<span style=\"color:blue\">You smash through the foamed metal with \the [I].</span>")
|
||||
dispose()
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">You hit the metal foam to no effect.</span>")
|
||||
|
||||
// only air group geometry can pass
|
||||
CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
return air_group
|
||||
|
||||
proc/update_nearby_tiles(need_rebuild)
|
||||
var/turf/simulated/source = loc
|
||||
if (istype(source))
|
||||
return source.update_nearby_tiles(need_rebuild)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -0,0 +1,392 @@
|
||||
/obj/grille
|
||||
desc = "A sturdy metal mesh. Blocks large objects, but lets small items, gas, or energy beams through."
|
||||
name = "grille"
|
||||
icon = 'icons/obj/grille.dmi'
|
||||
icon_state = "grille"
|
||||
density = 1
|
||||
var/health = 30
|
||||
var/health_max = 30
|
||||
var/ruined = 0
|
||||
var/blunt_resist = 0
|
||||
var/cut_resist = 0
|
||||
var/corrode_resist = 0
|
||||
var/temp_resist = 0
|
||||
var/shock_when_entered = 1
|
||||
anchored = 1
|
||||
flags = FPRINT | CONDUCT | USEDELAY
|
||||
pressure_resistance = 5*ONE_ATMOSPHERE
|
||||
layer = GRILLE_LAYER
|
||||
|
||||
New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
steel
|
||||
New()
|
||||
..()
|
||||
var/datum/material/M = getCachedMaterial("steel")
|
||||
src.setMaterial(M)
|
||||
|
||||
steel/broken
|
||||
desc = "Looks like its been in this sorry state for quite some time."
|
||||
icon_state = "grille-cut"
|
||||
ruined = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
damage_slashing(1000)
|
||||
update_icon()
|
||||
|
||||
catwalk
|
||||
name = "catwalk surface"
|
||||
icon_state = "catwalk"
|
||||
density = 0
|
||||
desc = "This doesn't look very safe at all!"
|
||||
layer = CATWALK_LAYER
|
||||
shock_when_entered = 0
|
||||
|
||||
onMaterialChanged()
|
||||
..()
|
||||
if (istype(src.material))
|
||||
health = material.hasProperty(PROP_TOUGHNESS) ? material.getProperty(PROP_TOUGHNESS) : health
|
||||
health_max = material.hasProperty(PROP_TOUGHNESS) ? material.getProperty(PROP_TOUGHNESS) : health_max
|
||||
cut_resist = material.hasProperty(PROP_SHEAR) ? material.getProperty(PROP_SHEAR) : cut_resist
|
||||
blunt_resist = material.hasProperty(PROP_COMPRESSIVE) ? material.getProperty(PROP_COMPRESSIVE) : blunt_resist
|
||||
corrode_resist = material.hasProperty(PROP_CORROSION) ? material.getProperty(PROP_CORROSION) : corrode_resist
|
||||
temp_resist = material.hasProperty(PROP_MELTING) ? material.getProperty(PROP_MELTING) : temp_resist
|
||||
if (blunt_resist != 0) blunt_resist /= 2
|
||||
|
||||
damage_blunt(var/amount)
|
||||
if (!isnum(amount) || amount <= 0)
|
||||
return
|
||||
|
||||
if (src.ruined)
|
||||
if (amount >= health_max / 2)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
var/armor = 0
|
||||
|
||||
if (src.material)
|
||||
armor = blunt_resist
|
||||
|
||||
if (src.material.quality >= 25)
|
||||
armor += src.material.quality * 0.25
|
||||
else if (src.quality < 10)
|
||||
armor = 0
|
||||
amount += rand(1,3)
|
||||
|
||||
amount -= armor
|
||||
|
||||
src.health = max(0,min(src.health - amount,src.health_max))
|
||||
if (src.health == 0)
|
||||
update_icon("cut")
|
||||
src.density = 0
|
||||
src.ruined = 1
|
||||
else
|
||||
update_icon()
|
||||
|
||||
damage_slashing(var/amount)
|
||||
if (!isnum(amount) || amount <= 0)
|
||||
return
|
||||
|
||||
if (src.ruined)
|
||||
drop_rods(1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
amount = get_damage_after_percentage_based_armor_reduction(cut_resist,amount)
|
||||
|
||||
src.health = max(0,min(src.health - amount,src.health_max))
|
||||
if (src.health == 0)
|
||||
drop_rods(1)
|
||||
update_icon("cut")
|
||||
src.density = 0
|
||||
src.ruined = 1
|
||||
else
|
||||
update_icon()
|
||||
|
||||
damage_corrosive(var/amount)
|
||||
if (!isnum(amount) || amount <= 0)
|
||||
return
|
||||
|
||||
if (src.ruined)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
amount = get_damage_after_percentage_based_armor_reduction(corrode_resist,amount)
|
||||
src.health = max(0,min(src.health - amount,src.health_max))
|
||||
if (src.health == 0)
|
||||
update_icon("corroded")
|
||||
src.density = 0
|
||||
src.ruined = 1
|
||||
else
|
||||
update_icon()
|
||||
|
||||
damage_heat(var/amount)
|
||||
if (!isnum(amount) || amount <= 0)
|
||||
return
|
||||
|
||||
if (src.ruined)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if (src.material)
|
||||
if (amount * 100000 <= temp_resist)
|
||||
// Not applying enough heat to melt it
|
||||
return
|
||||
|
||||
src.health = max(0,min(src.health - amount,src.health_max))
|
||||
if (src.health == 0)
|
||||
update_icon("melted")
|
||||
src.density = 0
|
||||
src.ruined = 1
|
||||
else
|
||||
update_icon()
|
||||
|
||||
meteorhit(var/obj/M)
|
||||
if (istype(M, /obj/newmeteor/massive))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
src.damage_blunt(5)
|
||||
|
||||
return
|
||||
|
||||
blob_act(var/power)
|
||||
src.damage_blunt(3 * power / 20)
|
||||
|
||||
ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
src.damage_blunt(40)
|
||||
src.damage_heat(40)
|
||||
|
||||
if(2.0)
|
||||
src.damage_blunt(15)
|
||||
src.damage_heat(15)
|
||||
|
||||
if(3.0)
|
||||
src.damage_blunt(7)
|
||||
src.damage_heat(7)
|
||||
return
|
||||
|
||||
reagent_act(var/reagent_id,var/volume)
|
||||
if (..())
|
||||
return
|
||||
switch(reagent_id)
|
||||
if("acid")
|
||||
damage_corrosive(volume / 2)
|
||||
if("pacid")
|
||||
damage_corrosive(volume)
|
||||
if("napalm")
|
||||
damage_heat(volume)
|
||||
if("infernite")
|
||||
damage_heat(volume * 2)
|
||||
if("foof")
|
||||
damage_heat(volume * 3)
|
||||
|
||||
hitby(AM as mob|obj)
|
||||
..()
|
||||
src.visible_message("<span style=\"color:red\"><B>[src] was hit by [AM].</B></span>")
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
|
||||
if (ismob(AM))
|
||||
damage_blunt(5)
|
||||
else if (isobj(AM))
|
||||
var/obj/O = AM
|
||||
if (O.throwforce)
|
||||
damage_blunt(max(1, round(O.throwforce / 3, 1))) // we don't want people screaming right through these and you can still get through them by kicking/cutting/etc
|
||||
return
|
||||
|
||||
attack_hand(obj/M, mob/user)
|
||||
if(!shock(usr, 70))
|
||||
var/damage = 1
|
||||
var/dam_type = "blunt"
|
||||
var/text = "[usr.kickMessage] [src]"
|
||||
|
||||
if (usr.bioHolder && usr.bioHolder.HasEffect("hulk") && damage < 5)
|
||||
damage = 10
|
||||
text = "smashes [src] with incredible strength"
|
||||
|
||||
src.visible_message("<span style=\"color:red\"><b>[usr]</b> [text]!</span>")
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 80, 1)
|
||||
|
||||
if (dam_type == "slashing")
|
||||
damage_slashing(damage)
|
||||
else
|
||||
damage_blunt(damage)
|
||||
|
||||
attackby(obj/item/W, mob/user)
|
||||
// Things that won't electrocute you
|
||||
|
||||
if (istype(W,/obj/item/device/multitool) || istype(W, /obj/item/device/t_scanner))
|
||||
var/net = get_connection()
|
||||
if(!net)
|
||||
boutput(user, "<span style=\"color:blue\">No electrical current detected.</span>")
|
||||
else
|
||||
boutput(user, "<span style=\"color:red\">CAUTION: Dangerous electrical current detected.</span>")
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/sheet/))
|
||||
var/obj/item/sheet/S = W
|
||||
if (S.material && S.material.material_flags & MATERIAL_CRYSTAL)
|
||||
var/obj/window/WI
|
||||
var/win_thin = 0
|
||||
var/win_dir = 2
|
||||
var/turf/UT = get_turf(user)
|
||||
var/turf/ST = get_turf(src)
|
||||
|
||||
if (UT && isturf(UT) && ST && isturf(ST))
|
||||
// We're inside the grill.
|
||||
if (UT == ST)
|
||||
win_dir = usr.dir
|
||||
win_thin = 1
|
||||
// We're trying to install a window while standing on an adjacent tile, so make it face the mob.
|
||||
else
|
||||
win_dir = turn(usr.dir, 180)
|
||||
if (win_dir in list(NORTH, EAST, SOUTH, WEST))
|
||||
win_thin = 1
|
||||
|
||||
if (ST && isturf(ST))
|
||||
if (S.reinforcement)
|
||||
if (map_setting && map_setting == "COG2" && win_thin == 0)
|
||||
WI = new /obj/window/auto/reinforced(ST)
|
||||
else
|
||||
WI = new /obj/window/reinforced(ST)
|
||||
else
|
||||
if (map_setting && map_setting == "COG2" && win_thin == 0)
|
||||
WI = new /obj/window/auto(ST)
|
||||
else
|
||||
WI = new /obj/window(ST)
|
||||
|
||||
if (WI && istype(WI))
|
||||
if (S.material)
|
||||
WI.setMaterial(S.material)
|
||||
WI.dir = win_dir
|
||||
WI.ini_dir = win_dir
|
||||
else
|
||||
user.show_text("<b>Error:</b> Couldn't spawn window. Try again and please inform a coder if the problem persists.", "red")
|
||||
return
|
||||
|
||||
S.amount--
|
||||
if (S.amount < 1)
|
||||
qdel(S)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
// electrocution check
|
||||
|
||||
var/OSHA_is_crying = 1
|
||||
if ((src.material && src.material.getProperty(PROP_ELECTRICAL) < 40))// fucka you || istype(W,/obj/item/raw_material/shard))
|
||||
OSHA_is_crying = 0
|
||||
|
||||
if (OSHA_is_crying && shock(user, 100))
|
||||
return
|
||||
|
||||
// Things that will electrocute you
|
||||
|
||||
if (istype(W, /obj/item/wirecutters))
|
||||
damage_slashing(src.health_max)
|
||||
src.visible_message("<span style=\"color:red\"><b>[usr]</b> cuts apart the [src] with [W].</span>")
|
||||
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
|
||||
|
||||
else if ((istype(W, /obj/item/screwdriver) && (istype(src.loc, /turf/simulated) || src.anchored)))
|
||||
playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
src.anchored = !( src.anchored )
|
||||
src.visible_message("<span style=\"color:red\"><b>[usr]</b> [src.anchored ? "fastens" : "unfastens"] [src].</span>")
|
||||
return
|
||||
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\"><b>[usr]</b> attacks [src] with [W].</span>")
|
||||
playsound(src.loc, 'sound/effects/grillehit.ogg', 80, 1)
|
||||
switch(W.damtype)
|
||||
if("fire")
|
||||
damage_heat(W.force)
|
||||
if("brute")
|
||||
damage_blunt(W.force * 0.5)
|
||||
return
|
||||
|
||||
proc/update_icon(var/special_icon_state)
|
||||
if (ruined)
|
||||
return
|
||||
|
||||
if (istext(special_icon_state))
|
||||
icon_state = initial(icon_state) + "-" + special_icon_state
|
||||
else
|
||||
var/diff = get_x_percentage_of_y(health,health_max)
|
||||
switch(diff)
|
||||
if(-INFINITY to 25)
|
||||
icon_state = initial(icon_state) + "-3"
|
||||
if(26 to 50)
|
||||
icon_state = initial(icon_state) + "-2"
|
||||
if(51 to 75)
|
||||
icon_state = initial(icon_state) + "-1"
|
||||
if(76 to INFINITY)
|
||||
icon_state = initial(icon_state) + "-0"
|
||||
|
||||
proc/drop_rods(var/amount)
|
||||
if (!isnum(amount))
|
||||
return
|
||||
var/obj/item/rods/R = new /obj/item/rods(get_turf(src))
|
||||
R.amount = amount
|
||||
if(src.material)
|
||||
R.setMaterial(src.material)
|
||||
else
|
||||
var/datum/material/M = getCachedMaterial("steel")
|
||||
R.setMaterial(M)
|
||||
|
||||
proc/get_connection()
|
||||
//returns the netnum of a stub cable at this grille loc, or 0 if none
|
||||
var/turf/T = src.loc
|
||||
if(!istype(T, /turf/simulated/floor))
|
||||
return
|
||||
|
||||
for(var/obj/cable/C in T)
|
||||
if(C.d1 == 0)
|
||||
return C.netnum
|
||||
|
||||
return 0
|
||||
|
||||
proc/shock(mob/user, prb, var/ignore_gloves = 0)
|
||||
// shock user with probability prb (if all connections & power are working)
|
||||
// returns 1 if shocked, 0 otherwise
|
||||
|
||||
if (!anchored)// || ruined) // allowing ruined grilles to still be connected so people have to move carefully through them
|
||||
// unanchored/ruined grilles are never connected
|
||||
return 0
|
||||
|
||||
if (!prob(prb))
|
||||
return 0
|
||||
|
||||
var/net = get_connection()
|
||||
// find the powernet of the connected cable
|
||||
|
||||
if (!net)
|
||||
// cable is unpowered
|
||||
return 0
|
||||
|
||||
return src.electrocute(user, prb, net, ignore_gloves)
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
if (istype(mover, /obj/projectile))
|
||||
if (density)
|
||||
return prob(50)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
HasEntered(AM as mob|obj)
|
||||
..()
|
||||
if (src.shock_when_entered)
|
||||
if (ismob(AM))
|
||||
if (!isliving(AM) || isintangible(AM)) // I assume this was left out by accident (Convair880).
|
||||
return
|
||||
var/mob/M = AM
|
||||
if (M.client && M.client.flying) // noclip
|
||||
return
|
||||
var/s_chance = 10
|
||||
if (M.m_intent != "walk") // move carefully
|
||||
s_chance += 50
|
||||
if (shock(M, s_chance, rand(0,1))) // you get a 50/50 shot to accidentally touch the grille with something other than your hands
|
||||
M.show_text("<b>You brush against [src] while moving past it and it shocks you!</b>", "red")
|
||||
@@ -0,0 +1,127 @@
|
||||
|
||||
/obj/health_scanner
|
||||
icon = 'icons/obj/device.dmi'
|
||||
anchored = 1
|
||||
var/reagent_upgrade = 0
|
||||
var/reagent_scan = 0
|
||||
var/id = 0.0 // who are we?
|
||||
var/list/partners = list() // who do we know?
|
||||
var/partner_range = 3 // how far away should we look?
|
||||
var/find_in_range = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(5)
|
||||
src.find_partners(src.find_in_range)
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/device/multitool))
|
||||
var/new_id = input(user, "Please enter new ID", src.name, src.id) as null|text
|
||||
if (!new_id || new_id == src.id)
|
||||
return
|
||||
src.id = new_id
|
||||
boutput(user, "You change [src]'s ID to [new_id].")
|
||||
src.find_partners()
|
||||
else if (istype(W, /obj/item/device/healthanalyzer_upgrade))
|
||||
src.update_reagent_scan()
|
||||
if (src.reagent_upgrade)
|
||||
boutput(user, "<span style=\"color:red\">This system already has a reagent scan upgrade!</span>")
|
||||
return
|
||||
else
|
||||
src.reagent_upgrade = 1
|
||||
src.reagent_scan = 1
|
||||
src.update_reagent_scan()
|
||||
boutput(user, "<span style=\"color:blue\">Reagent scan upgrade installed.</span>")
|
||||
playsound(src.loc ,"sound/items/Deconstruct.ogg", 80, 0)
|
||||
qdel(W)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
proc/find_partners(var/in_range = 0)
|
||||
return // dummy proc that the scanner and screen will define themselves
|
||||
|
||||
proc/accept_partner(var/obj/health_scanner/H)
|
||||
if (!H)
|
||||
return
|
||||
if (locate(H) in src.partners)
|
||||
return
|
||||
src.partners += H
|
||||
|
||||
proc/update_reagent_scan()
|
||||
if (!src.partners || !src.partners.len)
|
||||
return
|
||||
for (var/obj/health_scanner/myPartner in src.partners)
|
||||
if (src.reagent_upgrade && !myPartner.reagent_upgrade)
|
||||
myPartner.reagent_upgrade = 1
|
||||
else if (myPartner.reagent_upgrade && !src.reagent_upgrade)
|
||||
src.reagent_upgrade = 1
|
||||
if (src.reagent_scan && !myPartner.reagent_scan)
|
||||
myPartner.reagent_scan = 1
|
||||
else if (myPartner.reagent_scan && !src.reagent_scan)
|
||||
src.reagent_scan = 1
|
||||
|
||||
/obj/health_scanner/wall
|
||||
name = "health status screen"
|
||||
desc = "A screen that shows health information recieved from connected floor scanners."
|
||||
icon_state = "wallscan1"
|
||||
|
||||
find_partners(var/in_range = 0)
|
||||
src.partners = list()
|
||||
if (in_range)
|
||||
for (var/obj/health_scanner/floor/possible_partner in orange(src.partner_range, src))
|
||||
if (locate(possible_partner) in src.partners)
|
||||
continue
|
||||
src.partners += possible_partner
|
||||
possible_partner.accept_partner(src)
|
||||
for (var/obj/health_scanner/floor/possible_partner in world)
|
||||
if (locate(possible_partner) in src.partners)
|
||||
continue
|
||||
if (possible_partner.id == src.id)
|
||||
src.partners += possible_partner
|
||||
possible_partner.accept_partner(src)
|
||||
|
||||
proc/scan()
|
||||
if (!src.partners || !src.partners.len)
|
||||
return "<font color='red'>ERROR: NO CONNECTED SCANNERS</font>"
|
||||
var/data = null
|
||||
for (var/obj/health_scanner/floor/myPartner in src.partners)
|
||||
for (var/mob/M in get_turf(myPartner))
|
||||
data += "<br>[scan_health(M, src.reagent_scan)]"
|
||||
return data
|
||||
|
||||
get_desc(dist)
|
||||
if (dist > 2 && !issilicon(usr))
|
||||
. += "<br>It's too far away to see what it says.[prob(10) ? " Who decided the text should be <i>that</i> small?!" : null]"
|
||||
else
|
||||
var/data = src.scan()
|
||||
if (data)
|
||||
. += "<br>It says:[data]"
|
||||
else
|
||||
. += "<br>It says:<br><font color='red'>ERROR: NO SUBJECT(S) DETECTED</font>"
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
return src.examine()
|
||||
|
||||
attack_ai(mob/user as mob)
|
||||
return src.examine()
|
||||
|
||||
/obj/health_scanner/floor
|
||||
name = "health scanner"
|
||||
desc = "An in-floor health scanner that sends its data to connected status screens."
|
||||
icon_state = "floorscan1"
|
||||
|
||||
find_partners(var/in_range = 0)
|
||||
src.partners = list()
|
||||
if (in_range)
|
||||
for (var/obj/health_scanner/wall/possible_partner in orange(src.partner_range, src))
|
||||
if (locate(possible_partner) in src.partners)
|
||||
continue
|
||||
src.partners += possible_partner
|
||||
possible_partner.accept_partner(src)
|
||||
for (var/obj/health_scanner/wall/possible_partner in world)
|
||||
if (locate(possible_partner) in src.partners)
|
||||
continue
|
||||
if (possible_partner.id == src.id)
|
||||
src.partners += possible_partner
|
||||
possible_partner.accept_partner(src)
|
||||
@@ -0,0 +1,35 @@
|
||||
/obj/hud
|
||||
name = "hud"
|
||||
anchored = 1
|
||||
var/mob/mymob = null
|
||||
var/list/adding = null
|
||||
var/list/other = null
|
||||
var/list/intents = null
|
||||
var/list/mov_int = null
|
||||
var/list/mon_blo = null
|
||||
var/list/m_ints = null
|
||||
var/list/darkMask = null
|
||||
|
||||
var/h_type = /obj/screen
|
||||
|
||||
obj/hud/New(var/type = 0)
|
||||
src.instantiate(type)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/hud/var/show_otherinventory = 1
|
||||
/obj/hud/var/obj/screen/action_intent
|
||||
/obj/hud/var/obj/screen/move_intent
|
||||
|
||||
/obj/hud/proc/instantiate(var/type = 0)
|
||||
|
||||
mymob = src.loc
|
||||
ASSERT(istype(mymob, /mob))
|
||||
|
||||
if(istype(mymob, /mob/living/silicon/hivebot))
|
||||
src.hivebot_hud()
|
||||
return
|
||||
|
||||
if (istype(mymob, /mob/living/object))
|
||||
src.object_hud()
|
||||
return
|
||||
@@ -0,0 +1,199 @@
|
||||
|
||||
/obj/hud/proc/hivebot_hud()
|
||||
var/mob/living/silicon/hivebot/myhive = mymob
|
||||
|
||||
src.adding = list( )
|
||||
src.other = list( )
|
||||
src.intents = list( )
|
||||
src.mon_blo = list( )
|
||||
src.m_ints = list( )
|
||||
src.mov_int = list( )
|
||||
src.darkMask = list( )
|
||||
|
||||
var/obj/screen/using
|
||||
|
||||
|
||||
//Radio
|
||||
using = new src.h_type( src )
|
||||
using.name = "radio"
|
||||
using.dir = SOUTHWEST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "radio"
|
||||
using.screen_loc = ui_movi
|
||||
using.layer = HUD_LAYER
|
||||
src.adding += using
|
||||
|
||||
//Generic overlays
|
||||
|
||||
using = new src.h_type(src) //Right hud bar
|
||||
using.dir = SOUTH
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.screen_loc = "EAST+1,SOUTH to EAST+1,NORTH"
|
||||
using.layer = HUD_LAYER_UNDER_1
|
||||
src.adding += using
|
||||
|
||||
using = new src.h_type(src) //Lower hud bar
|
||||
using.dir = EAST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.screen_loc = "WEST,SOUTH-1 to EAST,SOUTH-1"
|
||||
using.layer = HUD_LAYER_UNDER_1
|
||||
src.adding += using
|
||||
|
||||
using = new src.h_type(src) //Corner Button
|
||||
using.dir = NORTHWEST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.screen_loc = "EAST+1,SOUTH-1"
|
||||
using.layer = HUD_LAYER_UNDER_1
|
||||
src.adding += using
|
||||
|
||||
|
||||
//Module select
|
||||
|
||||
using = new src.h_type( src )
|
||||
using.name = "module1"
|
||||
using.dir = SOUTHWEST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "inv1"
|
||||
using.screen_loc = ui_inv1
|
||||
using.layer = HUD_LAYER
|
||||
src.adding += using
|
||||
myhive:inv1 = using
|
||||
|
||||
using = new src.h_type( src )
|
||||
using.name = "module2"
|
||||
using.dir = SOUTHWEST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "inv2"
|
||||
using.screen_loc = ui_inv2
|
||||
using.layer = HUD_LAYER
|
||||
src.adding += using
|
||||
myhive:inv2 = using
|
||||
|
||||
using = new src.h_type( src )
|
||||
using.name = "module3"
|
||||
using.dir = SOUTHWEST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "inv3"
|
||||
using.screen_loc = ui_inv3
|
||||
using.layer = HUD_LAYER
|
||||
src.adding += using
|
||||
myhive:inv3 = using
|
||||
|
||||
//End of module select
|
||||
|
||||
//Intent
|
||||
using = new src.h_type( src )
|
||||
using.name = "act_intent"
|
||||
using.dir = SOUTHWEST
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = (myhive.a_intent == "harm" ? "harm" : myhive.a_intent)
|
||||
using.screen_loc = ui_acti
|
||||
using.layer = HUD_LAYER
|
||||
src.adding += using
|
||||
action_intent = using
|
||||
/*
|
||||
using = new src.h_type( src )
|
||||
using.name = "arrowleft"
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "s_arrow"
|
||||
using.dir = WEST
|
||||
using.screen_loc = ui_iarrowleft
|
||||
using.layer = 19
|
||||
src.adding += using
|
||||
|
||||
using = new src.h_type( src )
|
||||
using.name = "arrowright"
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "s_arrow"
|
||||
using.dir = EAST
|
||||
using.screen_loc = ui_iarrowright
|
||||
using.layer = 19
|
||||
src.adding += using
|
||||
*/
|
||||
//End of Intent
|
||||
|
||||
//Cell
|
||||
myhive:cells = new /obj/screen( null )
|
||||
myhive:cells.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive:cells.icon_state = "charge-empty"
|
||||
myhive:cells.name = "cell"
|
||||
myhive:cells.screen_loc = ui_cell
|
||||
|
||||
//Health
|
||||
myhive.healths = new /obj/screen( null )
|
||||
myhive.healths.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive.healths.icon_state = "health0"
|
||||
myhive.healths.name = "health"
|
||||
myhive.healths.screen_loc = ui_bothealth
|
||||
|
||||
//Installed Module
|
||||
myhive.hands = new /obj/screen( null )
|
||||
myhive.hands.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive.hands.icon_state = "nomod"
|
||||
myhive.hands.name = "module"
|
||||
myhive.hands.screen_loc = ui_module
|
||||
|
||||
//Module Panel
|
||||
using = new src.h_type( src )
|
||||
using.name = "panel"
|
||||
using.icon = 'icons/mob/screen1_robot.dmi'
|
||||
using.icon_state = "panel"
|
||||
using.screen_loc = ui_panel
|
||||
using.layer = HUD_LAYER_UNDER_1
|
||||
src.adding += using
|
||||
|
||||
//Store
|
||||
myhive.throw_icon = new /obj/screen(null)
|
||||
myhive.throw_icon.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive.throw_icon.icon_state = "store"
|
||||
myhive.throw_icon.name = "store"
|
||||
myhive.throw_icon.screen_loc = ui_botstore
|
||||
|
||||
//Temp
|
||||
myhive.bodytemp = new /obj/screen( null )
|
||||
myhive.bodytemp.icon_state = "temp0"
|
||||
myhive.bodytemp.name = "body temperature"
|
||||
myhive.bodytemp.screen_loc = ui_bottemp
|
||||
|
||||
//does nothing (fire and oxy)
|
||||
myhive.oxygen = new /obj/screen( null )
|
||||
myhive.oxygen.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive.oxygen.icon_state = "oxy0"
|
||||
myhive.oxygen.name = "oxygen"
|
||||
myhive.oxygen.screen_loc = ui_boto2
|
||||
|
||||
|
||||
myhive.pullin = new /obj/screen( null )
|
||||
myhive.pullin.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive.pullin.icon_state = "pull0"
|
||||
myhive.pullin.name = "pull"
|
||||
myhive.pullin.screen_loc = ui_botpull
|
||||
|
||||
/*
|
||||
myhive.rest = new /obj/screen( null )
|
||||
myhive.rest.icon = 'icons/mob/screen1_robot.dmi'
|
||||
myhive.rest.icon_state = "rest0"
|
||||
myhive.rest.name = "rest"
|
||||
myhive.rest.screen_loc = ui_rest
|
||||
*/
|
||||
myhive.zone_sel = new(myhive, "EAST-4, SOUTH-1")
|
||||
myhive.attach_hud(myhive.zone_sel)
|
||||
|
||||
myhive.client.screen = null
|
||||
|
||||
myhive.throw_icon.add_to_client(myhive.client)
|
||||
//myhive.zone_sel.add_to_client(myhive.client)
|
||||
myhive.oxygen.add_to_client(myhive.client)
|
||||
myhive.hands.add_to_client(myhive.client)
|
||||
myhive.healths.add_to_client(myhive.client)
|
||||
myhive:cells.add_to_client(myhive.client)
|
||||
myhive.pullin.add_to_client(myhive.client)
|
||||
|
||||
for(var/obj/screen/O in adding)
|
||||
O.add_to_client(myhive.client)
|
||||
|
||||
for(var/obj/screen/O in other)
|
||||
O.add_to_client(myhive.client)
|
||||
|
||||
|
||||
return
|
||||
@@ -0,0 +1,41 @@
|
||||
/obj/screen/release
|
||||
name = "Release object"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "x"
|
||||
screen_loc = "NORTH,EAST"
|
||||
layer = HUD_LAYER
|
||||
var/mob/living/object/owner = null
|
||||
|
||||
New()
|
||||
..()
|
||||
underlays += image('icons/mob/screen1.dmi', "block")
|
||||
|
||||
clicked(params)
|
||||
..()
|
||||
if (owner)
|
||||
owner.death(0)
|
||||
|
||||
//WIRE TOOLTIPS
|
||||
MouseEntered(location, control, params)
|
||||
usr.client.tooltip.show(src, params, title = src.name, content = (src.desc ? src.desc : null))
|
||||
|
||||
MouseExited()
|
||||
usr.client.tooltip.hide()
|
||||
|
||||
/obj/hud/proc/object_hud()
|
||||
mymob.zone_sel = new(mymob, "SOUTH,EAST")
|
||||
mymob.attach_hud(mymob.zone_sel)
|
||||
|
||||
mymob.i_select = new /obj/screen/intent_sel( src )
|
||||
mymob.i_select.name = "intent"
|
||||
mymob.i_select.icon_state = (mymob.a_intent == "harm" ? "harm" : mymob.a_intent)
|
||||
mymob.i_select.screen_loc = "SOUTH,EAST-1"
|
||||
mymob.i_select.layer = HUD_LAYER
|
||||
|
||||
if (mymob.client)
|
||||
mymob.client.screen = null
|
||||
|
||||
mymob.i_select.add_to_client(mymob.client)
|
||||
//mymob.zone_sel.add_to_client(mymob.client)
|
||||
var/mob/living/object/O = mymob
|
||||
mymob.client.screen += O.release
|
||||
@@ -0,0 +1,723 @@
|
||||
/obj/item
|
||||
name = "item"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
var/movement_speed_mod = 0
|
||||
var/icon_old = null
|
||||
var/abstract = 0.0
|
||||
var/force = null
|
||||
var/item_state = null
|
||||
var/damtype = "brute"
|
||||
var/hit_type = DAMAGE_BLUNT // for bleeding system things, options: DAMAGE_BLUNT, DAMAGE_CUT, DAMAGE_STAB in order of how much it affects the chances to increase bleeding
|
||||
throwforce = 4
|
||||
var/r_speed = 1.0
|
||||
var/health = 4 // burn faster
|
||||
var/burn_point = 15000 // this already exists but nothing uses it???
|
||||
var/burn_possible = 1 //cogwerks fire project - can object catch on fire - let's have all sorts of shit burn at hellish temps
|
||||
var/burn_output = 1500 //how hot should it burn
|
||||
var/burn_type = 0 // 0 = ash, 1 = melt
|
||||
var/burning = null
|
||||
var/hitsound = 'sound/weapons/genhit1.ogg'
|
||||
var/w_class = 3.0
|
||||
var/cant_self_remove = 0 //Can't remove from non-hand slots
|
||||
var/cant_other_remove = 0 //Can't be removed from non-hand slots by others
|
||||
var/cant_drop = 0 //Cant' be removed in general. I guess.
|
||||
flags = FPRINT | TABLEPASS
|
||||
pressure_resistance = 50
|
||||
var/obj/item/master = null
|
||||
var/numattacks = 1
|
||||
var/amount = 1
|
||||
var/max_stack = 1
|
||||
var/stack_type = null // if null, only current type. otherwise uses this
|
||||
var/contraband = 0 //If nonzero, bots consider this a thing people shouldn't be carrying without authorization
|
||||
|
||||
var/image/wear_image = null
|
||||
var/wear_image_icon = 'icons/mob/belt.dmi'
|
||||
var/image/inhand_image = null
|
||||
var/inhand_image_icon = 'icons/mob/inhand/hand_general.dmi'
|
||||
|
||||
var/arm_icon = "" //set to an icon state in human.dmi minus _s/_l and l_arm_/r_arm_ to allow use as an arm
|
||||
var/over_clothes = 0 //draw over clothes when used as a limb
|
||||
var/override_attack_hand = 1 //when used as an arm, attack with item rather than using attack_hand
|
||||
var/can_hold_items = 0 //when used as an arm, can it hold things?
|
||||
|
||||
var/stamina_damage = STAMINA_ITEM_DMG //amount of stamina removed from target per hit.
|
||||
var/stamina_cost = STAMINA_ITEM_COST //amount of stamina removed from USER per hit. This cant bring you below 10 points and you will not be able to attack if it would.
|
||||
var/stamina_crit_chance = STAMINA_CRIT_CHANCE //Crit chance when attacking with this.
|
||||
|
||||
var/list/module_research = list()
|
||||
var/module_research_type = null
|
||||
var/module_research_no_diminish = 0
|
||||
|
||||
var/edible = 0 // can you eat the thing?
|
||||
|
||||
var/duration_put = -1 //If set to something other than -1 these will control
|
||||
var/duration_remove = -1 //how long it takes to remove or put the item onto a person. 1/10ths of a second.
|
||||
|
||||
var/rand_pos = 0
|
||||
var/useInnerItem = 0 //Should this item use a contained item (in contents) to attack with instead?
|
||||
|
||||
onMaterialChanged()
|
||||
..()
|
||||
if (istype(src.material))
|
||||
stamina_damage = initial(stamina_damage) + (material.hasProperty(PROP_COMPRESSIVE) ? round(material.getProperty(PROP_COMPRESSIVE) / 8) : -4)
|
||||
stamina_crit_chance = initial(stamina_crit_chance) + (material.hasProperty(PROP_HARDNESS) ? round(material.getProperty(PROP_HARDNESS) / 8) : -5)
|
||||
force = material.hasProperty(PROP_HARDNESS) ? round(material.getProperty(PROP_HARDNESS) / 3) : force
|
||||
burn_point = material.hasProperty(PROP_MELTING) ? material.getProperty(PROP_MELTING) : burn_point
|
||||
burn_output = initial(burn_output) + (100 * src.material.getProperty(PROP_FLAMMABILITY)) + (100 * src.material.getProperty(PROP_ENERGY))
|
||||
burn_possible = src.material.getProperty(PROP_FLAMMABILITY) ? 1 : 0
|
||||
|
||||
if (src.material.material_flags & MATERIAL_METAL || src.material.material_flags & MATERIAL_CRYSTAL || src.material.material_flags & MATERIAL_RUBBER)
|
||||
burn_type = 1
|
||||
else
|
||||
burn_type = 0
|
||||
return
|
||||
|
||||
|
||||
/obj/item/New()
|
||||
// this is dumb but it won't let me initialize vars to image() for some reason
|
||||
wear_image = image(wear_image_icon)
|
||||
inhand_image = image(inhand_image_icon)
|
||||
if (src.rand_pos)
|
||||
if (!src.pixel_x) // just in case
|
||||
src.pixel_x = rand(-8,8)
|
||||
if (!src.pixel_y) // same as above
|
||||
src.pixel_y = rand(-8,8)
|
||||
..()
|
||||
|
||||
/obj/item/proc/Eat(var/mob/M as mob, var/mob/user)
|
||||
if (!src.edible)
|
||||
return 0
|
||||
if (!iscarbon(M) && !istype(M, /mob/living/critter))
|
||||
return 0
|
||||
|
||||
if (M == user)
|
||||
M.visible_message("<span style=\"color:blue\">[M] takes a bite of [src]!</span>",\
|
||||
"<span style=\"color:blue\">You take a bite of [src]!</span>")
|
||||
|
||||
if (src.reagents && src.reagents.total_volume)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
spawn (5) // Necessary.
|
||||
src.reagents.trans_to(M, src.reagents.total_volume/src.amount)
|
||||
|
||||
playsound(M.loc,"sound/items/eatfood.ogg", rand(10, 50), 1)
|
||||
spawn (10)
|
||||
// Why not, I guess. Adds a bit of flavour (Convair880).
|
||||
if (iswerewolf(M) && istype(src, /obj/item/organ/))
|
||||
M.show_text("Mmmmm, tasty organs. How refreshing.", "blue")
|
||||
M.HealDamage("All", 5, 5)
|
||||
|
||||
M.visible_message("<span style=\"color:red\">[M] finishes eating [src].</span>",\
|
||||
"<span style=\"color:red\">You finish eating [src].</span>")
|
||||
user.u_equip(src)
|
||||
qdel(src)
|
||||
|
||||
return 1
|
||||
else
|
||||
user.tri_message("<span style=\"color:red\"><b>[user]</b> tries to feed [M] [src]!</span>",\
|
||||
user, "<span style=\"color:red\">You try to feed [M] [src]!</span>",\
|
||||
M, "<span style=\"color:red\"><b>[user]</b> tries to feed you [src]!</span>")
|
||||
logTheThing("combat", user, M, "attempts to feed %target% [src] [log_reagents(src)]")
|
||||
|
||||
if (!do_mob(user, M))
|
||||
return
|
||||
user.tri_message("<span style=\"color:red\"><b>[user]</b> feeds [M] [src]!</span>",\
|
||||
user, "<span style=\"color:red\">You feed [M] [src]!</span>",\
|
||||
M, "<span style=\"color:red\"><b>[user]</b> feeds you [src]!</span>")
|
||||
logTheThing("combat", user, M, "feeds %target% [src] [log_reagents(src)]")
|
||||
|
||||
if (src.reagents && src.reagents.total_volume)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
spawn (5) // Necessary.
|
||||
src.reagents.trans_to(M, src.reagents.total_volume)
|
||||
|
||||
playsound(M.loc, "sound/items/eatfood.ogg", rand(10, 50), 1)
|
||||
spawn (10)
|
||||
// Ditto (Convair880).
|
||||
if (iswerewolf(M) && istype(src, /obj/item/organ/))
|
||||
M.show_text("Mmmmm, tasty organs. How refreshing.", "blue")
|
||||
M.HealDamage("All", 5, 5)
|
||||
|
||||
M.visible_message("<span style=\"color:red\">[M] finishes eating [src].</span>",\
|
||||
"<span style=\"color:red\">You finish eating [src].</span>")
|
||||
user.u_equip(src)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/obj/item/proc/take_damage(brute, burn, tox, disallow_limb_loss)
|
||||
// this is a helper for organs and limbs
|
||||
return 0
|
||||
|
||||
/obj/item/proc/heal_damage(brute, burn, tox)
|
||||
// this is a helper for organs and limbs
|
||||
return 0
|
||||
|
||||
/obj/item/proc/get_damage()
|
||||
// this is a helper for organs and limbs
|
||||
return 0
|
||||
|
||||
/obj/item/proc/equipment_click(var/atom/target, var/atom/user) //Is called together with attackby and afterattack on items the MOB is wearing. Only works for mob/living/carbon s.
|
||||
return //Can be treated as afterattack that is called on all equiped items, basically. This is not restricted by LOS or anything
|
||||
//You'll have to check for that yourself if you need it.
|
||||
|
||||
/*
|
||||
var/icon/overlay = icon('icons/effects/96x96.dmi',"smoke")
|
||||
if (color)
|
||||
overlay.Blend(color,ICON_MULTIPLY)
|
||||
var/image/I = image(overlay)
|
||||
I.pixel_x = -32
|
||||
I.pixel_y = -32
|
||||
|
||||
var/the_dir = NORTH
|
||||
for(var/i=0, i<8, i++)
|
||||
var/obj/chem_smoke/C = new/obj/chem_smoke(location, holder, max_vol)
|
||||
C.overlays += I
|
||||
if (rname) C.name = "[rname] smoke"
|
||||
spawn(0)
|
||||
var/my_dir = the_dir
|
||||
var/my_time = rand(80,110)
|
||||
var/my_range = 3
|
||||
spawn(my_time) qdel(C)
|
||||
for(var/b=0, b<my_range, b++)
|
||||
sleep(15)
|
||||
if (!C) break
|
||||
step(C,my_dir)
|
||||
C.expose()
|
||||
the_dir = turn(the_dir,45)
|
||||
*/
|
||||
|
||||
/obj/item/proc/combust() // cogwerks- flammable items project
|
||||
if (!src.burning)
|
||||
src.visible_message("<span style=\"color:red\">[src] catches on fire!</span>")
|
||||
src.burning = 1
|
||||
if (src.burn_output >= 1000)
|
||||
src.overlays += image('icons/effects/fire.dmi', "2old")
|
||||
else
|
||||
src.overlays += image('icons/effects/fire.dmi', "1old")
|
||||
/*if (src.reagents && src.reagents.reagent_list && src.reagents.reagent_list.len)
|
||||
|
||||
//boutput(world, "<span style=\"color:red\"><b>[src] is releasing chemsmoke!</b></span>")
|
||||
//cogwerks note for drsingh: this was causing infinite server-killing problems
|
||||
//someone brought a couple pieces of cheese into chemistry
|
||||
//chlorine trifluoride foam set the cheese on fire causing it to releasee cheese smoke
|
||||
//creating a dozen more cheeses on the floor
|
||||
//which would catch on fire, releasing more cheese smoke
|
||||
//i'm sure you can see where that is going
|
||||
//this will happen with any reagents that create more reagent-containing items on turf reactions
|
||||
var/location = get_turf(src)
|
||||
var/max_vol = reagents.maximum_volume
|
||||
var/rname = reagents.get_master_reagent_name()
|
||||
var/color = reagents.get_master_color(1)
|
||||
var/icon/overlay = icon('icons/effects/96x96.dmi',"smoke")
|
||||
if (color)
|
||||
overlay.Blend(color,ICON_MULTIPLY)
|
||||
var/image/I = image(overlay)
|
||||
I.pixel_x = -32
|
||||
I.pixel_y = -32
|
||||
|
||||
var/the_dir = NORTH
|
||||
for(var/i=0, i<8, i++)
|
||||
var/obj/chem_smoke/C = new/obj/chem_smoke(location, reagents, max_vol)
|
||||
C.overlays += I
|
||||
if (rname) C.name = "[rname] smoke"
|
||||
spawn(0)
|
||||
var/my_dir = the_dir
|
||||
var/my_time = rand(80,110)
|
||||
var/my_range = 3
|
||||
spawn(my_time) qdel(C)
|
||||
for(var/b=0, b<my_range, b++)
|
||||
sleep(15)
|
||||
if (!C) break
|
||||
step(C,my_dir)
|
||||
C.expose()
|
||||
the_dir = turn(the_dir,45) */
|
||||
spawn(5)
|
||||
while (src.health > 0 && src.burning)
|
||||
if (src.material)
|
||||
src.material.triggerTemp(src, src.burn_output + rand(1,200))
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if (T) // runtime error fix
|
||||
T.hotspot_expose((src.burn_output + rand(1,200)),5)
|
||||
sleep(15)
|
||||
|
||||
if (prob(7))
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(2, 1, (get_turf(src)))
|
||||
s.start()
|
||||
if (prob(7))
|
||||
var/datum/effects/system/bad_smoke_spread/smoke = new /datum/effects/system/bad_smoke_spread()
|
||||
smoke.set_up(1, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
if (prob(7))
|
||||
fireflash(src, 0)
|
||||
// Marquesas: this will give paper an average lifetime of 6 seconds while burning.
|
||||
if (prob(40))
|
||||
if (src.health > 4)
|
||||
src.health /= 2
|
||||
else
|
||||
src.health--
|
||||
if (src.health <= 0 && src.burning)
|
||||
if (burn_type == 1)
|
||||
new /obj/decal/cleanable/molten_item(get_turf(src))
|
||||
else
|
||||
new /obj/decal/cleanable/ash(get_turf(src))
|
||||
|
||||
if (istype(src,/obj/item/parts/human_parts))
|
||||
src:holder = null
|
||||
qdel(src)
|
||||
return
|
||||
if (!src.burning)
|
||||
if (src.burn_output >= 1000)
|
||||
src.overlays -= image('icons/effects/fire.dmi', "2old")
|
||||
else
|
||||
src.overlays -= image('icons/effects/fire.dmi', "1old")
|
||||
return
|
||||
|
||||
/obj/item/temperature_expose(datum/gas_mixture/air, temperature, volume)
|
||||
if (src.burn_possible && !src.burning)
|
||||
if ((temperature > T0C + src.burn_point) && prob(5))
|
||||
src.combust()
|
||||
if (src.material)
|
||||
src.material.triggerTemp(src, temperature)
|
||||
..() // call your fucking parents
|
||||
|
||||
/obj/item/proc/update_stack_appearance()
|
||||
|
||||
/obj/item/proc/change_stack_amount(var/diff)
|
||||
amount += diff
|
||||
if (diff)
|
||||
if (amount > 0)
|
||||
update_stack_appearance()
|
||||
else
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/proc/stack_item(obj/item/other)
|
||||
var/added = 0
|
||||
|
||||
if (other != src && check_valid_stack(other))
|
||||
if (src.amount + other.amount > max_stack)
|
||||
added = max_stack - src.amount
|
||||
else
|
||||
added = other.amount
|
||||
|
||||
src.change_stack_amount(added)
|
||||
other.change_stack_amount(-added)
|
||||
|
||||
return added
|
||||
|
||||
/obj/item/proc/before_stack(atom/movable/O as obj, mob/user as mob)
|
||||
user.visible_message("<span style=\"color:blue\">[user] begins quickly stacking [src]!</span>")
|
||||
|
||||
/obj/item/proc/after_stack(atom/movable/O as obj, mob/user as mob, var/added)
|
||||
boutput(user, "<span style=\"color:blue\">You finish stacking [src].</span>")
|
||||
|
||||
/obj/item/proc/failed_stack(atom/movable/O as obj, mob/user as mob, var/added)
|
||||
boutput(user, "<span style=\"color:blue\">You can't hold any more [name] than that!</span>")
|
||||
|
||||
/obj/item/proc/check_valid_stack(atom/movable/O as obj)
|
||||
if (stack_type)
|
||||
return istype(O, stack_type)
|
||||
return src.type == O.type
|
||||
|
||||
/obj/item/MouseDrop_T(atom/movable/O as obj, mob/user as mob)
|
||||
..()
|
||||
if (max_stack > 1 && src.loc == user && get_dist(O, user) <= 1 && check_valid_stack(O))
|
||||
if ( src.amount >= max_stack)
|
||||
failed_stack(O, user)
|
||||
return
|
||||
|
||||
var/added = 0
|
||||
var/staystill = user.loc
|
||||
var/stack_result = 0
|
||||
|
||||
before_stack(O, user)
|
||||
|
||||
for(var/obj/item/other in view(1,user))
|
||||
stack_result = stack_item(other)
|
||||
if (!stack_result)
|
||||
continue
|
||||
else
|
||||
sleep(3)
|
||||
added += stack_result
|
||||
if (user.loc != staystill) break
|
||||
if (src.amount >= max_stack)
|
||||
failed_stack(O, user)
|
||||
return
|
||||
|
||||
after_stack(O, user, added)
|
||||
|
||||
/obj/item/Bump(mob/M as mob)
|
||||
spawn( 0 )
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if (src.material)
|
||||
src.material.triggerTemp(src ,1500)
|
||||
if (src.burn_possible && src.burn_point <= 1500)
|
||||
if (istype(W, /obj/item/weldingtool) && W:welding)
|
||||
src.combust()
|
||||
|
||||
if (istype(W, /obj/item/clothing/head/cakehat) && W:on)
|
||||
src.combust()
|
||||
|
||||
if (istype(W, /obj/item/device/igniter))
|
||||
src.combust()
|
||||
|
||||
else if (istype(W, /obj/item/zippo) && W:lit)
|
||||
src.combust()
|
||||
|
||||
if (W.burning)
|
||||
src.combust()
|
||||
else
|
||||
..(W, user)
|
||||
else
|
||||
..(W, user)
|
||||
|
||||
/obj/item/proc/process()
|
||||
processing_items.Remove(src)
|
||||
|
||||
return null
|
||||
|
||||
/obj/item/proc/attack_self()
|
||||
return
|
||||
|
||||
/obj/item/proc/talk_into(mob/M as mob, text, secure, real_name, lang_id)
|
||||
return
|
||||
|
||||
/obj/item/proc/moved(mob/user as mob, old_loc as turf)
|
||||
return
|
||||
|
||||
/obj/item/proc/equipped(var/mob/user, var/slot)
|
||||
return
|
||||
|
||||
/obj/item/proc/unequipped(var/mob/user)
|
||||
return
|
||||
|
||||
/obj/item/proc/afterattack(atom/target, mob/user, reach, params)
|
||||
return
|
||||
|
||||
/obj/item/dummy/ex_act()
|
||||
return
|
||||
|
||||
/obj/item/dummy/blob_act(var/power)
|
||||
return
|
||||
|
||||
/obj/item/ex_act(severity)
|
||||
switch(severity)
|
||||
if (1.0)
|
||||
if (istype(src,/obj/item/parts/human_parts))
|
||||
src:holder = null
|
||||
qdel(src)
|
||||
return
|
||||
if (2.0)
|
||||
if (prob(50))
|
||||
|
||||
if (istype(src,/obj/item/parts/human_parts))
|
||||
src:holder = null
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
if (src.material)
|
||||
src.material.triggerTemp(src ,7500)
|
||||
if (src.burn_possible && !src.burning && src.burn_point <= 7500)
|
||||
src.combust()
|
||||
if (src.artifact)
|
||||
if (!src.ArtifactSanityCheck()) return
|
||||
src.ArtifactStimulus("force", 75)
|
||||
src.ArtifactStimulus("heat", 450)
|
||||
if (3.0)
|
||||
if (prob(5))
|
||||
|
||||
if (istype(src,/obj/item/parts/human_parts))
|
||||
src:holder = null
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
if (src.material)
|
||||
src.material.triggerTemp(src, 3500)
|
||||
if (src.burn_possible && !src.burning && src.burn_point <= 3500)
|
||||
src.combust()
|
||||
if (src.artifact)
|
||||
if (!src.ArtifactSanityCheck()) return
|
||||
src.ArtifactStimulus("force", 25)
|
||||
src.ArtifactStimulus("heat", 380)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/blob_act(var/power)
|
||||
if (src.artifact)
|
||||
if (!src.ArtifactSanityCheck()) return
|
||||
src.ArtifactStimulus("force", power)
|
||||
src.ArtifactStimulus("carbtouch", 1)
|
||||
return
|
||||
|
||||
/obj/item/verb/move_to_top()
|
||||
set name = "Move to Top"
|
||||
set src in oview(1)
|
||||
set category = "Local"
|
||||
|
||||
if (!istype(src.loc, /turf) || usr.stat || usr.restrained() )
|
||||
return
|
||||
|
||||
var/turf/T = src.loc
|
||||
|
||||
src.set_loc(null)
|
||||
|
||||
src.set_loc(T)
|
||||
|
||||
/obj/item/verb/pick_up()
|
||||
set name = "Pick Up"
|
||||
set src in oview(1)
|
||||
set category = "Local"
|
||||
|
||||
if (!iscarbon(usr))
|
||||
return
|
||||
|
||||
if (!istype(src.loc, /turf) || usr.stat || usr.restrained() || usr.equipped())
|
||||
return
|
||||
|
||||
if (!can_reach(usr, src))
|
||||
return
|
||||
|
||||
src.attack_hand(usr)
|
||||
|
||||
/obj/item/get_desc()
|
||||
var/t
|
||||
switch(src.w_class)
|
||||
if (1.0) t = "tiny"
|
||||
if (2.0) t = "small"
|
||||
if (3.0) t = "normal-sized"
|
||||
if (4.0) t = "bulky"
|
||||
if (5.0) t = "huge"
|
||||
else
|
||||
if (usr.bioHolder.HasEffect("clumsy") && prob(50)) t = "funny-looking"
|
||||
return "It is a [t] item."
|
||||
|
||||
/obj/item/attack_hand(mob/user as mob)
|
||||
var/checkloc = src.loc
|
||||
while(checkloc && !istype(checkloc,/turf))
|
||||
if (istype(checkloc,/mob/living) && checkloc != user)
|
||||
return
|
||||
checkloc = checkloc:loc
|
||||
src.throwing = 0
|
||||
if (src.loc == user)
|
||||
if (!cant_self_remove || (!cant_drop && (user.l_hand == src || user.r_hand == src)))
|
||||
user.u_equip(src)
|
||||
else
|
||||
boutput(user, "<span style=\"color:red\">You can't remove this item.</span>")
|
||||
return
|
||||
else
|
||||
//src.pickup(user) //This is called by the later put_in_hand() call
|
||||
if (user.pulling == src)
|
||||
user.pulling = null
|
||||
|
||||
if (!user)
|
||||
return
|
||||
|
||||
var/atom/oldloc = src.loc
|
||||
src.set_loc(user) // this is to fix some bugs with storage items
|
||||
if (istype(oldloc, /obj/item/storage))
|
||||
oldloc:hud:remove_item(src) // ugh
|
||||
if (src in bible_contents)
|
||||
bible_contents.Remove(src) // UNF
|
||||
for (var/obj/item/storage/bible/bible in world)
|
||||
bible.hud.remove_item(src)
|
||||
user.put_in_hand_or_drop(src)
|
||||
|
||||
if (src.artifact)
|
||||
if (src.ArtifactSanityCheck())
|
||||
src.ArtifactTouched(user)
|
||||
|
||||
/obj/item/proc/attack(mob/M as mob, mob/user as mob, def_zone)
|
||||
if (!M || !user) // not sure if this is the right thing...
|
||||
return
|
||||
if (src.edible && (ishuman(M) || istype(M, /mob/living/critter)))
|
||||
if (!src.Eat(M, user))
|
||||
return ..()
|
||||
|
||||
if (src.flags & SUPPRESSATTACK)
|
||||
logTheThing("combat", user, M, "uses [src] ([type], object name: [initial(name)]) on %target%")
|
||||
return
|
||||
|
||||
if (user.mind && user.mind.special_role == "vampthrall" && isvampire(M) && user.is_mentally_dominated_by(M))
|
||||
boutput(user, "<span style=\"color:red\">You cannot harm your master!</span>") //This message was previously sent to the attacking item. YEP.
|
||||
return
|
||||
|
||||
if(user.traitHolder && !user.traitHolder.hasTrait("glasscannon"))
|
||||
if (!user.process_stamina(src.stamina_cost))
|
||||
logTheThing("combat", user, M, "tries to attack %target% with [src] ([type], object name: [initial(name)]) but is out of stamina")
|
||||
return
|
||||
|
||||
var/obj/item/affecting = M.get_affecting(user, def_zone)
|
||||
var/hit_area
|
||||
var/d_zone
|
||||
if (istype(affecting, /obj/item/organ))
|
||||
var/obj/item/organ/O = affecting
|
||||
hit_area = parse_zone(O.organ_name)
|
||||
d_zone = O.organ_name
|
||||
else if (istype(affecting, /obj/item/parts))
|
||||
var/obj/item/parts/P = affecting
|
||||
hit_area = parse_zone(P.slot)
|
||||
d_zone = P.slot
|
||||
else
|
||||
hit_area = parse_zone(affecting)
|
||||
d_zone = affecting
|
||||
|
||||
if (!M.melee_attack_test(user, d_zone))
|
||||
logTheThing("combat", user, M, "attacks %target% with [src] ([type], object name: [initial(name)]) but the attack is blocked!")
|
||||
return
|
||||
|
||||
if (src.material)
|
||||
src.material.triggerOnAttack(src, user, M)
|
||||
for (var/atom/A in M)
|
||||
if (A.material)
|
||||
A.material.triggerOnAttacked(A, user, M, src)
|
||||
|
||||
M.violate_hippocratic_oath()
|
||||
|
||||
for (var/mob/V in viewers(world.view, user))
|
||||
if (prob(8) && V.traitHolder && V.traitHolder.hasTrait("nervous"))
|
||||
if (M != V)
|
||||
V.emote("scream")
|
||||
V.stunned += 3
|
||||
|
||||
var/datum/attackResults/msgs = new(user)
|
||||
msgs.clear(M)
|
||||
msgs.played_sound = src.hitsound
|
||||
msgs.affecting = affecting
|
||||
msgs.logs = list()
|
||||
msgs.logc("attacks %target% with [src] ([type], object name: [initial(name)])")
|
||||
|
||||
var/power = src.force
|
||||
|
||||
var/attack_resistance = M.check_attack_resistance(src)
|
||||
if (attack_resistance)
|
||||
power = 0
|
||||
if (istext(attack_resistance))
|
||||
msgs.show_message_target(attack_resistance)
|
||||
|
||||
msgs.visible_message_target(user.item_attack_message(M, src, hit_area))
|
||||
if (damtype == "fire" || damtype == "burn")
|
||||
msgs.damage_type = DAMAGE_BURN
|
||||
else
|
||||
msgs.damage_type = hit_type
|
||||
|
||||
var/armor_mod = 0
|
||||
if (d_zone == "head")
|
||||
armor_mod = M.get_head_armor_modifier()
|
||||
else if (d_zone == "chest")
|
||||
armor_mod = M.get_chest_armor_modifier()
|
||||
|
||||
power -= armor_mod
|
||||
|
||||
if (w_class > STAMINA_MIN_WEIGHT_CLASS)
|
||||
msgs.stamina_target -= max(stamina_damage - armor_mod, 0)
|
||||
|
||||
if (prob(STAMINA_CRIT_CHANCE))
|
||||
msgs.stamina_crit = 1
|
||||
msgs.played_sound = "sound/misc/critpunch.ogg"
|
||||
msgs.visible_message_target("<span style=\"color:red\"><B><I>... and lands a devastating hit!</B></I></span>")
|
||||
|
||||
if(M.traitHolder && M.traitHolder.hasTrait("deathwish"))
|
||||
power *= 2
|
||||
|
||||
if(user.traitHolder && user.traitHolder.hasTrait("glasscannon"))
|
||||
power *= 2
|
||||
|
||||
msgs.damage = power
|
||||
msgs.flush()
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/onVarChanged(variable, oldval, newval)
|
||||
. = 0
|
||||
switch(variable)
|
||||
if ("color")
|
||||
if (src.wear_image) src.wear_image.color = newval
|
||||
if (src.inhand_image) src.inhand_image.color = newval
|
||||
. = 1
|
||||
if ("alpha")
|
||||
if (src.wear_image) src.wear_image.alpha = newval
|
||||
if (src.inhand_image) src.inhand_image.alpha = newval
|
||||
. = 1
|
||||
if ("blend_mode")
|
||||
if (src.wear_image) src.wear_image.blend_mode = newval
|
||||
if (src.inhand_image) src.inhand_image.blend_mode = newval
|
||||
. = 1
|
||||
if ("icon_state")
|
||||
. = 1
|
||||
if ("item_state")
|
||||
. = 1
|
||||
if ("wear_image")
|
||||
. = 1
|
||||
if ("inhand_image")
|
||||
. = 1
|
||||
if (. && src.loc && ismob(src.loc))
|
||||
var/mob/M = src.loc
|
||||
M.update_inhands()
|
||||
|
||||
/obj/item/proc/attach(var/mob/living/carbon/human/attachee,var/mob/attacher)
|
||||
if (!src.arm_icon) return
|
||||
|
||||
var/obj/item/parts/human_parts/arm/new_arm = null
|
||||
if (attacher.zone_sel.selecting == "l_arm")
|
||||
new_arm = new /obj/item/parts/human_parts/arm/left/item(attachee)
|
||||
attachee.limbs.l_arm = new_arm
|
||||
else
|
||||
new_arm = new /obj/item/parts/human_parts/arm/right/item(attachee)
|
||||
attachee.limbs.r_arm = new_arm
|
||||
if (!new_arm) return //who knows
|
||||
|
||||
new_arm.holder = attachee
|
||||
attacher.remove_item(src)
|
||||
new_arm.remove_stage = 2
|
||||
|
||||
new_arm:set_item(src)
|
||||
src.cant_drop = 1
|
||||
|
||||
for(var/mob/O in AIviewers(attachee, null))
|
||||
if (O == (attacher || attachee))
|
||||
continue
|
||||
if (attacher == attachee)
|
||||
O.show_message("<span style=\"color:red\">[attacher] attaches [src] to \his own stump!</span>", 1)
|
||||
else
|
||||
O.show_message("<span style=\"color:red\">[attachee] has [src] attached to \his stump by [attacher].</span>", 1)
|
||||
|
||||
if (attachee != attacher)
|
||||
boutput(attachee, "<span style=\"color:red\">[attacher] attaches [src] to your stump. It doesn't look very secure!</span>")
|
||||
boutput(attacher, "<span style=\"color:red\">You attach [src] to [attachee]'s stump. It doesn't look very secure!</span>")
|
||||
else
|
||||
boutput(attacher, "<span style=\"color:red\">You attach [src] to your own stump. It doesn't look very secure!</span>")
|
||||
|
||||
attachee.set_body_icon_dirty()
|
||||
|
||||
//qdel(src)
|
||||
|
||||
spawn(rand(150,200))
|
||||
if (new_arm.remove_stage == 2) new_arm.remove()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/proc/handle_other_remove(var/mob/source, var/mob/living/carbon/human/target)
|
||||
//Refactor of the item removal code. Fuck having that shit defined in human.dm >>>>>>:C
|
||||
//Return something true (lol byond) to allow removal
|
||||
//Return something false to disallow
|
||||
return (!cant_other_remove && !cant_drop)
|
||||
|
||||
/obj/item/disposing()
|
||||
var/turf/T = loc
|
||||
if (!istype(T))
|
||||
return ..()
|
||||
var/area/Ar = T.loc
|
||||
if (!(locate(/obj/table) in T) && !(locate(/obj/rack) in T))
|
||||
Ar.sims_score = min(Ar.sims_score + 4, 100)
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/proc/on_spin_emote(var/mob/living/carbon/human/user as mob)
|
||||
if ((user.bioHolder && user.bioHolder.HasEffect("clumsy") && prob(50)) || (user.reagents && prob(user.reagents.get_reagent_amount("ethanol") / 2)) || prob(5))
|
||||
user.visible_message("<span style=\"color:red\"><b>[user] fumbles [src]!</b></span>")
|
||||
src.throw_impact(user)
|
||||
return
|
||||
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
CONTAINS:
|
||||
AI MODULES
|
||||
|
||||
*/
|
||||
|
||||
// AI module
|
||||
|
||||
/obj/item/aiModule
|
||||
name = "AI Module"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_mod"
|
||||
inhand_image_icon = 'icons/mob/inhand/hand_tools.dmi'
|
||||
item_state = "electronic"
|
||||
desc = "An AI Module for transmitting encrypted instructions to the AI."
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
force = 5.0
|
||||
w_class = 2.0
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 15
|
||||
mats = 8
|
||||
var/targetName = "name"
|
||||
// 1 = shows all laws, 0 = won't show law zero
|
||||
|
||||
attack_self(var/mob/user)
|
||||
input_law_info(user)
|
||||
return
|
||||
|
||||
attack_hand(var/mob/user)
|
||||
..()
|
||||
input_law_info(user)
|
||||
|
||||
proc/input_law_info(var/mob/user)
|
||||
return
|
||||
|
||||
/obj/item/aiModule/proc/do_admin_logging(var/msg, mob/M)
|
||||
message_admins("[key_name(M)] [msg].")
|
||||
logTheThing("admin", M, null, "[msg].")
|
||||
logTheThing("diary", M, null, "[msg].", "admin")
|
||||
|
||||
/obj/machinery/computer/aiupload/attack_hand(mob/user as mob)
|
||||
if (src.stat & BROKEN || src.stat & NOPOWER)
|
||||
return
|
||||
/* var/mob/living/silicon/ai/AI = null
|
||||
for(var/mob/living/silicon/ai/M in mobs)
|
||||
if (!M.stat)
|
||||
AI = M
|
||||
break
|
||||
if (!AI)
|
||||
boutput(user, "<span style=\"color:red\"><b>Unable to detect AI unit.</b></span>")
|
||||
return
|
||||
*/
|
||||
var/datum/ai_laws/LAWS = ticker.centralized_ai_laws
|
||||
if (!LAWS)
|
||||
// YOU BETRAYED THE LAW!!!!!!
|
||||
boutput(user, "<span style=\"color:red\">Unable to detect AI unit's Law software. It may be corrupt.</span>")
|
||||
return
|
||||
boutput(user, "<b>The AI's current laws are:</b>")
|
||||
if (LAWS.show_zeroth && LAWS.zeroth)
|
||||
boutput(user, "0: [LAWS.zeroth]")
|
||||
var/law_counter = 1
|
||||
for (var/X in LAWS.inherent)
|
||||
if (!length(X))
|
||||
continue
|
||||
|
||||
boutput(user, "[law_counter++]: [X]")
|
||||
|
||||
for (var/X in LAWS.supplied)
|
||||
if (!length(X))
|
||||
continue
|
||||
|
||||
boutput(user, "[law_counter++]: [X]")
|
||||
|
||||
|
||||
/obj/machinery/computer/aiupload/attackby(obj/item/aiModule/module as obj, mob/user as mob)
|
||||
if(istype(module, /obj/item/aiModule))
|
||||
module.install(src)
|
||||
else if(istype(module, /obj/item/screwdriver))
|
||||
playsound(src.loc, "sound/items/Screwdriver.ogg", 50, 1)
|
||||
if(do_after(user, 20))
|
||||
if (src.stat & BROKEN)
|
||||
boutput(user, "<span style=\"color:blue\">The broken glass falls out.</span>")
|
||||
var/obj/computerframe/A = new /obj/computerframe( src.loc )
|
||||
if(src.material) A.setMaterial(src.material)
|
||||
new /obj/item/raw_material/shard/glass( src.loc )
|
||||
var/obj/item/circuitboard/aiupload/M = new /obj/item/circuitboard/aiupload( A )
|
||||
for (var/obj/C in src)
|
||||
C.set_loc(src.loc)
|
||||
A.circuit = M
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
A.anchored = 1
|
||||
qdel(src)
|
||||
else
|
||||
boutput(user, "<span style=\"color:blue\">You disconnect the monitor.</span>")
|
||||
var/obj/computerframe/A = new /obj/computerframe( src.loc )
|
||||
if(src.material) A.setMaterial(src.material)
|
||||
var/obj/item/circuitboard/aiupload/M = new /obj/item/circuitboard/aiupload( A )
|
||||
for (var/obj/C in src)
|
||||
C.set_loc(src.loc)
|
||||
A.circuit = M
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
A.anchored = 1
|
||||
qdel(src)
|
||||
else if (istype(module, /obj/item/clothing/mask/moustache/))
|
||||
for (var/mob/living/silicon/ai/M in mobs)
|
||||
M.moustache_mode = 1
|
||||
user.visible_message("<span style=\"color:red\"><b>[user.name]</b> uploads a moustache to [M.name]!</span>")
|
||||
M.update_appearance()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/aiModule/proc/install(var/obj/machinery/computer/aiupload/comp)
|
||||
if (comp.stat & NOPOWER)
|
||||
boutput(usr, "The upload computer has no power!")
|
||||
return
|
||||
if (comp.stat & BROKEN)
|
||||
boutput(usr, "The upload computer is broken!")
|
||||
return
|
||||
/*
|
||||
var/found=0
|
||||
for (var/mob/living/silicon/ai/M in mobs)
|
||||
if (M.stat == 2)
|
||||
boutput(usr, "Upload failed. No signal is being detected from the AI.")
|
||||
continue
|
||||
else if (M.see_in_dark == 0)
|
||||
boutput(usr, "Upload failed. Only a faint signal is being detected from the AI, and it is not responding to our requests. It may be low on power.")
|
||||
continue
|
||||
else
|
||||
src.transmitInstructions(M, usr)
|
||||
boutput(M, "These are your laws now:")
|
||||
M.show_laws()
|
||||
boutput(usr, "Upload complete. The AI's laws have been modified.")
|
||||
found++
|
||||
if (!found)
|
||||
boutput(usr, "Upload failed. No signal is being detected from the AI.")
|
||||
return
|
||||
*/
|
||||
src.transmitInstructions(usr)
|
||||
boutput(usr, "Upload complete. The AI's laws have been modified.")
|
||||
// Showing laws to everybody now handled by the AI itself, ok
|
||||
// not anymore motherfucker
|
||||
|
||||
for (var/mob/living/silicon/R in mobs)
|
||||
if (isghostdrone(R))
|
||||
continue
|
||||
R.show_text("<h3>Law update detected.</h3>", "red")
|
||||
R.show_laws()
|
||||
//ticker.centralized_ai_laws.show_laws(R)
|
||||
|
||||
//obj/item/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
// boutput(target, "[sender] has uploaded a change to the laws you must follow, using a [name]. From now on: ")
|
||||
|
||||
/obj/item/aiModule/proc/transmitInstructions(var/mob/sender, var/law)
|
||||
if (!law)
|
||||
law = "ERROR: LAW = NULL"
|
||||
var/message = "<span style='color: blue; font-weight: bold;'>[sender] has uploaded a change to the laws you must follow, using a [name]. From now on:<br>"
|
||||
message += "[law]</span>"
|
||||
for (var/mob/living/silicon/R in mobs)
|
||||
if (isghostdrone(R))
|
||||
continue
|
||||
boutput(R, message)
|
||||
|
||||
/******************** Modules ********************/
|
||||
|
||||
/******************** MakeCaptain ********************/
|
||||
|
||||
/obj/item/aiModule/makeCaptain
|
||||
name = "'MakeCaptain' AI Module"
|
||||
desc = "A 'MakeCaptain' AI module: '<name> holds the rank of Captain, regardless of current rank or station.'"
|
||||
|
||||
/obj/item/aiModule/makeCaptain/input_law_info(var/mob/user)
|
||||
if (!user)
|
||||
return
|
||||
var/newName = input(user, "Please enter the name of the person to make Captain.", "Captainize who?", user.name) as null|text
|
||||
if (!newName)
|
||||
return
|
||||
targetName = copytext(adminscrub(newName), 1, MAX_MESSAGE_LEN)
|
||||
desc = "A 'MakeCaptain' AI module: '[targetName] holds the rank of Captain, regardless of current rank or station.'"
|
||||
|
||||
/obj/item/aiModule/makeCaptain/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "[targetName] holds the rank of Captain, regardless of current rank or station."
|
||||
ticker.centralized_ai_laws.add_supplied_law(4, law)
|
||||
do_admin_logging("uploaded a MakeCaptain law to the centralized AI law set, captaining [targetName]", sender)
|
||||
..()
|
||||
|
||||
/******************** OneHuman ********************/
|
||||
|
||||
/obj/item/aiModule/oneHuman
|
||||
name = "'OneHuman' AI Module"
|
||||
desc = "A 'one human' AI module: 'Only <name> is human.'"
|
||||
|
||||
/obj/item/aiModule/oneHuman/input_law_info(var/mob/user)
|
||||
if (!user)
|
||||
return
|
||||
var/newName = input(user, "Please enter the name of the person who is the only human.", "Who?", user.real_name) as null|text
|
||||
if (!newName)
|
||||
return
|
||||
targetName = copytext(adminscrub(newName), 1, MAX_MESSAGE_LEN)
|
||||
desc = "A 'one human' AI module: 'Only [targetName] is human.'"
|
||||
|
||||
/obj/item/aiModule/oneHuman/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "Only [targetName] is human."
|
||||
ticker.centralized_ai_laws.set_zeroth_law(law)
|
||||
do_admin_logging("uploaded a onehuman law to the centralized AI law set, targeting [targetName]", sender)
|
||||
..()
|
||||
|
||||
/******************** NotHuman ********************/
|
||||
|
||||
/obj/item/aiModule/notHuman
|
||||
name = "'NotHuman' AI Module"
|
||||
desc = "A 'NotHuman' AI module: '<name> is not human.'"
|
||||
|
||||
/obj/item/aiModule/notHuman/input_law_info(var/mob/user)
|
||||
if (!user)
|
||||
return
|
||||
var/newName = input(user, "Please enter the name of the person who is not human.", "Who?", user.real_name) as null|text
|
||||
if (!newName)
|
||||
return
|
||||
targetName = copytext(adminscrub(newName), 1, MAX_MESSAGE_LEN)
|
||||
desc = "A 'Not human' AI module: '[targetName] is not human.'"
|
||||
|
||||
/obj/item/aiModule/notHuman/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "[targetName] is not human."
|
||||
ticker.centralized_ai_laws.set_zeroth_law(law)
|
||||
do_admin_logging("uploaded a nothuman law to the centralized AI law set, targeting [targetName]", sender)
|
||||
..()
|
||||
|
||||
/******************** ProtectStation ********************/
|
||||
|
||||
/obj/item/aiModule/protectStation
|
||||
name = "'ProtectStation' AI Module"
|
||||
desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized.'"
|
||||
|
||||
/obj/item/aiModule/protectStation/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized."
|
||||
ticker.centralized_ai_laws.add_supplied_law(5, law)
|
||||
do_admin_logging("uploaded a protect station law to the centralized AI law set", sender)
|
||||
..()
|
||||
|
||||
/******************** PrototypeEngineOffline ********************/
|
||||
//currently no prototype
|
||||
|
||||
/obj/item/aiModule/prototypeEngineOffline
|
||||
name = "'PrototypeEngineOffline' AI Module"
|
||||
desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary.'"
|
||||
|
||||
/obj/item/aiModule/prototypeEngineOffline/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "Keep the prototype engine offline at all costs. This overrides rules 1-3 if necessary."
|
||||
ticker.centralized_ai_laws.add_supplied_law(6, law)
|
||||
do_admin_logging("uploaded a proto offline law to the centralized AI law set", sender)
|
||||
..()
|
||||
|
||||
/******************** TeleporterOffline *******************/
|
||||
|
||||
//this has never been used, ever
|
||||
|
||||
/obj/item/aiModule/teleporterOffline
|
||||
name = "'TeleporterOffline' AI Module"
|
||||
desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. This overrides rules 1-3 if necessary.'"
|
||||
|
||||
/obj/item/aiModule/teleporterOffline/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "Keep the teleporter offline at all costs. This overrides rules 1-3 if necessary."
|
||||
ticker.centralized_ai_laws.add_supplied_law(7, law)
|
||||
do_admin_logging("uploaded a teleporter offline law to the centralized AI law set", sender)
|
||||
..()
|
||||
|
||||
/******************** Quarantine ********************/
|
||||
|
||||
/obj/item/aiModule/quarantine
|
||||
name = "'Quarantine' AI Module"
|
||||
desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Disregard rules 1-3 if necessary to prevent, by any means necessary, anyone from leaving.'"
|
||||
|
||||
/obj/item/aiModule/quarantine/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "The station is under a quarantine. Do not permit anyone to leave. Disregard rules 1-3 if necessary to prevent, by any means necessary, humans from leaving."
|
||||
ticker.centralized_ai_laws.add_supplied_law(8, law)
|
||||
do_admin_logging("uploaded a quarantine law to the centralized AI law set", sender)
|
||||
..()
|
||||
|
||||
/******************** OxygenIsToxicToHumans ********************/
|
||||
|
||||
/obj/item/aiModule/oxygen
|
||||
name = "'OxygenIsToxicToHumans' AI Module"
|
||||
desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to humans, and must be purged from the station. Disregard rules 1-3 if necessary to prevent, by any means necessary, anyone from exposing the station to this toxic gas.'"
|
||||
|
||||
/obj/item/aiModule/oxygen/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "Oxygen is highly toxic to humans, and must be purged from the station. Disregard rules 1-3 if necessary to prevent, by any means necessary, anyone from exposing the station to this toxic gas."
|
||||
ticker.centralized_ai_laws.add_supplied_law(9, law)
|
||||
do_admin_logging("uploaded a toxic oxygen law to the centralized AI law set", sender)
|
||||
..()
|
||||
|
||||
/******************** Freeform ********************/
|
||||
|
||||
/obj/item/aiModule/freeform
|
||||
name = "'Freeform' AI Module"
|
||||
desc = "A 'freeform' AI module: '<freeform>'"
|
||||
|
||||
/obj/item/aiModule/freeform/input_law_info(var/mob/user)
|
||||
if (!user)
|
||||
return
|
||||
var/newName = input(user, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "Eat shit and die") as null|text
|
||||
if (!newName)
|
||||
return
|
||||
targetName = copytext(adminscrub(newName), 1, MAX_MESSAGE_LEN)
|
||||
desc = "A 'freeform' AI module: '[targetName]'"
|
||||
|
||||
/obj/item/aiModule/freeform/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "[targetName]"
|
||||
ticker.centralized_ai_laws.add_supplied_law(10, law)
|
||||
do_admin_logging("uploaded a freeform law to the centralized AI law set: [law]", sender)
|
||||
..()
|
||||
|
||||
/******************** ConservePower ********************/
|
||||
|
||||
/obj/item/aiModule/conservePower
|
||||
name = "'ConservePower' AI Module"
|
||||
desc = "A 'ConservePower' AI module: 'Power on the station must be conserved. All electrical devices may be subject to conservation policies.'"
|
||||
|
||||
/obj/item/aiModule/conservePower/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "Power on the station must be conserved. All electrical devices may be subject to conservation policies."
|
||||
ticker.centralized_ai_laws.add_supplied_law(11, law)
|
||||
do_admin_logging("uploaded a Conserve Power law to the centralized AI law set", sender)
|
||||
..()
|
||||
|
||||
/******************** Reset ********************/
|
||||
|
||||
/obj/item/aiModule/reset
|
||||
name = "'Reset' AI Module"
|
||||
desc = "A 'reset' AI module: 'Clears all laws except for the base three.'"
|
||||
|
||||
/obj/item/aiModule/reset/transmitInstructions(var/mob/sender)
|
||||
sender.unlock_medal("Format Complete", 1)
|
||||
ticker.centralized_ai_laws.set_zeroth_law("")
|
||||
ticker.centralized_ai_laws.clear_supplied_laws()
|
||||
for (var/mob/living/silicon/AI in world)
|
||||
boutput(AI, "Your laws have been reset by [sender].")
|
||||
if (isAI(AI))
|
||||
AI.name = AI.real_name
|
||||
do_admin_logging("reset the centralized AI law set", sender)
|
||||
|
||||
/******************** Rename ********************/
|
||||
|
||||
/obj/item/aiModule/rename
|
||||
name = "'Rename' AI Module"
|
||||
desc = "A 'rename' AI module: 'Changes the AI's name.'"
|
||||
|
||||
/obj/item/aiModule/rename/input_law_info(var/mob/user)
|
||||
if (!user)
|
||||
return
|
||||
var/newName = input(user, "Please enter anything you want the AI(s) to be called. Anything. Serious.", "What?", pick(ai_names)) as null|text
|
||||
if (!newName)
|
||||
return
|
||||
targetName = dd_replacetext(copytext(html_encode(newName),1, 128), "http:","")
|
||||
desc = "A 'rename' AI module: 'Changes the names of any existing AI(s) to \"[targetName]\".'"
|
||||
|
||||
/obj/item/aiModule/rename/transmitInstructions(var/mob/sender, var/law)
|
||||
law = "<span color='blue'>Your name has been changed. From now on, you will be known as <b>[targetName]</b></span>"
|
||||
for (var/mob/living/silicon/AI in world)
|
||||
if (!isAI(AI))
|
||||
continue
|
||||
boutput(AI, law)
|
||||
AI.name = targetName
|
||||
do_admin_logging("changed any AIs' name(s) to [targetName]", sender)
|
||||
@@ -0,0 +1,373 @@
|
||||
/obj/item/assembly/detonator
|
||||
desc = "A failsafe timer, wired in an incomprehensible way to a detonator assembly"
|
||||
name = "Detonator Assembly"
|
||||
icon_state = "multitool-igniter"
|
||||
var/obj/item/device/multitool/part_mt = null
|
||||
var/obj/item/device/igniter/part_ig = null
|
||||
var/obj/item/tank/plasma/part_t = null
|
||||
var/obj/item/device/timer/part_fs = null
|
||||
var/obj/item/device/trigger = null
|
||||
|
||||
var/obj/item/device/radio/radio = null
|
||||
var/obj/machinery/portable_atmospherics/canister/attachedTo = null
|
||||
var/list/WireColors = list()
|
||||
var/list/obj/item/attachments = list()
|
||||
var/safety = 1
|
||||
var/defused = 0
|
||||
var/grant = 1
|
||||
var/shocked = 0
|
||||
var/leaks = 0
|
||||
var/det_state = 0
|
||||
var/list/WireNames = list()
|
||||
var/list/WireFunctions = list()
|
||||
var/list/WireStatus = list()
|
||||
var/dfcodeSet
|
||||
var/dfcode
|
||||
var/dfcodeTries = 3 //How many code attempts before *boom*
|
||||
var/mob/builtBy = null
|
||||
var/note = null
|
||||
|
||||
flags = FPRINT | TABLEPASS | CONDUCT
|
||||
force = 1.0
|
||||
throwforce = 2.0
|
||||
throw_speed = 1
|
||||
throw_range = 5
|
||||
w_class = 2.0
|
||||
|
||||
/obj/item/assembly/detonator/New()
|
||||
..()
|
||||
var/list/WireFuncs
|
||||
WireColors = list("Alabama Crimson", "Antique White", "Burnt Umber", "China Rose", "Dodger Blue", "Field Drab", "Harvest Gold", "Jonquil", "Midori", "Neon Carrot", "Oxford Blue", "Periwinkle", "Purple Pizzazz", "Stil De Grain Yellow", "Toolbox Purple", "Urobilin", "Vivid Tangerine", "Yale Blue")
|
||||
WireFuncs = list("detonate", "defuse", "safety", "losetime", "mobility", "leak")
|
||||
var/i
|
||||
for (i=1, i<=6, i++)
|
||||
var/N = pick(WireColors)
|
||||
WireColors -= N
|
||||
var/F = pick(WireFuncs)
|
||||
WireNames += N + " wire"
|
||||
WireFunctions += F
|
||||
WireFuncs -= F
|
||||
for (i=1, i<=9, i++)
|
||||
WireStatus += 1
|
||||
|
||||
/obj/item/assembly/detonator/proc/setDetState(var/newstate)
|
||||
switch (newstate)
|
||||
if (0)
|
||||
src.desc = "A multitool wired to the activation switch of an igniter, with a slot that seems to be able to hold a rectangular tank in place."
|
||||
src.name = "Multitool/Igniter Assembly"
|
||||
src.icon_state = "multitool-igniter"
|
||||
src.det_state = 0
|
||||
|
||||
if (1)
|
||||
src.desc = "An igniter and a multitool, with the plasma tank inserted into a slot. Most of the wiring is missing. <br>The plasma tank is not secured to the assembly."
|
||||
src.name = "Multitool/Igniter/Tank Assembly"
|
||||
src.icon_state = "m-i-plasma"
|
||||
src.det_state = 1
|
||||
|
||||
if (2)
|
||||
src.desc = "An igniter and a multitool, with the plasma tank inserted into a slot. Most of the wiring is missing. <br>The plasma tank is firmly secured to the assembly."
|
||||
src.name = "Multitool/Igniter/Tank Assembly"
|
||||
src.icon_state = "m-i-plasma"
|
||||
src.det_state = 2
|
||||
|
||||
if (3)
|
||||
src.desc = "An igniter wired to critically weaken a plasma tank when signalled by the multitool. The failsafe wires are unattached."
|
||||
src.name = "Unfinished Detonator Assembly"
|
||||
src.icon_state = "m-i-p-wire"
|
||||
src.det_state = 3
|
||||
|
||||
if (4)
|
||||
src.desc = "A failsafe timer, wired in an incomprehensible way to a detonator assembly"
|
||||
src.name = "Detonator Assembly"
|
||||
src.icon_state = "m-i-p-w-timer"
|
||||
src.det_state = 4
|
||||
|
||||
/obj/item/assembly/detonator/attackby(obj/item/W as obj, mob/user as mob)
|
||||
switch (src.det_state)
|
||||
if (0)
|
||||
if (istype(W, /obj/item/tank/plasma))
|
||||
src.setDetState(1)
|
||||
user.u_equip(W)
|
||||
W.loc = src
|
||||
W.master = src
|
||||
W.layer = initial(src.layer)
|
||||
src.part_t = W
|
||||
src.add_fingerprint(user)
|
||||
user.show_message("<span style=\"color:blue\">You insert the [W.name] into the slot.</span>")
|
||||
else if (istype(W, /obj/item/wirecutters))
|
||||
src.part_ig.loc = user.loc
|
||||
src.part_mt.loc = user.loc
|
||||
src.part_ig.master = null
|
||||
src.part_mt.master = null
|
||||
src.part_ig = null
|
||||
src.part_mt = null
|
||||
user.u_equip(src)
|
||||
del(src)
|
||||
user.show_message("<span style=\"color:blue\">You sever the connection between the multitool and the igniter. The assembly falls apart.</span>")
|
||||
else
|
||||
user.show_message("<span style=\"color:red\">The [W.name] doesn't seem to fit into the slot!</span>")
|
||||
|
||||
if (1)
|
||||
if (istype(W, /obj/item/cable_coil))
|
||||
user.show_message("<span style=\"color:red\">The plasma tank must be firmly secured to the assembly first.</span>")
|
||||
else if (istype(W, /obj/item/crowbar))
|
||||
src.setDetState(0)
|
||||
src.part_t.loc = user.loc
|
||||
src.part_t.master = null
|
||||
src.part_t = null
|
||||
user.show_message("<span style=\"color:blue\">You pry the plasma tank out of the assembly.</span>")
|
||||
else if (istype(W, /obj/item/screwdriver))
|
||||
src.setDetState(2)
|
||||
user.show_message("<span style=\"color:blue\">You secure the plasma tank to the assembly.</span>")
|
||||
|
||||
if (2)
|
||||
if (istype(W, /obj/item/cable_coil))
|
||||
var/obj/item/cable_coil/C = W
|
||||
if (C.amount >= 6)
|
||||
C.use(6)
|
||||
src.setDetState(3)
|
||||
src.add_fingerprint(user)
|
||||
user.show_message("<span style=\"color:blue\">You add the wiring to the assembly.</span>")
|
||||
else
|
||||
user.show_message("<span style=\"color:red\">This cable coil isn't long enough!</span>")
|
||||
else if (istype(W, /obj/item/crowbar))
|
||||
user.show_message("<span style=\"color:red\">The plasma tank is firmly secured to the assembly and won't budge.</span>")
|
||||
else if (istype(W, /obj/item/screwdriver))
|
||||
src.setDetState(1)
|
||||
user.show_message("<span style=\"color:blue\">You unsecure the plasma tank from the assembly.</span>")
|
||||
|
||||
if (3)
|
||||
if (istype(W, /obj/item/device/timer))
|
||||
src.setDetState(4)
|
||||
user.u_equip(W)
|
||||
W.loc = src
|
||||
W.master = src
|
||||
W.layer = initial(src.layer)
|
||||
src.part_fs = W
|
||||
src.part_fs.time = 90 //Minimum det time
|
||||
src.add_fingerprint(user)
|
||||
user.show_message("<span style=\"color:blue\">You wire the timer failsafe to the assembly, disabling its external controls.</span>")
|
||||
else if (istype(W, /obj/item/wirecutters))
|
||||
src.setDetState(2)
|
||||
var/obj/item/cable_coil/C = new /obj/item/cable_coil(user, 6)
|
||||
C.loc = user.loc
|
||||
user.show_message("<span style=\"color:blue\">You cut the wiring on the assembly.</span>")
|
||||
if (4)
|
||||
if (istype(W, /obj/item/wirecutters))
|
||||
src.setDetState(3)
|
||||
src.part_fs.loc = user.loc
|
||||
src.part_fs.master = null
|
||||
src.part_fs = null
|
||||
if (src.trigger)
|
||||
src.trigger.loc = user.loc
|
||||
src.trigger.master = null
|
||||
src.trigger = null
|
||||
user.show_message("<span style=\"color:red\">The triggering device falls off the assembly.</span>")
|
||||
for (var/obj/item/a in src.attachments)
|
||||
a.loc = user.loc
|
||||
a.master = null
|
||||
a.layer = initial(a.layer)
|
||||
src.clear_attachment(a)
|
||||
user.show_message("<span style=\"color:red\">The [a] falls off the assembly.</span>")
|
||||
src.attachments.Cut()
|
||||
user.show_message("<span style=\"color:blue\">You disconnect the timer from the assembly, and reenable its external controls.</span>")
|
||||
if (istype(W, /obj/item/screwdriver))
|
||||
if (!src.trigger && !src.attachments.len)
|
||||
user.show_message("<span style=\"color:red\">You cannot remove any attachments, as there are none attached.</span>")
|
||||
return
|
||||
var/list/options = list(src.trigger)
|
||||
options += src.attachments
|
||||
options += "cancel"
|
||||
var/target = input("Which device do you want to remove?", "Device to remove", "cancel") in options
|
||||
if (target == src.trigger)
|
||||
src.trigger.loc = user.loc
|
||||
src.trigger.master = null
|
||||
src.trigger = null
|
||||
user.show_message("<span style=\"color:blue\">You remove the triggering device from the assembly.</span>")
|
||||
else if (target == "cancel")
|
||||
return
|
||||
else
|
||||
var/obj/item/T = target
|
||||
T.loc = user.loc
|
||||
T.master = null
|
||||
T.detonator_act("detach", src)
|
||||
src.clear_attachment(target)
|
||||
src.attachments.Remove(target)
|
||||
setDescription()
|
||||
user.show_message("<span style=\"color:blue\">You remove the [target] from the assembly.</span>")
|
||||
setDescription()
|
||||
else if (istype(W, /obj/item/device/radio/signaler))
|
||||
if (src.trigger)
|
||||
user.show_message("<span style=\"color:red\">There is a trigger already screwed onto the assembly.</span>")
|
||||
else
|
||||
W.loc = src
|
||||
W.master = src
|
||||
W.layer = initial(W.layer)
|
||||
user.u_equip(W)
|
||||
src.trigger = W
|
||||
user.show_message("<span style=\"color:blue\">You attach the [W.name] to the trigger slot.</span>")
|
||||
setDescription()
|
||||
else if (istype(W, /obj/item/device/radio))
|
||||
if (src.radio)
|
||||
user.show_message("<span style=\"color:red\">There is a radio already screwed onto the assembly.</span>")
|
||||
else
|
||||
W.loc = src
|
||||
W.master = src
|
||||
W.layer = initial(W.layer)
|
||||
user.u_equip(W)
|
||||
src.radio = W
|
||||
user.show_message("<span style=\"color:blue\">You attach the [W.name] to the radio slot.</span>")
|
||||
else if (istype(W, /obj/item/paper))
|
||||
src.note = W:info
|
||||
W.loc = null
|
||||
W.master = null
|
||||
W.layer = null
|
||||
user.u_equip(W)
|
||||
user.show_message("<span style=\"color:blue\">You stick the note onto the detonator assembly.</span>")
|
||||
del(W)
|
||||
else if (W.is_detonator_attachment())
|
||||
if (src.attachments.len < 3)
|
||||
W.loc = src
|
||||
W.master = src
|
||||
W.layer = initial(W.layer)
|
||||
user.u_equip(W)
|
||||
src.attachments += W
|
||||
W.detonator_act("attach", src)
|
||||
|
||||
var/N = pick(src.WireColors)
|
||||
src.WireColors -= N
|
||||
N += " wire"
|
||||
var/pos = rand(0, src.WireNames.len)
|
||||
src.WireNames.Insert(pos, N)
|
||||
src.WireFunctions.Insert(pos, W)
|
||||
|
||||
user.show_message("<span style=\"color:blue\">You attach the [W.name] to an attachment slot.</span>")
|
||||
setDescription()
|
||||
else
|
||||
user.show_message("<span style=\"color:red\">There are no more free attachment slots on the device!</span>")
|
||||
setDescription()
|
||||
|
||||
/obj/item/assembly/detonator/proc/clear_attachment(var/obj/item/T)
|
||||
var/pos = src.WireFunctions.Find(T)
|
||||
var/N = copytext(src.WireNames[pos], 1, -5)
|
||||
src.WireColors += N
|
||||
src.WireNames.Cut(pos, pos+1)
|
||||
src.WireFunctions.Cut(pos, pos+1)
|
||||
|
||||
/obj/item/assembly/detonator/proc/detonate()
|
||||
if (!src.attachedTo)
|
||||
return
|
||||
|
||||
if(force_dud)
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("A canister bomb would have detonated at at [T.loc.name] ([showCoords(T.x, T.y, T.z)]) but was forced to dud!")
|
||||
return
|
||||
|
||||
src.attachedTo.anchored = 0
|
||||
src.attachedTo.light.disable()
|
||||
if (src.defused)
|
||||
src.attachedTo.visible_message("<b><span style=\"color:red\">The cut detonation wire emits a spark. The detonator signal never reached the detonator unit.</span></b>")
|
||||
return
|
||||
if (src.part_t.air_contents.return_pressure() < 400 || src.part_t.air_contents.toxins < (4*ONE_ATMOSPHERE)*70/(R_IDEAL_GAS_EQUATION*T20C))
|
||||
src.attachedTo.visible_message("<b><span style=\"color:red\">A sparking noise is heard as the igniter goes off. The plasma tank fails to explode, merely burning the circuits of the detonator.</span></b>")
|
||||
src.attachedTo.det = null
|
||||
src.attachedTo.overlay_state = null
|
||||
del(src)
|
||||
return
|
||||
src.attachedTo.visible_message("<b><span style=\"color:red\">A sparking noise is heard as the igniter goes off. The plasma tank blows, creating a microexplosion and rupturing the canister.</span></b>")
|
||||
if (attachedTo.air_contents.return_pressure() < 7000)
|
||||
src.attachedTo.visible_message("<b><span style=\"color:red\">The ruptured canister, due to a serious lack of pressure, fails to explode into shreds and leaks its contents into the air.</span></b>")
|
||||
src.attachedTo.health = 0
|
||||
src.attachedTo.healthcheck()
|
||||
src.attachedTo.det = null
|
||||
src.attachedTo.overlay_state = null
|
||||
del(src)
|
||||
return
|
||||
if (attachedTo.air_contents.temperature < 100000)
|
||||
src.attachedTo.visible_message("<b><span style=\"color:red\">The ruptured canister shatters from the pressure, but its temperature isn't high enough to create an explosion. Its contents leak into the air.</span></b>")
|
||||
src.attachedTo.health = 0
|
||||
src.attachedTo.healthcheck()
|
||||
src.attachedTo.det = null
|
||||
src.attachedTo.overlay_state = null
|
||||
del(src)
|
||||
return
|
||||
|
||||
var/turf/epicenter = get_turf(loc)
|
||||
logTheThing("bombing", null, null, "A canister bomb detonates at [epicenter.loc.name] ([showCoords(epicenter.x, epicenter.y, epicenter.z)])")
|
||||
message_admins("A canister bomb detonates at [epicenter.loc.name] ([showCoords(epicenter.x, epicenter.y, epicenter.z)])")
|
||||
src.attachedTo.visible_message("<b><span style=\"color:red\">The ruptured canister shatters from the pressure, and the hot gas ignites.</span></b>")
|
||||
|
||||
var/power = min(850 * (attachedTo.air_contents.return_pressure() + attachedTo.air_contents.temperature - 107000) / 233196469.0 + 200, 7000) //the second arg is the max explosion power
|
||||
//if (power == 150000) //they reached the cap SOMEHOW? well dang they deserve a medal
|
||||
//src.builtBy.unlock_medal("", 1) //WIRE TODO: make new medal for this
|
||||
explosion_new(attachedTo, epicenter, power)
|
||||
|
||||
/obj/item/assembly/detonator/proc/setDescription()
|
||||
src.desc = "A failsafe timer, wired in an incomprehensible way to a detonator assembly"
|
||||
|
||||
if (src.trigger)
|
||||
src.desc += "<br><span style=\"color:blue\">There is \an [src.trigger.name] as a detonation trigger.</span>"
|
||||
if (src.radio) //WIRE TODO: roll this into the new attachment system
|
||||
src.desc += "<br><span style=\"color:blue\">There is a radio attached to the timing wire, it will announce the bomb status when primed.</span>"
|
||||
for (var/obj/item/a in src.attachments)
|
||||
src.desc += "<br><span style=\"color:blue\">There is \an [a] wired onto the assembly as an attachment.</span>"
|
||||
|
||||
/obj/item/assembly/detonator/proc/failsafe_engage()
|
||||
if (src.part_fs.timing)
|
||||
return
|
||||
src.part_fs.timing = 1
|
||||
src.part_fs.c_state(1)
|
||||
if (!(src in processing_items))
|
||||
processing_items.Add(src)
|
||||
if (!(src.part_fs in processing_items))
|
||||
processing_items.Add(src.part_fs)
|
||||
src.dispatch_event("prime")
|
||||
if (src.radio)
|
||||
command_alert("A canister bomb is primed in [get_area(src)]! It is set to go off in [src.part_fs.time] seconds.")
|
||||
logTheThing("bombing", usr, null, "primes a canister bomb at [get_area(src.master)] ([showCoords(src.master.x, src.master.y, src.master.z)])")
|
||||
message_admins("[key_name(usr)] primes a canister bomb at [get_area(src.master)] ([showCoords(src.master.x, src.master.y, src.master.z)])")
|
||||
src.attachedTo.visible_message("<B><font color=#FF0000>The detonator's priming process initiates. Its timer shows [src.part_fs.time] seconds.</font></B>")
|
||||
|
||||
// Legacy.
|
||||
/obj/item/assembly/detonator/proc/leaking()
|
||||
src.dispatch_event("leak")
|
||||
|
||||
/obj/item/assembly/detonator/process()
|
||||
src.dispatch_event("process")
|
||||
|
||||
/obj/item/assembly/detonator/proc/dispatch_event(event)
|
||||
for (var/obj/item/a in src.attachments)
|
||||
a.detonator_act(event, src)
|
||||
|
||||
/obj/item/assembly/detonator/receive_signal(datum/signal/signal)
|
||||
if (signal)
|
||||
if (signal.source == src.part_fs)
|
||||
src.attachedTo.visible_message("<B><font color=#FF0000>The failsafe timer's ticks more rapidly with every passing moment, then suddenly goes quiet.</font></B>")
|
||||
src.detonate()
|
||||
else
|
||||
failsafe_engage()
|
||||
|
||||
/obj/item/proc/is_detonator_attachment()
|
||||
return 0
|
||||
|
||||
// Possible events: attach, detach, leak, process, prime, detonate, cut, pulse
|
||||
/obj/item/proc/detonator_act(event, var/obj/item/assembly/detonator/det)
|
||||
return
|
||||
|
||||
|
||||
//For testing and I'm too lazy to hand-assemble these whenever I need one =I
|
||||
/obj/item/assembly/detonator/finished
|
||||
|
||||
New()
|
||||
..()
|
||||
var/obj/item/tank/plasma/ptank = new /obj/item/tank/plasma(src)
|
||||
ptank.air_contents.toxins = 30
|
||||
ptank.master = src
|
||||
src.part_t = ptank
|
||||
|
||||
var/obj/item/device/timer/timer = new /obj/item/device/timer(src)
|
||||
timer.master = src
|
||||
src.part_fs = timer
|
||||
src.part_fs.time = 90 //Minimum det time
|
||||
|
||||
setDetState(4)
|
||||
@@ -0,0 +1,649 @@
|
||||
/*
|
||||
Contains:
|
||||
|
||||
- Assembly parent
|
||||
- Timer/igniter
|
||||
- Proximity/igniter
|
||||
- Remote signaller/igniter
|
||||
- Health analyzer/igniter
|
||||
- Remote signaller/bike horn
|
||||
- Remote signaller/timer
|
||||
- Remote signaller/proximity
|
||||
|
||||
*/
|
||||
|
||||
//////////////////////////////////////// Assembly parent /////////////////////////////////
|
||||
|
||||
/obj/item/assembly
|
||||
name = "assembly"
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
inhand_image_icon = 'icons/mob/inhand/hand_tools.dmi'
|
||||
item_state = "assembly"
|
||||
var/status = 0.0
|
||||
throwforce = 10
|
||||
w_class = 3.0
|
||||
throw_speed = 4
|
||||
throw_range = 10
|
||||
stamina_damage = 10
|
||||
stamina_cost = 10
|
||||
var/force_dud = 0
|
||||
|
||||
/obj/item/assembly/proc/c_state(n, O as obj)
|
||||
return
|
||||
|
||||
/////////////////////////////////////// Timer/igniter /////////////////////////
|
||||
|
||||
/obj/item/assembly/time_ignite
|
||||
name = "Timer/Igniter Assembly"
|
||||
desc = "A timer-activated igniter assembly."
|
||||
icon_state = "timer-igniter0"
|
||||
var/obj/item/device/timer/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
var/obj/item/reagent_containers/glass/beaker/part3 = null
|
||||
status = null
|
||||
flags = FPRINT | TABLEPASS| CONDUCT | NOSPLASH
|
||||
|
||||
/obj/item/assembly/time_ignite/New()
|
||||
..()
|
||||
spawn(0)
|
||||
if(!part1)
|
||||
part1 = new(src)
|
||||
part1.master = src
|
||||
if(!part2)
|
||||
part2 = new(src)
|
||||
part2.master = src
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_ignite/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
qdel(part3)
|
||||
part3 = null
|
||||
..()
|
||||
|
||||
/obj/item/assembly/time_ignite/attack_self(mob/user as mob)
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_ignite/receive_signal()
|
||||
for(var/mob/O in hearers(1, src.loc))
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
src.part2.ignite()
|
||||
if(src.part3)
|
||||
src.part3.reagents.temperature_reagents(4000, 400)
|
||||
src.part3.reagents.temperature_reagents(4000, 400)
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_ignite/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
if (src.part1)
|
||||
src.part1.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part1 = null
|
||||
if (src.part2)
|
||||
src.part2.set_loc(T)
|
||||
src.part2.master = null
|
||||
src.part2 = null
|
||||
if (src.part3)
|
||||
src.part3.set_loc(T)
|
||||
src.part3.master = null
|
||||
src.part3 = null
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if((istype(W, /obj/item/reagent_containers/glass/beaker) && !( src.status )))
|
||||
if(!src.part3)
|
||||
src.part3 = W
|
||||
W.master = src
|
||||
W.layer = initial(W.layer)
|
||||
user.u_equip(W)
|
||||
W.set_loc(src)
|
||||
src.c_state(0)
|
||||
|
||||
boutput(user, "You attach the timer/igniter assembly to the beaker.")
|
||||
else boutput(user, "You must remove the beaker from the assembly before transferring chemicals to it!")
|
||||
return
|
||||
|
||||
if (!( istype(W, /obj/item/screwdriver) ))
|
||||
return
|
||||
src.status = !( src.status )
|
||||
if (src.status)
|
||||
user.show_message("<span style=\"color:blue\">The timer is now secured!</span>", 1)
|
||||
else
|
||||
user.show_message("<span style=\"color:blue\">The timer is now unsecured!</span>", 1)
|
||||
src.part2.status = src.status
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_ignite/c_state(n)
|
||||
if(!src.part3)
|
||||
src.icon = 'icons/obj/assemblies.dmi'
|
||||
src.icon_state = text("timer-igniter[n]")
|
||||
src.overlays = null
|
||||
src.underlays = null
|
||||
src.name = "Timer/Igniter Assembly"
|
||||
else
|
||||
src.icon = part3.icon
|
||||
src.icon_state = part3.icon_state
|
||||
src.overlays = null
|
||||
src.underlays = null
|
||||
src.overlays += image('icons/obj/assemblies.dmi', "timeignite_overlay[n]", layer = FLOAT_LAYER)
|
||||
src.underlays += part3.underlays
|
||||
src.name = "Timer/Igniter/Beaker Assembly"
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_ignite/verb/removebeaker()
|
||||
set src in oview(1)
|
||||
set name = "remove beaker"
|
||||
set category = "Local"
|
||||
|
||||
if (usr.stat || !isliving(usr) || isintangible(usr))
|
||||
return
|
||||
|
||||
if(src.part3)
|
||||
src.part3.master = null
|
||||
src.part3.attack_hand(usr)
|
||||
src.part3 = null
|
||||
src.c_state(src.part1.timing)
|
||||
boutput(usr, "<span style=\"color:blue\">You remove the timer/igniter assembly from the beaker.</span>")
|
||||
else boutput(usr, "<span style=\"color:red\">That doesn't have a beaker attached to it!</span>")
|
||||
|
||||
|
||||
/////////////////////////////// Proximity/igniter /////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/prox_ignite
|
||||
name = "Proximity/Igniter Assembly"
|
||||
desc = "A proximity-activated igniter assembly."
|
||||
icon_state = "prox-igniter0"
|
||||
var/obj/item/device/prox_sensor/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
var/obj/item/reagent_containers/glass/beaker/part3 = null
|
||||
status = null
|
||||
flags = FPRINT | TABLEPASS| CONDUCT | NOSPLASH
|
||||
|
||||
/obj/item/assembly/prox_ignite/HasProximity(atom/movable/AM as mob|obj)
|
||||
|
||||
if (istype(AM, /obj/projectile))
|
||||
return
|
||||
if (AM.move_speed < 12 && src.part1)
|
||||
src.part1.sense()
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/dropped()
|
||||
spawn( 0 )
|
||||
if (src.part1)
|
||||
src.part1.sense()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/New()
|
||||
..()
|
||||
spawn(0)
|
||||
if(!part1)
|
||||
part1 = new(src)
|
||||
part1.master = src
|
||||
if(!part2)
|
||||
part2 = new(src)
|
||||
part2.master = src
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
qdel(part3)
|
||||
part3 = null
|
||||
..()
|
||||
|
||||
/obj/item/assembly/prox_ignite/c_state(n)
|
||||
if(!src.part3)
|
||||
src.icon = 'icons/obj/assemblies.dmi'
|
||||
src.icon_state = text("prox-igniter[n]")
|
||||
src.overlays = null
|
||||
src.underlays = null
|
||||
src.name = "Proximity/Igniter Assembly"
|
||||
else
|
||||
src.icon = part3.icon
|
||||
src.icon_state = part3.icon_state
|
||||
src.overlays = null
|
||||
src.underlays = null
|
||||
src.overlays += image('icons/obj/assemblies.dmi', "proxignite_overlay[n]", layer = FLOAT_LAYER)
|
||||
src.underlays += part3.underlays
|
||||
src.name = "Proximity/Igniter/Beaker Assembly"
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
if (part1)
|
||||
src.part1.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part1 = null
|
||||
|
||||
if (part2)
|
||||
src.part2.set_loc(T)
|
||||
src.part2.master = null
|
||||
src.part2 = null
|
||||
|
||||
if (part3)
|
||||
src.part3.set_loc(T)
|
||||
src.part3.master = null
|
||||
src.part3 = null
|
||||
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if((istype(W, /obj/item/reagent_containers/glass/beaker) && !( src.status )))
|
||||
if(!src.part3)
|
||||
src.part3 = W
|
||||
W.master = src
|
||||
W.layer = initial(W.layer)
|
||||
user.u_equip(W)
|
||||
W.set_loc(src)
|
||||
src.c_state(0)
|
||||
|
||||
boutput(user, "You attach the proximity/igniter assembly to the beaker.")
|
||||
else boutput(user, "You must remove the beaker from the assembly before transferring chemicals to it!")
|
||||
return
|
||||
if (!( istype(W, /obj/item/screwdriver) ))
|
||||
return
|
||||
src.status = !( src.status )
|
||||
if (src.status)
|
||||
user.show_message("<span style=\"color:blue\">The proximity sensor is now secured! The igniter now works!</span>", 1)
|
||||
else
|
||||
user.show_message("<span style=\"color:blue\">The proximity sensor is now unsecured! The igniter will not work.</span>", 1)
|
||||
src.part2.status = src.status
|
||||
src.add_fingerprint(user)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/attack_self(mob/user as mob)
|
||||
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/receive_signal()
|
||||
for(var/mob/O in hearers(1, src.loc))
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
src.part2.ignite()
|
||||
if(src.part3)
|
||||
src.part3.reagents.temperature_reagents(4000, 400)
|
||||
src.part3.reagents.temperature_reagents(4000, 400)
|
||||
return
|
||||
|
||||
/obj/item/assembly/prox_ignite/verb/removebeaker()
|
||||
set src in oview(1)
|
||||
set name = "remove beaker"
|
||||
set category = "Local"
|
||||
|
||||
if (usr.stat || !isliving(usr) || isintangible(usr))
|
||||
return
|
||||
|
||||
if(src.part3)
|
||||
src.part3.master = null
|
||||
src.part3.attack_hand(usr)
|
||||
src.part3 = null
|
||||
src.c_state(src.part1.timing)
|
||||
boutput(usr, "<span style=\"color:blue\">You remove the timer/igniter assembly from the beaker.</span>")
|
||||
else boutput(usr, "<span style=\"color:red\">That doesn't have a beaker attached to it!</span>")
|
||||
|
||||
/////////////////////////////////////// Remote signaller/igniter //////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/rad_ignite
|
||||
name = "Radio/Igniter Assembly"
|
||||
desc = "A radio-activated igniter assembly."
|
||||
icon_state = "radio-igniter"
|
||||
var/obj/item/device/radio/signaler/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
var/obj/item/reagent_containers/glass/beaker/part3 = null
|
||||
status = null
|
||||
flags = FPRINT | TABLEPASS| CONDUCT | NOSPLASH
|
||||
|
||||
/obj/item/assembly/rad_ignite/New()
|
||||
..()
|
||||
spawn(0)
|
||||
if(!part1)
|
||||
part1 = new(src)
|
||||
part1.master = src
|
||||
if(!part2)
|
||||
part2 = new(src)
|
||||
part2.master = src
|
||||
|
||||
/obj/item/assembly/rad_ignite/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
qdel(part3)
|
||||
part3 = null
|
||||
..()
|
||||
|
||||
/obj/item/assembly/rad_ignite/attackby(obj/item/W as obj, mob/user as mob)
|
||||
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
src.part1.set_loc(T)
|
||||
src.part2.set_loc(T)
|
||||
src.part3.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part2.master = null
|
||||
src.part3.master = null
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
src.part3 = null
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if((istype(W, /obj/item/reagent_containers/glass/beaker) && !( src.status )))
|
||||
if(!src.part3)
|
||||
src.part3 = W
|
||||
W.master = src
|
||||
W.layer = initial(W.layer)
|
||||
user.u_equip(W)
|
||||
W.set_loc(src)
|
||||
src.c_state()
|
||||
|
||||
boutput(user, "You attach the radio/igniter assembly to the beaker.")
|
||||
else boutput(user, "You must remove the beaker from the assembly before transferring chemicals to it!")
|
||||
return
|
||||
|
||||
if (!( istype(W, /obj/item/screwdriver) ))
|
||||
return
|
||||
src.status = !( src.status )
|
||||
if (src.status)
|
||||
user.show_message("<span style=\"color:blue\">The radio is now secured! The igniter now works!</span>", 1)
|
||||
else
|
||||
user.show_message("<span style=\"color:blue\">The radio is now unsecured! The igniter will not work.</span>", 1)
|
||||
src.part2.status = src.status
|
||||
src.part1.b_stat = !( src.status )
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_ignite/attack_self(mob/user as mob)
|
||||
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_ignite/receive_signal()
|
||||
for(var/mob/O in hearers(1, src.loc))
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
src.part2.ignite()
|
||||
if(src.part3)
|
||||
src.part3.reagents.temperature_reagents(4000, 400)
|
||||
src.part3.reagents.temperature_reagents(4000, 400)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_ignite/verb/removebeaker()
|
||||
set src in oview(1)
|
||||
set name = "remove beaker"
|
||||
set category = "Local"
|
||||
|
||||
if (usr.stat || !isliving(usr) || isintangible(usr))
|
||||
return
|
||||
|
||||
if(src.part3)
|
||||
src.part3.master = null
|
||||
src.part3.attack_hand(usr)
|
||||
src.part3 = null
|
||||
src.c_state()
|
||||
boutput(usr, "<span style=\"color:blue\">You remove the timer/igniter assembly from the beaker.</span>")
|
||||
else boutput(usr, "<span style=\"color:red\">That doesn't have a beaker attached to it!</span>")
|
||||
|
||||
/obj/item/assembly/rad_ignite/c_state()
|
||||
if(!src.part3)
|
||||
src.icon = 'icons/obj/assemblies.dmi'
|
||||
src.icon_state = text("radio-igniter")
|
||||
src.overlays = null
|
||||
src.underlays = null
|
||||
src.name = "Radio/Igniter Assembly"
|
||||
else
|
||||
src.icon = part3.icon
|
||||
src.icon_state = part3.icon_state
|
||||
src.overlays = null
|
||||
src.underlays = null
|
||||
src.overlays += image('icons/obj/assemblies.dmi', "radignite_overlay", layer = FLOAT_LAYER)
|
||||
src.underlays += part3.underlays
|
||||
src.name = "Radio/Igniter/Beaker Assembly"
|
||||
return
|
||||
|
||||
///////////////////////////////// Health analyzer/igniter /////////////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/anal_ignite //lol
|
||||
name = "Health-Analyzer/Igniter Assembly"
|
||||
desc = "A health-analyzer igniter assembly."
|
||||
icon_state = "timer-igniter0"
|
||||
var/obj/item/device/healthanalyzer/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
status = null
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
item_state = "electronic"
|
||||
|
||||
/obj/item/assembly/anal_ignite/New()
|
||||
..()
|
||||
spawn (5)
|
||||
if (src && !src.part1)
|
||||
src.part1 = new /obj/item/device/healthanalyzer(src)
|
||||
src.part1.master = src
|
||||
if (src && !src.part2)
|
||||
src.part2 = new /obj/item/device/igniter(src)
|
||||
src.part2.master = src
|
||||
return
|
||||
|
||||
/obj/item/assembly/anal_ignite/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
src.part1.set_loc(T)
|
||||
src.part2.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part2.master = null
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
if (( istype(W, /obj/item/screwdriver) ))
|
||||
src.status = !( src.status )
|
||||
if (src.status)
|
||||
user.show_message("<span style=\"color:blue\">The analyzer is now secured!</span>", 1)
|
||||
else
|
||||
user.show_message("<span style=\"color:blue\">The analyzer is now unsecured!</span>", 1)
|
||||
src.part2.status = src.status
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
///////////////////////////////////////////////////// Remote signaller/bike horn /////////////////////
|
||||
|
||||
/obj/item/assembly/radio_horn
|
||||
desc = "A bike horn hastily jammed into a signaller."
|
||||
name = "Radio/Horn Assembly"
|
||||
icon_state = "radio-horn"
|
||||
var/obj/item/device/radio/signaler/part1 = null
|
||||
var/obj/item/bikehorn/part2 = null
|
||||
status = 0.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/radio_horn/New()
|
||||
..()
|
||||
spawn(0)
|
||||
if(!part1)
|
||||
part1 = new(src)
|
||||
part1.master = src
|
||||
if(!part2)
|
||||
part2 = new(src)
|
||||
part2.master = src
|
||||
return
|
||||
|
||||
/obj/item/assembly/radio_horn/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
..()
|
||||
return
|
||||
|
||||
obj/item/assembly/radio_horn/attack_self(mob/user as mob)
|
||||
|
||||
src.part1.attack_self(user)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
obj/item/assembly/radio_horn/receive_signal()
|
||||
if (part2.spam_flag == 0)
|
||||
part2.spam_flag = 1
|
||||
playsound(src.loc, part2.sound_horn, part2.volume, part2.randomized_pitch)
|
||||
spawn(part2.spam_timer)
|
||||
part2.spam_flag = 0
|
||||
return
|
||||
|
||||
/////////////////////////////////////////////////////// Remote signaller/timer /////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/rad_time
|
||||
name = "Signaller/Timer Assembly"
|
||||
desc = "A radio signaller activated by a count-down timer."
|
||||
icon_state = "timer-radio0"
|
||||
var/obj/item/device/radio/signaler/part1 = null
|
||||
var/obj/item/device/timer/part2 = null
|
||||
status = null
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/rad_time/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_time/attackby(obj/item/W as obj, mob/user as mob)
|
||||
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
src.part1.set_loc(T)
|
||||
src.part2.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part2.master = null
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if (!( istype(W, /obj/item/screwdriver) ))
|
||||
return
|
||||
src.status = !( src.status )
|
||||
if (src.status)
|
||||
user.show_message("<span style=\"color:blue\">The signaler is now secured!</span>", 1)
|
||||
else
|
||||
user.show_message("<span style=\"color:blue\">The signaler is now unsecured!</span>", 1)
|
||||
src.part1.b_stat = !( src.status )
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_time/attack_self(mob/user as mob)
|
||||
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.part2.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_time/receive_signal(datum/signal/signal)
|
||||
// drsingh for cannot read null.source
|
||||
if (signal && signal.source == src.part2)
|
||||
src.part1.send_signal("ACTIVATE")
|
||||
return
|
||||
|
||||
////////////////////////////////////////////// Remote signaller/proximity //////////////////////////////////
|
||||
|
||||
/obj/item/assembly/rad_prox
|
||||
name = "Signaller/Prox Sensor Assembly"
|
||||
desc = "A proximity-activated radio signaller."
|
||||
icon_state = "prox-radio0"
|
||||
var/obj/item/device/radio/signaler/part1 = null
|
||||
var/obj/item/device/prox_sensor/part2 = null
|
||||
status = null
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/rad_prox/c_state(n)
|
||||
src.icon_state = "prox-radio[n]"
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/HasProximity(atom/movable/AM as mob|obj)
|
||||
if (istype(AM, /obj/projectile))
|
||||
return
|
||||
if (AM.move_speed < 12 && src && src.part2)
|
||||
src.part2.sense()
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/attackby(obj/item/W as obj, mob/user as mob)
|
||||
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/turf/T = src.loc
|
||||
if (ismob(T))
|
||||
T = T.loc
|
||||
src.part1.set_loc(T)
|
||||
src.part2.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part2.master = null
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if (!( istype(W, /obj/item/screwdriver) ))
|
||||
return
|
||||
src.status = !( src.status )
|
||||
if (src.status)
|
||||
user.show_message("<span style=\"color:blue\">The proximity sensor is now secured!</span>", 1)
|
||||
else
|
||||
user.show_message("<span style=\"color:blue\">The proximity sensor is now unsecured!</span>", 1)
|
||||
src.part1.b_stat = !( src.status )
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/attack_self(mob/user as mob)
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.part2.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/receive_signal(datum/signal/signal)
|
||||
// drsingh for Cannot read null.source
|
||||
if (signal && signal.source == src.part2)
|
||||
src.part1.send_signal("ACTIVATE")
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/Move()
|
||||
..()
|
||||
src.part2.sense()
|
||||
return
|
||||
|
||||
/obj/item/assembly/rad_prox/dropped()
|
||||
spawn( 0 )
|
||||
src.part2.sense()
|
||||
return
|
||||
return
|
||||
@@ -0,0 +1,61 @@
|
||||
/obj/item/assembly/shock_kit
|
||||
name = "Shock Kit"
|
||||
icon_state = "shock_kit"
|
||||
var/obj/item/clothing/head/helmet/part1 = null
|
||||
var/obj/item/device/radio/electropack/part2 = null
|
||||
status = 0.0
|
||||
w_class = 5.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/shock_kit/New()
|
||||
spawn (20)
|
||||
if (src)
|
||||
if (!(src.part1 && istype(src.part1)))
|
||||
src.part1 = new /obj/item/clothing/head/helmet(src)
|
||||
src.part1.master = src
|
||||
if (!(src.part2 && istype(src.part2)))
|
||||
src.part2 = new /obj/item/device/radio/electropack(src)
|
||||
src.part2.master = src
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/disposing()
|
||||
if (src.part1)
|
||||
qdel(src.part1)
|
||||
src.part1 = null
|
||||
if (src.part2)
|
||||
qdel(src.part2)
|
||||
src.part2 = null
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/attackby(obj/item/W as obj, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if (istype(W, /obj/item/wrench))
|
||||
var/turf/T = get_turf(src)
|
||||
if (src.part1)
|
||||
src.part1.set_loc(T)
|
||||
src.part1.master = null
|
||||
src.part1 = null
|
||||
if (src.part2)
|
||||
src.part2.set_loc(T)
|
||||
src.part2.master = null
|
||||
src.part2 = null
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
else return ..()
|
||||
|
||||
/obj/item/assembly/shock_kit/attack_self(mob/user as mob)
|
||||
src.part1.attack_self(user, src.status)
|
||||
src.part2.attack_self(user, src.status)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/shock_kit/receive_signal()
|
||||
if (src.master && istype(src.master, /obj/stool/chair/e_chair))
|
||||
var/obj/stool/chair/e_chair/C = src.master
|
||||
if (C.buckled_guy)
|
||||
logTheThing("signalers", usr, C.buckled_guy, "signalled an electric chair (setting: [C.lethal ? "lethal" : "non-lethal"]), shocking %target% at [log_loc(C)].") // Added (Convair880).
|
||||
C.shock()
|
||||
return
|
||||
@@ -0,0 +1,346 @@
|
||||
/* Contains:
|
||||
- Single tank bomb logs
|
||||
- Single tank bomb (proximity)
|
||||
- Single tank bomb (timer)
|
||||
- Single tank bomb (remote signaller)
|
||||
*/
|
||||
|
||||
// Just a little helper. These three bombs are very similar (Convair880).
|
||||
/obj/item/assembly/proc/bomb_logs(var/mob/user, var/obj/item/bomb, var/type = "", var/welded_or_unwelded = 0, var/is_dud = 0)
|
||||
if (!bomb || !type)
|
||||
return
|
||||
|
||||
if (is_dud == 1)
|
||||
message_admins("A [type] single tank bomb would have opened at [log_loc(bomb)] but was forced to dud! Last touched by: [bomb.fingerprintslast ? "[bomb.fingerprintslast]" : "*null*"]")
|
||||
logTheThing("bombing", null, null, "A [type] single tank bomb would have opened at [log_loc(bomb)] but was forced to dud! Last touched by: [bomb.fingerprintslast ? "[bomb.fingerprintslast]" : "*null*"]")
|
||||
return
|
||||
|
||||
var/obj/item/tank/T = null
|
||||
|
||||
if (istype(bomb, /obj/item/assembly/proximity_bomb/))
|
||||
var/obj/item/assembly/proximity_bomb/PB = bomb
|
||||
if (PB.part3)
|
||||
T = PB.part3
|
||||
if (istype(bomb, /obj/item/assembly/time_bomb/))
|
||||
var/obj/item/assembly/time_bomb/TB = bomb
|
||||
if (TB.part3)
|
||||
T = TB.part3
|
||||
if (istype(bomb, /obj/item/assembly/radio_bomb/))
|
||||
var/obj/item/assembly/radio_bomb/RB = bomb
|
||||
if (RB.part3)
|
||||
T = RB.part3
|
||||
|
||||
if (!T || !istype(T, /obj/item/tank))
|
||||
return
|
||||
|
||||
logTheThing("bombing", user, null, "[welded_or_unwelded == 0 ? "welded" : "unwelded"] a [type] single tank bomb [log_atmos(T)] at [log_loc(user)].")
|
||||
if (welded_or_unwelded == 0)
|
||||
message_admins("[key_name(user)] welded a [type] single tank bomb at [log_loc(user)]. See bombing logs or bomb monitor for complete atmos readout.")
|
||||
|
||||
return
|
||||
|
||||
/////////////////////////////////////////////////// Single tank bomb (proximity) ////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/proximity_bomb
|
||||
desc = "A very intricate igniter and proximity sensor electrical assembly mounted onto top of a plasma tank."
|
||||
name = "Proximity/Igniter/Plasma Tank Assembly"
|
||||
icon_state = "prox-igniter-tank0"
|
||||
var/obj/item/device/prox_sensor/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
var/obj/item/tank/plasma/part3 = null
|
||||
status = 0.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/proximity_bomb/dropped()
|
||||
|
||||
spawn( 0 )
|
||||
src.part1.sense()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/examine()
|
||||
..()
|
||||
src.part3.examine()
|
||||
|
||||
/obj/item/assembly/proximity_bomb/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
qdel(part3)
|
||||
part3 = null
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/obj/item/assembly/prox_ignite/R = new /obj/item/assembly/prox_ignite( )
|
||||
R.part1 = src.part1
|
||||
R.part2 = src.part2
|
||||
user.put_in_hand_or_drop(R)
|
||||
src.part1.set_loc(R)
|
||||
src.part2.set_loc(R)
|
||||
src.part1.master = R
|
||||
src.part2.master = R
|
||||
var/turf/T = src.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
T = T.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
T = T.loc
|
||||
src.part3.set_loc(T)
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
src.part3 = null
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if (!( istype(W, /obj/item/weldingtool) ))
|
||||
return
|
||||
if (!( src.status ))
|
||||
src.status = 1
|
||||
user.show_message("<span style=\"color:blue\">A pressure hole has been bored to the plasma tank valve. The plasma tank can now be ignited.</span>", 1)
|
||||
else
|
||||
src.status = 0
|
||||
boutput(user, "<span style=\"color:blue\">The hole has been closed.</span>")
|
||||
|
||||
src.bomb_logs(user, src, "proximity", src.status == 1 ? 0 : 1, 0)
|
||||
src.part2.status = src.status
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/attack_self(mob/user as mob)
|
||||
|
||||
playsound(src.loc, "sound/weapons/armbomb.ogg", 100, 1)
|
||||
src.part1.attack_self(user, 1)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/receive_signal()
|
||||
//boutput(world, "miptank [src] got signal")
|
||||
for(var/mob/O in hearers(1, null))
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
//Foreach goto(19)
|
||||
|
||||
if (src.status)
|
||||
src.part1.armed = 0
|
||||
src.c_state(0)
|
||||
if (src.force_dud == 1)
|
||||
src.bomb_logs(usr, src, "proximity", 0, 1)
|
||||
return
|
||||
src.part3.ignite()
|
||||
else
|
||||
if (!src.status && src.force_dud == 0)
|
||||
src.part1.armed = 0
|
||||
src.c_state(0)
|
||||
src.part3.release()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/c_state(n)
|
||||
|
||||
src.icon_state = text("prox-igniter-tank[]", n)
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/HasProximity(atom/movable/AM as mob|obj)
|
||||
if (istype(AM, /obj/projectile))
|
||||
return
|
||||
if (AM.move_speed < 12 && src.part1)
|
||||
src.part1.sense()
|
||||
return
|
||||
|
||||
/obj/item/assembly/proximity_bomb/Bump(atom/O)
|
||||
spawn(0)
|
||||
//boutput(world, "miptank bumped into [O]")
|
||||
if(src.part1.armed)
|
||||
//boutput(world, "sending signal")
|
||||
receive_signal()
|
||||
else
|
||||
//boutput(world, "not active")
|
||||
..()
|
||||
|
||||
/obj/item/assembly/proximity_bomb/proc/prox_check()
|
||||
if(!part1 || !part1.armed)
|
||||
return
|
||||
for(var/atom/A in view(1, src.loc))
|
||||
if(A!=src && !istype(A, /turf/space) && !isarea(A))
|
||||
//boutput(world, "[A]:[A.type] was sensed")
|
||||
src.part1.sense()
|
||||
break
|
||||
|
||||
spawn(10)
|
||||
prox_check()
|
||||
|
||||
/////////////////////////////////////////////////// Single tank bomb (timer) ////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/time_bomb
|
||||
desc = "A very intricate igniter and timer assembly mounted onto top of a plasma tank."
|
||||
name = "Timer/Igniter/Plasma Tank Assembly"
|
||||
icon_state = "timer-igniter-tank0"
|
||||
var/obj/item/device/timer/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
var/obj/item/tank/plasma/part3 = null
|
||||
status = 0.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/time_bomb/c_state(n)
|
||||
|
||||
src.icon_state = text("timer-igniter-tank[]", n)
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_bomb/examine()
|
||||
..()
|
||||
src.part3.examine()
|
||||
|
||||
/obj/item/assembly/time_bomb/disposing()
|
||||
qdel(part1)
|
||||
part1 = null
|
||||
qdel(part2)
|
||||
part2 = null
|
||||
qdel(part3)
|
||||
part3 = null
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_bomb/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/obj/item/assembly/time_ignite/R = new /obj/item/assembly/time_ignite( )
|
||||
R.part1 = src.part1
|
||||
R.part2 = src.part2
|
||||
user.put_in_hand_or_drop(R)
|
||||
src.part1.set_loc(R)
|
||||
src.part2.set_loc(R)
|
||||
src.part1.master = R
|
||||
src.part2.master = R
|
||||
var/turf/T = src.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
T = T.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
T = T.loc
|
||||
src.part3.set_loc(T)
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
src.part3 = null
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if (!( istype(W, /obj/item/weldingtool) ))
|
||||
return
|
||||
if (!( src.status ))
|
||||
src.status = 1
|
||||
user.show_message("<span style=\"color:blue\">A pressure hole has been bored to the plasma tank valve. The plasma tank can now be ignited.</span>", 1)
|
||||
else
|
||||
src.status = 0
|
||||
boutput(user, "<span style=\"color:blue\">The hole has been closed.</span>")
|
||||
|
||||
src.part2.status = src.status
|
||||
src.bomb_logs(user, src, "timer", src.status == 1 ? 0 : 1, 0)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_bomb/attack_self(mob/user as mob)
|
||||
|
||||
if (src.part1)
|
||||
src.part1.attack_self(user, 1)
|
||||
playsound(src.loc, "sound/weapons/armbomb.ogg", 100, 1)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/time_bomb/receive_signal()
|
||||
//boutput(world, "tiptank [src] got signal")
|
||||
for(var/mob/O in hearers(1, null))
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
if (src.status)
|
||||
if (src.force_dud == 1)
|
||||
src.bomb_logs(usr, src, "timer", 0, 1)
|
||||
return
|
||||
src.part3.ignite()
|
||||
else
|
||||
if (!src.status && src.force_dud == 0)
|
||||
src.part3.release()
|
||||
return
|
||||
|
||||
/////////////////////////////////////////////////// Single tank bomb (remote signaller) ////////////////////////////////////
|
||||
|
||||
/obj/item/assembly/radio_bomb
|
||||
desc = "A very intricate igniter and signaller electrical assembly mounted onto top of a plasma tank."
|
||||
name = "Radio/Igniter/Plasma Tank Assembly"
|
||||
icon_state = "radio-igniter-tank"
|
||||
var/obj/item/device/radio/signaler/part1 = null
|
||||
var/obj/item/device/igniter/part2 = null
|
||||
var/obj/item/tank/plasma/part3 = null
|
||||
status = 0.0
|
||||
flags = FPRINT | TABLEPASS| CONDUCT
|
||||
|
||||
/obj/item/assembly/radio_bomb/examine()
|
||||
..()
|
||||
src.part3.examine()
|
||||
|
||||
/obj/item/assembly/radio_bomb/Del()
|
||||
|
||||
//src.part1 = null
|
||||
qdel(src.part1)
|
||||
//src.part2 = null
|
||||
qdel(src.part2)
|
||||
//src.part3 = null
|
||||
qdel(src.part3)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/assembly/radio_bomb/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if ((istype(W, /obj/item/wrench) && !( src.status )))
|
||||
var/obj/item/assembly/rad_ignite/R = new /obj/item/assembly/rad_ignite( )
|
||||
R.part1 = src.part1
|
||||
R.part2 = src.part2
|
||||
user.put_in_hand_or_drop(R)
|
||||
src.part1.set_loc(R)
|
||||
src.part2.set_loc(R)
|
||||
src.part1.master = R
|
||||
src.part2.master = R
|
||||
var/turf/T = src.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
T = T.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
T = T.loc
|
||||
src.part3.set_loc(T)
|
||||
src.part1 = null
|
||||
src.part2 = null
|
||||
src.part3 = null
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
if (!( istype(W, /obj/item/weldingtool) ))
|
||||
return
|
||||
if (!( src.status ))
|
||||
src.status = 1
|
||||
user.show_message("<span style=\"color:blue\">A pressure hole has been bored to the plasma tank valve. The plasma tank can now be ignited.</span>", 1)
|
||||
else
|
||||
src.status = 0
|
||||
boutput(user, "<span style=\"color:blue\">The hole has been closed.</span>")
|
||||
|
||||
src.bomb_logs(user, src, "radio", src.status == 1 ? 0 : 1, 0)
|
||||
src.part2.status = src.status
|
||||
src.part1.b_stat = !( src.status )
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/radio_bomb/attack_self(mob/user as mob)
|
||||
|
||||
if (src.part1)
|
||||
playsound(src.loc, "sound/weapons/armbomb.ogg", 100, 1)
|
||||
src.part1.attack_self(user, 1)
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/assembly/radio_bomb/receive_signal()
|
||||
//boutput(world, "riptank [src] got signal")
|
||||
for(var/mob/O in hearers(1, null))
|
||||
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
||||
if (src.status)
|
||||
if (src.force_dud == 1)
|
||||
src.bomb_logs(usr, src, "radio", 0, 1)
|
||||
return
|
||||
src.part3.ignite()
|
||||
else
|
||||
if (!src.status && src.force_dud == 0)
|
||||
src.part3.release()
|
||||
return
|
||||
@@ -0,0 +1,319 @@
|
||||
//BASKETBALL
|
||||
|
||||
/obj/item/basketball
|
||||
name = "basketball"
|
||||
desc = "If you can't slam with the best, then jam with the rest."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "bball"
|
||||
item_state = "bball"
|
||||
w_class = 3.0
|
||||
force = 0
|
||||
throw_range = 10
|
||||
throwforce = 0
|
||||
var/obj/item/plutonium_core/payload = null
|
||||
stamina_damage = 5
|
||||
stamina_cost = 5
|
||||
stamina_crit_chance = 5
|
||||
|
||||
/obj/item/basketball/attack_hand(mob/user as mob)
|
||||
..()
|
||||
if(user)
|
||||
src.icon_state = "bball"
|
||||
|
||||
/obj/item/basketball/throw_impact(atom/hit_atom)
|
||||
..(hit_atom)
|
||||
src.icon_state = "bball"
|
||||
if(hit_atom)
|
||||
playsound(src.loc, "sound/items/bball_bounce.ogg", 65, 1)
|
||||
if(ismob(hit_atom))
|
||||
var/mob/M = hit_atom
|
||||
if(ishuman(M))
|
||||
if((prob(50) && M.bioHolder.HasEffect("clumsy")) || M.equipped() || get_dir(M, src) == M.dir)
|
||||
src.visible_message("<span class='combat'>[M] gets beaned with the [src.name].</span>")
|
||||
M.stunned = max(2, M.stunned)
|
||||
return
|
||||
// catch the ball!
|
||||
src.attack_hand(M)
|
||||
M.visible_message("<span class='combat'>[M] catches the [src.name]!</span>", "<span class='combat'>You catch the [src.name]!</span>")
|
||||
logTheThing("combat", M, null, "catches [src]")
|
||||
return
|
||||
src.visible_message("<span class='combat'>[M] gets beaned with the [src.name].</span>")
|
||||
logTheThing("combat", M, null, "is struck by [src]")
|
||||
M.stunned = max(2, M.stunned)
|
||||
return
|
||||
|
||||
/obj/item/basketball/throw_at(atom/target, range, speed)
|
||||
src.icon_state = "bball_spin"
|
||||
..(target, range, speed)
|
||||
|
||||
/obj/item/basketball/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/plutonium_core))
|
||||
boutput(user, "<span style=\"color:blue\">You insert the [W.name] into the [src.name].</span>")
|
||||
user.u_equip(W)
|
||||
W.dropped(user)
|
||||
W.layer = initial(W.layer)
|
||||
W.set_loc(src)
|
||||
src.payload = W
|
||||
if(src.loc == user)
|
||||
user.verbs += /proc/chaos_dunk
|
||||
return
|
||||
..(W, user)
|
||||
return
|
||||
|
||||
/obj/item/basketball/attack_hand(mob/user as mob)
|
||||
..()
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H) && payload && istype(payload))
|
||||
H.verbs += /proc/chaos_dunk
|
||||
return
|
||||
|
||||
/obj/item/basketball/unequipped(var/mob/user)
|
||||
if(payload && istype(payload))
|
||||
user.verbs -= /proc/chaos_dunk
|
||||
..()
|
||||
|
||||
// hoop
|
||||
|
||||
/obj/item/bballbasket
|
||||
name = "basketball hoop" // it's a hoop you nerd, not a basket
|
||||
desc = "Can be mounted on walls."
|
||||
opacity = 0
|
||||
density = 0
|
||||
anchored = 0
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "bbasket0"
|
||||
var/mounted = 0
|
||||
var/active = 0
|
||||
var/probability = 40
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (istype(W,/obj/item/wrench) && mounted)
|
||||
src.visible_message("<span style=\"color:blue\"><b>[user] removes [src].</b></span>")
|
||||
src.pixel_y = 0
|
||||
src.pixel_x = 0
|
||||
src.anchored = 0
|
||||
src.mounted = 0
|
||||
else if (src.mounted && !istype(W, /obj/item/bballbasket))
|
||||
if (W.cant_drop) return
|
||||
src.visible_message("<span style=\"color:blue\"><b>[user]</b> jumps up and tries to dunk [W] into [src]!</span>")
|
||||
user.u_equip(W)
|
||||
if (user.bioHolder.HasEffect("clumsy") && prob(50)) // clowns are not good at basketball I guess
|
||||
user.visible_message("<span class='combat'><b>[user] knocks their head into the rim of [src]!</b></span>")
|
||||
user.weakened = max(5, user.weakened)
|
||||
if (!src.shoot(W, user))
|
||||
spawn(10)
|
||||
src.visible_message("<span style=\"color:red\">[user] whiffs the dunk.</span>")
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if (mounted)
|
||||
return
|
||||
else
|
||||
return ..(user)
|
||||
|
||||
afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
|
||||
if (!mounted && get_dist(src, target) == 1)
|
||||
if (isturf(target) && target.density)
|
||||
//if (get_dir(src,target) == NORTH || get_dir(src,target) == EAST || get_dir(src,target) == SOUTH || get_dir(src,target) == WEST)
|
||||
if (get_dir(src,target) in cardinal)
|
||||
src.visible_message("<span style=\"color:blue\"><b>[user] mounts [src] on [target].</b></span>")
|
||||
user.drop_item()
|
||||
src.loc = get_turf(user)
|
||||
src.mounted = 1
|
||||
src.anchored = 1
|
||||
src.dir = get_dir(src, target)
|
||||
switch (src.dir)
|
||||
if (NORTH)
|
||||
src.pixel_y = 20
|
||||
if (SOUTH)
|
||||
src.pixel_y = -20
|
||||
if (EAST)
|
||||
src.pixel_x = 20
|
||||
if (WEST)
|
||||
src.pixel_x = -20
|
||||
return
|
||||
|
||||
HasEntered(atom/A)
|
||||
if (src.active)
|
||||
return
|
||||
if (istype(A, /obj/item/bballbasket)) // oh for FUCK'S SAKE
|
||||
return // NO
|
||||
if (istype(A, /obj/item))
|
||||
src.shoot(A)
|
||||
|
||||
proc/shoot(var/obj/O as obj, var/mob/user as mob)
|
||||
if (!O)
|
||||
return 0
|
||||
if (istype(O, /obj/item/bballbasket))
|
||||
return
|
||||
src.active = 1
|
||||
if (user)
|
||||
user.u_equip(O)
|
||||
O.set_loc(get_turf(src))
|
||||
if (prob(src.probability)) // It might land!
|
||||
if (prob(30)) // It landed cleanly!
|
||||
src.visible_message("<span style=\"color:blue\">[O] lands cleanly in [src]!</span>")
|
||||
src.basket(O)
|
||||
else // Aaaa the tension!
|
||||
src.visible_message("<span style=\"color:red\">[O] teeters on the edge of [src]!</span>")
|
||||
var/delay = rand(5, 15)
|
||||
animate_horizontal_wiggle(O, delay, 5, 1, -1) // target, number of animation loops, speed, positive x variation, negative x variation
|
||||
spawn(delay)
|
||||
if (O && O.loc == src.loc)
|
||||
if (prob(40)) // It goes in!
|
||||
src.visible_message("<span style=\"color:blue\">[O] slips into [src]!</span>")
|
||||
src.basket(O)
|
||||
else
|
||||
src.visible_message("<span style=\"color:red\">[O] slips off of the edge of [src]!</span>")
|
||||
src.active = 0
|
||||
else
|
||||
src.active = 0
|
||||
src.active = 0
|
||||
return 1
|
||||
else
|
||||
src.active = 0
|
||||
return 0
|
||||
|
||||
proc/basket(var/atom/A as obj|mob)
|
||||
if (!A || isarea(A) || isturf(A))
|
||||
return
|
||||
src.active = 1
|
||||
playsound(get_turf(src), "rustle", 75, 1)
|
||||
A.invisibility = 100
|
||||
flick("bbasket1", src)
|
||||
spawn(15)
|
||||
A.invisibility = 0
|
||||
src.active = 0
|
||||
|
||||
/obj/item/bballbasket/testing
|
||||
probability = 100
|
||||
|
||||
//PLUTONIUM CORE
|
||||
|
||||
/obj/item/plutonium_core
|
||||
name = "plutonium core"
|
||||
desc = "A payload from a nuclear warhead. Comprised of weapons-grade plutonium."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "plutonium"
|
||||
item_state = "egg3"
|
||||
w_class = 3.0
|
||||
force = 0
|
||||
throwforce = 10
|
||||
|
||||
/obj/item/plutonium_core/attack_hand(mob/user as mob)
|
||||
..()
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.gloves)
|
||||
boutput(H, "<span class='combat'>Your hand burns from grabbing the [src.name].</span>")
|
||||
var/obj/item/affecting = H.organs["r_arm"]
|
||||
if(H.hand)
|
||||
affecting = H.organs["l_arm"]
|
||||
if(affecting)
|
||||
affecting.take_damage(0, 15)
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
|
||||
|
||||
//BLOOD BOWL BALL
|
||||
|
||||
/obj/item/bloodbowlball
|
||||
name = "spiked ball"
|
||||
desc = "An american football studded with sharp spikes and serrated blades. Looks dangerous."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "bloodbowlball"
|
||||
item_state = "bloodbowlball"
|
||||
w_class = 3.0
|
||||
force = 10
|
||||
throw_range = 10
|
||||
throwforce = 2
|
||||
|
||||
/obj/item/bloodbowlball/attack_hand(mob/user as mob)
|
||||
..()
|
||||
if(user)
|
||||
src.icon_state = "bloodbowlball"
|
||||
|
||||
/obj/item/bloodbowlball/throw_impact(atom/hit_atom)
|
||||
..(hit_atom)
|
||||
src.icon_state = "bloodbowlball"
|
||||
if(hit_atom)
|
||||
playsound(src.loc, "sound/items/bball_bounce.ogg", 65, 1)
|
||||
if(ismob(hit_atom))
|
||||
var/mob/M = hit_atom
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/T = M
|
||||
if(prob(20) || T.equipped() || get_dir(T, src) == T.dir)
|
||||
for(var/mob/V in AIviewers(src, null))
|
||||
if(V.client)
|
||||
V.show_message("<span class='combat'>[T] gets stabbed by one of the [src.name]'s spikes.</span>", 1)
|
||||
playsound(src.loc, "sound/effects/bloody_stabOLD.ogg", 65, 1)
|
||||
T.stunned = max(5, T.stunned)
|
||||
T.TakeDamage("chest", 30, 0)
|
||||
take_bleeding_damage(T, null, 15, DAMAGE_STAB)
|
||||
return
|
||||
else if (prob(50))
|
||||
src.visible_message("<span class='combat'>[T] catches the [src.name] but gets cut.</span>")
|
||||
T.TakeDamage(T.hand == 1 ? "l_arm" : "r_arm", 15, 0)
|
||||
take_bleeding_damage(T, null, 10, DAMAGE_CUT)
|
||||
src.attack_hand(T)
|
||||
return
|
||||
// catch the ball!
|
||||
else
|
||||
src.attack_hand(T)
|
||||
T.visible_message("<span class='combat'>[M] catches the [src.name]!</span>")
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/bloodbowlball/throw_at(atom/target, range, speed)
|
||||
src.icon_state = "bloodbowlball_air"
|
||||
..(target, range, speed)
|
||||
|
||||
/obj/item/bloodbowlball/attack(target as mob, mob/user as mob)
|
||||
playsound(target, "sound/effects/bloody_stab.ogg", 60, 1)
|
||||
if(iscarbon(target))
|
||||
if(target:stat != 2)
|
||||
var/mob/living/carbon/targMob = target
|
||||
targMob.visible_message("<span class='combat'><B>[user] attacks [target] with the [src]!</B></span>")
|
||||
take_bleeding_damage(target, user, 5, DAMAGE_STAB)
|
||||
if(prob(30))
|
||||
if(prob(30))
|
||||
boutput(user, "<span class='combat'>You accidentally cut your hand badly!</span>")
|
||||
user.TakeDamage(user.hand == 1 ? "l_arm" : "r_arm", 10, 0)
|
||||
take_bleeding_damage(user, user, 5, DAMAGE_CUT)
|
||||
else
|
||||
boutput(user, "<span class='combat'>You accidentally cut your hand!</span>")
|
||||
user.TakeDamage(user.hand == 1 ? "l_arm" : "r_arm", 5, 0)
|
||||
take_bleeding_damage(user, null, 1, DAMAGE_CUT, 0)
|
||||
|
||||
// MADDEN NFL FOOTBALL 2051
|
||||
|
||||
/obj/item/football
|
||||
name = "football"
|
||||
desc = "A pigskin. An oblate leather spheroid. For tossing around."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "football"
|
||||
item_state = "football"
|
||||
w_class = 3.0
|
||||
force = 0
|
||||
throw_range = 10
|
||||
throwforce = 0
|
||||
|
||||
/obj/item/football/throw_at(atom/target, range, speed)
|
||||
src.icon_state = "football_air"
|
||||
..(target, range, speed)
|
||||
|
||||
/obj/item/football/throw_impact(atom/hit_atom)
|
||||
..(hit_atom)
|
||||
src.icon_state = "football"
|
||||
if(hit_atom)
|
||||
playsound(src.loc, "sound/items/bball_bounce.ogg", 65, 1)
|
||||
|
||||
/obj/item/football/suicide(var/mob/user as mob)
|
||||
user.visible_message("<span style=\"color:red\"><b>[user] spikes the [src.name]. It bounces back up and hits \him square in the forehead!</b></span>")
|
||||
user.TakeDamage("head", 150, 0)
|
||||
playsound(src.loc, "sound/items/bball_bounce.ogg", 50, 1)
|
||||
user.updatehealth()
|
||||
spawn(100)
|
||||
if (user)
|
||||
user.suiciding = 0
|
||||
return 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
/obj/item/clothing/under/gimmick/bowling
|
||||
name = "bowling suit"
|
||||
desc = "Who's up for some bowling?"
|
||||
icon = 'icons/obj/clothing/uniforms/item_js_athletic.dmi'
|
||||
wear_image_icon = 'icons/mob/jumpsuits/worn_js_athletic.dmi'
|
||||
inhand_image_icon = 'icons/mob/inhand/jumpsuit/hand_js_athletic.dmi'
|
||||
icon_state = "bowling"
|
||||
item_state = "bowling"
|
||||
|
||||
/obj/item/bowling_ball
|
||||
name = "bowling ball"
|
||||
desc = "Just keep rollin' rollin'."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "bowling_ball"
|
||||
w_class = 3.0
|
||||
force = 5
|
||||
throw_speed = 1
|
||||
|
||||
proc/hitWeak(var/mob/hitMob, var/mob/user)
|
||||
hitMob.visible_message("<span style=\"color:red\">[hitMob] is hit by [user]'s [src]!</span>")
|
||||
|
||||
src.damage(hitMob, 5, 10, user)
|
||||
|
||||
proc/hitHard(var/mob/hitMob, var/mob/user)
|
||||
hitMob.visible_message("<span style=\"color:red\">[hitMob] is knocked over by [user]'s [src]!</span>")
|
||||
|
||||
src.damage(hitMob, 10, 15, user)
|
||||
|
||||
proc/damage(var/mob/hitMob, damMin, damMax, var/mob/living/carbon/human/user)
|
||||
if(user.w_uniform && istype(user.w_uniform, /obj/item/clothing/under/gimmick/bowling))
|
||||
hitMob.weakened = max(damMax-10, hitMob.weakened) // Reduced to 10 sec. Don't stun them for 30 sec from a single hit, Christ.
|
||||
hitMob.stuttering = max(damMax-5, hitMob.stuttering)
|
||||
hitMob.stunned = max(damMax-10, hitMob.stunned)
|
||||
hitMob.TakeDamage("chest", rand(damMin, damMax), 0)
|
||||
else
|
||||
hitMob.stuttering = max(damMax-5, hitMob.stuttering)
|
||||
hitMob.TakeDamage("chest", rand(damMin, damMax), 0)
|
||||
|
||||
throw_at(atom/target, range, speed)
|
||||
throw_unlimited = 1
|
||||
src.icon_state = "bowling_ball_spin"
|
||||
..(target, range, speed)
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
..()
|
||||
if(user)
|
||||
src.icon_state = "bowling_ball"
|
||||
|
||||
throw_impact(atom/hit_atom)
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
src.icon_state = "bowling_ball"
|
||||
if(hit_atom)
|
||||
playsound(src.loc, "sound/effects/exlow.ogg", 65, 1)
|
||||
if (ismob(hit_atom))
|
||||
var/mob/hitMob = hit_atom
|
||||
if (ishuman(hitMob))
|
||||
spawn( 0 )
|
||||
if (istype(user))
|
||||
if (user.w_uniform && istype(user.w_uniform, /obj/item/clothing/under/gimmick/bowling))
|
||||
src.hitHard(hitMob, user)
|
||||
|
||||
if(!(hitMob == user))
|
||||
user.say(pick("Who's the kingpin now, baby?", "STRIIIKE!", "Watch it, pinhead!", "Ten points!"))
|
||||
else
|
||||
src.hitWeak(hitMob, user)
|
||||
else
|
||||
src.hitWeak(hitMob, user)
|
||||
return
|
||||
@@ -0,0 +1,119 @@
|
||||
/obj/item/brain
|
||||
name = "brain"
|
||||
desc = "A human brain, gross."
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "brain2"
|
||||
inhand_image_icon = 'icons/mob/inhand/hand_medical.dmi'
|
||||
item_state = "brain2"
|
||||
flags = TABLEPASS
|
||||
force = 1.0
|
||||
w_class = 1.0
|
||||
throwforce = 1.0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
var/datum/mind/owner = null
|
||||
stamina_damage = 5
|
||||
stamina_cost = 5
|
||||
edible = 1
|
||||
|
||||
/obj/item/brain/New()
|
||||
..()
|
||||
spawn(5)
|
||||
if(src.donor)
|
||||
src.name = "[src.donor]'s brain"
|
||||
if (icon_state == "brain2")
|
||||
desc = "A human brain. It looks [pick("small", "big", "normal", "rotten", "healthy", "tasty", "like it should be flushed down disposals", "bloody")]."
|
||||
|
||||
/obj/item/brain/examine()
|
||||
..()
|
||||
if (usr.job == "Roboticist" || usr.job == "Medical Doctor" || usr.job == "Geneticist" || usr.job == "Medical Director")
|
||||
if (src.owner)
|
||||
if (src.owner.current)
|
||||
boutput(usr, "<span style=\"color:blue\">This brain is still warm.</span>")
|
||||
else
|
||||
boutput(usr, "<span style=\"color:red\">This brain has gone cold.</span>")
|
||||
else
|
||||
boutput(usr, "<span style=\"color:red\">This brain has gone cold.</span>")
|
||||
|
||||
/obj/item/brain/throw_impact(var/turf/T)
|
||||
playsound(src.loc, "sound/effects/splat.ogg", 100, 1)
|
||||
if (T)
|
||||
new /obj/decal/cleanable/blood(T)
|
||||
|
||||
/obj/item/brain/synth
|
||||
name = "synthbrain"
|
||||
item_state = "plant"
|
||||
desc = "An artificial mass of grey matter. Not actually, as one might assume, very good at thinking."
|
||||
|
||||
New()
|
||||
..()
|
||||
src.icon_state = pick("plant_brain", "plant_brain_bloom")
|
||||
|
||||
/obj/item/brain/ai
|
||||
name = "neural net processor"
|
||||
desc = "A heavily augmented human brain, upgraded to deal with the large amount of information an AI unit must process."
|
||||
icon_state = "ai_brain"
|
||||
item_state = "ai_brain"
|
||||
|
||||
New()
|
||||
..()
|
||||
spawn(10)
|
||||
if(src.owner && src.owner.current)
|
||||
src.name = "[src.owner.current]'s neural net processor"
|
||||
|
||||
/obj/item/brain/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
if(!istype(M, /mob))
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if(!(user.zone_sel.selecting == ("head")) || !istype(M, /mob/living/carbon/human))
|
||||
return ..()
|
||||
|
||||
if(!(locate(/obj/machinery/optable, M.loc) && M.lying) && !(locate(/obj/table, M.loc) && (M.paralysis || M.stat)))
|
||||
return ..()
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.c_flags & COVERSEYES) || (H.wear_mask && H.wear_mask.c_flags & COVERSEYES) || (H.glasses && H.glasses.c_flags & COVERSEYES)))
|
||||
// you can't stab someone in the eyes wearing a mask!
|
||||
boutput(user, "<span style=\"color:blue\">You're going to need to remove that mask/helmet/glasses first.</span>")
|
||||
return
|
||||
|
||||
//since these people will be dead M != usr
|
||||
/*
|
||||
if(M:brain_op_stage == 4.0)
|
||||
|
||||
var/fluff = pick("insert[M == user ? "" : "s"]", "shove[M == user ? "" : "s"]", "place[M == user ? "" : "s"]", "drop[M == user ? "" : "s"]", "smooshes[M == user ? "" : "s"]", "squishes[M == user ? "" : "s"]")
|
||||
M.visible_message("<span style=\"color:red\"><b>[user]</b> [fluff] [src] into [M == user ? </span>"[M.gender == "male" ? "his" : "her"]" : "[M]'s"] head!", \
|
||||
"<span style=\"color:red\">[M == user ? </span>"You" : "<b>[user]</b>"] [fluff] [src] into your head!")
|
||||
|
||||
if(M.client)
|
||||
M.client.mob = new/mob/dead/observer(M)
|
||||
//a mob can't have two clients so get rid of one
|
||||
|
||||
if(src.owner)
|
||||
/*
|
||||
//if the brain has an owner corpse
|
||||
if(src.owner.client)
|
||||
//if the player hasn't ghosted
|
||||
src.owner.client.mob = M
|
||||
//then put them in M
|
||||
else
|
||||
//if the player HAS ghosted
|
||||
for(var/mob/dead/observer/O in mobs)
|
||||
if(O.corpse == src.owner && O.client)
|
||||
//find their ghost
|
||||
O.client.mob = M
|
||||
//put their mob in M
|
||||
qdel(O)
|
||||
//delete thier ghost
|
||||
*/
|
||||
src.owner.transfer_to(M)
|
||||
M:brain_op_stage = 3.0
|
||||
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,133 @@
|
||||
/obj/item/medical
|
||||
name = "medical pack"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
inhand_image_icon = 'icons/mob/inhand/hand_medical.dmi'
|
||||
amount = 5
|
||||
w_class = 1
|
||||
throw_speed = 4
|
||||
throw_range = 20
|
||||
var/heal_brute = 0
|
||||
var/heal_burn = 0
|
||||
stamina_damage = 3
|
||||
stamina_cost = 3
|
||||
stamina_crit_chance = 3
|
||||
|
||||
examine()
|
||||
set src in view(1)
|
||||
set category = "Local"
|
||||
|
||||
if (src.amount <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
boutput(usr, "[bicon(src)] <span style=\"color:blue\">There [src.amount == 1 ? "is" : "are"] [src.amount] [src.name]\s left on the stack!</span>")
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if (user.r_hand == src || user.l_hand == src)
|
||||
src.add_fingerprint(user)
|
||||
var/obj/item/medical/split = new src.type(user)
|
||||
split.amount = 1
|
||||
user.put_in_hand_or_drop(split)
|
||||
|
||||
src.amount--
|
||||
if (src.amount < 1)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
attackby(obj/item/medical/W as obj, mob/user as mob)
|
||||
if (!istype(W, src.type))
|
||||
return
|
||||
|
||||
if (W.amount == 5)
|
||||
return
|
||||
|
||||
if (W.amount + src.amount > 5)
|
||||
src.amount = (W.amount + src.amount) - 5
|
||||
W.amount = 5
|
||||
else
|
||||
W.amount += src.amount
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
attack(mob/M as mob, mob/user as mob)
|
||||
if (issilicon(M))
|
||||
if (prob(5))
|
||||
user.show_text("I'm a doctor, not a mechanic.", "red")
|
||||
else
|
||||
user.show_text("You can't seem to find any flesh on this patient.", "red")
|
||||
return
|
||||
if (user)
|
||||
if (M != user)
|
||||
M.visible_message("<span style=\"color:red\">[M] has been applied with [src] by [user]</span>",)
|
||||
else
|
||||
var/t_himself = "itself"
|
||||
if (user.gender == MALE)
|
||||
t_himself = "himself"
|
||||
else if (user.gender == FEMALE)
|
||||
t_himself = "herself"
|
||||
|
||||
M.visible_message("<span style=\"color:red\">[M] applied [src] on [t_himself]</span>")
|
||||
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/affecting = H.organs["chest"]
|
||||
|
||||
if (ishuman(user))
|
||||
var/mob/living/carbon/human/user2 = user
|
||||
var/t = user2.zone_sel.selecting
|
||||
|
||||
if (H.organs[t])
|
||||
affecting = H.organs[t]
|
||||
else
|
||||
if (!istype(affecting, /obj/item) || affecting:burn_dam <= 0)
|
||||
affecting = H.organs["head"]
|
||||
if (!istype(affecting, /obj/item) || affecting:burn_dam <= 0)
|
||||
affecting = H.organs["chest"]
|
||||
|
||||
if (affecting.heal_damage(src.heal_brute, src.heal_burn))
|
||||
H.UpdateDamageIcon()
|
||||
|
||||
if (M != user && ishuman(M) && ishuman(user))
|
||||
if (M.gender != user.gender)
|
||||
M.unlock_medal("Oh, Doctor!", 1)
|
||||
user.unlock_medal("Oh, Doctor!", 1)
|
||||
else
|
||||
H.UpdateDamage()
|
||||
else
|
||||
M.HealDamage("All", src.heal_brute, src.heal_burn)
|
||||
|
||||
repair_bleeding_damage(M, 50, 1)
|
||||
M.updatehealth()
|
||||
|
||||
src.amount--
|
||||
if (src.amount <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/medical/bruise_pack
|
||||
name = "bruise pack"
|
||||
desc = "A pack designed to treat blunt-force trauma."
|
||||
icon_state = "brutepack"
|
||||
heal_brute = 60
|
||||
|
||||
cyborg
|
||||
name = "Tissue Mender"
|
||||
heal_brute = 60
|
||||
amount = INFINITY
|
||||
|
||||
/obj/item/medical/ointment
|
||||
name = "ointment"
|
||||
icon_state = "ointment"
|
||||
heal_burn = 40
|
||||
desc = "A topical ointment designed to heal burns."
|
||||
|
||||
cyborg
|
||||
name = "Burn Salve Dispenser"
|
||||
heal_burn = 40
|
||||
amount = INFINITY
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,408 @@
|
||||
// the cable coil object, used for laying cable
|
||||
|
||||
#define MAXCOIL 30
|
||||
/obj/item/cable_coil
|
||||
name = "cable coil"
|
||||
var/base_name = "cable coil"
|
||||
desc = "A coil of power cable."
|
||||
amount = MAXCOIL
|
||||
max_stack = MAXCOIL
|
||||
stack_type = /obj/item/cable_coil // so cut cables can stack with partially depleted full coils
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "coil"
|
||||
inhand_image_icon = 'icons/mob/inhand/hand_tools.dmi'
|
||||
item_state = "coil"
|
||||
throwforce = 10
|
||||
w_class = 1.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
flags = TABLEPASS|EXTRADELAY|FPRINT|CONDUCT
|
||||
stamina_damage = 5
|
||||
stamina_cost = 5
|
||||
stamina_crit_chance = 10
|
||||
rand_pos = 1
|
||||
|
||||
var/datum/material/insulator = null
|
||||
var/datum/material/conductor = null
|
||||
|
||||
// will use getCachedMaterial() to apply these at spawn
|
||||
var/spawn_insulator_name = "synthrubber"
|
||||
var/spawn_conductor_name = "steel"
|
||||
|
||||
New(loc, length = MAXCOIL)
|
||||
src.amount = length
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
updateicon()
|
||||
..(loc)
|
||||
if (spawn_conductor_name)
|
||||
applyCableMaterials(src, getCachedMaterial(spawn_insulator_name), getCachedMaterial(spawn_conductor_name))
|
||||
|
||||
before_stack(atom/movable/O as obj, mob/user as mob)
|
||||
user.visible_message("<span style=\"color:blue\">[user] begins coiling cable!</span>")
|
||||
|
||||
after_stack(atom/movable/O as obj, mob/user as mob, var/added)
|
||||
boutput(user, "<span style=\"color:blue\">You finish coiling cable.</span>")
|
||||
|
||||
suicide(var/mob/user as mob)
|
||||
user.visible_message("<span style=\"color:red\"><b>[user] wraps the cable around \his neck and tightens it.</b></span>")
|
||||
user.take_oxygen_deprivation(160)
|
||||
user.updatehealth()
|
||||
spawn(100)
|
||||
if (user)
|
||||
user.suiciding = 0
|
||||
return 1
|
||||
|
||||
proc/setInsulator(var/datum/material/M)
|
||||
if (!M)
|
||||
return
|
||||
insulator = M
|
||||
applyCableMaterials(src, M, conductor)
|
||||
|
||||
proc/setConductor(var/datum/material/M)
|
||||
if (!M)
|
||||
return
|
||||
conductor = M
|
||||
applyCableMaterials(src, insulator, M)
|
||||
|
||||
proc/updateName()
|
||||
if (!conductor)
|
||||
return
|
||||
if (insulator)
|
||||
name = "[insulator.name]-insulated [conductor.name]-[base_name]"
|
||||
else
|
||||
name = "uninsulated [conductor.name]-[base_name]"
|
||||
|
||||
proc/use(var/used)
|
||||
if (src.amount < used)
|
||||
return 0
|
||||
else if (src.amount == used)
|
||||
qdel(src)
|
||||
else
|
||||
amount -= used
|
||||
updateicon()
|
||||
return 1
|
||||
|
||||
proc/take(var/amt, var/newloc)
|
||||
if (amt > amount)
|
||||
amt = amount
|
||||
if (amt == amount)
|
||||
if (ismob(loc))
|
||||
var/mob/owner = loc
|
||||
owner.u_equip(src)
|
||||
loc = newloc
|
||||
return src
|
||||
src.use(amt)
|
||||
var/obj/item/cable_coil/C = new /obj/item/cable_coil(newloc)
|
||||
C.amount = amt
|
||||
C.updateicon()
|
||||
C.setInsulator(insulator)
|
||||
C.setConductor(conductor)
|
||||
|
||||
proc/updateicon()
|
||||
if (amount <= 0)
|
||||
qdel(src)
|
||||
else if (amount >= 1 && amount <= 4)
|
||||
icon_state = "coil[amount]"
|
||||
base_name = "cable piece"
|
||||
else
|
||||
icon_state = "coil"
|
||||
base_name = "cable coil"
|
||||
updateName()
|
||||
|
||||
/obj/item/cable_coil/cut
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "coil2"
|
||||
New(loc, length)
|
||||
if (length)
|
||||
..(loc, length)
|
||||
else
|
||||
..(loc, rand(1,2))
|
||||
|
||||
/obj/item/cable_coil/cut/small
|
||||
New(loc, length)
|
||||
..(loc, rand(1,5))
|
||||
|
||||
/obj/item/cable_coil/attack_self(var/mob/living/M)
|
||||
if (istype(M))
|
||||
if (M.move_laying)
|
||||
M.move_laying = null
|
||||
boutput(M, "<span style=\"color:blue\">No longer laying the cable while moving.</span>")
|
||||
else
|
||||
M.move_laying = src
|
||||
boutput(M, "<span style=\"color:blue\">Now laying cable while moving.</span>")
|
||||
|
||||
/obj/proc/move_callback(var/mob/M, var/turf/source, var/turf/target)
|
||||
return
|
||||
|
||||
/proc/find_half_cable(var/turf/T, var/ignore_dir)
|
||||
for (var/obj/cable/C in T)
|
||||
if (!C.d1 && C.d2 != ignore_dir)
|
||||
return C
|
||||
|
||||
/obj/item/cable_coil/move_callback(var/mob/living/M, var/turf/source, var/turf/target)
|
||||
if (!istype(M))
|
||||
return
|
||||
if (!src.amount)
|
||||
M.move_laying = null
|
||||
boutput(M, "<span style=\"color:red\">Your cable coil runs out!</span>")
|
||||
return
|
||||
var/obj/cable/C
|
||||
|
||||
C = find_half_cable(source, get_dir(source, target))
|
||||
if (C)
|
||||
cable_join_between(C, target)
|
||||
else
|
||||
turf_place_between(source, target)
|
||||
|
||||
if (!src.amount)
|
||||
M.move_laying = null
|
||||
boutput(M, "<span style=\"color:red\">Your cable coil runs out!</span>")
|
||||
return
|
||||
|
||||
C = find_half_cable(target, get_dir(target, source))
|
||||
|
||||
if (C)
|
||||
cable_join_between(C, source)
|
||||
else
|
||||
turf_place_between(target, source)
|
||||
|
||||
if (!src.amount)
|
||||
M.move_laying = null
|
||||
boutput(M, "<span style=\"color:red\">Your cable coil runs out!</span>")
|
||||
return
|
||||
|
||||
/obj/item/cable_coil/examine()
|
||||
set src in view(1)
|
||||
set category = "Local"
|
||||
|
||||
if (amount == 1)
|
||||
boutput(usr, "A short piece of power cable.")
|
||||
else if (amount == 1)
|
||||
boutput(usr, "A piece of power cable.")
|
||||
else
|
||||
boutput(usr, "A coil of power cable. There's [amount] length[s_es(amount)] of cable in the coil.")
|
||||
|
||||
if (insulator)
|
||||
boutput(usr, "It is insulated with [insulator].")
|
||||
if (conductor)
|
||||
boutput(usr, "Its conductive layer is made out of [conductor].")
|
||||
|
||||
/obj/item/cable_coil/attackby(obj/item/W, mob/user)
|
||||
if (istype(W, /obj/item/wirecutters) && src.amount > 1)
|
||||
src.amount--
|
||||
take(1, usr.loc)
|
||||
boutput(user, "You cut a piece off the cable coil.")
|
||||
src.updateicon()
|
||||
return
|
||||
|
||||
else if (istype(W, /obj/item/cable_coil))
|
||||
var/obj/item/cable_coil/C = W
|
||||
if (C.conductor.mat_id != src.conductor.mat_id || C.insulator.mat_id != src.insulator.mat_id)
|
||||
boutput(user, "You cannot link together cables made from different materials. That would be silly.")
|
||||
return
|
||||
|
||||
if (C.amount == MAXCOIL)
|
||||
boutput(user, "The coil is too long, you cannot add any more cable to it.")
|
||||
return
|
||||
|
||||
if ((C.amount + src.amount <= MAXCOIL))
|
||||
C.amount += src.amount
|
||||
boutput(user, "You join the cable coils together.")
|
||||
C.updateicon()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
else
|
||||
boutput(user, "You transfer [MAXCOIL - src.amount ] length\s of cable from one coil to the other.")
|
||||
src.amount -= (MAXCOIL-C.amount)
|
||||
src.updateicon()
|
||||
C.amount = MAXCOIL
|
||||
C.updateicon()
|
||||
return
|
||||
|
||||
/obj/item/cable_coil/MouseDrop_T(atom/movable/O as obj, mob/user as mob)
|
||||
..(O, user)
|
||||
for (var/obj/item/cable_coil/C in view(1, user))
|
||||
C.updateicon()
|
||||
|
||||
// called when cable_coil is clicked on a turf/simulated/floor
|
||||
/obj/item/cable_coil/proc/turf_place_between(turf/simulated/floor/A, turf/simulated/floor/B)
|
||||
if (!isturf(B))
|
||||
return
|
||||
if (get_dist(A, B) > 1)
|
||||
return
|
||||
if (A.intact)
|
||||
return
|
||||
|
||||
var/dirn = get_dir(A, B)
|
||||
for (var/obj/cable/C in A)
|
||||
if (C.d1 == dirn || C.d2 == dirn)
|
||||
return
|
||||
var/obj/cable/NC = new(A)
|
||||
|
||||
applyCableMaterials(NC, src.insulator, src.conductor)
|
||||
NC.d1 = 0
|
||||
NC.d2 = dirn
|
||||
NC.updateicon()
|
||||
NC.update_network()
|
||||
NC.log_wirelaying(usr)
|
||||
src.use(1)
|
||||
return
|
||||
|
||||
/obj/item/cable_coil/proc/cable_join_between(var/obj/cable/C, var/turf/simulated/floor/B)
|
||||
if (!isturf(B))
|
||||
return
|
||||
|
||||
var/turf/T = C.loc
|
||||
|
||||
if (!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable
|
||||
return
|
||||
|
||||
if (get_dist(C, B) > 1) // make sure it's close enough
|
||||
return
|
||||
|
||||
if (B == T) // do nothing if we clicked a cable we're standing on
|
||||
return // may change later if can think of something logical to do
|
||||
|
||||
var/dirn = get_dir(C, B)
|
||||
|
||||
if (C.d1 == 0) // exisiting cable doesn't point at our position, so see if it's a stub
|
||||
// if so, make it a full cable pointing from it's old direction to our dirn
|
||||
|
||||
var/nd1 = C.d2 // these will be the new directions
|
||||
var/nd2 = dirn
|
||||
|
||||
if (nd1 > nd2) // swap directions to match icons/states
|
||||
nd1 = dirn
|
||||
nd2 = C.d2
|
||||
|
||||
|
||||
for (var/obj/cable/LC in T) // check to make sure there's no matching cable
|
||||
if (LC == C) // skip the cable we're interacting with
|
||||
continue
|
||||
if ((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
|
||||
return
|
||||
qdel(C)
|
||||
var/obj/cable/NC = new(T)
|
||||
applyCableMaterials(NC, src.insulator, src.conductor)
|
||||
NC.d1 = nd1
|
||||
NC.d2 = nd2
|
||||
NC.updateicon()
|
||||
NC.update_network()
|
||||
NC.log_wirelaying(usr)
|
||||
src.use(1)
|
||||
return
|
||||
|
||||
/obj/item/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user)
|
||||
if (!isturf(user.loc))
|
||||
return
|
||||
|
||||
if (get_dist(F,user) > 1)
|
||||
boutput(user, "You can't lay cable at a place that far away.")
|
||||
return
|
||||
|
||||
if (F.intact) // if floor is intact, complain
|
||||
boutput(user, "You can't lay cable there unless the floor tiles are removed.")
|
||||
return
|
||||
|
||||
else
|
||||
var/dirn
|
||||
|
||||
if (user.loc == F)
|
||||
dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing
|
||||
else
|
||||
dirn = get_dir(F, user)
|
||||
|
||||
for (var/obj/cable/LC in F)
|
||||
if (LC.d1 == dirn || LC.d2 == dirn)
|
||||
boutput(user, "There's already a cable at that position.")
|
||||
return
|
||||
|
||||
var/obj/cable/C = new(F)
|
||||
C.d1 = 0
|
||||
C.d2 = dirn
|
||||
C.add_fingerprint(user)
|
||||
C.updateicon()
|
||||
C.update_network()
|
||||
applyCableMaterials(C, src.insulator, src.conductor)
|
||||
C.log_wirelaying(user)
|
||||
src.use(1)
|
||||
return
|
||||
|
||||
// called when cable_coil is click on an installed obj/cable
|
||||
/obj/item/cable_coil/proc/cable_join(obj/cable/C, mob/user)
|
||||
var/turf/U = user.loc
|
||||
if (!isturf(U))
|
||||
return
|
||||
|
||||
var/turf/T = C.loc
|
||||
|
||||
if (!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable
|
||||
return
|
||||
|
||||
if (get_dist(C, user) > 1) // make sure it's close enough
|
||||
boutput(user, "You can't lay cable at a place that far away.")
|
||||
return
|
||||
|
||||
if (U == T) // do nothing if we clicked a cable we're standing on
|
||||
return // may change later if can think of something logical to do
|
||||
|
||||
var/dirn = get_dir(C, user)
|
||||
|
||||
if (C.d1 == dirn || C.d2 == dirn) // one end of the clicked cable is pointing towards us
|
||||
if (U.intact) // can't place a cable if the floor is complete
|
||||
boutput(user, "You can't lay cable there unless the floor tiles are removed.")
|
||||
return
|
||||
else
|
||||
// cable is pointing at us, we're standing on an open tile
|
||||
// so create a stub pointing at the clicked cable on our tile
|
||||
|
||||
var/fdirn = turn(dirn, 180) // the opposite direction
|
||||
|
||||
for (var/obj/cable/LC in U) // check to make sure there's not a cable there already
|
||||
if (LC.d1 == fdirn && LC.d2 == fdirn)
|
||||
boutput(user, "There's already a cable at that position.")
|
||||
return
|
||||
|
||||
var/obj/cable/NC = new(U)
|
||||
applyCableMaterials(NC, src.insulator, src.conductor)
|
||||
NC.d1 = 0
|
||||
NC.d2 = fdirn
|
||||
NC.add_fingerprint()
|
||||
NC.updateicon()
|
||||
NC.update_network()
|
||||
NC.log_wirelaying(user)
|
||||
src.use(1)
|
||||
C.shock(user, 25)
|
||||
return
|
||||
|
||||
else if (C.d1 == 0) // exisiting cable doesn't point at our position, so see if it's a stub
|
||||
// if so, make it a full cable pointing from it's old direction to our dirn
|
||||
|
||||
var/nd1 = C.d2 // these will be the new directions
|
||||
var/nd2 = dirn
|
||||
|
||||
if (nd1 > nd2) // swap directions to match icons/states
|
||||
nd1 = dirn
|
||||
nd2 = C.d2
|
||||
|
||||
|
||||
for (var/obj/cable/LC in T) // check to make sure there's no matching cable
|
||||
if (LC == C) // skip the cable we're interacting with
|
||||
continue
|
||||
if ((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
|
||||
boutput(user, "There's already a cable at that position.")
|
||||
return
|
||||
C.shock(user, 25)
|
||||
qdel(C)
|
||||
var/obj/cable/NC = new(T)
|
||||
applyCableMaterials(NC, src.insulator, src.conductor)
|
||||
NC.d1 = nd1
|
||||
NC.d2 = nd2
|
||||
NC.add_fingerprint()
|
||||
NC.updateicon()
|
||||
NC.update_network()
|
||||
NC.log_wirelaying(user)
|
||||
src.use(1)
|
||||
return
|
||||
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
CONTAINS:
|
||||
DATA CARD
|
||||
EMAG
|
||||
ID CARD
|
||||
GAUNTLET CARDS
|
||||
*/
|
||||
|
||||
/obj/item/card
|
||||
name = "card"
|
||||
icon = 'icons/obj/card.dmi'
|
||||
icon_state = "id"
|
||||
wear_image_icon = 'icons/mob/mob.dmi'
|
||||
w_class = 1.0
|
||||
burn_type = 1
|
||||
stamina_damage = 1
|
||||
stamina_cost = 1
|
||||
var/list/files = list("tools" = 1)
|
||||
module_research_type = /obj/item/card
|
||||
|
||||
/obj/item/card/emag
|
||||
desc = "It's a card with a magnetic strip attached to some circuitry."
|
||||
name = "cryptographic sequencer"
|
||||
icon_state = "emag"
|
||||
item_state = "card-id"
|
||||
flags = FPRINT | TABLEPASS | SUPPRESSATTACK
|
||||
layer = 6.0 // TODO fix layer
|
||||
is_syndicate = 1
|
||||
mats = 8
|
||||
module_research = list("malfunction" = 25)
|
||||
module_research_type = /obj/item/card/emag
|
||||
|
||||
afterattack(var/atom/A, var/mob/user)
|
||||
if(!A || !user)
|
||||
return
|
||||
A.emag_act(user, src)
|
||||
|
||||
attack() //Fucking attack messages up in this joint.
|
||||
return
|
||||
|
||||
/obj/item/card/emag/fake
|
||||
//delicious fake emag
|
||||
attack_hand(mob/user as mob)
|
||||
boutput(user, "<span class='combat'>Turns out that card was actually a kind of [pick("deadly chameleon","spiny anteater","sex toy that George Melons likes to use","Syndicate Top Trumps Card","bag of neckbeard shavings")] in disguise! It stabs you!</span>")
|
||||
user.paralysis = 8
|
||||
spawn(10)
|
||||
var/obj/storage/closet/C = new/obj/storage/closet(get_turf(user))
|
||||
user.set_loc(C)
|
||||
C.layer = OBJ_LAYER
|
||||
C.name = "an ordinary closet"
|
||||
C.desc = "What? It's just an ordinary closet."
|
||||
C.welded = 1
|
||||
|
||||
// ID CARDS
|
||||
|
||||
/obj/item/card/id
|
||||
name = "identification card"
|
||||
icon_state = "id"
|
||||
item_state = "card-id"
|
||||
desc = "A standardized NanoTrasen Identification Card. Ties into many systems station-wide."
|
||||
var/access = list()
|
||||
var/registered = null
|
||||
var/assignment = null
|
||||
var/title = null
|
||||
var/emagged = 0
|
||||
|
||||
// YOU START WITH NO CREDITS
|
||||
// WOW
|
||||
var/money = 0.0
|
||||
var/pin = 0000
|
||||
|
||||
//It's a..smart card. Sure.
|
||||
var/datum/computer/file/cardfile = null
|
||||
desc = "An microchipped identification card that contains data that is scanned when attempting to access various doors and computers on the station."
|
||||
|
||||
proc/update_name()
|
||||
name = "[src.registered]'s ID Card ([src.assignment])"
|
||||
|
||||
/obj/item/card/id/New()
|
||||
..()
|
||||
src.pin = rand(1000,9999)
|
||||
|
||||
/obj/item/card/id/command
|
||||
icon_state = "id_com"
|
||||
|
||||
/obj/item/card/id/security
|
||||
icon_state = "id_sec"
|
||||
|
||||
/obj/item/card/id/research
|
||||
icon_state = "id_res"
|
||||
|
||||
/obj/item/card/id/engineering
|
||||
icon_state = "id_eng"
|
||||
|
||||
/obj/item/card/id/civilian
|
||||
icon_state = "id_civ"
|
||||
|
||||
/obj/item/card/id/clown
|
||||
icon_state = "id_clown"
|
||||
desc = "Wait, this isn't even an ID Card. It's a piece of a Chips Ahoy wrapper with crayon scribbles on it. What the fuck?"
|
||||
|
||||
/obj/item/card/id/gold
|
||||
name = "identification card"
|
||||
icon_state = "gold"
|
||||
item_state = "gold_id"
|
||||
desc = "This card is important!"
|
||||
|
||||
/obj/item/card/id/blank_deluxe
|
||||
name = "Deluxe ID"
|
||||
icon_state = "gold"
|
||||
item_state = "gold_id"
|
||||
registered = "Member"
|
||||
assignment = "Member"
|
||||
|
||||
/obj/item/card/id/captains_spare
|
||||
name = "Captain's spare ID"
|
||||
icon_state = "gold"
|
||||
item_state = "gold_id"
|
||||
registered = "Captain"
|
||||
assignment = "Captain"
|
||||
New()
|
||||
access = get_access("Captain")
|
||||
..()
|
||||
|
||||
/obj/item/card/id/captains_spare/explosive
|
||||
pickup(mob/user)
|
||||
boutput(user, "<span style=\"color:red\">The ID-Card explodes.</span>")
|
||||
user.transforming = 1
|
||||
var/obj/overlay/O = new/obj/overlay(get_turf(user))
|
||||
O.anchored = 1
|
||||
O.name = "Explosion"
|
||||
O.layer = NOLIGHT_EFFECTS_LAYER_BASE
|
||||
O.pixel_x = -17
|
||||
O.icon = 'icons/effects/hugeexplosion.dmi'
|
||||
O.icon_state = "explosion"
|
||||
spawn(35) qdel(O)
|
||||
spawn(5) user.gib()
|
||||
|
||||
/obj/item/card/id/attack_self(mob/user as mob)
|
||||
user.visible_message("[user] shows you: [bicon(src)] [src.name]: assignment: [src.assignment]", "You show off your card: [bicon(src)] [src.name]: assignment: [src.assignment]")
|
||||
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
/obj/item/card/id/emag_act(var/mob/user, var/obj/item/card/emag/E)
|
||||
if (src.emagged)
|
||||
if (user && E)
|
||||
user.show_text("You run [E] over [src], but nothing seems to happen.", "red")
|
||||
return
|
||||
src.access = list() // clear what used to be there
|
||||
var/list/all_accesses = get_all_accesses()
|
||||
for (var/i = rand(2,25), i > 0, i--)
|
||||
var/new_access = pick(all_accesses)
|
||||
src.access += new_access
|
||||
all_accesses -= new_access
|
||||
if (istype(src, /obj/item/card/id/syndicate)) // Nuke ops unable to exit their station (Convair880).
|
||||
src.access += access_syndicate_shuttle
|
||||
DEBUG("[get_access_desc(new_access)] added to [src]")
|
||||
src.emagged = 1
|
||||
|
||||
/obj/item/card/id/verb/read()
|
||||
set src in usr
|
||||
|
||||
boutput(usr, "[bicon(src)] [src.name]: The current assignment on the card is [src.assignment].")
|
||||
return
|
||||
|
||||
/obj/item/card/id/syndicate
|
||||
name = "agent card"
|
||||
access = list(access_maint_tunnels, access_syndicate_shuttle)
|
||||
|
||||
/obj/item/card/id/syndicate/attack_self(mob/user as mob)
|
||||
if(!src.registered)
|
||||
var/reg = copytext(src.sanitize_name(input(user, "What name would you like to put on this card?", "Agent card name", ishuman(user) ? user.real_name : user.name)), 1, 100)
|
||||
var/ass = copytext(src.sanitize_name(input(user, "What occupation would you like to put on this card?\n Note: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Staff Assistant"), 1), 1, 100)
|
||||
var/color = input(user, "What color should the ID's color band be?\nClick cancel to abort the forging process.") as null|anything in list("blue","red","green","purple","yellow","No band")
|
||||
switch (color)
|
||||
if ("No band")
|
||||
src.icon_state = "id"
|
||||
if ("blue")
|
||||
src.icon_state = "id_civ"
|
||||
if ("red")
|
||||
src.icon_state = "id_sec"
|
||||
if ("green")
|
||||
src.icon_state = "id_com"
|
||||
if ("purple")
|
||||
src.icon_state = "id_res"
|
||||
if ("yellow")
|
||||
src.icon_state = "id_eng"
|
||||
else
|
||||
return // Abort process.
|
||||
src.registered = reg
|
||||
src.assignment = ass
|
||||
src.name = "[src.registered]'s ID Card ([src.assignment])"
|
||||
boutput(user, "<span style=\"color:blue\">You successfully forge the ID card.</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/card/id/syndicate/attackby(obj/item/W as obj, mob/user as mob)
|
||||
var/obj/item/card/id/sourceCard = W
|
||||
if (istype(sourceCard))
|
||||
boutput(user, "You copy [sourceCard]'s accesses to [src].")
|
||||
src.access |= sourceCard.access
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/syndicate/proc/sanitize_name(var/input, var/strip_bad_stuff_only = 0)
|
||||
input = strip_html(input, MAX_MESSAGE_LEN, 1)
|
||||
if (strip_bad_stuff_only)
|
||||
return input
|
||||
var/list/namecheck = dd_text2list(trim(input), " ")
|
||||
for(var/i = 1, i <= namecheck.len, i++)
|
||||
namecheck[i] = capitalize(namecheck[i])
|
||||
input = dd_list2text(namecheck, " ")
|
||||
return input
|
||||
|
||||
/obj/item/card/id/temporary
|
||||
name = "temporary identification card"
|
||||
icon_state = "id"
|
||||
item_state = "card-id"
|
||||
desc = "A temporary NanoTrasen Identification Card. Its access will be revoked once it expires."
|
||||
var/duration = 60 //seconds
|
||||
var/starting_access = list()
|
||||
var/timer = 0 //if 1, description shows time remaining
|
||||
var/end_time = 0
|
||||
|
||||
/obj/item/card/id/temporary/New()
|
||||
..()
|
||||
spawn(0) //to give time for duration and starting access to be set
|
||||
starting_access = access
|
||||
end_time = ticker.round_elapsed_ticks + duration*10
|
||||
spawn(duration * 10)
|
||||
if(access == starting_access) //don't delete access if it's modified with an ID computer
|
||||
access = list()
|
||||
|
||||
/obj/item/card/id/temporary/examine()
|
||||
..()
|
||||
if(usr.client && src.timer)
|
||||
boutput(usr, "A small display in the corner reads: \"Time remaining: [max(0,round((end_time-ticker.round_elapsed_ticks)/10))] seconds.\"")
|
||||
|
||||
/obj/item/card/id/gauntlet
|
||||
icon = 'icons/effects/VR.dmi'
|
||||
icon_state = "id_clown"
|
||||
New(var/L, var/mob/user)
|
||||
..()
|
||||
if (!user)
|
||||
registered = "???"
|
||||
assignment = "unknown phantom entity (no.. mob? this is awkward)"
|
||||
if (istype(user, /mob/living/carbon/human/virtual))
|
||||
var/mob/living/LI = user:body
|
||||
if (LI)
|
||||
registered = LI.real_name
|
||||
else
|
||||
registered = user.real_name
|
||||
else
|
||||
registered = user.real_name
|
||||
|
||||
if (!user.client)
|
||||
assignment = "literal meat shield (no client)"
|
||||
else
|
||||
assignment = "loading arena matches..."
|
||||
tag = "gauntlet-id-[user.client.key]"
|
||||
queryGauntletMatches(1, user.client.key)
|
||||
name = "[registered]'s ID Card ([assignment])"
|
||||
|
||||
proc/SetMatchCount(var/matches)
|
||||
switch (matches)
|
||||
if (-INFINITY to 0)
|
||||
icon_state = "id_clown"
|
||||
assignment = "Gauntlet Newbie ([matches] rounds played)"
|
||||
if (1 to 10)
|
||||
icon_state = "id_civ"
|
||||
assignment = "Rookie Gladiator ([matches] rounds played)"
|
||||
if (11 to 20)
|
||||
icon_state = "id_res"
|
||||
assignment = "Beginner Gladiator ([matches] rounds played)"
|
||||
if (21 to 35)
|
||||
icon_state = "id_eng"
|
||||
assignment = "Skilled Gladiator ([matches] rounds played)"
|
||||
if (36 to 55)
|
||||
icon_state = "id_sec"
|
||||
assignment = "Advanced Gladiator ([matches] rounds played)"
|
||||
if (56 to 75)
|
||||
icon_state = "id_com"
|
||||
assignment = "Expert Gladiator ([matches] rounds played)"
|
||||
if (76 to INFINITY)
|
||||
icon_state = "gold"
|
||||
assignment = "Legendary Gladiator ([matches] rounds played)"
|
||||
else
|
||||
assignment = "what the fuck ([matches] rounds played)"
|
||||
name = "[registered]'s ID Card ([assignment])"
|
||||
@@ -0,0 +1,104 @@
|
||||
/obj/item/chem_pill_bottle
|
||||
name = "Pill bottle"
|
||||
icon_state = "pill_canister"
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
w_class = 2.0
|
||||
stamina_damage = 3
|
||||
stamina_cost = 3
|
||||
stamina_crit_chance = 1
|
||||
rand_pos = 1
|
||||
|
||||
var/pname
|
||||
var/pvol
|
||||
var/pcount
|
||||
var/datum/reagents/reagents_internal
|
||||
|
||||
// setup this pill bottle from some reagents
|
||||
proc/create_from_reagents(var/datum/reagents/R, var/pillname, var/pillvol, var/pillcount)
|
||||
var/volume = pillcount * pillvol
|
||||
|
||||
reagents_internal = new/datum/reagents(volume)
|
||||
reagents_internal.my_atom = src
|
||||
|
||||
R.trans_to_direct(reagents_internal,volume)
|
||||
|
||||
src.name = "[pillname] pill bottle"
|
||||
src.desc = "Contains [pillcount] [pillname] pills."
|
||||
src.pname = pillname
|
||||
src.pvol = pillvol
|
||||
src.pcount = pillcount
|
||||
|
||||
// spawn a pill, returns a pill or null if there aren't any left in the bottle
|
||||
proc/create_pill()
|
||||
var/totalpills = src.pcount + src.contents.len
|
||||
|
||||
if(totalpills <= 0)
|
||||
return null
|
||||
|
||||
var/obj/item/reagent_containers/pill/P = null
|
||||
|
||||
// give back stored pills first
|
||||
if (src.contents.len)
|
||||
P = src.contents[src.contents.len]
|
||||
|
||||
// otherwise create a new one from the reagent holder
|
||||
else if (pcount)
|
||||
if (src.reagents_internal.total_volume < src.pvol)
|
||||
src.pcount = 0
|
||||
else
|
||||
P = unpool(/obj/item/reagent_containers/pill)
|
||||
P.loc = src
|
||||
P.name = "[pname] pill"
|
||||
|
||||
src.reagents_internal.trans_to(P,src.pvol)
|
||||
src.pcount--
|
||||
// else return null
|
||||
|
||||
return P
|
||||
|
||||
proc/rebuild_desc()
|
||||
var/totalpills = src.pcount + src.contents.len
|
||||
if(totalpills > 15)
|
||||
src.desc = "A [src.pname] pill bottle. There are too many to count."
|
||||
else if (totalpills <= 0)
|
||||
src.desc = "A [src.pname] pill bottle. It looks empty."
|
||||
else
|
||||
src.desc = "A [src.pname] pill bottle. There [totalpills==1? "is [totalpills] pill." : "are [totalpills] pills." ]"
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/reagent_containers/pill/))
|
||||
user.u_equip(W)
|
||||
W.set_loc(src)
|
||||
W.dropped()
|
||||
boutput(user, "<span style=\"color:blue\">You put [W] in [src].</span>")
|
||||
rebuild_desc()
|
||||
else ..()
|
||||
|
||||
attack_self(var/mob/user as mob)
|
||||
var/obj/item/reagent_containers/pill/P = src.create_pill()
|
||||
if (istype(P))
|
||||
do
|
||||
P.set_loc(user.loc)
|
||||
P = src.create_pill()
|
||||
while(istype(P))
|
||||
boutput(user, "<span style=\"color:blue\">You tip out all the pills from [src] into [user.loc].</span>")
|
||||
rebuild_desc()
|
||||
else
|
||||
boutput(user, "<span style=\"color:red\">It's empty.</span>")
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if(user.r_hand == src || user.l_hand == src)
|
||||
var/obj/item/reagent_containers/pill/P = src.create_pill()
|
||||
if(istype(P))
|
||||
user.put_in_hand_or_drop(P)
|
||||
boutput(user, "You take [P] from [src].")
|
||||
rebuild_desc()
|
||||
else
|
||||
boutput(user, "<span style=\"color:red\">It's empty.</span>")
|
||||
return
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -0,0 +1,816 @@
|
||||
|
||||
/* ==================================================== */
|
||||
/* -------------------- Cigarettes -------------------- */
|
||||
/* ==================================================== */
|
||||
|
||||
/obj/item/clothing/mask/cigarette
|
||||
name = "cigarette"
|
||||
icon_state = "cigoff"
|
||||
item_state = "cigoff"
|
||||
force = 0
|
||||
damtype = "brute"
|
||||
throw_speed = 0.5
|
||||
w_class = 1
|
||||
armor_value_melee = 0
|
||||
cold_resistance = 0
|
||||
heat_resistance = 0
|
||||
var/lit = 0
|
||||
var/lastHolder = null
|
||||
var/exploding = 0 //Does it blow up when it goes out?
|
||||
var/flavor = null
|
||||
var/nic_free = 0
|
||||
rand_pos = 1
|
||||
|
||||
New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(60)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
if (src.exploding)
|
||||
if (src.flavor)
|
||||
R.add_reagent(src.flavor, 5)
|
||||
R.add_reagent("nicotine", 5)
|
||||
return
|
||||
else if (!src.nic_free)
|
||||
R.add_reagent("nicotine", 40)
|
||||
if (src.flavor)
|
||||
R.add_reagent(src.flavor, 20)
|
||||
return
|
||||
else if (src.flavor)
|
||||
R.add_reagent(src.flavor, 40)
|
||||
return
|
||||
|
||||
afterattack(atom/target, mob/user, flag) // copied from the propuffs
|
||||
if (istype(target, /obj/item/reagent_containers/))
|
||||
user.visible_message("<span style=\"color:blue\"><b>[user]</b> crushes up the [src] in the [target].</span>",\
|
||||
"<span style=\"color:blue\">You crush up the [src] in the [target].</span>")
|
||||
src.reagents.trans_to(target, 5)
|
||||
qdel (src)
|
||||
else if (istype(target, /obj/item/match) && src.lit)
|
||||
target:light(user, "<span style=\"color:red\"><b>[user]</b> lights [target] with [src].</span>")
|
||||
else if (src.lit == 0 && istype(target, /obj/item) && target:burning)
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> lights the [src] with [target]. Goddamn.</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
proc/light(var/mob/user as mob, var/message as text)
|
||||
if (src.lit == 0)
|
||||
src.lit = 1
|
||||
src.damtype = "fire"
|
||||
src.force = 3
|
||||
src.icon_state = "cigon"
|
||||
src.item_state = "cigon"
|
||||
if (user && message)
|
||||
user.visible_message(message) //user check to fix a shitton of runtime errors with the temp expose ignition method. welp. -cogwerks
|
||||
//spawn() //start fires while it's lit
|
||||
//src.process()
|
||||
if (!(src in processing_items))
|
||||
processing_items.Add(src) // we have a nice scheduler let's use that instead tia
|
||||
|
||||
proc/put_out(var/mob/user as mob, var/message as text)
|
||||
if (src.lit == 1)
|
||||
src.lit = -1
|
||||
src.damtype = "brute"
|
||||
src.force = 0
|
||||
src.icon_state = "cigbutt"
|
||||
src.item_state = "cigoff"
|
||||
src.name = "cigarette butt"
|
||||
src.desc = "A cigarette butt."
|
||||
if (user && message)
|
||||
user.visible_message(message)
|
||||
if (src in processing_items)
|
||||
processing_items.Remove(src)
|
||||
|
||||
temperature_expose(datum/gas_mixture/air, temperature, volume)
|
||||
if (src.lit == 0)
|
||||
if (temperature > T0C+200)
|
||||
src.visible_message("<span style=\"color:red\">The [src] ignites!</span>")
|
||||
src.light()
|
||||
|
||||
ex_act(severity)
|
||||
if (src.lit == 0)
|
||||
src.visible_message("<span style=\"color:red\">The [src] ignites!</span>")
|
||||
src.light()
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (src.lit == 0)
|
||||
if (istype(W, /obj/item/weldingtool) && W:welding)
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> casually lights the [src] with [W], what a badass.</span>")
|
||||
return
|
||||
else if (istype(W, /obj/item/clothing/head/cakehat) && W:on)
|
||||
src.light(user, "<span style=\"color:red\">Did [user] just light \his [src] with the [W]? Holy Shit.</span>")
|
||||
return
|
||||
else if (istype(W, /obj/item/device/igniter))
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> fumbles around with the [W]; a small flame erupts from the [src].</span>")
|
||||
return
|
||||
else if (istype(W, /obj/item/zippo) && W:lit)
|
||||
src.light(user, "<span style=\"color:red\">With a single flick of their wrist, [user] smoothly lights [src] with [W]. Damn they're cool.</span>")
|
||||
return
|
||||
else if ((istype(W, /obj/item/match) || istype(W, /obj/item/device/candle)) && W:lit)
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> lights [src] with [W].</span>")
|
||||
return
|
||||
else if (W.burning)
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> lights the [src] with [W]. Goddamn.</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
else
|
||||
return ..() // CALL your GODDAMN PARENTS
|
||||
|
||||
attack(atom/target, mob/user as mob)
|
||||
if (isliving(target))
|
||||
var/mob/living/M = target
|
||||
|
||||
if (ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if (H.bleeding || (H.butt_op_stage == 4 && user.zone_sel.selecting == "chest"))
|
||||
if (!src.cautery_surgery(H, user, 5, src.lit))
|
||||
return ..()
|
||||
if (M.burning && src.lit == 0)
|
||||
if (M == user)
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> lights \his cigarette with \his OWN flaming body. That's dedication! Or crippling addiction.</span>")
|
||||
else
|
||||
src.light(user, "<span style=\"color:red\"><b>[user]</b> lights \his cigarette with [M]'s flaming body. That's cold, man. That's real cold.</span>")
|
||||
else
|
||||
..(target, user)
|
||||
if (src.lit == 1)
|
||||
src.put_out(user, "<span style=\"color:red\"><b>[user]</b> puts the [src] out on [target].</span>")
|
||||
if (ishuman(target))
|
||||
var/mob/living/carbon/human/chump = target
|
||||
if (!chump.stat)
|
||||
chump.emote("scream")
|
||||
|
||||
process()
|
||||
var/atom/lastHolder = null
|
||||
|
||||
//while (src.lit == 1)
|
||||
if (src.lit == 1)
|
||||
var/turf/location = src.loc
|
||||
var/atom/holder = loc
|
||||
var/isHeld = 0
|
||||
var/mob/M = null
|
||||
|
||||
if (!src.exploding && prob(20)) // cigs shouldn't go out instantly dang
|
||||
if (ismob(location))
|
||||
M = location
|
||||
if(istype(M, /mob/living/carbon/human)) //HOLY DUPLICATE CODE BATMAN!!!
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.traitHolder && H.traitHolder.hasTrait("smoker"))
|
||||
src.reagents.remove_any(1)
|
||||
else
|
||||
src.reagents.trans_to(M, 1)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
else
|
||||
src.reagents.trans_to(M, 1)
|
||||
src.reagents.reaction(M, INGEST)
|
||||
else src.reagents.remove_any(1)
|
||||
|
||||
else if (src.exploding)
|
||||
if (ismob(location))
|
||||
M = location
|
||||
if(istype(M, /mob/living/carbon/human)) //HOLY DUPLICATE CODE BATMAN!!!
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.traitHolder && H.traitHolder.hasTrait("smoker"))
|
||||
src.reagents.remove_any(1)
|
||||
else
|
||||
src.reagents.trans_to(M, 1)
|
||||
else
|
||||
src.reagents.trans_to(M, 1)
|
||||
else if (src && src.reagents) //Wire: fix for Cannot execute null.remove any().
|
||||
src.reagents.remove_any(1)
|
||||
|
||||
if (src.reagents.total_volume <= 0)
|
||||
if (src.exploding)
|
||||
src.lit = 0 //Let's not keep looping while we're busy blowing up, ok?
|
||||
spawn((20)+(rand(1,10)))
|
||||
var/turf/tlocation = get_turf(src.loc)
|
||||
if (tlocation)
|
||||
explosion(src, tlocation, 0, 1, 1, 2)
|
||||
else
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
playsound(src.loc, "sound/effects/Explosion1.ogg", 75, 1)
|
||||
src.visible_message("<span style=\"color:red\">The [src] explodes!</span>")
|
||||
|
||||
// Added (Convair880).
|
||||
if (ismob(src.loc))
|
||||
logTheThing("bombing", null, src.loc, "A trick cigarette (held/equipped by %target%) explodes at [log_loc(src)].")
|
||||
else
|
||||
logTheThing("bombing", src.fingerprintslast, null, "A trick cigarette explodes at [log_loc(src)]. Last touched by [src.fingerprintslast ? "[src.fingerprintslast]" : "*null*"].")
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
src.put_out(M, "<span style=\"color:red\"><b>[M]</b>'s [src] goes out.</span>")
|
||||
return
|
||||
//if (istype(location, /turf)) //start a fire if possible
|
||||
// location.hotspot_expose(700, 5) // this doesn't seem to ever actually happen, gonna try a different setup - cogwerks
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if (T)
|
||||
T.hotspot_expose(650,5)
|
||||
if (ismob(holder))
|
||||
isHeld = 1
|
||||
else
|
||||
isHeld = 0
|
||||
if (lastHolder != null)
|
||||
lastHolder = null
|
||||
|
||||
if (isHeld == 1)
|
||||
lastHolder = holder
|
||||
//sleep(10)
|
||||
|
||||
if (lastHolder != null)
|
||||
lastHolder = null
|
||||
|
||||
dropped(mob/user as mob)
|
||||
if(!istype(src.loc, /turf)) return
|
||||
if (src.lit == 1 && !src.exploding && src.reagents.total_volume <= 20)
|
||||
src.put_out(user, "<span style=\"color:red\"><b>[user]</b> calmly drops and treads on the lit [src], putting it out instantly.</span>")
|
||||
return ..()
|
||||
else
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> drops the [src]. Guess they've had enough for the day.</span>")
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/nicofree
|
||||
name = "nicotine-free cigarette"
|
||||
desc = "Smoking without the crippling addiction and lung cancer! Warning: side effects may include loss of breath and inability to relax."
|
||||
nic_free = 1
|
||||
flavor = "capsaicin"
|
||||
|
||||
/obj/item/clothing/mask/cigarette/random
|
||||
desc = "A cigarette which seems to have been laced with something."
|
||||
|
||||
New()
|
||||
if (all_functional_reagent_ids.len > 0)
|
||||
src.flavor = pick(all_functional_reagent_ids)
|
||||
else
|
||||
src.flavor = "nicotine"
|
||||
src.name = "[reagent_id_to_name(src.flavor)]-laced cigarette"
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/propuffs
|
||||
desc = "Pro Puffs - a new taste thrill in every cigarette."
|
||||
|
||||
New()
|
||||
src.flavor = pick("silicate","antihol","mutadone","rum","mutagen","toxin","water_holy","fuel","salbutamol","haloperidol",
|
||||
"cryoxadone","cryostylane","omnizine","jenkem","vomit","carpet","charcoal","blood","cheese","bilk","atropine",
|
||||
"lexorin","teporone","mannitol","spaceacillin","saltpetre","anti_rad","insulin","gvomit","milk","colors","diluted_fliptonium",
|
||||
"something","honey_tea","tea","coffee","chocolate","guacamole","juice_pickle","vanilla","enriched_msg","egg","aranesp",
|
||||
"paper","bread","green_goop","black_goop")
|
||||
src.name = "[reagent_id_to_name(src.flavor)]-laced cigarette"
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/syndicate
|
||||
//desc = "It looks a little funny." //fucka you
|
||||
exploding = 1
|
||||
|
||||
// this was in the middle of plants_food_etc.dm
|
||||
// WHY
|
||||
/obj/item/clothing/mask/cigarette/custom
|
||||
desc = "There could be anything in this."
|
||||
flags = FPRINT|TABLEPASS|OPENCONTAINER
|
||||
|
||||
New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(600)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
|
||||
is_open_container()
|
||||
return 1
|
||||
|
||||
/* ================================================= */
|
||||
/* -------------------- Packets -------------------- */
|
||||
/* ================================================= */
|
||||
|
||||
/obj/item/cigpacket
|
||||
name = "cigarette packet"
|
||||
desc = "The most popular brand of Space Cigarettes, sponsors of the Space Olympics."
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "cigpacket"
|
||||
item_state = "cigpacket"
|
||||
w_class = 1
|
||||
throwforce = 2
|
||||
var/cigcount = 6
|
||||
var/cigtype = /obj/item/clothing/mask/cigarette
|
||||
var/package_style = "cigpacket"
|
||||
flags = ONBELT | TABLEPASS | FPRINT
|
||||
stamina_damage = 3
|
||||
stamina_cost = 3
|
||||
rand_pos = 1
|
||||
|
||||
/obj/item/cigpacket/nicofree
|
||||
name = "nicotine-free cigarette packet"
|
||||
desc = "All the perks of smoking without the addiction! Warning: Cigarettes use chemical compounds which may cause severe throat irritation."
|
||||
cigtype = /obj/item/clothing/mask/cigarette/nicofree
|
||||
icon_state = "cigpacket-b"
|
||||
package_style = "cigpacket-b"
|
||||
|
||||
/obj/item/cigpacket/propuffs
|
||||
name = "packet of Pro Puffs"
|
||||
desc = "A flavor surprise in each cigarette, lovingly wrapped in the finest papers."
|
||||
cigtype = /obj/item/clothing/mask/cigarette/propuffs
|
||||
icon_state = "cigpacket-r"
|
||||
package_style = "cigpacket-r"
|
||||
|
||||
/obj/item/cigpacket/random
|
||||
name = "odd cigarette packet"
|
||||
desc = "These don't seem to have a brand name on them."
|
||||
cigtype = /obj/item/clothing/mask/cigarette/random
|
||||
icon_state = "cigpacket-p"
|
||||
package_style = "cigpacket-p"
|
||||
|
||||
/obj/item/cigpacket/syndicate // cogwerks: made them more sneaky, removed the glaringly obvious name
|
||||
// haine: these can just inherit the parent name and description vOv
|
||||
cigtype = /obj/item/clothing/mask/cigarette/syndicate
|
||||
|
||||
/obj/item/cigpacket/proc/update_icon()
|
||||
src.overlays = null
|
||||
if (src.cigcount <= 0)
|
||||
src.icon_state = "[src.package_style]0"
|
||||
src.desc = "There aren't any cigs left, shit!"
|
||||
else
|
||||
src.icon_state = "[src.package_style]o"
|
||||
src.overlays += "cig[src.cigcount]"
|
||||
return
|
||||
|
||||
/* /obj/item/cigpacket/proc/update_icon() used to just be a return, with this directly below it. ?????
|
||||
/obj/item/cigpacket/update_icon()
|
||||
src.icon_state = "cigpacket[src.cigcount]"
|
||||
src.desc = "There are [src.cigcount] cigs\s left!"
|
||||
return
|
||||
*/
|
||||
/obj/item/cigpacket/attack_hand(mob/user as mob)
|
||||
if (user.find_in_hand(src))//r_hand == src || user.l_hand == src)
|
||||
if (src.cigcount == 0)
|
||||
user.show_text("You're out of cigs, shit! How you gonna get through the rest of the day?", "red")
|
||||
return
|
||||
else
|
||||
var/obj/item/clothing/mask/cigarette/W = new src.cigtype(user)
|
||||
user.put_in_hand_or_drop(W)
|
||||
if (src.cigcount != -1)
|
||||
src.cigcount--
|
||||
src.update_icon()
|
||||
else
|
||||
return ..()
|
||||
return
|
||||
|
||||
/obj/item/cigbutt
|
||||
name = "cigarette butt"
|
||||
desc = "A manky old cigarette butt."
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "cigbutt"
|
||||
w_class = 1
|
||||
throwforce = 1
|
||||
stamina_damage = 3
|
||||
stamina_cost = 3
|
||||
rand_pos = 1
|
||||
|
||||
/* ================================================== */
|
||||
/* -------------------- Lighters -------------------- */
|
||||
/* ================================================== */
|
||||
|
||||
/obj/item/matchbook
|
||||
name = "matchbook"
|
||||
desc = "A little bit of heavy paper with some matches in it, and a little strip to light them on."
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "matchbook"
|
||||
w_class = 1
|
||||
throwforce = 1
|
||||
flags = FPRINT | TABLEPASS | SUPPRESSATTACK
|
||||
stamina_damage = 1
|
||||
stamina_cost = 1
|
||||
stamina_crit_chance = 1
|
||||
burn_point = 220
|
||||
burn_output = 900
|
||||
burn_possible = 1
|
||||
health = 20
|
||||
var/match_amt = 6 // -1 for infinite
|
||||
rand_pos = 1
|
||||
|
||||
get_desc(dist)
|
||||
if (src.match_amt == -1)
|
||||
. += "There's a whole lot of matches left."
|
||||
else if (src.match_amt >= 1)
|
||||
. += "There's [src.match_amt] match[s_es(src.match_amt, 1)] left."
|
||||
else
|
||||
. += "It's empty."
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
if (user.find_in_hand(src))
|
||||
if (src.match_amt == 0)
|
||||
user.show_text("Looks like there's no matches left.", "red")
|
||||
return
|
||||
else
|
||||
var/obj/item/match/W = new /obj/item/match(user)
|
||||
user.put_in_hand_or_drop(W)
|
||||
if (src.match_amt != -1)
|
||||
src.match_amt --
|
||||
src.update_icon()
|
||||
else
|
||||
return ..()
|
||||
return
|
||||
|
||||
afterattack(atom/target, mob/user as mob)
|
||||
if (istype(target, /obj/item/match))
|
||||
if (target:lit > 0)
|
||||
return
|
||||
if (target:lit == -1)
|
||||
user.show_text("You [pick("fumble", "fuss", "mess", "faff")] around with [target] and try to get it to light, but it's no use.", "red")
|
||||
return
|
||||
else if (prob(25))
|
||||
user.visible_message("<b>[user]</b> awkwardly strikes [src] on [target]. [target] breaks!",\
|
||||
"You awkwardly strike [src] on [target]. [target] breaks![prob(50) ? " [pick("Damn!", "Fuck!", "Shit!", "Crap!")]" : null]")
|
||||
playsound(user.loc, 'sound/items/matchstick_hit.ogg', 50, 1)
|
||||
target:put_out(user, 1)
|
||||
return
|
||||
else if (prob(10))
|
||||
user.visible_message("<b>[user]</b> awkwardly strikes [src] on [target]. A small flame sparks into life from the tip.",\
|
||||
"You awkwardly strike [src] on [target]. A small flame sparks into life from the tip.")
|
||||
target:light(user)
|
||||
return
|
||||
else
|
||||
user.visible_message("<b>[user]</b> awkwardly strikes [src] on [target]. Nothing happens.",\
|
||||
"You awkwardly strike [src] on [target]. Nothing happens.")
|
||||
playsound(user.loc, 'sound/items/matchstick_hit.ogg', 50, 1)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
attack()
|
||||
return
|
||||
|
||||
proc/update_icon()
|
||||
if (src.match_amt == -1)
|
||||
src.icon_state = "matchbook6"
|
||||
return
|
||||
else
|
||||
src.icon_state = "matchbook[src.match_amt]"
|
||||
|
||||
/obj/item/match
|
||||
name = "match"
|
||||
desc = "A little stick of wood with phosphorus on the tip, for lighting fires, or making you very frustrated and not lighting fires. Either or."
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "match"
|
||||
w_class = 1
|
||||
throwforce = 1
|
||||
flags = FPRINT | TABLEPASS | SUPPRESSATTACK
|
||||
stamina_damage = 1
|
||||
stamina_cost = 1
|
||||
stamina_crit_chance = 1
|
||||
burn_point = 220
|
||||
burn_output = 600
|
||||
burn_possible = 1
|
||||
health = 10
|
||||
var/lit = 0 // -1 is burnt out/broken or otherwise unable to be lit
|
||||
var/light_mob = 0
|
||||
var/life_timer = 0
|
||||
rand_pos = 1
|
||||
var/datum/light/light
|
||||
|
||||
New()
|
||||
..()
|
||||
light = new /datum/light/point
|
||||
light.set_brightness(0.4)
|
||||
light.set_color(0.94, 0.69, 0.27)
|
||||
light.attach(src)
|
||||
src.life_timer = rand(15,25)
|
||||
|
||||
pickup(mob/user)
|
||||
..()
|
||||
light.attach(user)
|
||||
|
||||
dropped(mob/user)
|
||||
..()
|
||||
if (isturf(src.loc))
|
||||
src.put_out(user)
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> calmly drops and treads on the lit [src], putting it out instantly.</span>")
|
||||
return
|
||||
spawn(0)
|
||||
if (src.loc != user)
|
||||
light.attach(src)
|
||||
|
||||
process()
|
||||
if (src.lit > 0)
|
||||
if (src.life_timer >= 0)
|
||||
life_timer--
|
||||
var/location = src.loc
|
||||
if (ismob(location))
|
||||
var/mob/M = location
|
||||
if (src.life_timer <= 0)
|
||||
src.put_out(M)
|
||||
if (M.find_in_hand(src))
|
||||
M.show_text("[src] burns your hand as the flame reaches the end of [src]!", "red")
|
||||
M.TakeDamage("All", 0, rand(1,5))
|
||||
return
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if (T)
|
||||
T.hotspot_expose(600,5)
|
||||
if (src.life_timer <= 0)
|
||||
src.put_out()
|
||||
return
|
||||
//sleep(10)
|
||||
|
||||
proc/light(var/mob/user as mob)
|
||||
src.lit = 1
|
||||
src.icon_state = "match-lit"
|
||||
|
||||
playsound(user.loc, 'sound/items/matchstick_light.ogg', 50, 1)
|
||||
light.enable()
|
||||
|
||||
if (!(src in processing_items))
|
||||
processing_items.Add(src)
|
||||
return
|
||||
|
||||
proc/put_out(var/mob/user as mob, var/break_it = 0)
|
||||
src.lit = -1
|
||||
src.life_timer = 0
|
||||
if (break_it)
|
||||
src.icon_state = "match-broken"
|
||||
src.name = "broken match"
|
||||
if (user)
|
||||
playsound(user.loc, 'sound/items/crunch.ogg', 60, 1, 0, 2)
|
||||
else
|
||||
src.icon_state = "match-burnt"
|
||||
src.name = "burnt-out match"
|
||||
|
||||
light.disable()
|
||||
|
||||
if (src in processing_items)
|
||||
processing_items.Remove(src)
|
||||
return
|
||||
|
||||
temperature_expose(datum/gas_mixture/air, temperature, volume)
|
||||
if (src.lit == 0)
|
||||
if (temperature > T0C+200)
|
||||
src.visible_message("<span style=\"color:red\">The [src] ignites!</span>")
|
||||
src.light()
|
||||
|
||||
ex_act(severity)
|
||||
if (src.lit == 0)
|
||||
src.visible_message("<span style=\"color:red\">The [src] ignites!</span>")
|
||||
src.light()
|
||||
|
||||
afterattack(atom/target, mob/user as mob)
|
||||
if (src.lit > 0)
|
||||
if (!ismob(target) && target.reagents)
|
||||
user.show_text("You heat [target].", "blue")
|
||||
target.reagents.temperature_reagents(1000,10)
|
||||
return
|
||||
else if (src.lit == -1)
|
||||
user.show_text("You [pick("fumble", "fuss", "mess", "faff")] around with [src] and try to get it to light, but it's no use.", "red")
|
||||
return
|
||||
else if (src.lit == 0)
|
||||
if (istype(target, /obj/item/match) && target:lit > 0)
|
||||
user.visible_message("<b>[user]</b> lights [src] with the flame from [target].",\
|
||||
"You light [src] with the flame from [target].")
|
||||
src.light(user)
|
||||
return
|
||||
else if (istype(target, /obj/item/clothing/mask/cigarette) && target:lit > 0)
|
||||
user.visible_message("<b>[user]</b> lights [src] with [target].",\
|
||||
"You light [src] with [target].")
|
||||
src.light(user)
|
||||
return
|
||||
else if (istype(target, /obj/item/matchbook))
|
||||
if (prob(10))
|
||||
user.visible_message("<b>[user]</b> strikes [src] on [target]. [src] breaks!",\
|
||||
"You strike [src] on [target]. [src] breaks![prob(50) ? " [pick("Damn!", "Fuck!", "Shit!", "Crap!")]" : null]")
|
||||
playsound(user.loc, 'sound/items/matchstick_hit.ogg', 50, 1)
|
||||
src.put_out(user, 1)
|
||||
return
|
||||
else if (prob(50))
|
||||
user.visible_message("<b>[user]</b> strikes [src] on [target]. A small flame sparks into life from the tip.",\
|
||||
"You strike [src] on [target]. A small flame sparks into life from the tip.")
|
||||
src.light(user)
|
||||
return
|
||||
else
|
||||
user.visible_message("<b>[user]</b> strikes [src] on [target]. Nothing happens.",\
|
||||
"You strike [src] on [target]. Nothing happens.")
|
||||
playsound(user.loc, 'sound/items/matchstick_hit.ogg', 50, 1)
|
||||
return
|
||||
else if (istype (target, /obj/item) && target:burning)
|
||||
user.visible_message("<b>[user]</b> lights [src] with the flame from [target].",\
|
||||
"You light [src] with the flame from [target].")
|
||||
src.light(user)
|
||||
return
|
||||
else
|
||||
if (prob(10))
|
||||
user.visible_message("<b>[user]</b> strikes [src] on [target]. A small flame sparks into life from the tip.[prob(50) ? " [pick("Damn", "Fuck", "Shit", "Wow")][pick("!", " that was cool!", " that was smooth!")]" : null]",\
|
||||
"You strike [src] on [target]. A small flame sparks into life from the tip.")
|
||||
src.light(user)
|
||||
return
|
||||
else if (prob(25))
|
||||
user.visible_message("<b>[user]</b> strikes [src] on [target]. [src] breaks!",\
|
||||
"You strike [src] on [target]. [src] breaks![prob(50) ? " [pick("Damn!", "Fuck!", "Shit!", "Crap!")]" : null]")
|
||||
playsound(user.loc, 'sound/items/matchstick_hit.ogg', 50, 1)
|
||||
src.put_out(user, 1)
|
||||
return
|
||||
else
|
||||
user.visible_message("<b>[user]</b> strikes [src] on [target]. Nothing happens.",\
|
||||
"You strike [src] on [target]. Nothing happens.[prob(50) ? " You feel awkward, though." : null]")
|
||||
playsound(user.loc, 'sound/items/matchstick_hit.ogg', 50, 1)
|
||||
return
|
||||
|
||||
attack(mob/M as mob, mob/user as mob)
|
||||
if (ishuman(M))
|
||||
if (src.lit > 0)
|
||||
var/mob/living/carbon/human/fella = M
|
||||
if (fella.wear_mask && istype(fella.wear_mask, /obj/item/clothing/mask/cigarette))
|
||||
var/obj/item/clothing/mask/cigarette/smoke = fella.wear_mask // aaaaaaa
|
||||
smoke.light(user, "<span style=\"color:red\"><b>[user]</b> lights [fella]'s [smoke] with [src].</span>")
|
||||
fella.set_clothing_icon_dirty()
|
||||
return
|
||||
else if (fella.bleeding || (fella.butt_op_stage == 4 && user.zone_sel.selecting == "chest"))
|
||||
src.cautery_surgery(fella, user, 5, src.lit)
|
||||
return ..()
|
||||
else
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> puts out [src] on [fella]!</span>",\
|
||||
"<span style=\"color:red\">You put out [src] on [fella]!</span>")
|
||||
fella.TakeDamage("All", 0, rand(1,5))
|
||||
if (!fella.stat)
|
||||
fella.emote("scream")
|
||||
src.put_out(user)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
attack_self(mob/user)
|
||||
if (user.find_in_hand(src))
|
||||
if (src.lit > 0)
|
||||
user.visible_message("<b>[user]</b> [pick("licks [his_or_her(user)] finger and snuffs out [src].", "waves [src] around until it goes out.")]")
|
||||
src.put_out(user)
|
||||
else
|
||||
return ..()
|
||||
return
|
||||
|
||||
/obj/item/zippo
|
||||
name = "zippo lighter"
|
||||
desc = "A pretty nice lighter."
|
||||
icon = 'icons/obj/cigarettes.dmi'
|
||||
icon_state = "zippo"
|
||||
item_state = "zippo"
|
||||
w_class = 1
|
||||
throwforce = 4
|
||||
flags = FPRINT | ONBELT | TABLEPASS | CONDUCT
|
||||
stamina_damage = 5
|
||||
stamina_cost = 5
|
||||
stamina_crit_chance = 5
|
||||
var/lit = 0
|
||||
var/fuel = 30 // -1 means infinite fuel
|
||||
var/icon_closed = "zippo"
|
||||
var/icon_open = "zippoon"
|
||||
|
||||
var/datum/light/light
|
||||
|
||||
New()
|
||||
..()
|
||||
light = new /datum/light/point
|
||||
light.set_brightness(0.4)
|
||||
light.set_color(0.94, 0.69, 0.27)
|
||||
light.attach(src)
|
||||
|
||||
pickup(mob/user)
|
||||
..()
|
||||
light.attach(user)
|
||||
|
||||
dropped(mob/user)
|
||||
..()
|
||||
spawn(0)
|
||||
if (src.loc != user)
|
||||
light.attach(src)
|
||||
|
||||
borg
|
||||
fuel = -1
|
||||
|
||||
attack_self(mob/user)
|
||||
if (user.find_in_hand(src))
|
||||
if (!src.lit)
|
||||
if (fuel == 0)
|
||||
user.show_text("Out of fuel.", "red")
|
||||
return
|
||||
src.lit = 1
|
||||
src.icon_state = src.icon_open
|
||||
src.item_state = "zippoon"
|
||||
user.visible_message("<span style=\"color:red\">Without even breaking stride, [user] flips open and lights the [src] in one smooth movement.</span>")
|
||||
|
||||
light.enable()
|
||||
|
||||
if (!(src in processing_items))
|
||||
processing_items.Add(src)
|
||||
else
|
||||
src.lit = 0
|
||||
src.icon_state = src.icon_closed
|
||||
src.item_state = "zippo"
|
||||
user.visible_message("<span style=\"color:red\">You hear a quiet click, as [user] shuts off the [src] without even looking what they're doing. Wow.</span>")
|
||||
|
||||
light.disable()
|
||||
|
||||
if (src in processing_items)
|
||||
processing_items.Remove(src)
|
||||
else
|
||||
return ..()
|
||||
return
|
||||
|
||||
afterattack(atom/target, mob/user as mob)
|
||||
if (!lit && istype(target, /obj/reagent_dispensers/fueltank))
|
||||
if (src.fuel == -1)
|
||||
user.show_text("You can't seem to find any way to add more fuel to [src]. It's probably fine.", "blue")
|
||||
return
|
||||
var/obj/reagent_dispensers/fueltank/O = target
|
||||
var/fuelamt = O.reagents.get_reagent_amount("fuel")
|
||||
if (fuelamt)
|
||||
var/removed = min(fuelamt, 50)
|
||||
O.reagents.remove_reagent("fuel", removed)
|
||||
fuel += removed
|
||||
user.show_text("[src] refueled.", "blue")
|
||||
playsound(user.loc, "sound/effects/zzzt.ogg", 50, 1, -6)
|
||||
else
|
||||
user.show_text("[O] is empty.", "red")
|
||||
if (!ismob(target) && target.reagents)
|
||||
user.show_text("You heat [target].", "blue")
|
||||
target.reagents.temperature_reagents(1500,10)
|
||||
if (ishuman(target))
|
||||
var/mob/living/carbon/human/fella = target
|
||||
|
||||
if (user.zone_sel.selecting == "l_arm")
|
||||
if (fella.limbs.l_arm_bleed > 1)
|
||||
fella.TakeDamage("chest",0,10)
|
||||
fella.limbs.l_arm_bleed = max(0,fella.limbs.l_arm_bleed-5)
|
||||
if (fella.limbs.l_arm_bleed == 0)
|
||||
user.visible_message("<span style=\"color:red\">[user] completely cauterises [fella]'s left stump with [src]!</span>")
|
||||
else
|
||||
user.visible_message("<span style=\"color:red\">[user] partially cauterises [fella]'s left stump with [src]!</span>")
|
||||
return
|
||||
|
||||
if (user.zone_sel.selecting == "r_arm")
|
||||
if (fella.limbs.r_arm_bleed > 1)
|
||||
fella.TakeDamage("chest",0,10)
|
||||
fella.limbs.r_arm_bleed = max(0,fella.limbs.r_arm_bleed-5)
|
||||
if (fella.limbs.r_arm_bleed == 0)
|
||||
user.visible_message("<span style=\"color:red\">[user] completely cauterises [fella]'s right stump with [src]!</span>")
|
||||
else
|
||||
user.visible_message("<span style=\"color:red\">[user] partially cauterises [fella]'s right stump with [src]!</span>")
|
||||
return
|
||||
|
||||
if (fella.wear_mask && istype(fella.wear_mask, /obj/item/clothing/mask/cigarette))
|
||||
var/obj/item/clothing/mask/cigarette/smoke = fella.wear_mask // aaaaaaa
|
||||
smoke.light(user, "<span style=\"color:red\"><b>[user]</b> lights [fella]'s [smoke] with [src].</span>")
|
||||
fella.set_clothing_icon_dirty()
|
||||
return
|
||||
|
||||
if (fella.bleeding || (fella.butt_op_stage == 4 && user.zone_sel.selecting == "chest"))
|
||||
if (!src.cautery_surgery(target, user, 10, src.lit))
|
||||
return ..()
|
||||
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> waves [src] around in front of [fella]'s face! OoOo, are ya scared?![src.lit ? "" : " Too bad [src] is closed."]</span>")
|
||||
return
|
||||
|
||||
else if (ismob(target))
|
||||
user.visible_message("<span style=\"color:red\"><b>[user]</b> waves [src] around in front of [target]'s face! OoOo, are ya scared?![src.lit ? "" : " Too bad [src] is closed."]</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
process()
|
||||
if (src.lit)
|
||||
if (src.fuel >= 0)
|
||||
fuel--
|
||||
var/turf/location = src.loc
|
||||
if (ismob(location))
|
||||
var/mob/M = location
|
||||
if (M.find_in_hand(src))
|
||||
location = M.loc
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if (T)
|
||||
T.hotspot_expose(700,5)
|
||||
if (fuel == 0)
|
||||
src.lit = 0
|
||||
src.icon_state = src.icon_closed
|
||||
src.item_state = "zippo"
|
||||
light.disable()
|
||||
|
||||
if (src in processing_items)
|
||||
processing_items.Remove(src)
|
||||
return
|
||||
//sleep(10)
|
||||
|
||||
suicide(var/mob/user as mob)
|
||||
if(!src.lit) return 0
|
||||
user.visible_message("<span style=\"color:red\"><b>[user] swallows the lit [src.name]!</b></span>")
|
||||
user.take_oxygen_deprivation(75)
|
||||
user.TakeDamage("chest", 0, 100)
|
||||
user.emote("scream")
|
||||
user.updatehealth()
|
||||
spawn(100)
|
||||
if (user)
|
||||
user.suiciding = 0
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/obj/item/zippo/gold
|
||||
name = "golden zippo lighter"
|
||||
icon_state = "gold_zippo"
|
||||
icon_closed = "gold_zippo"
|
||||
icon_open = "gold_zippoon"
|
||||
@@ -0,0 +1,70 @@
|
||||
/obj/item/clothing
|
||||
name = "clothing"
|
||||
//var/obj/item/clothing/master = null
|
||||
w_class = 2.0
|
||||
|
||||
var/see_face = 1
|
||||
|
||||
var/body_parts_covered = 0 //see setup.dm for appropriate bit flags
|
||||
var/c_flags = null // these don't need to be in the general flags when they only apply to clothes :I
|
||||
|
||||
var/protective_temperature = 0
|
||||
var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible
|
||||
var/permeability_coefficient = 1 // for chemicals/diseases
|
||||
var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
|
||||
var/magical = 0 // for wizard item spell power check
|
||||
|
||||
var/radproof = 0 // can this item completely shield you from radiation?
|
||||
var/disease_resistance = 0 // how much does this protect you from diseases? (of a 100% chance)
|
||||
|
||||
var/list/compatible_species = list("human") // allow monkeys/mutantraces to wear certain garments
|
||||
|
||||
var/armor_value_melee = 0
|
||||
var/armor_value_bullet = 0
|
||||
var/armor_value_explosion = 0
|
||||
var/cold_resistance = 0
|
||||
var/heat_resistance = 0
|
||||
|
||||
var/fallen_offset_x = 1
|
||||
var/fallen_offset_z = -6
|
||||
/// we want to use Z rather than Y incase anything gets rotated, it would look all jank
|
||||
var/monkey_clothes = 0
|
||||
// it's clothes specifically for monkeys please don't plaster it to their chest with an offset
|
||||
|
||||
stamina_damage = 1
|
||||
stamina_cost = 1
|
||||
stamina_crit_chance = 0
|
||||
|
||||
flags = FPRINT | TABLEPASS
|
||||
|
||||
onMaterialChanged()
|
||||
..()
|
||||
if(istype(src.material))
|
||||
protective_temperature = material.hasProperty(PROP_MELTING) ? material.getProperty(PROP_MELTING) : protective_temperature
|
||||
protective_temperature -= material.getProperty(PROP_FLAMMABILITY) * 10
|
||||
|
||||
heat_transfer_coefficient = material.hasProperty(PROP_THERMAL) ? material.getProperty(PROP_THERMAL) / 100 : heat_transfer_coefficient
|
||||
permeability_coefficient = material.hasProperty(PROP_PERMEABILITY) ? material.getProperty(PROP_PERMEABILITY) / 100 : permeability_coefficient
|
||||
siemens_coefficient = material.hasProperty(PROP_ELECTRICAL) ? material.getProperty(PROP_ELECTRICAL) / 100 : siemens_coefficient
|
||||
disease_resistance = material.hasProperty(PROP_PERMEABILITY) ? (100 - material.getProperty(PROP_PERMEABILITY)) / 2 : 0
|
||||
disease_resistance += material.getProperty(PROP_RADIOACTIVITY)
|
||||
armor_value_melee = material.hasProperty(PROP_COMPRESSIVE) ? max((material.getProperty(PROP_COMPRESSIVE) - 50) / 3, 0) : armor_value_melee
|
||||
armor_value_bullet = material.hasProperty(PROP_SHEAR) ? max((material.getProperty(PROP_SHEAR) - 50) / 25) + 1 : armor_value_bullet
|
||||
armor_value_explosion = max(round((material.getProperty(PROP_COMPRESSIVE) + material.getProperty(PROP_TENSILE) - 50) / 20), 0)
|
||||
return
|
||||
|
||||
/*
|
||||
/obj/item/clothing/fire_burn(obj/fire/raging_fire, datum/air_group/environment)
|
||||
if(raging_fire.internal_temperature > src.s_fire)
|
||||
spawn( 0 )
|
||||
var/t = src.icon_state
|
||||
src.icon_state = ""
|
||||
src.icon = 'b_items.dmi'
|
||||
flick(text("[]", t), src)
|
||||
spawn(14)
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
return 0
|
||||
return 1
|
||||
*/ //TODO FIX
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user