diff --git a/code/modules/admin/admin_verb_lists_vr.dm b/code/modules/admin/admin_verb_lists_vr.dm index e104916d2d..aad0440423 100644 --- a/code/modules/admin/admin_verb_lists_vr.dm +++ b/code/modules/admin/admin_verb_lists_vr.dm @@ -194,7 +194,8 @@ var/list/admin_verbs_spawn = list( /client/proc/map_template_upload, /client/proc/map_template_load_on_new_z, /client/proc/eventkit_open_mob_spawner, - /client/proc/generic_structure //VOREStation Add + /client/proc/generic_structure, //VOREStation Add + /client/proc/generic_item //VOREStation Add ) var/list/admin_verbs_server = list( diff --git a/code/modules/eventkit/generic_objects/generic_item.dm b/code/modules/eventkit/generic_objects/generic_item.dm new file mode 100644 index 0000000000..aba094ce3c --- /dev/null +++ b/code/modules/eventkit/generic_objects/generic_item.dm @@ -0,0 +1,241 @@ +/obj/item/generic_item + name = "unusual object" + desc = "An unusual object of some sort." + icon = 'icons/obj/props/items.dmi' + icon_state = "old_handheld" + var/on = 0 + var/icon_state_off = "old_handheld" + var/icon_state_on = "old_handheld_on" + var/activatable_hand = 1 + var/togglable = 1 + var/text_activated = "The item turns on." + var/text_deactivated = "The item turns off." + var/effect = 0 + var/object = 0 + var/sound_activated = 0 + var/delay_time = 0 + var/icon_off = 0 + var/icon_on = 0 + +/obj/item/generic_item/attack_self(mob/user) + if(activatable_hand) + if(!on) + if(delay_time) + if(!do_after(user, delay_time, src, exclusive = TASK_USER_EXCLUSIVE)) + return 0 + on = 1 + if(icon_on) + icon = icon_on + else + icon = 'icons/obj/props/items.dmi' + icon_state = icon_state_on + src.visible_message("[text_activated]") + update_icon() + if(effect == 1) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(3, 1, src) + s.start() + if(effect == 2) + for(var/obj/machinery/light/L in machines) + if(L.z != user.z || get_dist(user,L) > 10) + continue + else + L.flicker(10) + if(effect == 3) + for (var/mob/O in viewers(user, null)) + if(get_dist(user, O) > 3) + continue + + var/flash_time = 10 + if(istype(O, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = O + //VOREStation Edit Start + if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION)) + H.nif.notify("High intensity light detected, and blocked!",TRUE) + continue + //VOREStation Edit End + if(!H.eyecheck() <= 0) + continue + flash_time *= H.species.flash_mod + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] + if(!E) + return + if(E.is_bruised() && prob(E.damage + 50)) + H.flash_eyes() + E.damage += rand(1, 5) + else + if(!O.blinded && isliving(O)) + var/mob/living/L = O + L.flash_eyes() + O.Weaken(flash_time) + if(effect == 4) + var/atom/o = new object(get_turf(user)) + src.visible_message("[src] has produced [o]!") + if(sound_activated) + playsound(src, sound_activated, 50, 1) + else if(togglable) + if(delay_time) + if(!do_after(user, delay_time, src, exclusive = TASK_USER_EXCLUSIVE)) + return 0 + on = 0 + icon_state = icon_state_off + if(icon_off) + icon = icon_off + else + icon = 'icons/obj/props/items.dmi' + src.visible_message("[text_deactivated]") + update_icon() + return ..() + +/client/proc/generic_item() + set category = "EventKit" + set name = "Spawn Generic Item" + set desc = "Spawn a customisable item with a range of different options." + + var/s_activatable = 0 + var/s_togglable = 0 + var/s_icon_state_on = 0 + var/s_icon = 0 + var/s_icon2 = 0 + var/s_delay = 0 + var/s_text_activated = 0 + var/s_text_deactivated = 0 + var/s_effect = 0 + var/s_sound = 0 + var/s_object = 0 + var/list/icon_state_options = list("old_handheld", + "old_handheld_on", + "switch", + "switch_on", + "chalice", + "staffofnothing", + "staffofchange", + "staffofanimation", + "staffofchaos", + "scroll_rolledup", + "scroll_blank", + "scroll_text", + "scroll_textseal", + "scroll_rolledupseal", + "revolver", + "universal_id", + "universal_id_glow", + "partypopper", + "partypopper_e", + "screwdriver", + "screwdriver_glow", + "crystal", + "crystal_red", + "old_phone", + "old_phone_on", + "flash", + "flash_red", + "flash_burnt", + "techball_green", + "techball_yellow", + "techball_red", + "techball_blue", + "fleshorb", + "fleshorb_moving", + "Upload Own Sprite") + var/list/sound_options = list('sound/effects/alert.ogg', + 'sound/effects/bamf.ogg', + 'sound/effects/bang.ogg', + 'sound/effects/blobattack.ogg', + 'sound/effects/cascade.ogg', + 'sound/effects/clockcult_gateway_disrupted.ogg', + 'sound/effects/closet_close.ogg', + 'sound/effects/confetti_ball.ogg', + 'sound/effects/deskbell.ogg', + 'sound/effects/EMPulse.ogg', + 'sound/effects/Explosion1.ogg', + 'sound/effects/ghost.ogg', + 'sound/effects/Glassbr1.ogg', + 'sound/effects/lightningshock.ogg', + 'sound/effects/lighton.ogg', + 'sound/effects/magnetclamp.ogg', + 'sound/effects/pai_boot.ogg', + 'sound/effects/pai_login.ogg', + 'sound/effects/pai-restore.ogg', + 'sound/effects/radio_common.ogg', + 'sound/effects/refill.ogg', + 'sound/effects/siren.ogg', + 'sound/effects/smoke.ogg', + 'sound/effects/sparks1.ogg', + 'sound/effects/spray.ogg', + 'sound/effects/squelch1.ogg', + 'sound/effects/supermatter.ogg', + 'sound/effects/Whipcrack.ogg', + 'sound/effects/woodcutting.ogg') + + var/check_togglable + + + if(!holder) + return + + var/s_name = tgui_input_text(src, "Item Name:", "Name") + var/s_desc = tgui_input_text(src, "Item Description:", "Description") + var/s_icon_state_off = tgui_input_list(src, "Choose starting icon state:", "icon_state_off", icon_state_options) + if(s_icon_state_off == "Upload Own Sprite") + s_icon = input(usr, "Choose an image file to upload. Images that are not 32x32 will need to have their positions offset.","Upload Icon") as null|file + var/check_activatable = tgui_alert(src, "Allow it to be turned on?", "activatable", list("Yes", "No", "Cancel")) + if(check_activatable == "Cancel") + return + if(check_activatable == "No") + s_activatable = 0 + if(check_activatable == "Yes") + s_activatable = 1 + s_text_activated = tgui_input_text(src, "Activation text:", "Activation Text") + check_togglable = tgui_alert(src, "Allow it to be turned back off again?", "togglable", list("Yes", "No", "Cancel")) + if(check_togglable == "Cancel") + return + if(check_togglable == "No") + s_togglable = 0 + if(check_togglable == "Yes") + s_text_deactivated = tgui_input_text(src, "Deactivation text:", "Deactivation Text") + s_togglable = 1 + s_icon_state_on = tgui_input_list(src, "Choose activated icon state:", "icon_state_on", icon_state_options) + if(s_icon_state_on == "Upload Own Sprite") + s_icon2 = input(usr, "Choose an image file to upload. Images that are not 32x32 will need to have their positions offset.","Upload Icon") as null|file + s_delay = tgui_input_number(src, "Do you want it to take time to put turn on? Choose a number of deciseconds to activate, or 0 for instant.", "Delay") + var/check_effect = tgui_alert(src, "Produce an effect on activation?", "Effect?", list("No", "Spark", "Flicker Lights", "Flash", "Spawn Item", "Cancel")) + if(check_effect == "Cancel") + return + if(check_effect == "No") + s_effect = 0 + if(check_effect == "Spark") + s_effect = 1 + if(check_effect == "Flicker Lights") + s_effect = 2 + if(check_effect == "Flash") + s_effect = 3 + if(check_effect == "Spawn Item") + s_effect = 4 + s_object = get_path_from_partial_text() + var/check_sound = tgui_alert(src, "Play a sound when turning on?", "Sound", list("Yes", "No", "Cancel")) + if(check_sound == "Cancel") + return + if(check_sound == "Yes") + s_sound = tgui_input_list(src, "Choose a sound to play on activation:", "Sound", sound_options) + + var/spawnloc = get_turf(src.mob) + var/obj/item/generic_item/P = new(spawnloc) + P.name = s_name + P.desc = s_desc + P.icon_state_off = s_icon_state_off + P.icon_state_on = s_icon_state_on + P.activatable_hand = s_activatable + P.togglable = s_togglable + P.text_activated = s_text_activated + P.text_deactivated = s_text_deactivated + P.effect = s_effect + P.sound_activated = s_sound + P.delay_time = s_delay + P.object = s_object + P.icon_state = s_icon_state_off + P.icon_off = s_icon + P.icon_on = s_icon2 + if(s_icon) + P.icon = s_icon + P.update_icon() diff --git a/code/modules/eventkit/generic_objects/generic_structure.dm b/code/modules/eventkit/generic_objects/generic_structure.dm index d7be876bdb..5334111cc3 100644 --- a/code/modules/eventkit/generic_objects/generic_structure.dm +++ b/code/modules/eventkit/generic_objects/generic_structure.dm @@ -16,8 +16,11 @@ var/text_activated = "The strucutre turns on." var/text_deactivated = "The structure turns off." var/effect = 0 + var/object = 0 var/sound_activated = 0 var/delay_time = 0 + var/icon_on = 0 + var/icon_off = 0 /obj/structure/generic_structure/attack_hand(mob/user) if(activatable_hand) @@ -27,12 +30,53 @@ return 0 on = 1 icon_state = icon_state_on + if(icon_on) + icon = icon_on + else + icon = 'icons/obj/props/decor.dmi' + icon_state = icon_state_on src.visible_message("[text_activated]") update_icon() - if(effect) + if(effect == 1) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() + if(effect == 2) + for(var/obj/machinery/light/L in machines) + if(L.z != src.z || get_dist(src,L) > 10) + continue + else + L.flicker(10) + if(effect == 3) + for (var/mob/O in viewers(src, null)) + if(get_dist(src, O) > 3) + continue + + var/flash_time = 10 + if(istype(O, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = O + //VOREStation Edit Start + if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION)) + H.nif.notify("High intensity light detected, and blocked!",TRUE) + continue + //VOREStation Edit End + if(!H.eyecheck() <= 0) + continue + flash_time *= H.species.flash_mod + var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES] + if(!E) + return + if(E.is_bruised() && prob(E.damage + 50)) + H.flash_eyes() + E.damage += rand(1, 5) + else + if(!O.blinded && isliving(O)) + var/mob/living/L = O + L.flash_eyes() + O.Weaken(flash_time) + if(effect == 4) + var/atom/o = new object(get_turf(src)) + src.visible_message("[src] has produced [o]!") if(sound_activated) playsound(src, sound_activated, 50, 1) else if(togglable) @@ -41,6 +85,10 @@ return 0 on = 0 icon_state = icon_state_off + if(icon_off) + icon = icon_off + else + icon = 'icons/obj/props/decor.dmi' src.visible_message("[text_deactivated]") update_icon() return ..() @@ -67,6 +115,9 @@ var/s_text_deactivated = 0 var/s_effect = 0 var/s_sound = 0 + var/s_object = 0 + var/s_icon = 0 + var/s_icon2 = 0 var/list/icon_state_options = list("bsb_off", "bsb_on", "bsc", @@ -133,7 +184,8 @@ "ob_warhead_2", "ob_warhead_3", "ob_warhead_4", - "angel") + "angel", + "Upload Own Sprite") var/list/sound_options = list('sound/effects/alert.ogg', 'sound/effects/bamf.ogg', 'sound/effects/bang.ogg', @@ -194,6 +246,8 @@ if(check_wrenchable == "Yes") s_wrenchable = 1 var/s_icon_state_off = tgui_input_list(src, "Choose starting icon state:", "icon_state_off", icon_state_options) + if(s_icon_state_off == "Upload Own Sprite") + s_icon = input(usr, "Choose an image file to upload. Images that are not 32x32 will need to have their positions offset.","Upload Icon") as null|file var/check_activatable = tgui_alert(src, "Allow it to be turned on?", "activatable", list("Yes", "No", "Cancel")) if(check_activatable == "Cancel") return @@ -211,14 +265,23 @@ s_text_deactivated = tgui_input_text(src, "Deactivation text:", "Deactivation Text") s_togglable = 1 s_icon_state_on = tgui_input_list(src, "Choose activated icon state:", "icon_state_on", icon_state_options) + if(s_icon_state_on == "Upload Own Sprite") + s_icon2 = input(usr, "Choose an image file to upload. Images that are not 32x32 will need to have their positions offset.","Upload Icon") as null|file s_delay = tgui_input_number(src, "Do you want it to take time to put turn on? Choose a number of deciseconds to activate, or 0 for instant.", "Delay") - var/check_effect = tgui_alert(src, "Spark when turning on?", "Spark?", list("Yes", "No", "Cancel")) + var/check_effect = tgui_alert(src, "Produce an effect on activation?", "Effect?", list("No", "Spark", "Flicker Lights", "Flash", "Spawn Item", "Cancel")) if(check_effect == "Cancel") return if(check_effect == "No") s_effect = 0 - if(check_effect == "Yes") + if(check_effect == "Spark") s_effect = 1 + if(check_effect == "Flicker Lights") + s_effect = 2 + if(check_effect == "Flash") + s_effect = 3 + if(check_effect == "Spawn Item") + s_effect = 4 + s_object = get_path_from_partial_text() var/check_sound = tgui_alert(src, "Play a sound when turning on?", "Sound", list("Yes", "No", "Cancel")) if(check_sound == "Cancel") return @@ -241,5 +304,36 @@ P.effect = s_effect P.sound_activated = s_sound P.delay_time = s_delay + P.object = s_object + P.icon_state = s_icon_state_off + P.icon_off = s_icon + P.icon_on = s_icon2 + if(s_icon) + P.icon = s_icon P.update_icon() +/client/proc/get_path_from_partial_text(default_path) + var/desired_path = tgui_input_text(usr, "Enter full or partial typepath.","Typepath","[default_path]") + + if(!desired_path) //VOREStation Add - If you don't give it anything it builds a list of every possible thing in the game and crashes your client. + return //VOREStation Add - And the main way for it to do that is to push the cancel button, which should just do nothing. :U + + var/list/types = typesof(/atom) + var/list/matches = list() + + for(var/path in types) + if(findtext("[path]", desired_path)) + matches += path + + if(matches.len==0) + tgui_alert_async(usr, "No results found. Sorry.") + return + + var/result = null + + if(matches.len==1) + result = matches[1] + else + result = tgui_input_list(usr, "Select an atom type", "Spawn Atom", matches, strict_modern = TRUE) + return result + diff --git a/icons/obj/props/items.dmi b/icons/obj/props/items.dmi new file mode 100644 index 0000000000..98a5538c79 Binary files /dev/null and b/icons/obj/props/items.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 6ebe54698e..cd057eceee 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2266,6 +2266,7 @@ #include "code\modules\error_handler\error_viewer.dm" #include "code\modules\error_handler\~defines.dm" #include "code\modules\eventkit\event_machinery.dm" +#include "code\modules\eventkit\generic_objects\generic_item.dm" #include "code\modules\eventkit\generic_objects\generic_structure.dm" #include "code\modules\eventkit\gm_interfaces\fake_pda_conversations.dm" #include "code\modules\eventkit\gm_interfaces\mob_spawner.dm"