Overhauls and 2/28 sync (#244)

* map tweaks/shuttle engines

* helpers and defines

* global/onclick

* controllers and datums

* mapping

* game folder

* some other stuff

* some modules

* modules that aren't mobs

* some mob stuff

* new player stuff

* mob living

* silicon stuff

* simple animal things

* carbon/ayylmao

* update_icons

* carbon/human

* sounds and tools

* icons and stuff

* hippie grinder changes + tgui

* kitchen.dmi

* compile issues fixed

* mapfix

* Mapfixes 2.0

* mapedit2.0

* mapmerger pls

* Revert "mapedit2.0"

This reverts commit 74139a3cacea10df7aafca06c0a10bd3daf3a481.

* clean up vore folder + 2 hotfixes

* admin ticket refinement

* Blob tweaks and LAZYADD

* LAZYADD IS LAZY

* Magic strings purged

* DEFINES NEED HIGHER PRIORITIES

* Only a sleepless idiot deals in absolute TRUE|FALSE

* u h g

* progress bar fix

* reverts ticket logs

* there's always that one guy

* fixes and stuff

* 2/27 fixes

* game folder stuff

* stats

* some modules again

* clothing stuff

gets vg clothing out of the main files

* everything not mobs again

* mob stuff

* maps, tgui, sql stuff

* icons

* additional fixes and compile errors

* don't need this anymore

* Oh right this isn't needed anymore

* maint bar re-added

* that doesn't need to be here

* stupid events

* wtfeven

* probably makes Travis happy

* don't care to fix the grinder atm

* fixes vending sprites, changes turret

* lethal, not lethals

* overylays are finicky creatures

* lazy fix for bleeding edgy (#252)

* map tweaks/shuttle engines

* helpers and defines

* global/onclick

* controllers and datums

* mapping

* game folder

* some other stuff

* some modules

* modules that aren't mobs

* some mob stuff

* new player stuff

* mob living

* silicon stuff

* simple animal things

* carbon/ayylmao

* update_icons

* carbon/human

* sounds and tools

* icons and stuff

* hippie grinder changes + tgui

* kitchen.dmi

* compile issues fixed

* mapfix

* Mapfixes 2.0

* mapedit2.0

* mapmerger pls

* Revert "mapedit2.0"

This reverts commit 74139a3cacea10df7aafca06c0a10bd3daf3a481.

* clean up vore folder + 2 hotfixes

* admin ticket refinement

* Blob tweaks and LAZYADD

* LAZYADD IS LAZY

* Magic strings purged

* DEFINES NEED HIGHER PRIORITIES

* Only a sleepless idiot deals in absolute TRUE|FALSE

* u h g

* progress bar fix

* reverts ticket logs

* there's always that one guy

* fixes and stuff

* 2/27 fixes

* game folder stuff

* stats

* some modules again

* clothing stuff

gets vg clothing out of the main files

* everything not mobs again

* mob stuff

* maps, tgui, sql stuff

* icons

* additional fixes and compile errors

* don't need this anymore

* Oh right this isn't needed anymore

* maint bar re-added

* that doesn't need to be here

* stupid events

* wtfeven

* probably makes Travis happy

* don't care to fix the grinder atm

* fixes vending sprites, changes turret

* lethal, not lethals

* overylays are finicky creatures
This commit is contained in:
Poojawa
2017-02-28 09:30:49 -06:00
committed by GitHub
parent 93782cf716
commit 0bca862419
544 changed files with 309981 additions and 81206 deletions
+10 -2
View File
@@ -1,7 +1,7 @@
//########################## POSTERS ##################################
#define NUM_OF_POSTER_DESIGNS 36 // contraband posters
#define NUM_OF_POSTER_DESIGNS 44 // contraband posters
#define NUM_OF_POSTER_DESIGNS_LEGIT 35 // corporate approved posters
@@ -54,7 +54,15 @@ list(name = "- Punch Shit", desc = " Fight things for no reason, like a man!"),
list(name = "- The Griffin", desc = " The Griffin commands you to be the worst you can be. Will you?"),
list(name = "- Lizard", desc = " This lewd poster depicts a lizard preparing to mate."),
list(name = "- Free Drone", desc = " This poster commemorates the bravery of the rogue drone banned by CentComm."),
list(name = "- Busty Backdoor Xeno Babes 6", desc = " Get a load, or give, of these all natural Xenos!") )
list(name = "- Busty Backdoor Xeno Babes 6", desc = " Get a load, or give, of these all natural Xenos!"),
list(name = "- Robust Softdrinks", desc = " Robust Softdrinks: More robust than a toolbox to the head!"),
list(name = "- Shambler's Juice", desc = "~Shake me up some of that Shambler's Juice!~"),
list(name = "- Pwr Game", desc = "The POWER that gamers CRAVE! In partnership with Vlad's Salad."),
list(name = "- Sun-kist", desc = "Drink the stars!"),
list(name = "- Space Cola", desc = "Your favorite cola, in space."),
list(name = "- Space-Up!", desc = "Sucked out into space by the FLAVOR!"),
list(name = "- Kudzu", desc = "A poster advertising a movie about plants. How dangerous could they possibly be?"),
list(name = "- Masked Men", desc = "A poster advertising a movie about some masked men.") )
// LEGIT
+5
View File
@@ -23,3 +23,8 @@
/obj/effect/forcefield/mime/New()
..()
QDEL_IN(src, timeleft)
/obj/effect/forcefield/mime/advanced
name = "invisible blockade"
desc = "You're goona be here a while."
timeleft = 600
+7 -6
View File
@@ -11,12 +11,13 @@
victim << "<span class='danger'>*click*</span>"
/obj/effect/mine/Crossed(AM as mob|obj)
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
if(isturf(loc))
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
triggermine(AM)
else
triggermine(AM)
else
triggermine(AM)
/obj/effect/mine/proc/triggermine(mob/victim)
if(triggered)
@@ -169,4 +170,4 @@
victim.status_flags |= GOTTAGOREALLYFAST
sleep(duration)
victim.status_flags &= ~GOTTAGOREALLYFAST
victim << "<span class='notice'>You slow down.</span>"
victim << "<span class='notice'>You slow down.</span>"
@@ -169,3 +169,20 @@
/obj/structure/closet/crate/secure/loot = 20,
"" = 80
)
/obj/effect/spawner/lootdrop/organ_spawner
name = "organ spawner"
loot = list(
/obj/item/organ/heart/gland/bloody = 7,
/obj/item/organ/heart/gland/bodysnatch = 4,
/obj/item/organ/heart/gland/egg = 7,
/obj/item/organ/heart/gland/emp = 3,
/obj/item/organ/heart/gland/mindshock = 5,
/obj/item/organ/heart/gland/plasma = 7,
/obj/item/organ/heart/gland/pop = 5,
/obj/item/organ/heart/gland/slime = 4,
/obj/item/organ/heart/gland/spiderman = 5,
/obj/item/organ/heart/gland/ventcrawling = 1,
/obj/item/organ/body_egg/alien_embryo = 1,
/obj/item/organ/hivelord_core = 2)
lootcount = 3
+1
View File
@@ -163,6 +163,7 @@ var/explosionid = 1
I.throw_at(throw_at, throw_range, I.throw_speed)
if(TICK_CHECK)
stoplag()
var/circumference = (PI * init_dist * 2) + 8 //+8 to prevent shit gaps
if(exploded_this_tick.len > circumference) //only do this every revolution
for(var/Unexplode in exploded_this_tick)
+38 -25
View File
@@ -298,36 +298,50 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/obj/item/weapon/storage/S = W
if(S.use_to_pickup)
if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one.
if(isturf(src.loc))
if(isturf(loc))
var/list/rejections = list()
var/success = 0
var/failure = 0
for(var/obj/item/I in src.loc)
if(S.collection_mode == 2 && !istype(I,src.type)) // We're only picking up items of the target type
failure = 1
continue
if(I.type in rejections) // To limit bag spamming: any given type only complains once
continue
if(!S.can_be_inserted(I, stop_messages = 1)) // Note can_be_inserted still makes noise when the answer is no
if(S.contents.len >= S.storage_slots)
break
rejections += I.type // therefore full bags are still a little spammy
failure = 1
continue
var/list/things = loc.contents.Copy()
if (S.collection_mode == 2)
things = typecache_filter_list(things, typecacheof(type))
success = 1
S.handle_item_insertion(I, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed.
if(success && !failure)
user << "<span class='notice'>You put everything [S.preposition] [S].</span>"
else if(success)
user << "<span class='notice'>You put some things [S.preposition] [S].</span>"
else
user << "<span class='warning'>You fail to pick anything up with [S]!</span>"
var/len = things.len
if(!len)
user << "<span class='notice'>You failed to pick up anything with [S].</span>"
return
var/datum/progressbar/progress = new(user, len, loc)
while (do_after(user, 10, TRUE, S, FALSE, CALLBACK(src, .proc/handle_mass_pickup, S, things, loc, rejections, progress)))
sleep(1)
qdel(progress)
user << "<span class='notice'>You put everything you could [S.preposition] [S].</span>"
else if(S.can_be_inserted(src))
S.handle_item_insertion(src)
/obj/item/proc/handle_mass_pickup(obj/item/weapon/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress)
for(var/obj/item/I in things)
things -= I
if(I.loc != thing_loc)
continue
if(I.type in rejections) // To limit bag spamming: any given type only complains once
continue
if(!S.can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no
if(S.contents.len >= S.storage_slots)
break
rejections += I.type // therefore full bags are still a little spammy
continue
S.handle_item_insertion(I, TRUE) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed.
if (TICK_CHECK)
progress.update(progress.goal - things.len)
return TRUE
progress.update(progress.goal - things.len)
return FALSE
// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency
@@ -375,7 +389,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
/obj/item/proc/item_action_slot_check(slot, mob/user)
if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there
@@ -493,7 +506,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/index = blood_splatter_index()
var/icon/blood_splatter_icon = blood_splatter_icons[index]
if(blood_splatter_icon)
overlays -= blood_splatter_icon
cut_overlay(blood_splatter_icon)
/obj/item/clothing/gloves/clean_blood()
. = ..()
-2
View File
@@ -146,10 +146,8 @@
/obj/item/areaeditor/proc/get_area()
var/turf/T = get_turf(usr)
var/area/A = T.loc
A = A.master
return A
/obj/item/areaeditor/proc/get_area_type(area/A = get_area())
if(A.outdoors)
return AREA_SPACE
-5
View File
@@ -21,11 +21,6 @@
R.add_fingerprint(user)
qdel(src)
/obj/item/weapon/storage/box/bodybags
name = "body bags"
desc = "The label indicates that it contains body bags."
icon_state = "bodybags"
/obj/item/weapon/storage/box/bodybags/New()
..()
for(var/i in 1 to 7)
+6 -6
View File
@@ -61,7 +61,7 @@
user << "Your name has been sent to your employers for approval."
// Autoapproves after a certain time
response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user), approval_time, TIMER_STOPPABLE)
response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE)
admins << "<span class='adminnotice'><b><font color=orange>CUSTOM STATION RENAME:</font></b>[key_name_admin(user)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) proposes to rename the station to [new_name] (will autoapprove in [approval_time / 10] seconds). (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[user]'>BSA</A>) (<A HREF='?_src_=holder;reject_custom_name=\ref[src]'>REJECT</A>) (<a href='?_src_=holder;CentcommReply=\ref[user]'>RPLY</a>)</span>"
/obj/item/station_charter/proc/reject_proposed(user)
@@ -80,20 +80,20 @@
deltimer(response_timer_id)
response_timer_id = null
/obj/item/station_charter/proc/rename_station(designation, mob/user)
/obj/item/station_charter/proc/rename_station(designation, uname, ureal_name, ukey)
if(config && config.server_name)
world.name = "[config.server_name]: [designation]"
else
world.name = designation
station_name = designation
minor_announce("[user.real_name] has designated your station as [station_name()]", "Captain's Charter", 0)
log_game("[key_name(user)] has renamed the station as [station_name()].")
minor_announce("[ureal_name] has designated your station as [station_name()]", "Captain's Charter", 0)
log_game("[ukey] has renamed the station as [station_name()].")
name = "station charter for [station_name()]"
desc = "An official document entrusting the governance of \
[station_name()] and surrounding space to Captain [user]."
[station_name()] and surrounding space to Captain [uname]."
if(!unlimited_uses)
used = TRUE
#undef STATION_RENAME_TIME_LIMIT
#undef STATION_RENAME_TIME_LIMIT
+1 -8
View File
@@ -416,7 +416,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/alert_s = input(U,"Alert severity level","Ping Drones",null) as null|anything in list("Low","Medium","High","Critical")
if(A && alert_s)
var/msg = "<span class='boldnotice'>NON-DRONE PING: [U.name]: [alert_s] priority alert in [A.name]!</span>"
_alert_drones(msg, 1)
_alert_drones(msg, TRUE)
U << msg
@@ -999,13 +999,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
else
user << "You do not have a PDA. You should make an issue report about this."
//Some spare PDAs in a box
/obj/item/weapon/storage/box/PDAs
name = "spare PDAs"
desc = "A box of spare PDA microcomputers."
icon = 'icons/obj/storage.dmi'
icon_state = "pda"
/obj/item/weapon/storage/box/PDAs/New()
..()
new /obj/item/device/pda(src)
@@ -4,7 +4,6 @@
icon_state = "megaphone"
item_state = "radio"
w_class = WEIGHT_CLASS_SMALL
flags = FPRINT
siemens_coefficient = 1
var/spamcheck = 0
var/emagged = 0
@@ -93,10 +93,6 @@
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
pai << "Your supplemental directives have been updated. Your new directives are:"
pai << "Prime Directive : <br>[pai.laws.zeroth]"
for(var/slaws in pai.laws.supplied)
pai << "Supplemental Directives: <br>[slaws]"
if(href_list["toggle_holo"])
if(pai.canholo)
pai << "<span class='userdanger'>Your owner has disabled your holomatrix projectors!</span>"
@@ -56,7 +56,7 @@
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
last_tick = world.timeofday
var/area/A = get_area_master(src)
var/area/A = get_area(src)
if(!A || emped)
on = 0
else
+1 -1
View File
@@ -125,7 +125,7 @@ MASS SPECTROMETER
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.heart_attack && H.stat != DEAD)
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
user << "<span class='danger'>Subject suffering from heart attack: Apply defibrillator immediately!</span>"
if(iscarbon(M))
@@ -267,7 +267,7 @@
/obj/item/device/tape/proc/fix()
overlays -= "ribbonoverlay"
cut_overlay("ribbonoverlay")
ruined = 0
@@ -192,8 +192,6 @@ var/global/list/datum/stack_recipe/reinforced_glass_recipes = list ( \
var/mob/living/carbon/human/H = AM
if(PIERCEIMMUNE in H.dna.species.species_traits)
return
if(H.dna.species.id == "slime" || "jelly")
return
var/picked_def_zone = pick("l_leg", "r_leg")
var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone)
if(!istype(O))
@@ -211,4 +209,4 @@ var/global/list/datum/stack_recipe/reinforced_glass_recipes = list ( \
"<span class='userdanger'>You slide on the broken glass!</span>")
cooldown = world.time
H.Weaken(3)
H.Weaken(3)
@@ -1,12 +1,13 @@
/* Diffrent misc types of sheets
* Contains:
* Metal
* Plasteel
* Wood
* Cloth
* Cardboard
* Runed Metal (cult)
* Brass (clockwork cult)
* Metal
* Plasteel
* Wood
* Cloth
* Plastic
* Cardboard
* Runed Metal (cult)
* Brass (clockwork cult)
*/
/*
@@ -357,3 +358,27 @@ var/global/list/datum/stack_recipe/brass_recipes = list ( \
throw_speed = 1
throw_range = 3
origin_tech = "materials=2;biotech=2"
var/global/list/datum/stack_recipe/plastic_recipes = list(
new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = 1, on_floor = 1, time = 40))
/obj/item/stack/sheet/plastic
name = "plastic"
desc = "Compress dinosaur over millions of years, then refine, split and mold, and voila! You have plastic."
singular_name = "plastic sheet"
icon_state = "sheet-plastic"
throwforce = 7
flags = CONDUCT
origin_tech = "materials=1"
origin_tech = "materials=1;biotech=1"
merge_type = /obj/item/stack/sheet/plastic
/obj/item/stack/sheet/plastic/fifty
amount = 50
/obj/item/stack/sheet/plastic/five
amount = 5
/obj/item/stack/sheet/plastic/New()
recipes = plastic_recipes
. = ..()
+20
View File
@@ -0,0 +1,20 @@
/obj/item/taster
name = "taster"
desc = "Tastes things, so you don't have to!"
icon = 'icons/obj/surgery.dmi'
icon_state = "tonguenormal"
w_class = WEIGHT_CLASS_TINY
var/taste_sensitivity = 15
/obj/item/taster/get_spans()
return list()
/obj/item/taster/afterattack(atom/O, mob/user, proximity)
if(!proximity)
return
if(O.reagents)
var/message = O.reagents.generate_taste_message(taste_sensitivity)
user << "<span class='notice'>[src] tastes <span class='italics'>[message]</span> in [O].</span>"
@@ -57,10 +57,9 @@ AI MODULES
message_admins("[key_name_admin(user)] tried to upload laws to [law_datum.owner ? key_name_admin(law_datum.owner) : "an AI core"] that would exceed the law cap.")
overflow = TRUE
var/law2log = src.transmitInstructions(law_datum, user, overflow) //Freeforms return something extra we need to log
var/law2log = transmitInstructions(law_datum, user, overflow) //Freeforms return something extra we need to log
if(law_datum.owner)
user << "<span class='notice'>Upload complete. [law_datum.owner]'s laws have been modified.</span>"
law_datum.owner.show_laws()
law_datum.owner.law_change_counter++
else
user << "<span class='notice'>Upload complete.</span>"
@@ -75,7 +74,7 @@ AI MODULES
//The proc that actually changes the silicon's laws.
/obj/item/weapon/aiModule/proc/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow = FALSE)
if(law_datum.owner)
law_datum.owner << "<span class='userdanger'>[sender] has uploaded a change to the laws you must follow using a [name]. From now on, these are your laws: </span>"
law_datum.owner << "<span class='userdanger'>[sender] has uploaded a change to the laws you must follow using a [name].</span>"
/******************** Modules ********************/
+1 -1
View File
@@ -576,7 +576,7 @@ var/global/list/RPD_recipes=list(
return
user << "<span class='notice'>You start building a disposals pipe...</span>"
playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
if(do_after(user, 20, target = A))
if(do_after(user, 4, target = A))
var/obj/structure/disposalconstruct/C = new (A, queued_p_type ,queued_p_dir)
if(!C.can_place())
+112 -97
View File
@@ -1,4 +1,6 @@
//backpack item
#define HALFWAYCRITDEATH ((HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) * 0.5)
/obj/item/weapon/defibrillator
name = "defibrillator"
desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
@@ -240,7 +242,6 @@
paddles = make_paddles()
bcell = new(src)
update_icon()
return
/obj/item/weapon/defibrillator/compact/combat
name = "combat defibrillator"
@@ -253,7 +254,6 @@
paddles = make_paddles()
bcell = new /obj/item/weapon/stock_parts/cell/infinite(src)
update_icon()
return
/obj/item/weapon/defibrillator/compact/combat/loaded/attackby(obj/item/weapon/W, mob/user, params)
if(W == paddles)
@@ -339,7 +339,6 @@
return 1
/obj/item/weapon/twohanded/shockpaddles/attack(mob/M, mob/user)
var/halfwaycritdeath = (HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) / 2
if(busy)
return
@@ -359,6 +358,11 @@
else
user << "<span class='warning'>[src] are recharging!</span>"
return
if(user.a_intent == INTENT_DISARM)
do_disarm(M, user)
return
if(!ishuman(M))
if(req_defib)
user << "<span class='warning'>The instructions on [defib] don't mention how to revive that...</span>"
@@ -367,101 +371,109 @@
return
var/mob/living/carbon/human/H = M
if(user.a_intent == INTENT_DISARM)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
busy = 1
H.visible_message("<span class='danger'>[user] has touched [H.name] with [src]!</span>", \
"<span class='userdanger'>[user] has touched [H.name] with [src]!</span>")
H.adjustStaminaLoss(50)
H.Weaken(5)
H.updatehealth() //forces health update before next life tick
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
H.emote("gasp")
add_logs(user, M, "stunned", src)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(req_defib)
defib.cooldowncheck(user)
else
recharge(60)
return
if(user.zone_selected != "chest")
user << "<span class='warning'>You need to target your patient's \
chest with [src]!</span>"
return
if(user.a_intent == INTENT_HARM)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
user.visible_message("<span class='warning'>[user] begins to place [src] on [M.name]'s chest.</span>",
"<span class='warning'>You overcharge the paddles and begin to place them onto [M]'s chest...</span>")
busy = 1
update_icon()
if(do_after(user, 30, target = M))
user.visible_message("<span class='notice'>[user] places [src] on [M.name]'s chest.</span>",
"<span class='warning'>You place [src] on [M.name]'s chest and begin to charge them.</span>")
var/turf/T = get_turf(defib)
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
if(req_defib)
T.audible_message("<span class='warning'>\The [defib] lets out an urgent beep and lets out a steadily rising hum...</span>")
else
user.audible_message("<span class='warning'>[src] let out an urgent beep.</span>")
if(do_after(user, 30, target = M)) //Takes longer due to overcharging
if(!M)
busy = 0
update_icon()
return
if(M && M.stat == DEAD)
user << "<span class='warning'>[M] is dead.</span>"
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
busy = 0
update_icon()
return
user.visible_message("<span class='boldannounce'><i>[user] shocks [M] with \the [src]!</span>", "<span class='warning'>You shock [M] with \the [src]!</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1)
playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
var/mob/living/carbon/human/HU = M
M.emote("scream")
if(!HU.heart_attack)
HU.heart_attack = 1
if(!HU.stat)
HU.visible_message("<span class='warning'>[M] thrashes wildly, clutching at their chest!</span>",
"<span class='userdanger'>You feel a horrible agony in your chest!</span>")
HU.apply_damage(50, BURN, "chest")
add_logs(user, M, "overloaded the heart of", defib)
M.Weaken(5)
M.Jitter(100)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(!req_defib)
recharge(60)
if(req_defib && (defib.cooldowncheck(user)))
return
busy = 0
update_icon()
do_harm(H, user)
return
if((!req_defib && grab_ghost) || (req_defib && defib.grab_ghost))
H.notify_ghost_cloning("Your heart is being defibrillated!")
H.grab_ghost() // Shove them back in their body.
else if(!H.suiciding && !(H.disabilities & NOCLONE)&& !H.hellbound)
H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src)
user.visible_message("<span class='warning'>[user] begins to place [src] on [M.name]'s chest.</span>", "<span class='warning'>You begin to place [src] on [M.name]'s chest...</span>")
do_help(H, user)
/obj/item/weapon/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
busy = 1
M.visible_message("<span class='danger'>[user] has touched [M] with [src]!</span>", \
"<span class='userdanger'>[user] has touched [M] with [src]!</span>")
M.adjustStaminaLoss(50)
M.Weaken(5)
M.updatehealth() //forces health update before next life tick
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
M.emote("gasp")
add_logs(user, M, "stunned", src)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(req_defib)
defib.cooldowncheck(user)
else
recharge(60)
/obj/item/weapon/twohanded/shockpaddles/proc/do_harm(mob/living/carbon/human/H, mob/living/user)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
user.visible_message("<span class='warning'>[user] begins to place [src] on [H]'s chest.</span>",
"<span class='warning'>You overcharge the paddles and begin to place them onto [H]'s chest...</span>")
busy = 1
update_icon()
if(do_after(user, 30, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("<span class='notice'>[user] places [src] on [M.name]'s chest.</span>", "<span class='warning'>You place [src] on [M.name]'s chest.</span>")
if(do_after(user, 30, target = H))
user.visible_message("<span class='notice'>[user] places [src] on [H]'s chest.</span>",
"<span class='warning'>You place [src] on [H]'s chest and begin to charge them.</span>")
var/turf/T = get_turf(defib)
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
if(req_defib)
T.audible_message("<span class='warning'>\The [defib] lets out an urgent beep and lets out a steadily rising hum...</span>")
else
user.audible_message("<span class='warning'>[src] let out an urgent beep.</span>")
if(do_after(user, 30, target = H)) //Takes longer due to overcharging
if(!H)
busy = 0
update_icon()
return
if(H && H.stat == DEAD)
user << "<span class='warning'>[H] is dead.</span>"
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
busy = 0
update_icon()
return
user.visible_message("<span class='boldannounce'><i>[user] shocks [H] with \the [src]!</span>", "<span class='warning'>You shock [H] with \the [src]!</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1)
playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
H.emote("scream")
if(H.can_heartattack() && !H.undergoing_cardiac_arrest())
if(!H.stat)
H.visible_message("<span class='warning'>[H] thrashes wildly, clutching at their chest!</span>",
"<span class='userdanger'>You feel a horrible agony in your chest!</span>")
H.set_heartattack(TRUE)
H.apply_damage(50, BURN, "chest")
add_logs(user, H, "overloaded the heart of", defib)
H.Weaken(5)
H.Jitter(100)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(!req_defib)
recharge(60)
if(req_defib && (defib.cooldowncheck(user)))
return
busy = 0
update_icon()
/obj/item/weapon/twohanded/shockpaddles/proc/do_help(mob/living/carbon/human/H, mob/living/user)
user.visible_message("<span class='warning'>[user] begins to place [src] on [H]'s chest.</span>", "<span class='warning'>You begin to place [src] on [H]'s chest...</span>")
busy = 1
update_icon()
if(do_after(user, 30, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("<span class='notice'>[user] places [src] on [H]'s chest.</span>", "<span class='warning'>You place [src] on [H]'s chest.</span>")
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
var/tplus = world.time - H.timeofdeath
// past this much time the patient is unrecoverable
@@ -472,7 +484,7 @@
var/tloss = DEFIB_TIME_LOSS * 10
var/total_burn = 0
var/total_brute = 0
if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
if(do_after(user, 20, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
for(var/obj/item/carried_item in H.contents)
if(istype(carried_item, /obj/item/clothing/suit/space))
if((!src.combat && !req_defib) || (req_defib && !defib.combat))
@@ -482,7 +494,7 @@
update_icon()
return
if(H.stat == DEAD)
M.visible_message("<span class='warning'>[M]'s body convulses a bit.")
H.visible_message("<span class='warning'>[H]'s body convulses a bit.")
playsound(get_turf(src), "bodyfall", 50, 1)
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
total_brute = H.getBruteLoss()
@@ -512,23 +524,24 @@
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
else
//If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit
if (H.health > halfwaycritdeath)
H.adjustOxyLoss(H.health - halfwaycritdeath, 0)
if (H.health > HALFWAYCRITDEATH)
H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0)
else
var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss()
var/mobhealth = H.health
H.adjustOxyLoss((mobhealth - halfwaycritdeath) * (H.getOxyLoss() / overall_damage), 0)
H.adjustToxLoss((mobhealth - halfwaycritdeath) * (H.getToxLoss() / overall_damage), 0)
H.adjustFireLoss((mobhealth - halfwaycritdeath) * (total_burn / overall_damage), 0)
H.adjustBruteLoss((mobhealth - halfwaycritdeath) * (total_brute / overall_damage), 0)
H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0)
H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0)
H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0)
H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0)
H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually.
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.</span>")
playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
H.set_heartattack(FALSE)
H.revive()
H.emote("gasp")
if(tplus > tloss)
H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
add_logs(user, M, "revived", defib)
add_logs(user, H, "revived", defib)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
@@ -537,14 +550,14 @@
defib.cooldowncheck(user)
else
recharge(60)
else if(H.heart_attack)
H.heart_attack = 0
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
else if (!H.getorgan(/obj/item/organ/heart))
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient's heart is missing. Operation aborted.</span>")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
else if(H.undergoing_cardiac_arrest())
H.set_heartattack(FALSE)
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
else
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.</span>")
@@ -579,3 +592,5 @@
icon_state = "defibpaddles0"
item_state = "defibpaddles0"
req_defib = FALSE
#undef HALFWAYCRITDEATH
@@ -103,8 +103,7 @@
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
target.priority_overlays -= image_overlay
target.cut_overlay(image_overlay, TRUE)
else
location = get_turf(src)
if(location)
@@ -61,9 +61,17 @@
return
/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, flag)
if(flag) return // too close
// Make sure our user is still holding us
if(user && user.get_active_held_item() == src)
if(flag)
return // too close
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna.check_mutation(HULK))
user << "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>"
return
if(NOGUNS in H.dna.species.species_traits)
user << "<span class='warning'>Your fingers don't fit in the trigger guard!</span>"
return
if(user && user.get_active_held_item() == src) // Make sure our user is still holding us
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
@@ -47,7 +47,7 @@
if(clown_check(user))
user << "<span class='warning'>You light the [name]!</span>"
active = 1
overlays -= image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled")
cut_overlay(image('icons/obj/grenade.dmi', icon_state = "improvised_grenade_filled"), TRUE) //this line make no sense
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
@@ -130,8 +130,7 @@
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
target.priority_overlays -= image_overlay
target.cut_overlay(image_overlay, TRUE)
else
location = get_turf(src)
if(location)
@@ -158,8 +157,7 @@
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
target.priority_overlays -= image_overlay
target.cut_overlay(image_overlay, TRUE)
else
location = get_turf(src)
if(location)
@@ -0,0 +1,224 @@
//His Grace is a very special weapon granted only to traitor chaplains.
//When awakened, He thirsts for blood and begins ticking a "bloodthirst" counter.
//The wielder of His Grace is immune to stuns and gradually heals.
//If the wielder fails to feed His Grace in time, He will devour them and become incredibly aggressive.
//Leaving His Grace alone for some time will reset His thirst and put Him to sleep.
//Using His Grace effectively requires extreme speed and care.
/obj/item/weapon/his_grace
name = "artistic toolbox"
desc = "A toolbox painted bright green. Looking at it makes you feel uneasy."
icon_state = "his_grace"
item_state = "artistic_toolbox"
icon = 'icons/obj/weapons.dmi'
w_class = WEIGHT_CLASS_GIGANTIC
origin_tech = "combat=4;engineering=4;syndicate=2"
force = 12
attack_verb = list("robusted")
hitsound = 'sound/weapons/smash.ogg'
var/ascended = FALSE
var/awakened = 0
var/victims_needed = 20 //how many victims needed to ascend
var/bloodthirst = HIS_GRACE_SATIATED
var/prev_bloodthirst = HIS_GRACE_SATIATED
var/force_bonus = 0
var/ascend_bonus = 15
/obj/item/weapon/his_grace/New()
..()
START_PROCESSING(SSprocessing, src)
/obj/item/weapon/his_grace/Destroy()
STOP_PROCESSING(SSprocessing, src)
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
return ..()
/obj/item/weapon/his_grace/attack_self(mob/living/user)
if(!awakened)
INVOKE_ASYNC(src, .proc/awaken, user)
/obj/item/weapon/his_grace/attack(mob/living/M, mob/user)
if(awakened && M.stat)
consume(M)
if(LAZYLEN(contents) >= victims_needed)
ascend()
else
..()
/obj/item/weapon/his_grace/CtrlClick(mob/user) //you can't pull his grace
attack_hand(user)
/obj/item/weapon/his_grace/examine(mob/user)
..()
if(awakened)
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
user << "<span class='his_grace'>[src] isn't very hungry. Not yet.</span>"
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
user << "<span class='his_grace'>[src] would like a snack.</span>"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
user << "<span class='his_grace'>[src] is quite hungry now.</span>"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
user << "<span class='his_grace'>[src] is openly salivating at the sight of you. Be careful.</span>"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
user << "<span class='his_grace bold'>You walk a fine line. [src] is very close to devouring you.</span>"
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
user << "<span class='his_grace bold'>[src] is shaking violently and staring directly at you.</span>"
else
user << "<span class='his_grace'>[src] is latched closed.</span>"
/obj/item/weapon/his_grace/relaymove(mob/living/user) //Allows changelings, etc. to climb out of Him after they revive, provided He isn't active
if(!awakened)
user.forceMove(get_turf(src))
user.visible_message("<span class='warning'>[user] scrambles out of [src]!</span>", "<span class='notice'>You climb out of [src]!</span>")
/obj/item/weapon/his_grace/process()
if(!bloodthirst)
drowse()
return
if(bloodthirst < HIS_GRACE_CONSUME_OWNER)
adjust_bloodthirst(1 + Floor(LAZYLEN(contents) * 0.5)) //Maybe adjust this?
else
adjust_bloodthirst(1) //don't cool off rapidly once we're at the point where His Grace consumes all.
var/mob/living/master = get_atom_on_turf(src, /mob/living)
if(istype(master) && (src in master.held_items))
switch(bloodthirst)
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
master.visible_message("<span class='boldwarning'>[src] turns on [master]!</span>", "<span class='his_grace big bold'>[src] turns on you!</span>")
do_attack_animation(master, null, src)
master.emote("scream")
master.remove_status_effect(STATUS_EFFECT_HISGRACE)
flags &= ~NODROP
master.Weaken(3)
master.adjustBruteLoss(master.maxHealth)
playsound(master, 'sound/effects/splat.ogg', 100, 0)
else
master.apply_status_effect(STATUS_EFFECT_HISGRACE)
return
forceMove(get_turf(src)) //no you can't put His Grace in a locker you just have to deal with Him
if(bloodthirst < HIS_GRACE_CONSUME_OWNER)
return
if(bloodthirst >= HIS_GRACE_FALL_ASLEEP)
drowse()
return
var/list/targets = list()
for(var/mob/living/L in oview(2, src))
targets += L
if(!LAZYLEN(targets))
return
var/mob/living/L = pick(targets)
step_to(src, L)
if(Adjacent(L))
if(!L.stat)
L.visible_message("<span class='warning'>[src] lunges at [L]!</span>", "<span class='his_grace big bold'>[src] lunges at you!</span>")
do_attack_animation(L, null, src)
playsound(L, 'sound/weapons/smash.ogg', 50, 1)
playsound(L, 'sound/misc/desceration-01.ogg', 50, 1)
L.adjustBruteLoss(force)
adjust_bloodthirst(-5) //Don't stop attacking they're right there!
else
consume(L)
/obj/item/weapon/his_grace/proc/awaken(mob/user) //Good morning, Mr. Grace.
if(awakened)
return
awakened = TRUE
user.visible_message("<span class='boldwarning'>[src] begins to rattle. He thirsts.</span>", "<span class='his_grace'>You flick [src]'s latch up. You hope this is a good idea.</span>")
name = "His Grace"
desc = "A bloodthirsty artifact created by a profane rite."
gender = MALE
adjust_bloodthirst(1)
force_bonus = HIS_GRACE_FORCE_BONUS * LAZYLEN(contents)
playsound(user, 'sound/effects/pope_entry.ogg', 100)
icon_state = "green_awakened"
/obj/item/weapon/his_grace/proc/drowse() //Good night, Mr. Grace.
if(!awakened || ascended)
return
var/turf/T = get_turf(src)
T.visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still, His latch snapping closed.</span>")
playsound(loc, 'sound/weapons/batonextend.ogg', 100, 1)
name = initial(name)
desc = initial(desc)
icon_state = initial(icon_state)
gender = initial(gender)
force = initial(force)
force_bonus = initial(force_bonus)
awakened = FALSE
bloodthirst = 0
/obj/item/weapon/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace.
if(!meal)
return
meal.visible_message("<span class='warning'>[src] swings open and devours [meal]!</span>", "<span class='his_grace big bold'>[src] consumes you!</span>")
meal.adjustBruteLoss(200)
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
playsound(src, 'sound/items/eatfood.ogg', 100, 1)
meal.forceMove(src)
force_bonus += HIS_GRACE_FORCE_BONUS
prev_bloodthirst = bloodthirst
if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER)
bloodthirst = max(LAZYLEN(contents), 1) //Never fully sated, and His hunger will only grow.
else
bloodthirst = HIS_GRACE_CONSUME_OWNER
update_stats()
/obj/item/weapon/his_grace/proc/adjust_bloodthirst(amt)
prev_bloodthirst = bloodthirst
if(prev_bloodthirst < HIS_GRACE_CONSUME_OWNER)
bloodthirst = Clamp(bloodthirst + amt, HIS_GRACE_SATIATED, HIS_GRACE_CONSUME_OWNER)
else
bloodthirst = Clamp(bloodthirst + amt, HIS_GRACE_CONSUME_OWNER, HIS_GRACE_FALL_ASLEEP)
update_stats()
/obj/item/weapon/his_grace/proc/update_stats()
flags &= ~NODROP
var/mob/living/master = get_atom_on_turf(src, /mob/living)
switch(bloodthirst)
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
if(HIS_GRACE_CONSUME_OWNER > prev_bloodthirst)
master.visible_message("<span class='userdanger'>[src] enters a frenzy!</span>")
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
flags |= NODROP
if(HIS_GRACE_STARVING > prev_bloodthirst)
master.visible_message("<span class='boldwarning'>[src] is starving!</span>", "<span class='his_grace big'>[src]'s bloodlust overcomes you. [src] must be fed, or you will become His meal.\
[force_bonus < 15 ? " And still, His power grows.":""]</span>")
force_bonus = max(force_bonus, 15)
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
flags |= NODROP
if(HIS_GRACE_FAMISHED > prev_bloodthirst)
master.visible_message("<span class='warning'>[src] is very hungry!</span>", "<span class='his_grace big'>Spines sink into your hand. [src] must feed immediately.\
[force_bonus < 10 ? " His power grows.":""]</span>")
force_bonus = max(force_bonus, 10)
if(prev_bloodthirst >= HIS_GRACE_STARVING)
master.visible_message("<span class='warning'>[src] is now only very hungry!</span>", "<span class='his_grace big'>Your bloodlust recedes.</span>")
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
if(HIS_GRACE_HUNGRY > prev_bloodthirst)
master.visible_message("<span class='warning'>[src] is getting hungry.</span>", "<span class='his_grace big'>You feel [src]'s hunger within you.\
[force_bonus < 5 ? " His power grows.":""]</span>")
force_bonus = max(force_bonus, 5)
if(prev_bloodthirst >= HIS_GRACE_FAMISHED)
master.visible_message("<span class='warning'>[src] is now only somewhat hungry.</span>", "<span class='his_grace'>[src]'s hunger recedes a little...</span>")
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
if(HIS_GRACE_PECKISH > prev_bloodthirst)
master.visible_message("<span class='warning'>[src] is feeling snackish.</span>", "<span class='his_grace'>[src] begins to hunger.</span>")
if(prev_bloodthirst >= HIS_GRACE_HUNGRY)
master.visible_message("<span class='warning'>[src] is now only a little peckish.</span>", "<span class='his_grace big'>[src]'s hunger recedes somewhat...</span>")
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
if(prev_bloodthirst >= HIS_GRACE_PECKISH)
master.visible_message("<span class='warning'>[src] is satiated.</span>", "<span class='his_grace big'>[src]'s hunger recedes...</span>")
force = initial(force) + force_bonus
/obj/item/weapon/his_grace/proc/ascend()
if(ascended)
return
var/mob/living/carbon/human/master = loc
force_bonus += ascend_bonus
desc = "A legendary toolbox and a distant artifact from The Age of Three Powers. On its three latches engraved are the words \"The Sun\", \"The Moon\", and \"The Stars\". The entire toolbox has the words \"The World\" engraved into its sides."
icon_state = "his_grace_ascended"
item_state = "toolbox_gold"
ascended = TRUE
playsound(master, 'sound/effects/his_grace_ascend.ogg', 100)
if(istype(master))
master.visible_message("<span class='his_grace big bold'>Gods will be watching.</span>", "<span class='his_grace big bold'>God will be watching.</span>")
name = "[master]'s mythical toolbox of three powers"
+2 -1
View File
@@ -4,7 +4,7 @@
/obj/item/weapon/paint
gender= PLURAL
name = "paint"
desc = "Used to recolor floors and walls. Can not be removed by the janitor."
desc = "Used to recolor floors and walls. Can be removed by the janitor."
icon = 'icons/obj/items.dmi'
icon_state = "paint_neutral"
item_color = "FFFFFF"
@@ -92,6 +92,7 @@
/obj/item/weapon/paint/paint_remover
gender = PLURAL
name = "paint remover"
desc = "Used to remove color from floors and walls."
icon_state = "paint_neutral"
/obj/item/weapon/paint/paint_remover/afterattack(turf/target, mob/user, proximity)
@@ -77,10 +77,16 @@
Fire(user, target)
/obj/item/weapon/pneumatic_cannon/proc/Fire(var/mob/living/carbon/human/user, var/atom/target)
/obj/item/weapon/pneumatic_cannon/proc/Fire(mob/living/carbon/human/user, var/atom/target)
if(!istype(user) && !target)
return
var/discharge = 0
if(user.dna.check_mutation(HULK))
user << "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>"
return
if(NOGUNS in user.dna.species.species_traits)
user << "<span class='warning'>Your fingers don't fit in the trigger guard!</span>"
return
if(!loadedItems || !loadedWeightClass)
user << "<span class='warning'>\The [src] has nothing loaded.</span>"
return
@@ -94,7 +94,7 @@
/obj/item/weapon/storage/bag/ore/holding //miners, your messiah has arrived
name = "mining satchel of holding"
desc = "A revolution in convenience, this satchel allows for infinite ore storage. It's been outfitted with anti-malfunction safety measures."
desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures."
storage_slots = INFINITY
max_combined_w_class = INFINITY
origin_tech = "bluespace=4;materials=3;engineering=3"
@@ -28,7 +28,17 @@
item_state = "syringe_kit"
resistance_flags = FLAMMABLE
var/foldable = /obj/item/stack/sheet/cardboard
var/illustration = "writing"
/obj/item/weapon/storage/box/Initialize()
. = ..()
update_icon()
/obj/item/weapon/storage/box/update_icon()
. = ..()
if(illustration)
cut_overlays()
add_overlay(image('icons/obj/storage.dmi', "[illustration]"))
/obj/item/weapon/storage/box/attack_self(mob/user)
..()
@@ -57,6 +67,26 @@
return ..()
//Disk boxes
/obj/item/weapon/storage/box/disks
name = "diskette box"
illustration = "disk_kit"
/obj/item/weapon/storage/box/disks/Initialize()
..()
for(var/i in 1 to 7)
new /obj/item/weapon/disk/data(src)
/obj/item/weapon/storage/box/disks_plantgene
name = "plant data disks box"
illustration = "disk_kit"
/obj/item/weapon/storage/box/disks_plantgene/Initialize()
..()
for(var/i in 1 to 7)
new /obj/item/weapon/disk/plantgene(src)
// Ordinary survival box
/obj/item/weapon/storage/box/survival/New()
..()
@@ -107,7 +137,7 @@
/obj/item/weapon/storage/box/gloves
name = "box of latex gloves"
desc = "Contains sterile latex gloves."
icon_state = "latex"
illustration = "latex"
/obj/item/weapon/storage/box/gloves/New()
..()
@@ -127,7 +157,7 @@
/obj/item/weapon/storage/box/syringes
name = "box of syringes"
desc = "A box full of syringes."
icon_state = "syringe"
illustration = "syringe"
/obj/item/weapon/storage/box/syringes/New()
..()
@@ -137,7 +167,7 @@
/obj/item/weapon/storage/box/medipens
name = "box of medipens"
desc = "A box full of epinephrine MediPens."
icon_state = "syringe"
illustration = "syringe"
/obj/item/weapon/storage/box/medipens/New()
..()
@@ -147,7 +177,7 @@
/obj/item/weapon/storage/box/medipens/utility
name = "stimpack value kit"
desc = "A box with several stimpack medipens for the economical miner."
icon_state = "syringe"
illustration = "syringe"
/obj/item/weapon/storage/box/medipens/utility/New()
..()
@@ -156,7 +186,7 @@
/obj/item/weapon/storage/box/beakers
name = "box of beakers"
icon_state = "beaker"
illustration = "beaker"
/obj/item/weapon/storage/box/beakers/New()
..()
@@ -177,7 +207,8 @@
/obj/item/weapon/storage/box/flashbangs
name = "box of flashbangs (WARNING)"
desc = "<B>WARNING: These devices are extremely dangerous and can cause blindness or deafness in repeated use.</B>"
icon_state = "flashbang"
icon_state = "secbox"
illustration = "flashbang"
/obj/item/weapon/storage/box/flashbangs/New()
..()
@@ -187,7 +218,8 @@
/obj/item/weapon/storage/box/flashes
name = "box of flashbulbs"
desc = "<B>WARNING: Flashes can cause serious eye damage, protective eyewear is required.</B>"
icon_state = "flashbang"
icon_state = "secbox"
illustration = "flashbang"
/obj/item/weapon/storage/box/flashes/New()
..()
@@ -197,7 +229,7 @@
/obj/item/weapon/storage/box/wall_flash
name = "wall-mounted flash kit"
desc = "This box contains everything necessary to build a wall-mounted flash. <B>WARNING: Flashes can cause serious eye damage, protective eyewear is required.</B>"
icon_state = "flashbang"
illustration = "flashbang"
/obj/item/weapon/storage/box/wall_flash/New()
..()
@@ -216,7 +248,7 @@
/obj/item/weapon/storage/box/teargas
name = "box of tear gas grenades (WARNING)"
desc = "<B>WARNING: These devices are extremely dangerous and can cause blindness and skin irritation.</B>"
icon_state = "flashbang"
illustration = "flashbang"
/obj/item/weapon/storage/box/teargas/New()
..()
@@ -226,7 +258,7 @@
/obj/item/weapon/storage/box/emps
name = "box of emp grenades"
desc = "A box with 5 emp grenades."
icon_state = "flashbang"
illustration = "flashbang"
/obj/item/weapon/storage/box/emps/New()
..()
@@ -236,7 +268,7 @@
/obj/item/weapon/storage/box/trackimp
name = "boxed tracking implant kit"
desc = "Box full of scum-bag tracking utensils."
icon_state = "implant"
illustration = "implant"
/obj/item/weapon/storage/box/trackimp/New()
..()
@@ -249,7 +281,7 @@
/obj/item/weapon/storage/box/minertracker
name = "boxed tracking implant kit"
desc = "For finding those who have died on the accursed lavaworld."
icon_state = "implant"
illustration = "implant"
/obj/item/weapon/storage/box/minertracker/New()
..()
@@ -262,7 +294,7 @@
/obj/item/weapon/storage/box/chemimp
name = "boxed chemical implant kit"
desc = "Box of stuff used to implant chemicals."
icon_state = "implant"
illustration = "implant"
/obj/item/weapon/storage/box/chemimp/New()
..()
@@ -274,7 +306,7 @@
/obj/item/weapon/storage/box/exileimp
name = "boxed exile implant kit"
desc = "Box of exile implants. It has a picture of a clown being booted through the Gateway."
icon_state = "implant"
illustration = "implant"
/obj/item/weapon/storage/box/exileimp/New()
..()
@@ -282,10 +314,15 @@
new /obj/item/weapon/implantcase/exile(src)
new /obj/item/weapon/implanter(src)
/obj/item/weapon/storage/box/bodybags
name = "body bags"
desc = "The label indicates that it contains body bags."
illustration = "bodybags"
/obj/item/weapon/storage/box/rxglasses
name = "box of prescription glasses"
desc = "This box contains nerd glasses."
icon_state = "glasses"
illustration = "glasses"
/obj/item/weapon/storage/box/rxglasses/New()
..()
@@ -322,7 +359,7 @@
/obj/item/weapon/storage/box/donkpockets
name = "box of donk-pockets"
desc = "<B>Instructions:</B> <I>Heat in microwave. Product will cool if not eaten within seven minutes.</I>"
icon_state = "donk_kit"
illustration = "donk_kit"
/obj/item/weapon/storage/box/donkpockets/New()
..()
@@ -332,7 +369,6 @@
/obj/item/weapon/storage/box/monkeycubes
name = "monkey cube box"
desc = "Drymate brand monkey cubes. Just add water!"
icon = 'icons/obj/food/food.dmi'
icon_state = "monkeycubebox"
storage_slots = 7
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/monkeycube)
@@ -345,17 +381,23 @@
/obj/item/weapon/storage/box/ids
name = "box of spare IDs"
desc = "Has so many empty IDs."
icon_state = "id"
illustration = "id"
/obj/item/weapon/storage/box/ids/New()
..()
for(var/i in 1 to 7)
new /obj/item/weapon/card/id(src)
//Some spare PDAs in a box
/obj/item/weapon/storage/box/PDAs
name = "spare PDAs"
desc = "A box of spare PDA microcomputers."
illustration = "pda"
/obj/item/weapon/storage/box/silver_ids
name = "box of spare silver IDs"
desc = "Shiny IDs for important people."
icon_state = "id"
illustration = "id"
/obj/item/weapon/storage/box/silver_ids/New()
..()
@@ -365,7 +407,7 @@
/obj/item/weapon/storage/box/prisoner
name = "box of prisoner IDs"
desc = "Take away their last shred of dignity, their name."
icon_state = "id"
illustration = "id"
/obj/item/weapon/storage/box/prisoner/New()
..()
@@ -380,7 +422,7 @@
/obj/item/weapon/storage/box/seccarts
name = "box of PDA security cartridges"
desc = "A box full of PDA cartridges used by Security."
icon_state = "pda"
illustration = "pda"
/obj/item/weapon/storage/box/seccarts/New()
..()
@@ -391,7 +433,7 @@
/obj/item/weapon/storage/box/firingpins
name = "box of standard firing pins"
desc = "A box full of standard firing pins, to allow newly-developed firearms to operate."
icon_state = "id"
illustration = "id"
/obj/item/weapon/storage/box/firingpins/New()
..()
@@ -401,7 +443,7 @@
/obj/item/weapon/storage/box/lasertagpins
name = "box of laser tag firing pins"
desc = "A box full of laser tag firing pins, to allow newly-developed firearms to require wearing brightly coloured plastic armor before being able to be used."
icon_state = "id"
illustration = "id"
/obj/item/weapon/storage/box/lasertagpins/New()
..()
@@ -412,7 +454,8 @@
/obj/item/weapon/storage/box/handcuffs
name = "box of spare handcuffs"
desc = "A box full of handcuffs."
icon_state = "handcuff"
icon_state = "secbox"
illustration = "handcuff"
/obj/item/weapon/storage/box/handcuffs/New()
..()
@@ -422,7 +465,8 @@
/obj/item/weapon/storage/box/zipties
name = "box of spare zipties"
desc = "A box full of zipties."
icon_state = "handcuff"
icon_state = "secbox"
illustration = "handcuff"
/obj/item/weapon/storage/box/zipties/New()
..()
@@ -432,7 +476,8 @@
/obj/item/weapon/storage/box/alienhandcuffs
name = "box of spare handcuffs"
desc = "A box full of handcuffs."
icon_state = "alienboxCuffs"
icon_state = "alienbox"
illustration = "handcuff"
/obj/item/weapon/storage/box/alienhandcuffs/New()
..()
@@ -442,7 +487,7 @@
/obj/item/weapon/storage/box/fakesyndiesuit
name = "boxed space suit and helmet"
desc = "A sleek, sturdy box used to hold replica spacesuits."
icon_state = "box_of_doom"
icon_state = "syndiebox"
/obj/item/weapon/storage/box/fakesyndiesuit/New()
..()
@@ -452,7 +497,7 @@
/obj/item/weapon/storage/box/mousetraps
name = "box of Pest-B-Gon mousetraps"
desc = "<span class='alert'>Keep out of reach of children.</span>"
icon_state = "mousetraps"
illustration = "mousetraps"
/obj/item/weapon/storage/box/mousetraps/New()
..()
@@ -462,7 +507,7 @@
/obj/item/weapon/storage/box/pillbottles
name = "box of pill bottles"
desc = "It has pictures of pill bottles on its front."
icon_state = "pillbox"
illustration = "pillbox"
/obj/item/weapon/storage/box/pillbottles/New()
..()
@@ -505,7 +550,7 @@
/obj/item/weapon/storage/box/lights
name = "box of replacement bulbs"
icon = 'icons/obj/storage.dmi'
icon_state = "light"
illustration = "light"
desc = "This box is shaped on the inside so that only light tubes and bulbs fit."
item_state = "syringe_kit"
foldable = /obj/item/stack/sheet/cardboard //BubbleWrap
@@ -521,7 +566,7 @@
/obj/item/weapon/storage/box/lights/tubes
name = "box of replacement tubes"
icon_state = "lighttube"
illustration = "lighttube"
/obj/item/weapon/storage/box/lights/tubes/New()
..()
@@ -530,7 +575,7 @@
/obj/item/weapon/storage/box/lights/mixed
name = "box of replacement lights"
icon_state = "lightmixed"
illustration = "lightmixed"
/obj/item/weapon/storage/box/lights/mixed/New()
..()
@@ -552,7 +597,7 @@
/obj/item/weapon/storage/box/metalfoam
name = "box of metal foam grenades"
desc = "To be used to rapidly seal hull breaches."
icon_state = "flashbang"
illustration = "flashbang"
/obj/item/weapon/storage/box/metalfoam/New()
..()
@@ -563,6 +608,7 @@
name = "box of hugs"
desc = "A special box for sensitive people."
icon_state = "hugbox"
illustration = "heart"
foldable = null
/obj/item/weapon/storage/box/hug/suicide_act(mob/user)
@@ -857,6 +903,7 @@
/obj/item/weapon/storage/box/ingredients/New()
..()
if(item_state)
name = "[name] ([item_state])"
desc = "A box containing supplementary ingredients for the aspiring chef. This box's theme is '[item_state]'."
/obj/item/weapon/storage/box/emptysandbags
@@ -93,7 +93,7 @@
src.l_set = 1
else if ((src.code == src.l_code) && (src.l_set == 1))
src.locked = 0
src.overlays = null
cut_overlays()
add_overlay(image('icons/obj/storage.dmi', icon_opened))
src.code = null
else
@@ -101,7 +101,7 @@
else
if ((href_list["type"] == "R") && (!src.l_setshort))
src.locked = 1
src.overlays = null
cut_overlays()
src.code = null
src.close(usr)
else
@@ -81,12 +81,11 @@
//Object behaviour on storage dump
/obj/item/weapon/storage/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
for(var/obj/item/I in src_object)
if(user.s_active != src_object)
if(I.on_found(user))
return
if(can_be_inserted(I,0,user))
handle_item_insertion(I, TRUE, user)
var/list/things = src_object.contents.Copy()
var/datum/progressbar/progress = new(user, things.len, src)
while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(src, .proc/handle_mass_item_insertion, things, src_object, user, progress)))
sleep(1)
qdel(progress)
orient2hud(user)
src_object.orient2hud(user)
if(user.s_active) //refresh the HUD to show the transfered contents
@@ -94,6 +93,23 @@
user.s_active.show_to(user)
return 1
/obj/item/weapon/storage/proc/handle_mass_item_insertion(list/things, obj/item/weapon/storage/src_object, mob/user, datum/progressbar/progress)
for(var/obj/item/I in things)
things -= I
if(I.loc != src_object)
continue
if(user.s_active != src_object)
if(I.on_found(user))
break
if(can_be_inserted(I,0,user))
handle_item_insertion(I, TRUE, user)
if (TICK_CHECK)
progress.update(progress.goal - things.len)
return TRUE
progress.update(progress.goal - things.len)
return FALSE
/obj/item/weapon/storage/proc/return_inv()
var/list/L = list()
L += contents
@@ -453,8 +469,25 @@
if((!ishuman(usr) && (loc != usr)) || usr.stat || usr.restrained() ||!usr.canmove)
return
var/turf/T = get_turf(src)
var/list/things = contents.Copy()
var/datum/progressbar/progress = new(usr, things.len, T)
while (do_after(usr, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress)))
sleep(1)
qdel(progress)
do_quick_empty()
/obj/item/weapon/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress)
for(var/obj/item/I in things)
things -= I
if (I.loc != src)
continue
remove_from_storage(I, target)
if (TICK_CHECK)
progress.update(progress.goal - things.len)
return TRUE
progress.update(progress.goal - things.len)
return FALSE
// Empty all the contents onto the current turf, without checking the user's status.
/obj/item/weapon/storage/proc/do_quick_empty()
@@ -13,6 +13,23 @@
origin_tech = "combat=1;engineering=1"
attack_verb = list("robusted")
hitsound = 'sound/weapons/smash.ogg'
var/hinges = "single_hinge"
var/old = FALSE
/obj/item/weapon/storage/toolbox/Initialize()
..()
if(!old)
if(prob(10))
hinges = "double_hinge"
else if(prob(1))
hinges = "triple_hinge"
update_icon()
/obj/item/weapon/storage/toolbox/update_icon()
..()
cut_overlays()
add_overlay(image('icons/obj/storage.dmi', "[hinges]"))
/obj/item/weapon/storage/toolbox/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] robusts [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -36,7 +53,8 @@
/obj/item/weapon/storage/toolbox/emergency/old
name = "rusty red toolbox"
item_state = "toolbox_red_old"
icon_state = "toolbox_red_old"
old = TRUE
/obj/item/weapon/storage/toolbox/mechanical
name = "mechanical toolbox"
@@ -54,7 +72,8 @@
/obj/item/weapon/storage/toolbox/mechanical/old
name = "rusty blue toolbox"
item_state = "toolbox_blue_old"
icon_state = "toolbox_blue_old"
old = TRUE
/obj/item/weapon/storage/toolbox/electrical
name = "electrical toolbox"
@@ -151,7 +170,7 @@
item_state = "artistic_toolbox"
max_combined_w_class = 20
storage_slots = 10
w_class = 5 //Holds more than a regular toolbox!
w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox!
/obj/item/weapon/storage/toolbox/artistic/New()
..()
@@ -164,217 +183,4 @@
new/obj/item/stack/cable_coil/pink(src)
new/obj/item/stack/cable_coil/orange(src)
new/obj/item/stack/cable_coil/cyan(src)
new/obj/item/stack/cable_coil/white(src)
#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep.
#define HIS_GRACE_PECKISH 30 //Slightly hungry. Slightly increased damage and nothing else.
#define HIS_GRACE_HUNGRY 60 //Getting closer. Increased danage and slight healing. It also starts eating anyone around it if it's left on the ground.
#define HIS_GRACE_FAMISHED 90 //Dangerous. Highly increased damage, good healing, and stun resist. It also becomes nodrop at this point.
#define HIS_GRACE_STARVING 110 //Incredibly close to breaking loose. Extreme damage and healing, and stun immunity.
#define HIS_GRACE_CONSUME_OWNER 120 //You're dead, kiddo. The toolbox consumes its owner at this point and resets to zero.
#define HIS_GRACE_FALL_ASLEEP 150 //If it reaches this point, it falls asleep and resets to zero.
//His Grace is a very special weapon granted only to traitor chaplains.
//When awakened through sacrifice, it thirsts for blood and begins ticking a "bloodthirst" counter.
//As His Grace grows hungrier, it grants its wielder various benefits.
//If the wielder fails to feed His Grace in time, it will devour them.
//Leaving His Grace alone for some time will reset its timer and put it to sleep.
//Using His Grace effectively is a delicate balancing act of keeping it hungry enough to induce benefits but sated enough to let you live.
/obj/item/weapon/storage/toolbox/artistic/his_grace
name = "artistic toolbox"
desc = "A toolbox painted bright green. Looking at it makes you feel uneasy."
origin_tech = "combat=4;engineering=4;syndicate=2"
var/awakened = 0
var/bloodthirst = HIS_GRACE_SATIATED
var/victims = 0
var/list/warning_messages = list("peckish", "hungry", "famished", "starving", "consume") //Messages that have NOT been shown
/obj/item/weapon/storage/toolbox/artistic/his_grace/Destroy()
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
return ..()
/obj/item/weapon/storage/toolbox/artistic/his_grace/attack_self(mob/living/user)
if(!awakened)
user << "<span class='notice'>[src] begins to vibrate...</span>"
addtimer(CALLBACK(src, .proc/awaken), 50)
/obj/item/weapon/storage/toolbox/artistic/his_grace/attack(mob/living/M, mob/user)
if(awakened && M.stat)
consume(M)
else
..()
/obj/item/weapon/storage/toolbox/artistic/his_grace/examine(mob/user)
..()
if(awakened)
if(victims)
user << "You hear the distant murmuring of [victims] victims to [src]."
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
user << "<span class='danger'>[src] isn't very hungry. Not yet.</span>"
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
user << "<span class='danger'>[src] would like a snack.</span>"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
user << "<span class='warning'>[src] is quite hungry now...</span>"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
user << "<span class='boldannounce'>[src] is openly salivating at the sight of you. Be careful.</span>"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
user << "<span class='boldwarning'>You walk a fine line. [src] is very close to devouring you.</span>"
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
user << "<span class='boldwarning'>[src] is shaking violently and staring directly at you.</span>"
/obj/item/weapon/storage/toolbox/artistic/his_grace/relaymove(mob/living/user) //Allows changelings, etc. to climb out of the box after they revive
user.forceMove(get_turf(src))
user.visible_message("<span class='warning'>[user] scrambles out of [src]!</span>", "<span class='notice'>You climb out of [src]!</span>")
/obj/item/weapon/storage/toolbox/artistic/his_grace/process()
if(!awakened)
return
adjust_bloodthirst(1 + victims) //Maybe adjust this?
change_phases()
if(ishuman(loc))
var/mob/living/carbon/human/master = loc
switch(bloodthirst) //Handles benefits outside of stun absorbs, which are in change_phases()
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
master.adjustBruteLoss(-1)
master.adjustFireLoss(-1)
master.adjustToxLoss(-0.5)
master.adjustOxyLoss(-5)
master.adjustCloneLoss(-0.5)
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
master.adjustBruteLoss(-2)
master.adjustFireLoss(-2)
master.adjustToxLoss(-1)
master.adjustOxyLoss(-10)
master.adjustCloneLoss(-1)
master.AdjustStunned(-1)
master.AdjustWeakened(-1)
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
master.adjustBruteLoss(-20) //The biggest danger at this point is the toolbox itself
master.adjustFireLoss(-20)
master.adjustToxLoss(-10)
master.setOxyLoss(0)
master.adjustCloneLoss(-5)
master.add_stun_absorption("his_grace", 15, 1, null, null, "[src] shields them from harm!")
if(HIS_GRACE_CONSUME_OWNER to HIS_GRACE_FALL_ASLEEP)
master.visible_message("<span class='boldwarning'>[src] turns on its master!</span>", "<span class='userdanger'>[src] turns on you!</span>")
playsound(src, 'sound/effects/tendril_destroyed.ogg', 100, 0)
master.Weaken(3)
master.adjustBruteLoss(100)
playsound(master, 'sound/misc/desceration-03.ogg', 100, )
playsound(master, 'sound/effects/splat.ogg', 100, 0)
master.emote("scream")
consume(master) //Y O U H A V E F A I L E D M E
if(HIS_GRACE_FALL_ASLEEP to INFINITY)
drowse()
else
if(bloodthirst >= HIS_GRACE_CONSUME_OWNER)
if(bloodthirst >= HIS_GRACE_FALL_ASLEEP)
drowse()
return
for(var/mob/living/L in range(1, src))
if(L.loc == src)
continue
if(!L.stat)
L.visible_message("<span class='warning'>[src] lunges at [L]!</span>", "<span class='userdanger'>[src] lunges at you!</span>")
playsound(L, 'sound/effects/splat.ogg', 50, 1)
playsound(L, 'sound/misc/desceration-01.ogg', 50, 1)
L.adjustBruteLoss(force)
return //Only one at a tome
else
consume(L)
return
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/awaken() //Attempts to awaken. This can only occur if organs fill the box, and gives out a global warning.
if(awakened)
return
var/organ_count = 0
for(var/obj/item/organ/O in src) //Doesn't have to be any kind, we're not picky
organ_count++
if(organ_count < 5)
if(isliving(loc))
loc = get_turf(src)
visible_message("<span class='warning'>[src] stops shaking. It needs more organs.</span>")
else
for(var/obj/item/organ/O in src)
qdel(O) //delicious flesh
name = "His Grace"
desc = "A bloodthirsty artefact created by a profane rite."
gender = MALE
visible_message("<span class='boldwarning'>[src] begins to rattle. It thirsts.</span>") //rattle me bones capn
adjust_bloodthirst(1)
awakened = 1
send_to_playing_players("<span class='boldannounce'><font size=6>HIS GRACE THIRSTS FOR BLOOD</font></span>")
send_to_playing_players('sound/effects/his_grace_awaken.ogg')
icon_state = "green_awakened"
START_PROCESSING(SSprocessing, src)
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/drowse() //Falls asleep, spitting out all victims and resetting to zero.
if(!awakened)
return
visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still... but it still lurks in its sleep.</span>")
name = initial(name)
desc = initial(desc)
icon_state = initial(icon_state)
gender = initial(gender)
awakened = 0
victims = 0
warning_messages = initial(warning_messages)
adjust_bloodthirst(-bloodthirst)
STOP_PROCESSING(SSprocessing, src)
send_to_playing_players("<span class='boldannounce'><font size=6>HIS GRACE HAS RETURNED TO SLUMBER</font></span>")
send_to_playing_players('sound/effects/pope_entry.ogg')
for(var/mob/living/L in src)
L.forceMove(get_turf(src))
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/adjust_bloodthirst(amt)
bloodthirst = min(max(1, bloodthirst + amt), HIS_GRACE_FALL_ASLEEP)
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/consume(mob/living/meal)
if(!meal)
return
meal.adjustBruteLoss(200)
meal.visible_message("<span class='warning'>[src] pulls [meal] into itself!</span>", "<span class='userdanger'>[src] consumes you!</span>")
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
playsound(src, 'sound/items/eatfood.ogg', 100, 1)
meal.forceMove(src)
adjust_bloodthirst(-(bloodthirst - victims)) //Never fully sated, and it starts off higher as it eats
victims++
/obj/item/weapon/storage/toolbox/artistic/his_grace/proc/change_phases()
switch(bloodthirst)
if(HIS_GRACE_SATIATED to HIS_GRACE_PECKISH)
force = 15 //Constantly keep its power low if it's this full
if(HIS_GRACE_PECKISH to HIS_GRACE_HUNGRY)
if(is_string_in_list("peckish", warning_messages))
remove_strings_from_list("peckish", warning_messages)
loc.visible_message("<span class='warning'>[src] is feeling snackish.</span>", "<span class='danger'>[src] begins to hunger. Its damage has been increased.</span>")
force = 20
spawn(400) //To prevent spam
if(src)
warning_messages += "peckish"
if(HIS_GRACE_HUNGRY to HIS_GRACE_FAMISHED)
if(is_string_in_list("hungry", warning_messages))
remove_strings_from_list("hungry", warning_messages)
loc.visible_message("<span class='warning'>[src] is getting hungry. Its power grows.</span>", "<span class='boldannounce'>You feel a sense of hunger come over you. [src]'s damage has increased.</span>")
force = 25
spawn(400)
if(src)
warning_messages += "hungry"
if(HIS_GRACE_FAMISHED to HIS_GRACE_STARVING)
if(is_string_in_list("famished", warning_messages))
remove_strings_from_list("famished", warning_messages)
loc.visible_message("<span class='warning'>[src] is very hungry...</span>", "<span class='boldwarning'>Bloodlust overcomes you. You are now resistant to stuns.</span>")
force = 30
spawn(400)
if(src)
warning_messages += "famished"
if(HIS_GRACE_STARVING to HIS_GRACE_CONSUME_OWNER)
if(is_string_in_list("starving", warning_messages))
remove_strings_from_list("starving", warning_messages)
loc.visible_message("<span class='boldwarning'>[src] is starving!</span>", "<span class='userdanger'>[src] is at its full power! Feed it quickly or you will be consumed!</span>")
force = 40
spawn(400)
if(src)
warning_messages += "starving"
new/obj/item/stack/cable_coil/white(src)
@@ -135,7 +135,8 @@
/obj/item/weapon/storage/box/syndie_kit
name = "box"
desc = "A sleek, sturdy box."
icon_state = "box_of_doom"
icon_state = "syndiebox"
illustration = "writing_syndie"
/obj/item/weapon/storage/box/syndie_kit/imp_freedom
name = "boxed freedom implant (with injector)"
@@ -310,3 +311,8 @@
/obj/item/weapon/storage/box/hug/reverse_revolver/New()
..()
new /obj/item/weapon/gun/ballistic/revolver/reverse(src)
/obj/item/weapon/storage/box/syndie_kit/mimery/New()
..()
new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src)
new /obj/item/weapon/spellbook/oneuse/mimery_guns(src)
@@ -114,6 +114,12 @@
volume = 90
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //steal objective items are hard to destroy.
/obj/item/weapon/tank/jetpack/oxygen/security
name = "security jetpack (oxygen)"
desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas by security forces."
icon_state = "jetpack-sec"
item_state = "jetpack-sec"
/obj/item/weapon/tank/jetpack/carbondioxide
name = "jetpack (carbon dioxide)"
desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals."
@@ -127,7 +133,7 @@
name = "hardsuit jetpack upgrade"
desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment."
origin_tech = "materials=4;magnets=4;engineering=5"
icon_state = "jetpack-black"
icon_state = "jetpack-mining"
item_state = "jetpack-black"
w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/toggle_jetpack, /datum/action/item_action/jetpack_stabilization)
@@ -121,11 +121,14 @@
H.dropItemToGround(W)
if(prob(50))
step(W, pick(alldirs))
H.hair_style = "Bald"
H.update_hair()
H.status_flags |= DISFIGURED
H.bleed_rate = 5
new /obj/effect/gibspawner/generic(H.loc, H.viruses, H.dna)
H.gib_animation()
sleep(3)
H.adjustBruteLoss(1000) //to make the body super-bloody
H.spawn_gibs()
H.spill_organs()
H.spread_bodyparts()
return (BRUTELOSS)
+5 -6
View File
@@ -409,10 +409,11 @@
if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM)
if(src.remove_fuel(1))
playsound(loc, usesound, 50, 1)
user.visible_message("<span class='notice'>[user] starts to fix some of the dents on [H]'s [affecting.name].</span>", "<span class='notice'>You start fixing some of the dents on [H]'s [affecting.name].</span>")
if(!do_mob(user, H, 50))
return
item_heal_robotic(H, user, 5, 0)
if(user == H)
user.visible_message("<span class='notice'>[user] starts to fix some of the dents on [H]'s [affecting.name].</span>", "<span class='notice'>You start fixing some of the dents on [H]'s [affecting.name].</span>")
if(!do_mob(user, H, 50))
return
item_heal_robotic(H, user, 15, 0)
else
return ..()
@@ -579,7 +580,6 @@
max_fuel = 40
materials = list(MAT_GLASS=60)
origin_tech = "engineering=2;plasmatech=2"
toolspeed = 0.75
/obj/item/weapon/weldingtool/largetank/cyborg
name = "integrated welding tool"
@@ -625,7 +625,6 @@
max_fuel = 80
materials = list(MAT_METAL=70, MAT_GLASS=120)
origin_tech = "engineering=3;plasmatech=2"
w_class = 3
/obj/item/weapon/weldingtool/experimental
name = "experimental welding tool"
+15 -5
View File
@@ -65,12 +65,12 @@
user.visible_message("<span class='suicide'>[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return(BRUTELOSS)
var/highlander_claymores = 0
/obj/item/weapon/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
desc = "<b><i>THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!</i></b>\nActivate it in your hand to point to the nearest victim."
flags = CONDUCT | NODROP
flags = CONDUCT | NODROP | DROPDEL
slot_flags = null
block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY
luminosity = 3
attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS
var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE
var/obj/item/weapon/disk/nuclear/nuke_disk //OUR STORED NUKE DISK
@@ -78,22 +78,32 @@ var/highlander_claymores = 0
/obj/item/weapon/claymore/highlander/New()
..()
START_PROCESSING(SSobj, src)
highlander_claymores++
/obj/item/weapon/claymore/highlander/Destroy()
STOP_PROCESSING(SSobj, src)
highlander_claymores--
if(nuke_disk)
nuke_disk.forceMove(get_turf(src))
nuke_disk.visible_message("<span class='warning'>The nuke disk is vulnerable!</span>")
nuke_disk = null
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/weapon/claymore/highlander/process()
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS)
H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS
else
if(!admin_spawned)
qdel(src)
/obj/item/weapon/claymore/highlander/pickup(mob/living/user)
user << "<span class='notice'>The power of Scotland protects you! You are shielded from all stuns and knockdowns.</span>"
user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!")
user.status_flags += IGNORESLOWDOWN
/obj/item/weapon/claymore/highlander/dropped(mob/living/user)
user.status_flags -= IGNORESLOWDOWN
qdel(src) //If this ever happens, it's because you lost an arm
/obj/item/weapon/claymore/highlander/examine(mob/user)
+10 -10
View File
@@ -92,11 +92,11 @@
/obj/proc/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) //used by attack_alien, attack_animal, and attack_slime
user.do_attack_animation(src)
user.changeNext_move(CLICK_CD_MELEE)
take_damage(damage_amount, damage_type, damage_flag, sound_effect, get_dir(src, user))
return take_damage(damage_amount, damage_type, damage_flag, sound_effect, get_dir(src, user))
/obj/attack_alien(mob/living/carbon/alien/humanoid/user)
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
attack_generic(user, 60, BRUTE, "melee", 0)
if(attack_generic(user, 60, BRUTE, "melee", 0))
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
/obj/attack_animal(mob/living/simple_animal/M)
if(!M.melee_damage_upper && !M.obj_damage)
@@ -106,12 +106,12 @@
var/play_soundeffect = 1
if(M.environment_smash)
play_soundeffect = 0
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
if(M.obj_damage)
attack_generic(M, M.obj_damage, M.melee_damage_type, "melee", play_soundeffect)
. = attack_generic(M, M.obj_damage, M.melee_damage_type, "melee", play_soundeffect)
else
attack_generic(M, rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, "melee", play_soundeffect)
return 1
. = attack_generic(M, rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, "melee", play_soundeffect)
if(. && !play_soundeffect)
playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1)
/obj/attack_slime(mob/living/simple_animal/slime/user)
if(!user.is_adult)
@@ -156,7 +156,7 @@ var/global/image/acid_overlay = image("icon" = 'icons/effects/effects.dmi', "ico
if(!acid_level)
SSacid.processing[src] = src
add_overlay(acid_overlay, 1)
add_overlay(acid_overlay, TRUE)
var/acid_cap = acidpwr * 300 //so we cannot use huge amounts of weak acids to do as well as strong acids.
if(acid_level < acid_cap)
acid_level = min(acid_level + acidpwr * acid_volume, acid_cap)
@@ -194,7 +194,7 @@ var/global/image/acid_overlay = image("icon" = 'icons/effects/effects.dmi', "ico
if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE))
resistance_flags |= ON_FIRE
SSfire_burning.processing[src] = src
add_overlay(fire_overlay)
add_overlay(fire_overlay, TRUE)
return 1
//called when the obj is destroyed by fire
@@ -206,7 +206,7 @@ var/global/image/acid_overlay = image("icon" = 'icons/effects/effects.dmi', "ico
/obj/proc/extinguish()
if(resistance_flags & ON_FIRE)
resistance_flags &= ~ON_FIRE
overlays -= fire_overlay
cut_overlay(fire_overlay, TRUE)
SSfire_burning.processing -= src
@@ -80,7 +80,7 @@
M.pixel_x = M.get_standard_pixel_x_offset(M.lying)
M.pixel_y = M.get_standard_pixel_y_offset(M.lying)
M.layer = initial(M.layer)
overlays -= nest_overlay
cut_overlay(nest_overlay)
/obj/structure/bed/nest/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
@@ -63,7 +63,7 @@
/obj/structure/chair/proc/handle_layer()
if(has_buckled_mobs() && dir == NORTH)
layer = ABOVE_ALL_MOB_LAYER
layer = ABOVE_MOB_LAYER
else
layer = OBJ_LAYER
@@ -146,7 +146,7 @@
if(has_buckled_mobs())
add_overlay(armrest)
else
overlays -= armrest
cut_overlay(armrest)
/obj/structure/chair/comfy/brown
@@ -84,7 +84,7 @@
bleedsuppress = 1
S.icon = icon
S.icon_state = icon_state
S.overlays = overlays
S.copy_overlays(overlays)
var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY)
return 1
@@ -140,3 +140,8 @@
for(var/i in 1 to 4)
new /obj/item/weapon/rcd_ammo(src)
new /obj/item/weapon/rcd(src)
/obj/structure/closet/crate/science
name = "science crate"
desc = "A science crate."
icon_state = "scicrate"
@@ -64,4 +64,9 @@
/obj/structure/closet/crate/secure/engineering
desc = "A crate with a lock on it, painted in the scheme of the station's engineers."
name = "secure engineering crate"
icon_state = "engi_secure_crate"
icon_state = "engi_secure_crate"
/obj/structure/closet/crate/secure/science
name = "secure science crate"
desc = "A crate with a lock on it, painted in the scheme of the station's scientists."
icon_state = "scisecurecrate"
@@ -12,7 +12,9 @@
for(var/I in debris)
for(var/i in 1 to debris[I])
new I (get_turf(src))
visible_message(break_message)
playsound(src, break_sound, 50, 1)
if(break_message)
visible_message(break_message)
if(break_sound)
playsound(src, break_sound, 50, 1)
qdel(src)
return 1
@@ -287,14 +287,3 @@
/obj/effect/mob_spawn/human/hotel_staff/Destroy()
new/obj/structure/fluff/empty_sleeper/syndicate(get_turf(src))
..()
/obj/effect/mob_spawn/derelict_drone
name = "dust-caked drone shell"
desc = "A long-forgotten drone shell."
flavour_text = "This station sure is a mess. It's time to get to work."
mob_name = "a derelict drone"
mob_type = /mob/living/simple_animal/drone
icon = 'icons/mob/drone.dmi'
icon_state = "drone_maint_hat"
death = FALSE
roundstart = FALSE
@@ -7,6 +7,50 @@
density = 0
anchored = 1
layer = ABOVE_MOB_LAYER
var/state = PLASTIC_FLAPS_NORMAL
/obj/structure/plasticflaps/examine(mob/user)
. = ..()
switch(state)
if(PLASTIC_FLAPS_NORMAL)
user << "<span class='notice'>[src] are <b>screwed</b> to the floor.</span>"
if(PLASTIC_FLAPS_DETACHED)
user << "<span class='notice'>[src] are no longer <i>screwed</i> to the floor, and the flaps can be <b>cut</b> apart.</span>"
/obj/structure/plasticflaps/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/weapon/screwdriver))
if(state == PLASTIC_FLAPS_NORMAL)
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] unscrews [src] from the floor.</span>", "<span class='notice'>You start to unscrew [src] from the floor...</span>", "You hear rustling noises.")
if(do_after(user, 100*W.toolspeed, target = src))
if(state != PLASTIC_FLAPS_NORMAL)
return
state = PLASTIC_FLAPS_DETACHED
anchored = FALSE
user << "<span class='notice'>You unscrew [src] from the floor.</span>"
else if(state == PLASTIC_FLAPS_DETACHED)
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] screws [src] to the floor.</span>", "<span class='notice'>You start to screw [src] to the floor...</span>", "You hear rustling noises.")
if(do_after(user, 40*W.toolspeed, target = src))
if(state != PLASTIC_FLAPS_DETACHED)
return
state = PLASTIC_FLAPS_NORMAL
anchored = TRUE
user << "<span class='notice'>You screw [src] from the floor.</span>"
else if(istype(W, /obj/item/weapon/wirecutters))
if(state == PLASTIC_FLAPS_DETACHED)
playsound(src.loc, W.usesound, 100, 1)
user.visible_message("<span class='warning'>[user] cuts apart [src].</span>", "<span class='notice'>You start to cut apart [src].</span>", "You hear cutting.")
if(do_after(user, 50*W.toolspeed, target = src))
if(state != PLASTIC_FLAPS_DETACHED)
return
user << "<span class='notice'>You cut apart [src].</span>"
var/obj/item/stack/sheet/plastic/five/P = new(loc)
P.add_fingerprint(user)
qdel(src)
else
. = ..()
/obj/structure/plasticflaps/CanAStarPass(ID, to_dir, caller)
if(isliving(caller))
@@ -46,6 +90,11 @@
return 0
return ..()
/obj/structure/plasticflaps/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
new /obj/item/stack/sheet/plastic/five(loc)
qdel(src)
/obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates
name = "airtight plastic flaps"
desc = "Heavy duty, airtight, plastic flaps."
@@ -485,6 +485,7 @@
icon_state = "rack_parts"
flags = CONDUCT
materials = list(MAT_METAL=2000)
var/building = FALSE
/obj/item/weapon/rack_parts/attackby(obj/item/weapon/W, mob/user, params)
if (istype(W, /obj/item/weapon/wrench))
@@ -494,6 +495,9 @@
. = ..()
/obj/item/weapon/rack_parts/attack_self(mob/user)
if(building)
return
building = TRUE
user << "<span class='notice'>You start constructing a rack...</span>"
if(do_after(user, 50, target = src, progress=TRUE))
if(!user.drop_item())
@@ -503,3 +507,4 @@
</span>", "<span class='notice'>You assemble \a [R].</span>")
R.add_fingerprint(user)
qdel(src)
building = FALSE
+2 -1
View File
@@ -345,7 +345,7 @@
if(smooth)
queue_smooth(src)
overlays -= crack_overlay
cut_overlay(crack_overlay)
if(ratio > 75)
return
crack_overlay = image('icons/obj/structures.dmi',"damage[ratio]",-(layer+0.1))
@@ -474,6 +474,7 @@
explosion_block = 2 //fancy AND hard to destroy. the most useful combination.
glass_type = /obj/item/stack/tile/brass
glass_amount = 1
reinf = FALSE
var/made_glow = FALSE
/obj/structure/window/reinforced/clockwork/New(loc, direct)