mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-25 14:16:58 +01:00
Merge master and build TGUI
This commit is contained in:
@@ -21,9 +21,61 @@
|
||||
/obj/item/device/starcaster_news/attack_self(mob/user as mob)
|
||||
|
||||
user.set_machine(src)
|
||||
ui_interact(user) //Activates nanoUI. Fuck nanoUI.
|
||||
tgui_interact(user) //Activates tgui. Bless tgui.
|
||||
return
|
||||
|
||||
/obj/item/device/starcaster_news/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StarcasterCh", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/device/starcaster_news/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) //Mostly ripped off from news_browser.dm
|
||||
var/list/data = list()
|
||||
|
||||
var/list/all_articles = list()
|
||||
data["showing_archived"] = show_archived
|
||||
data["article"] = null
|
||||
if(loaded_article) // Viewing an article.
|
||||
data["article"] = list(
|
||||
"title" = loaded_article.filename,
|
||||
"cover" = loaded_article.cover,
|
||||
"content" = loaded_article.stored_data,
|
||||
)
|
||||
else // Viewing list of articles
|
||||
for(var/datum/computer_file/data/news_article/F in ntnet_global.available_news)
|
||||
if(!show_archived && F.archived)
|
||||
continue
|
||||
all_articles.Add(list(list(
|
||||
"name" = F.filename,
|
||||
"uid" = F.uid,
|
||||
"archived" = F.archived
|
||||
)))
|
||||
data["all_articles"] = all_articles
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/device/starcaster_news/tgui_act(action, list/params, datum/tgui/ui) //Also ripped from news_browser.dm. Bless tgui
|
||||
if(..())
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("PRG_openarticle")
|
||||
. = TRUE
|
||||
if(loaded_article)
|
||||
return TRUE
|
||||
|
||||
for(var/datum/computer_file/data/news_article/N in ntnet_global.available_news)
|
||||
if(N.uid == text2num(params["uid"]))
|
||||
loaded_article = N.clone()
|
||||
break
|
||||
if("PRG_reset")
|
||||
. = TRUE
|
||||
loaded_article = null
|
||||
if("PRG_toggle_archived")
|
||||
. = TRUE
|
||||
show_archived = !show_archived
|
||||
|
||||
/* Deprecated nanoUI code. Keeping mostly for reference.
|
||||
/obj/item/device/starcaster_news/Topic(href, href_list) //Mostly ripped off from news_browser.dm
|
||||
if(..())
|
||||
return 1
|
||||
@@ -73,3 +125,4 @@
|
||||
ui.auto_update_layout = 1
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
*/
|
||||
@@ -1,70 +1,75 @@
|
||||
/obj/item/stack/animalhide
|
||||
name = "hide"
|
||||
desc = "The hide of some creature."
|
||||
icon_state = "sheet-hide"
|
||||
drop_sound = 'sound/items/drop/cloth.ogg'
|
||||
pickup_sound = 'sound/items/pickup/cloth.ogg'
|
||||
amount = 1
|
||||
stacktype = "hide"
|
||||
no_variants = TRUE
|
||||
|
||||
var/process_type = /obj/item/stack/hairlesshide
|
||||
|
||||
/obj/item/stack/animalhide/human
|
||||
name = "human skin"
|
||||
desc = "The by-product of human farming."
|
||||
singular_name = "human skin piece"
|
||||
name = "skin"
|
||||
desc = "The by-product of sapient farming."
|
||||
singular_name = "skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
no_variants = FALSE
|
||||
drop_sound = 'sound/items/drop/leather.ogg'
|
||||
pickup_sound = 'sound/items/pickup/leather.ogg'
|
||||
|
||||
/obj/item/stack/animalhide/human
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-human"
|
||||
|
||||
/obj/item/stack/animalhide/corgi
|
||||
name = "corgi hide"
|
||||
desc = "The by-product of corgi farming."
|
||||
singular_name = "corgi hide piece"
|
||||
icon_state = "sheet-corgi"
|
||||
|
||||
/obj/item/stack/animalhide/corgi
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-corgi"
|
||||
|
||||
/obj/item/stack/animalhide/cat
|
||||
name = "cat hide"
|
||||
desc = "The by-product of cat farming."
|
||||
singular_name = "cat hide piece"
|
||||
icon_state = "sheet-cat"
|
||||
|
||||
/obj/item/stack/animalhide/cat
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-cat"
|
||||
|
||||
/obj/item/stack/animalhide/monkey
|
||||
name = "monkey hide"
|
||||
desc = "The by-product of monkey farming."
|
||||
singular_name = "monkey hide piece"
|
||||
icon_state = "sheet-monkey"
|
||||
|
||||
/obj/item/stack/animalhide/monkey
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-monkey"
|
||||
|
||||
/obj/item/stack/animalhide/lizard
|
||||
name = "lizard skin"
|
||||
desc = "Sssssss..."
|
||||
singular_name = "lizard skin piece"
|
||||
icon_state = "sheet-lizard"
|
||||
|
||||
/obj/item/stack/animalhide/lizard
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-lizard"
|
||||
|
||||
/obj/item/stack/animalhide/xeno
|
||||
name = "alien hide"
|
||||
desc = "The skin of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
icon_state = "sheet-xeno"
|
||||
|
||||
/obj/item/stack/animalhide/xeno
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-xeno"
|
||||
|
||||
//don't see anywhere else to put these, maybe together they could be used to make the xenos suit?
|
||||
/obj/item/stack/xenochitin
|
||||
name = "alien chitin"
|
||||
desc = "A piece of the hide of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
singular_name = "alien chitin piece"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "chitin"
|
||||
|
||||
/obj/item/stack/xenochitin
|
||||
amount = 50
|
||||
amount = 1
|
||||
stacktype = "hide-chitin"
|
||||
|
||||
/obj/item/xenos_claw
|
||||
name = "alien claw"
|
||||
@@ -84,9 +89,22 @@
|
||||
singular_name = "hairless hide piece"
|
||||
icon_state = "sheet-hairlesshide"
|
||||
no_variants = FALSE
|
||||
amount = 1
|
||||
stacktype = "hairlesshide"
|
||||
var/cleaning = FALSE // Can we be water_acted, or are we busy? To prevent accidental hide duplication and the collapse of causality.
|
||||
|
||||
/obj/item/stack/hairlesshide
|
||||
amount = 50
|
||||
var/wet_type = /obj/item/stack/wetleather
|
||||
|
||||
/obj/item/stack/hairlesshide/water_act(var/wateramount)
|
||||
..()
|
||||
cleaning = TRUE
|
||||
while(amount > 0 && wateramount > 0)
|
||||
use(1)
|
||||
wateramount--
|
||||
new wet_type(get_turf(src))
|
||||
cleaning = FALSE
|
||||
|
||||
return
|
||||
|
||||
/obj/item/stack/wetleather
|
||||
name = "wet leather"
|
||||
@@ -96,29 +114,28 @@
|
||||
var/wetness = 30 //Reduced when exposed to high temperautres
|
||||
var/drying_threshold_temperature = 500 //Kelvin to start drying
|
||||
no_variants = FALSE
|
||||
amount = 1
|
||||
stacktype = "wetleather"
|
||||
|
||||
/obj/item/stack/wetleather
|
||||
amount = 50
|
||||
var/dry_type = /obj/item/stack/material/leather
|
||||
|
||||
//Step one - dehairing.
|
||||
/obj/item/stack/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if( istype(W, /obj/item/weapon/material/knife) || \
|
||||
istype(W, /obj/item/weapon/material/twohanded/fireaxe) || \
|
||||
istype(W, /obj/item/weapon/material/knife/machete/hatchet) )
|
||||
|
||||
if(has_edge(W) || is_sharp(W))
|
||||
//visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message)
|
||||
usr.visible_message("<span class='notice'>\The [usr] starts cutting hair off \the [src]</span>", "<span class='notice'>You start cutting the hair off \the [src]</span>", "You hear the sound of a knife rubbing against flesh")
|
||||
if(do_after(user,50))
|
||||
to_chat(usr, "<span class='notice'>You cut the hair from this [src.singular_name]</span>")
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/hairlesshide/HS in usr.loc)
|
||||
if(HS.amount < 50)
|
||||
if(HS.amount < 50 && istype(HS, process_type))
|
||||
HS.amount++
|
||||
src.use(1)
|
||||
break
|
||||
return
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/hairlesshide/HS = new(usr.loc)
|
||||
HS.amount = 1
|
||||
var/obj/item/stack/HS = new process_type(usr.loc)
|
||||
if(istype(HS))
|
||||
HS.amount = 1
|
||||
src.use(1)
|
||||
else
|
||||
..()
|
||||
@@ -132,15 +149,20 @@
|
||||
if(exposed_temperature >= drying_threshold_temperature)
|
||||
wetness--
|
||||
if(wetness == 0)
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/material/leather/HS in src.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
src.use(1)
|
||||
wetness = initial(wetness)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/material/leather/HS = new(src.loc)
|
||||
HS.amount = 1
|
||||
dry()
|
||||
|
||||
/obj/item/stack/wetleather/proc/dry()
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/material/leather/HS in src.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
wetness = initial(wetness)
|
||||
src.use(1)
|
||||
return
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/HS = new dry_type(src.loc)
|
||||
|
||||
if(istype(HS))
|
||||
HS.amount = 1
|
||||
wetness = initial(wetness)
|
||||
src.use(1)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
/obj/item/stack/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
|
||||
if(Adjacent(user))
|
||||
if(!uses_charge)
|
||||
. += "There are [src.amount] [src.singular_name]\s in the stack."
|
||||
@@ -380,17 +380,17 @@
|
||||
var/use_material
|
||||
var/pass_color
|
||||
|
||||
New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color)
|
||||
src.title = title
|
||||
src.result_type = result_type
|
||||
src.req_amount = req_amount
|
||||
src.res_amount = res_amount
|
||||
src.max_res_amount = max_res_amount
|
||||
src.time = time
|
||||
src.one_per_turf = one_per_turf
|
||||
src.on_floor = on_floor
|
||||
src.use_material = supplied_material
|
||||
src.pass_color = pass_stack_color
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0, supplied_material = null, pass_stack_color)
|
||||
src.title = title
|
||||
src.result_type = result_type
|
||||
src.req_amount = req_amount
|
||||
src.res_amount = res_amount
|
||||
src.max_res_amount = max_res_amount
|
||||
src.time = time
|
||||
src.one_per_turf = one_per_turf
|
||||
src.on_floor = on_floor
|
||||
src.use_material = supplied_material
|
||||
src.pass_color = pass_stack_color
|
||||
|
||||
/*
|
||||
* Recipe list datum
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/obj/item/weapon/implant/reagent_generator/egg
|
||||
name = "egg laying implant"
|
||||
name = "regular egg laying implant"
|
||||
desc = "This is an implant that allows the user to lay eggs."
|
||||
generated_reagents = list("egg" = 2)
|
||||
usable_volume = 500
|
||||
transfer_amount = 50
|
||||
usable_volume = 1500
|
||||
transfer_amount = 300
|
||||
var/verb_descriptor = list("squeezes", "pushes", "hugs")
|
||||
var/self_verb_descriptor = list("squeeze", "push", "hug")
|
||||
var/short_emote_descriptor = list("lays", "forces out", "pushes out")
|
||||
@@ -11,11 +11,13 @@
|
||||
random_emote = list("lets out an embarrassed moan", "yelps in embarrassment", "quietly groans in a mixture of discomfort and pleasure")
|
||||
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_egg
|
||||
var/eggtype = /obj/item/weapon/reagent_containers/food/snacks/egg
|
||||
var/cascade
|
||||
|
||||
/obj/item/weapon/implant/reagent_generator/egg/post_implant(mob/living/carbon/source)
|
||||
START_PROCESSING(SSobj, src)
|
||||
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
|
||||
source.verbs |= assigned_proc
|
||||
source.verbs |= /mob/living/carbon/human/proc/toggle_cascade
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/use_reagent_implant_egg()
|
||||
@@ -51,59 +53,82 @@
|
||||
to_chat(usr, "<span class='notice'>It seems that [src] is out of eggs!</span>")
|
||||
to_chat(src, "<span class='notice'>[pick(rimplant.empty_message)]</span>")
|
||||
return
|
||||
visible_message("<span class='notice'>[usr] starts squeezing [src]'s lower body firmly...</span>")
|
||||
if (rimplant && do_after(usr,60))
|
||||
var/egg = rimplant.eggtype
|
||||
new egg(get_turf(src))
|
||||
src.SetStunned(3)
|
||||
playsound(src,'sound/vore/insert.ogg',50,1)
|
||||
var/index = rand(1,3)
|
||||
visible_message("<span class='danger'>[usr] starts squeezing [src]'s lower body firmly...</span>")
|
||||
if (rimplant && do_after(usr,120,src))
|
||||
if(src.Adjacent(usr))
|
||||
var/egg = rimplant.eggtype
|
||||
new egg(get_turf(src))
|
||||
src.SetStunned(3)
|
||||
playsound(src,'sound/vore/insert.ogg',50,1)
|
||||
var/index = rand(1,3)
|
||||
|
||||
if (usr != src)
|
||||
var/emote = rimplant.emote_descriptor[index]
|
||||
var/verb_desc = rimplant.verb_descriptor[index]
|
||||
var/self_verb_desc = rimplant.self_verb_descriptor[index]
|
||||
visible_message("<span class='notice'>[usr] [verb_desc] [emote]</span>",
|
||||
"<span class='notice'>You [self_verb_desc] [emote]</span>")
|
||||
if (usr != src)
|
||||
var/emote = rimplant.emote_descriptor[index]
|
||||
var/verb_desc = rimplant.verb_descriptor[index]
|
||||
var/self_verb_desc = rimplant.self_verb_descriptor[index]
|
||||
visible_message("<span class='notice'>[usr] [verb_desc] [emote]</span>",
|
||||
"<span class='notice'>You [self_verb_desc] [emote]</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[src] [pick(rimplant.short_emote_descriptor)] an egg.</span>",
|
||||
"<span class='notice'>You [pick(rimplant.self_emote_descriptor)] an egg.</span>")
|
||||
|
||||
if(prob(15))
|
||||
visible_message("<span class='notice'>[src] [pick(rimplant.random_emote)].</span>")
|
||||
rimplant.reagents.remove_any(rimplant.transfer_amount)
|
||||
|
||||
if(rimplant.cascade)
|
||||
to_chat(src, "<span class='notice'>You feel your legs quake as your muscles fail to stand strong!</span>")
|
||||
while(rimplant.reagents.total_volume >= rimplant.transfer_amount)
|
||||
if(do_after(src,30))
|
||||
src.SetStunned(3)
|
||||
playsound(src,'sound/vore/insert.ogg',50,1)
|
||||
src.apply_effect(10,STUTTER,0)
|
||||
new egg(get_turf(src))
|
||||
rimplant.reagents.remove_any(rimplant.transfer_amount)
|
||||
if(prob(25))
|
||||
visible_message("<span class='notice'>[src] [pick(rimplant.random_emote)].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[src] [pick(rimplant.short_emote_descriptor)] an egg.</span>",
|
||||
"<span class='notice'>You [pick(rimplant.self_emote_descriptor)] an egg.</span>")
|
||||
return
|
||||
/mob/living/carbon/human/proc/toggle_cascade()
|
||||
|
||||
if(prob(15))
|
||||
visible_message("<span class='notice'>[src] [pick(rimplant.random_emote)].</span>")
|
||||
rimplant.reagents.remove_any(rimplant.transfer_amount)
|
||||
set name = "Toggle cascading"
|
||||
set desc = "Toggle whether or not being forced to lay an egg will cause you to lay all others as well, in rapid succession"
|
||||
set category = "Local"
|
||||
|
||||
var/obj/item/weapon/implant/reagent_generator/egg/rimplant
|
||||
for(var/obj/item/organ/external/E in organs)
|
||||
for(var/obj/item/weapon/implant/I in E.implants)
|
||||
if(istype(I, /obj/item/weapon/implant/reagent_generator))
|
||||
rimplant = I
|
||||
break
|
||||
|
||||
if(rimplant.cascade)
|
||||
rimplant.cascade = 0
|
||||
to_chat(src, "<span class='notice'>You toggle cascading off</span>")
|
||||
else
|
||||
rimplant.cascade = 1
|
||||
to_chat(src, "<span class='notice'>You toggle cascading on</span>")
|
||||
|
||||
if(prob(70*rimplant.reagents.total_volume/rimplant.usable_volume))
|
||||
to_chat(src, "<span class='notice'>You feel your legs quake as your muscles fail to stand strong!</span>")
|
||||
while(rimplant.reagents.total_volume >= rimplant.transfer_amount)
|
||||
if(do_after(src,30))
|
||||
src.SetStunned(5)
|
||||
playsound(src,'sound/vore/insert.ogg',50,1)
|
||||
src.apply_effect(10,STUTTER,0)
|
||||
new egg(get_turf(src))
|
||||
rimplant.reagents.remove_any(rimplant.transfer_amount)
|
||||
if(prob(25))
|
||||
visible_message("<span class='notice'>[src] [pick(rimplant.random_emote)].</span>")
|
||||
|
||||
/obj/item/weapon/implant/reagent_generator/egg/slow
|
||||
name = "slow egg laying implant"
|
||||
usable_volume = 3000
|
||||
transfer_amount = 300
|
||||
transfer_amount = 600
|
||||
|
||||
/obj/item/weapon/implant/reagent_generator/egg/veryslow
|
||||
name = "very slow egg laying implant"
|
||||
usable_volume = 6000
|
||||
transfer_amount = 600
|
||||
transfer_amount = 1200
|
||||
|
||||
/obj/item/weapon/implant/reagent_generator/egg/hicap
|
||||
name = "high capacity egg laying implant" // Note that the capacity does not affect the regeneration rate, rather, the transfer amount does
|
||||
usable_volume = 1000 // Effectively, the transfer_amount is the cost/time of making an egg. Usable volume is simply the max number of eggs.
|
||||
transfer_amount = 50
|
||||
usable_volume = 3000 // Effectively, the transfer_amount is the cost/time of making an egg. Usable volume is simply the max number of eggs.
|
||||
transfer_amount = 300
|
||||
|
||||
/obj/item/weapon/implant/reagent_generator/egg/doublehicap
|
||||
name = "extreme capacity egg laying implant"
|
||||
usable_volume = 2000
|
||||
transfer_amount = 50
|
||||
usable_volume = 6000
|
||||
transfer_amount = 300
|
||||
|
||||
/obj/item/weapon/implant/reagent_generator/egg/slowlowcap
|
||||
name = "slow, low capacity egg laying implant"
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
item_state = "candlebox5"
|
||||
throwforce = 2
|
||||
slot_flags = SLOT_BELT
|
||||
max_storage_space = ITEMSIZE_COST_SMALL * 5
|
||||
max_storage_space = ITEMSIZE_COST_TINY * 5 //CHOMPEdit
|
||||
starts_with = list(/obj/item/weapon/flame/candle = 5)
|
||||
|
||||
/obj/item/weapon/storage/fancy/whitecandle_box
|
||||
@@ -80,7 +80,7 @@
|
||||
item_state = "whitecandlebox5"
|
||||
throwforce = 2
|
||||
slot_flags = SLOT_BELT
|
||||
max_storage_space = ITEMSIZE_COST_SMALL * 5
|
||||
max_storage_space = ITEMSIZE_COST_TINY * 5 //CHOMPEdit
|
||||
starts_with = list(/obj/item/weapon/flame/candle/white = 5)
|
||||
|
||||
/obj/item/weapon/storage/fancy/blackcandle_box
|
||||
@@ -92,7 +92,7 @@
|
||||
item_state = "blackcandlebox5"
|
||||
throwforce = 2
|
||||
slot_flags = SLOT_BELT
|
||||
max_storage_space = ITEMSIZE_COST_SMALL * 5
|
||||
max_storage_space = ITEMSIZE_COST_TINY * 5 //CHOMPEdit
|
||||
starts_with = list(/obj/item/weapon/flame/candle/black = 5)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/obj/item/weapon/storage/fancy/cigar/cohiba
|
||||
name = "cohiban cigar case"
|
||||
starts_with = list(/obj/item/clothing/mask/smokable/cigarette/cigar/cohiba = 7)
|
||||
|
||||
/obj/item/weapon/storage/fancy/cigar/havana
|
||||
name = "havanian cigar case"
|
||||
starts_with = list(/obj/item/clothing/mask/smokable/cigarette/cigar/havana = 7)
|
||||
@@ -349,9 +349,11 @@
|
||||
to_chat(user, "<span class='danger'>You go blind!</span>")
|
||||
user.Blind(5)
|
||||
user.eye_blurry = 5
|
||||
user.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
user.disabilities &= ~NEARSIGHTED
|
||||
// Don't cure being nearsighted
|
||||
if(!(H.disabilities & NEARSIGHTED))
|
||||
user.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
user.disabilities &= ~NEARSIGHTED
|
||||
return
|
||||
|
||||
/obj/item/weapon/weldingtool/is_hot()
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
//Try not to question it too hard. These are the spicy tools.
|
||||
|
||||
/obj/item/weapon/tool/crowbar/heavysniper
|
||||
name = "anti-materiel sniper crowbar"
|
||||
desc = "This abomination or piece of art, depending on how you view it, seems to use a 14.5mm anti-materiel sniper rifle to the same effect of a crowbar."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "heavysniper"
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi')
|
||||
item_state = "heavysniper"
|
||||
toolspeed = 0.1
|
||||
force = 30
|
||||
usesound = 'sound/weapons/Gunshot_cannon.ogg'
|
||||
|
||||
/obj/item/weapon/weldingtool/lasercannon
|
||||
name = "laser cannon welding tool"
|
||||
desc = "This abomination or piece of art, depending on how you view it, seems to be a laser cannon converted into a welding tool."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "lasercannon"
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi')
|
||||
item_state = "mhdhowitzer-wielded"
|
||||
toolspeed = 0.1
|
||||
usesound = 'sound/weapons/lasercannonfire.ogg'
|
||||
acti_sound = 'sound/weapons/kenetic_reload.ogg'
|
||||
always_process = TRUE
|
||||
|
||||
/obj/item/weapon/weldingtool/lasercannon/process()
|
||||
if(get_fuel() <= get_max_fuel())
|
||||
reagents.add_reagent("fuel", 1)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/weldingtool/lasercannon/update_icon()
|
||||
// Lights
|
||||
if(welding && flame_intensity)
|
||||
set_light(flame_intensity, flame_intensity, flame_color)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
// icon_state = welding ? "[icon_state]1" : "[initial(icon_state)]"
|
||||
var/mob/M = loc
|
||||
if(istype(M))
|
||||
M.update_inv_l_hand()
|
||||
M.update_inv_r_hand()
|
||||
|
||||
/obj/item/weapon/tool/wrench/fuelrod
|
||||
name = "fuel-rod cannon wrench"
|
||||
desc = "This abomination or piece of art, depending on how you view it, seems to by some means use a fuel rod cannon as a wrench... how this is possible, one can only theorize."
|
||||
icon = 'icons/obj/railgun.dmi'
|
||||
icon_state = "fuelrodgun"
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi')
|
||||
item_state = "coilgun"
|
||||
usesound = 'sound/weapons/railgun.ogg'
|
||||
toolspeed = 0.1
|
||||
force = 30
|
||||
|
||||
/obj/item/weapon/tool/wirecutters/chainsaw
|
||||
name = "chainsaw wirecutters"
|
||||
desc = "This abomination or piece of art, depending on how you view it, seems to be a chainsaw that is by some means converted into wirecutters."
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "chainsaw0"
|
||||
item_state = "chainsaw0"
|
||||
usesound = 'sound/weapons/chainsaw_attack.ogg'
|
||||
random_color = FALSE
|
||||
toolspeed = 0.1
|
||||
force = 30
|
||||
|
||||
/obj/item/weapon/tool/screwdriver/diamonddrill
|
||||
name = "diamond drill power screwdriver"
|
||||
desc = "This abomination or piece of art, depending on how you view it, seems to be a diamond drill that was converted into a power screwdriver."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "diamonddrill"
|
||||
item_state = "jackhammer"
|
||||
hitsound = 'sound/items/drill_hit.ogg'
|
||||
usesound = 'sound/items/drill_use.ogg'
|
||||
random_color = FALSE
|
||||
toolspeed = 0.1
|
||||
force = 30
|
||||
|
||||
/obj/item/stack/cable_coil/alien/blood
|
||||
name = "Blood cable coil"
|
||||
desc = "This seems to be a blood red cable coil which magically replenishes itself, and if you look closely at the insulation you can read the words \"forged from the blood of our enemies\""
|
||||
icon = 'icons/obj/power.dmi'
|
||||
icon_state = "coil"
|
||||
item_state = "coil"
|
||||
color = "#8A0303"
|
||||
catalogue_data = null
|
||||
toolspeed = 0.1
|
||||
|
||||
/obj/item/weapon/storage/belt/utility/spicyfull
|
||||
starts_with = list(
|
||||
/obj/item/weapon/tool/crowbar/heavysniper,
|
||||
/obj/item/weapon/weldingtool/lasercannon,
|
||||
/obj/item/weapon/tool/wrench/fuelrod,
|
||||
/obj/item/weapon/tool/wirecutters/chainsaw,
|
||||
/obj/item/weapon/tool/screwdriver/diamonddrill,
|
||||
/obj/item/stack/cable_coil/alien/blood
|
||||
)
|
||||
@@ -0,0 +1,230 @@
|
||||
/obj/kbutton
|
||||
name = "button"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "launcherbtt"
|
||||
desc = "A remote control switch for something."
|
||||
anchored = 1.0
|
||||
var/nothing_sound_file //Sound to play when button fails to be pressed
|
||||
var/nothing_sound_volume //Volume of sound when button fails to be pressed
|
||||
var/pressed_sound_file = 'sound/machines/button.ogg'//Sound to play when button is successfully pressed
|
||||
var/pressed_sound_volume = 100 //Volume of sound when button is successfully pressed
|
||||
var/list/trig_target_paths = list() //What are the paths of whatever we want to call our proc on?
|
||||
var/trig_target_trigger_uid //What is the trigger_uid of whatever we want to call our proc on?
|
||||
var/trig_proc //What proc do we want to call?
|
||||
var/list/trig_args = list() //What are the arguments for said proc?
|
||||
var/trig_message = "You press the button" //Should we send a message to the person who pressed the button?
|
||||
var/trig_message_span_class = "notice" //Span class used for pressed message, normal ones include notice, warning, and danger.
|
||||
var/nothing_message = "Nothing happens." //Should we send a message if nothing happens when the button is pressed?
|
||||
var/nothing_message_span_class = "warning" //Span class used for nothing message, normal ones include notice, warning, and danger.
|
||||
var/list/trig_targets = list()
|
||||
var/trig_target_is_trigerrer = FALSE //Should we use the button presser as the target?
|
||||
|
||||
/obj/kbutton/attackby(obj/item/weapon/W, mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/kbutton/attack_hand(mob/user as mob)
|
||||
. = ..()
|
||||
if(can_press(user))
|
||||
if(trig_target_is_trigerrer)
|
||||
trig_targets = list(user)
|
||||
button_trigger()
|
||||
if(pressed_sound_file)
|
||||
playsound(src, pressed_sound_file, pressed_sound_volume, 1)
|
||||
if(trig_message)
|
||||
to_chat(user,"<span class='[trig_message_span_class]'>"+trig_message+"</span>")
|
||||
else
|
||||
if(nothing_sound_file)
|
||||
playsound(src, nothing_sound_file, nothing_sound_volume, 1)
|
||||
if(nothing_message)
|
||||
to_chat(user,"<span class='[nothing_message_span_class]'>"+nothing_message+"</span>")
|
||||
return
|
||||
|
||||
/obj/kbutton/proc/button_trigger()
|
||||
if(trig_proc)
|
||||
if(trig_targets.len)
|
||||
var/testname = trig_proc
|
||||
//Find one of the 3 possible ways they could have written /proc/PROCNAME
|
||||
if(findtext(trig_proc, "/proc/"))
|
||||
testname = replacetext(trig_proc, "/proc/", "")
|
||||
else if(findtext(trig_proc, "/proc"))
|
||||
testname = replacetext(trig_proc, "/proc", "")
|
||||
else if(findtext(trig_proc, "proc/"))
|
||||
testname = replacetext(trig_proc, "proc/", "")
|
||||
//Clear out any parenthesis if they're a dummy
|
||||
testname = replacetext(testname, "()", "")
|
||||
for(var/trig_target in trig_targets)
|
||||
if(trig_target && !hascall(trig_target,testname))
|
||||
message_admins("TRIGGER ERROR: ONE OR MORE TRIGGER TARGETS LACKS THE MENTIONED PROC")
|
||||
return
|
||||
for(var/trig_target in trig_targets)
|
||||
call(trig_target,testname)(arglist(trig_args))
|
||||
else
|
||||
var/procpath = text2path(trig_proc)
|
||||
if(!procpath)
|
||||
message_admins("TRIGGER ERROR: INVALID PROC")
|
||||
return
|
||||
call(procpath)(arglist(trig_args))
|
||||
|
||||
/obj/kbutton/proc/can_press(mob/user)
|
||||
return TRUE
|
||||
|
||||
/obj/kbutton/proc/update_trig_targets()
|
||||
trig_targets = list()
|
||||
for(var/path in trig_target_paths)
|
||||
var/trig_target_path = text2path(path)
|
||||
if(trig_target_path && trig_target_trigger_uid)
|
||||
var/list/candidates = get_all_of_type(trig_target_path)
|
||||
for(var/candidate in candidates)
|
||||
var/datum/cand_datum = candidate
|
||||
if(istype(cand_datum))
|
||||
if(cand_datum.trigger_uid == trig_target_trigger_uid)
|
||||
trig_targets += candidate
|
||||
continue
|
||||
continue
|
||||
if(!trig_targets.len)
|
||||
message_admins("TRIGGER ERROR: trig_targets STILL EMPTY AFTER CALLED update_trig_targets()")
|
||||
|
||||
/obj/kbutton/Initialize(mapload)
|
||||
. = ..()
|
||||
update_trig_targets()
|
||||
return
|
||||
|
||||
/obj/kbutton/single_use
|
||||
name = "single use button"
|
||||
var/has_been_pressed = FALSE
|
||||
|
||||
/obj/kbutton/single_use/button_trigger()
|
||||
has_been_pressed = TRUE
|
||||
..()
|
||||
|
||||
/obj/kbutton/single_use/can_press(mob/user)
|
||||
return !has_been_pressed
|
||||
|
||||
/obj/kbutton/single_use_per_mob
|
||||
name = "button"
|
||||
var/list/been_triggered_by = list()
|
||||
|
||||
/obj/kbutton/single_use_per_mob/can_press(mob/user)
|
||||
if(user in been_triggered_by)
|
||||
return FALSE
|
||||
else
|
||||
been_triggered_by |= user
|
||||
return TRUE
|
||||
|
||||
/obj/kbutton/toggle
|
||||
name = "toggle button"
|
||||
var/toggled = FALSE
|
||||
//For each of the following, each of the following variables will be used when switching to that state,
|
||||
//and if it's set to null, it will use def(short for default)
|
||||
var/trig_message_types = list(\
|
||||
"def" = "You toggle the button.", \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/nothing_message_types = list(\
|
||||
"def" = "Nothing happens.", \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/pressed_sound_file_types = list(\
|
||||
"def" = 'sound/machines/button.ogg', \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/pressed_sound_volume_types = list(\
|
||||
"def" = 100, \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/nothing_sound_file_types = list(\
|
||||
"def" = null, \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/nothing_sound_volume_types = list(\
|
||||
"def" = null, \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/icon_types = list(\
|
||||
"def" = 'icons/obj/objects.dmi', \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/icon_state_types = list(\
|
||||
"def" = "launcherbtt", \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/trig_proc_types = list(\
|
||||
"def" = null, \
|
||||
"on" = null, \
|
||||
"off" = null)
|
||||
var/trig_args_types = list(\
|
||||
"def" = list(), \
|
||||
"on" = list(), \
|
||||
"off" = list())
|
||||
|
||||
/obj/kbutton/toggle/Initialize(mapload)
|
||||
. = ..()
|
||||
update_variables()
|
||||
|
||||
/obj/kbutton/toggle/proc/update_variables()
|
||||
var/index = toggled ? "on" : "off"
|
||||
trig_message = trig_message_types[index] ? trig_message_types[index] : trig_message_types["def"]
|
||||
nothing_message = nothing_message_types[index] ? nothing_message_types[index] : nothing_message_types["def"]
|
||||
pressed_sound_file = pressed_sound_file_types[index] ? pressed_sound_file_types[index] : pressed_sound_file_types["def"]
|
||||
pressed_sound_volume = pressed_sound_volume_types[index] ? pressed_sound_volume_types[index] : pressed_sound_volume_types["def"]
|
||||
nothing_sound_file = nothing_sound_file_types[index] ? nothing_sound_file_types[index] : nothing_sound_file_types["def"]
|
||||
nothing_sound_volume = nothing_sound_volume_types[index] ? nothing_sound_volume_types[index] : nothing_sound_volume_types["def"]
|
||||
icon = icon_types[index] ? icon_types[index] : icon_types["def"]
|
||||
icon_state = icon_state_types[index] ? icon_state_types[index] : icon_state_types["def"]
|
||||
trig_proc = trig_proc_types[index] ? trig_proc_types[index] : trig_proc_types["def"]
|
||||
trig_args = trig_args_types[index].len ? trig_args_types[index] : trig_args_types["def"]
|
||||
|
||||
/obj/kbutton/toggle/button_trigger()
|
||||
toggled = !toggled
|
||||
update_variables()
|
||||
..()
|
||||
//An example button which opens and closes a closet.
|
||||
/obj/kbutton/toggle/example
|
||||
var/press_wait_time = 25
|
||||
var/last_pressed = 0
|
||||
|
||||
trig_target_paths = list("/obj/structure/closet")
|
||||
trig_target_trigger_uid = 97482
|
||||
|
||||
trig_message_types = list(\
|
||||
"def" = "You toggle the button.", \
|
||||
"on" = "You switch the button on.", \
|
||||
"off" = "You switch the button off.")
|
||||
nothing_message_types = list(\
|
||||
"def" = "Nothing happens.", \
|
||||
"on" = "You fail to switch the button off.", \
|
||||
"off" = "You fail to switch the button on.")
|
||||
pressed_sound_file_types = list(\
|
||||
"def" = 'sound/machines/button.ogg', \
|
||||
"on" = 'sound/machines/chime.ogg', \
|
||||
"off" = 'sound/machines/buttonbeep.ogg')
|
||||
pressed_sound_volume_types = list(\
|
||||
"def" = 80, \
|
||||
"on" = 80, \
|
||||
"off" = 80)
|
||||
nothing_sound_file_types = list(\
|
||||
"def" = 'sound/machines/buzz-sigh.ogg', \
|
||||
"on" = 'sound/machines/buzz-sigh.ogg', \
|
||||
"off" = 'sound/machines/buzz-two.ogg')
|
||||
nothing_sound_volume_types = list(\
|
||||
"def" = 100, \
|
||||
"on" = 100, \
|
||||
"off" = 100)
|
||||
icon_state_types = list(\
|
||||
"def" = "launcherbtt", \
|
||||
"on" = "launcheract", \
|
||||
"off" = "launcherbtt")
|
||||
trig_proc_types = list(\
|
||||
"def" = "close", \
|
||||
"on" = "open", \
|
||||
"off" = "close")
|
||||
|
||||
/obj/kbutton/toggle/example/can_press(mob/user)
|
||||
if(world.time > last_pressed + press_wait_time)
|
||||
last_pressed = world.time
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
//Corresponding closet for example button
|
||||
/obj/structure/closet/button_example
|
||||
trigger_uid = 97482
|
||||
@@ -250,6 +250,16 @@
|
||||
|
||||
removed.add_thermal_energy(heat_transfer)
|
||||
|
||||
for(var/mob/living/L in view(3, src))
|
||||
L.add_modifier(/datum/modifier/endothermic, 10 SECONDS, null, TRUE)
|
||||
|
||||
for(var/obj/item/stack/wetleather/WL in view(2, src))
|
||||
if(WL.wetness >= 0)
|
||||
WL.dry()
|
||||
continue
|
||||
|
||||
WL.wetness = max(0, WL.wetness - rand(1, 4))
|
||||
|
||||
env.merge(removed)
|
||||
|
||||
/obj/structure/bonfire/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
/obj/structure/flora/pottedplant/attackby(obj/item/I, mob/user)
|
||||
if(issilicon(user))
|
||||
return // Don't try to put modules in here, you're a borg. TODO: Inventory refactor to not be ass.
|
||||
|
||||
|
||||
if(stored_item)
|
||||
to_chat(user, "<span class='notice'>[I] won't fit in. There already appears to be something in here...</span>")
|
||||
return
|
||||
@@ -494,3 +494,47 @@
|
||||
|
||||
/obj/structure/flora/sif/tendrils/get_harvestable_desc()
|
||||
return "<span class='notice'>\The [src] seems to be growing over something.</span>"
|
||||
|
||||
/datum/category_item/catalogue/flora/frostbelle
|
||||
name = "Sivian Flora - Frostbelle"
|
||||
desc = "A rare plant native to Sif, with very peculiar growing requirements. Rarely seen outside of their original habitat,\
|
||||
or the homes of the wealthy, the plant's unique vein structure is actually used to carry the plant's reproductive material \
|
||||
to forming buds, the petals of which secrete the luminescent sap containing the pollen at the time of blooming. Certain \
|
||||
horticulturists have found ways of halting this process prior to the secretion of the sap, leaving the flower's petals \
|
||||
bright, at the cost of making that bud sterile."
|
||||
value = CATALOGUER_REWARD_HARD
|
||||
|
||||
/obj/structure/flora/sif/frostbelle
|
||||
name = "gnarly shrub"
|
||||
desc = "A stocky plant with fins bearing luminescent veins along its branches."
|
||||
icon_state = "grass"
|
||||
randomize_size = TRUE
|
||||
catalogue_data = list(/datum/category_item/catalogue/flora/frostbelle)
|
||||
|
||||
harvest_tool = /obj/item/weapon/material/knife
|
||||
max_harvests = 2
|
||||
min_harvests = -4
|
||||
harvest_loot = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/frostbelle = 1
|
||||
)
|
||||
|
||||
var/variantnum = null
|
||||
|
||||
/obj/structure/flora/sif/frostbelle/Initialize()
|
||||
. = ..()
|
||||
|
||||
variantnum = rand(1,3)
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/structure/flora/sif/frostbelle/update_icon()
|
||||
..()
|
||||
|
||||
if(max_harvests > 0 && harvest_count < max_harvests)
|
||||
icon_state = "[initial(icon_state)][variantnum]"
|
||||
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/structure/flora/sif/frostbelle/get_harvestable_desc()
|
||||
return "<span class='notice'>\The [src] seems to be budding.</span>"
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
/obj/structure/lattice/Initialize()
|
||||
. = ..()
|
||||
|
||||
if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open) || istype(src.loc, /turf/simulated/mineral)))
|
||||
if(!(istype(src.loc, /turf/space) || istype(src.loc, /turf/simulated/open) || istype(src.loc, /turf/simulated/mineral) || istype(src.loc, /turf/simulated/shuttle/plating/airless/carry)))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
for(var/obj/structure/lattice/LAT in src.loc)
|
||||
if(LAT != src)
|
||||
crash_with("Found multiple lattices at '[log_info_line(loc)]'")
|
||||
log_debug("Found multiple lattices at '[log_info_line(loc)]'") //VOREStation Edit, why was this a runtime, it's harmless
|
||||
return INITIALIZE_HINT_QDEL
|
||||
icon = 'icons/obj/smoothlattice.dmi'
|
||||
icon_state = "latticeblank"
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/obj/structure/reflector
|
||||
name = "reflector base"
|
||||
icon = 'icons/obj/tgs_structures_ch.dmi'
|
||||
icon_state = "reflector_map"
|
||||
desc = "A base for reflector assemblies."
|
||||
anchored = FALSE
|
||||
density = FALSE
|
||||
var/deflector_icon_state
|
||||
var/image/deflector_overlay
|
||||
var/finished = FALSE
|
||||
var/admin = FALSE //Can't be rotated or deconstructed
|
||||
var/can_rotate = TRUE
|
||||
var/framebuildstacktype = /obj/item/stack/material//metal
|
||||
var/framebuildstackamount = 5
|
||||
var/buildstacktype = /obj/item/stack/material//metal
|
||||
var/buildstackamount = 0
|
||||
var/fires_projectile = /obj/item/projectile/beam/emitter
|
||||
var/fires_accuracy = 10000
|
||||
var/fires_dispersion = 0
|
||||
var/list/allowed_projectile_typecache = list(/obj/item/projectile/beam)
|
||||
var/rotation_angle = -1
|
||||
var/can_decon = TRUE
|
||||
var/list/has_projectiles = list()
|
||||
var/bullet_act_in_progress = FALSE
|
||||
|
||||
/obj/structure/reflector/Initialize()
|
||||
. = ..()
|
||||
icon_state = "reflector_base"
|
||||
allowed_projectile_typecache = typecacheof(allowed_projectile_typecache)
|
||||
if(deflector_icon_state)
|
||||
deflector_overlay = image(icon, deflector_icon_state)
|
||||
add_overlay(deflector_overlay)
|
||||
|
||||
if(rotation_angle == -1)
|
||||
setAngle(dir2angle(dir))
|
||||
else
|
||||
setAngle(rotation_angle)
|
||||
|
||||
if(admin)
|
||||
can_rotate = FALSE
|
||||
|
||||
SSreflector.processing += src
|
||||
|
||||
/obj/structure/reflector/examine(mob/user)
|
||||
. = ..()
|
||||
if(finished)
|
||||
. += "It is set to [rotation_angle] degrees, and the rotation is [can_rotate ? "unlocked" : "locked"]."
|
||||
if(!admin)
|
||||
if(can_rotate)
|
||||
. += "<span class='notice'>Alt-click to adjust its direction.</span>"
|
||||
else
|
||||
. += "<span class='notice'>Use screwdriver to unlock the rotation.</span>"
|
||||
|
||||
/obj/structure/reflector/proc/Fire()
|
||||
UNTIL(!bullet_act_in_progress)
|
||||
var/list/angles = list()
|
||||
for(var/obj/item/projectile/P in has_projectiles)
|
||||
angles[num2text(has_projectiles[P])] += P.damage
|
||||
for(var/angle in angles)
|
||||
var/obj/item/projectile/P = new fires_projectile(src)
|
||||
P.firer = src
|
||||
P.damage = angles[angle]
|
||||
P.accuracy = 350
|
||||
P.dispersion = 0
|
||||
P.fire(text2num(angle))
|
||||
has_projectiles = list()
|
||||
|
||||
/obj/structure/reflector/proc/setAngle(new_angle)
|
||||
if(can_rotate)
|
||||
rotation_angle = new_angle
|
||||
if(deflector_overlay)
|
||||
cut_overlay(deflector_overlay)
|
||||
deflector_overlay.transform = turn(matrix(), new_angle)
|
||||
add_overlay(deflector_overlay)
|
||||
|
||||
/obj/structure/reflector/proc/redirect_projectile(obj/item/projectile/P,pangle)
|
||||
has_projectiles[P] = pangle
|
||||
qdel(P)
|
||||
|
||||
/obj/structure/reflector/set_dir(new_dir)
|
||||
return ..(NORTH)
|
||||
|
||||
/obj/structure/reflector/Crossed(atom/movable/AM) //Ok so this is my solution to garbage projectile code. Please god let this work.
|
||||
if(istype(AM,/obj/item/projectile))
|
||||
AM.Bump(src)
|
||||
|
||||
/obj/structure/reflector/bullet_act(obj/item/projectile/P)
|
||||
bullet_act_in_progress = TRUE
|
||||
var/pdir = P.dir
|
||||
var/pangle = P.Angle
|
||||
var/ploc = get_turf(P)
|
||||
if(!finished || !allowed_projectile_typecache[P.type] || !(P.dir in cardinal))
|
||||
return ..()
|
||||
if(auto_reflect(P, pdir, ploc, pangle) != 2)
|
||||
return ..()
|
||||
bullet_act_in_progress = FALSE
|
||||
|
||||
/obj/structure/reflector/proc/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
|
||||
P.ignore_source_check = TRUE
|
||||
return 2
|
||||
|
||||
/obj/structure/reflector/attackby(obj/item/W, mob/user, params)
|
||||
if(admin)
|
||||
return
|
||||
|
||||
if(W.is_screwdriver())
|
||||
can_rotate = !can_rotate
|
||||
to_chat(user, "<span class='notice'>You [can_rotate ? "unlock" : "lock"] [src]'s rotation.</span>")
|
||||
playsound(W, W.usesound, 50, 1)
|
||||
return
|
||||
|
||||
if(W.is_wrench() && can_decon)
|
||||
if(anchored)
|
||||
to_chat(user, "<span class='warning'>Unweld [src] from the floor first!</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts to dismantle [src].</span>", "<span class='notice'>You start to dismantle [src]...</span>")
|
||||
to_chat(user, "<span class='notice'>You dismantle [src].</span>")
|
||||
new framebuildstacktype(drop_location(), framebuildstackamount)
|
||||
if(buildstackamount)
|
||||
new buildstacktype(drop_location(), buildstackamount)
|
||||
qdel(src)
|
||||
else if(istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/I = W
|
||||
if(!anchored)
|
||||
if(!I.remove_fuel(1,user))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts to weld [src] to the floor.</span>",
|
||||
"<span class='notice'>You start to weld [src] to the floor...</span>",
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
anchored = TRUE
|
||||
to_chat(user, "<span class='notice'>You weld [src] to the floor.</span>")
|
||||
else
|
||||
if(!I.remove_fuel(1,user))
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts to cut [src] free from the floor.</span>",
|
||||
"<span class='notice'>You start to cut [src] free from the floor...</span>",
|
||||
"<span class='hear'>You hear welding.</span>")
|
||||
anchored = FALSE
|
||||
to_chat(user, "<span class='notice'>You cut [src] free from the floor.</span>")
|
||||
|
||||
//Finishing the frame
|
||||
else if(istype(W, /obj/item/stack/material))
|
||||
if(finished)
|
||||
return
|
||||
var/obj/item/stack/material/S = W
|
||||
if(istype(S, /obj/item/stack/material/glass))
|
||||
if(S.use(5))
|
||||
new /obj/structure/reflector/single(drop_location())
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need five sheets of glass to create a reflector!</span>")
|
||||
return
|
||||
if(istype(S, /obj/item/stack/material/glass/reinforced))
|
||||
if(S.use(10))
|
||||
new /obj/structure/reflector/double(drop_location())
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need ten sheets of reinforced glass to create a double reflector!</span>")
|
||||
return
|
||||
if(istype(S, /obj/item/stack/material/diamond))
|
||||
if(S.use(1))
|
||||
new /obj/structure/reflector/box(drop_location())
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/reflector/proc/rotate(mob/user)
|
||||
if (!can_rotate || admin)
|
||||
to_chat(user, "<span class='warning'>The rotation is locked!</span>")
|
||||
return FALSE
|
||||
var/new_angle = input(user, "Input a new angle for primary reflection face.", "Reflector Angle", rotation_angle) as null|num
|
||||
if(!CanUseTopic(user))
|
||||
return
|
||||
if(!isnull(new_angle))
|
||||
setAngle(SIMPLIFY_DEGREES(new_angle))
|
||||
return TRUE
|
||||
|
||||
/obj/structure/reflector/AltClick(mob/user)
|
||||
if(!CanUseTopic(user))
|
||||
return
|
||||
else if(finished)
|
||||
rotate(user)
|
||||
|
||||
|
||||
//TYPES OF REFLECTORS, SINGLE, DOUBLE, BOX
|
||||
|
||||
//SINGLE
|
||||
|
||||
/obj/structure/reflector/single
|
||||
name = "reflector"
|
||||
deflector_icon_state = "reflector"
|
||||
desc = "An angled mirror for reflecting laser beams."
|
||||
density = TRUE
|
||||
finished = TRUE
|
||||
buildstacktype = /obj/item/stack/material//glass
|
||||
buildstackamount = 5
|
||||
|
||||
/obj/structure/reflector/single/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/reflector/single/mapping
|
||||
admin = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/reflector/single/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
|
||||
var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, (P.Angle + 180))
|
||||
if(abs(incidence) > 90 && abs(incidence) < 270)
|
||||
return FALSE
|
||||
var/new_angle = SIMPLIFY_DEGREES(rotation_angle + incidence)
|
||||
redirect_projectile(P,new_angle)
|
||||
return ..()
|
||||
|
||||
//DOUBLE
|
||||
|
||||
/obj/structure/reflector/double
|
||||
name = "double sided reflector"
|
||||
deflector_icon_state = "reflector_double"
|
||||
desc = "A double sided angled mirror for reflecting laser beams."
|
||||
density = TRUE
|
||||
finished = TRUE
|
||||
buildstacktype = /obj/item/stack/material/glass/reinforced
|
||||
buildstackamount = 10
|
||||
|
||||
/obj/structure/reflector/double/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/reflector/double/mapping
|
||||
admin = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/reflector/double/auto_reflect(obj/item/projectile/P, pdir, turf/ploc, pangle)
|
||||
var/incidence = GET_ANGLE_OF_INCIDENCE(rotation_angle, (P.Angle + 180))
|
||||
var/new_angle = SIMPLIFY_DEGREES(rotation_angle + incidence)
|
||||
redirect_projectile(P,new_angle)
|
||||
return ..()
|
||||
|
||||
//BOX
|
||||
|
||||
/obj/structure/reflector/box
|
||||
name = "reflector box"
|
||||
deflector_icon_state = "reflector_box"
|
||||
desc = "A box with an internal set of mirrors that reflects all laser beams in a single direction."
|
||||
density = TRUE
|
||||
finished = TRUE
|
||||
buildstacktype = /obj/item/stack/material/diamond
|
||||
buildstackamount = 1
|
||||
|
||||
/obj/structure/reflector/box/Fire() //Since they all end up at the same angle, this should save a tad bit of processing power and memory <3
|
||||
UNTIL(!bullet_act_in_progress)
|
||||
var/total_damage = 0
|
||||
for(var/obj/item/projectile/P in has_projectiles)
|
||||
total_damage += P.damage
|
||||
if(total_damage)
|
||||
var/obj/item/projectile/P = new fires_projectile(src)
|
||||
P.firer = src
|
||||
P.damage = total_damage
|
||||
P.accuracy = 350
|
||||
P.dispersion = 0
|
||||
P.fire(rotation_angle)
|
||||
has_projectiles = list()
|
||||
|
||||
/obj/structure/reflector/box/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/reflector/box/mapping
|
||||
admin = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/reflector/box/auto_reflect(obj/item/projectile/P)
|
||||
redirect_projectile(P,rotation_angle)
|
||||
return ..()
|
||||
|
||||
/obj/structure/reflector/ex_act()
|
||||
if(admin)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/reflector/singularity_act()
|
||||
if(admin)
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/reflector/box/orderable
|
||||
name = "NanoTrasen reflector box"
|
||||
desc = "A box with an internal set of mirrors that reflects all laser beams in a single direction. This one is marked with NanoTrasen's logo."
|
||||
can_decon = FALSE
|
||||
|
||||
/datum/material/steel/generate_recipes()
|
||||
..()
|
||||
recipes += new/datum/stack_recipe("reflector frame", /obj/structure/reflector, 5, time = 25, one_per_turf = TRUE, on_floor = TRUE)
|
||||
|
||||
/datum/supply_pack/eng/reflector
|
||||
name = "Reflector crate"
|
||||
cost = 35
|
||||
containername = "Reflector crate"
|
||||
containertype = /obj/structure/closet/crate/secure/einstein
|
||||
contains = list(/obj/structure/reflector/box/orderable = 3)
|
||||
|
||||
//Below is mostly mapping stuff for the spicy storage I added to house these new reflectors ;p
|
||||
|
||||
/area/engineering/secret_storage
|
||||
name = "Engineering Secret Storage"
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
var/dont_burst = FALSE
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/phoron/cold/New()
|
||||
src.air_contents.temperature = 2.72
|
||||
..()
|
||||
Reference in New Issue
Block a user