@@ -13,7 +13,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list("tag","area","type","loc","locs",
|
||||
|
||||
if(perfectcopy && O && original)
|
||||
for(var/V in original.vars - GLOB.duplicate_forbidden_vars)
|
||||
if(istype(original.vars[V],/list))
|
||||
if(islist(original.vars[V]))
|
||||
var/list/L = original.vars[V]
|
||||
O.vars[V] = L.Copy()
|
||||
else if(istype(original.vars[V],/datum))
|
||||
@@ -21,12 +21,12 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list("tag","area","type","loc","locs",
|
||||
else
|
||||
O.vars[V] = original.vars[V]
|
||||
|
||||
if(istype(O, /obj))
|
||||
if(isobj(O))
|
||||
var/obj/N = O
|
||||
if(holoitem)
|
||||
N.resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF // holoitems do not burn
|
||||
|
||||
if(nerf && istype(O,/obj/item))
|
||||
if(nerf && isitem(O))
|
||||
var/obj/item/I = O
|
||||
I.damtype = STAMINA // thou shalt not
|
||||
|
||||
@@ -98,12 +98,12 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list("tag","area","type","loc","locs",
|
||||
|
||||
for(var/obj/O in T)
|
||||
var/obj/O2 = DuplicateObject(O , perfectcopy=TRUE, newloc = B, nerf=nerf_weapons, holoitem=TRUE)
|
||||
if(!O2)
|
||||
if(!O2)
|
||||
continue
|
||||
copiedobjs += O2.GetAllContents()
|
||||
|
||||
for(var/mob/M in T)
|
||||
if(istype(M, /mob/camera))
|
||||
if(istype(M, /mob/camera))
|
||||
continue // If we need to check for more mobs, I'll add a variable
|
||||
var/mob/SM = DuplicateObject(M , perfectcopy=TRUE, newloc = B, holoitem=TRUE)
|
||||
copiedobjs += SM.GetAllContents()
|
||||
|
||||
+206
-131
@@ -15,6 +15,9 @@
|
||||
The base of program_type will always be ignored; only subtypes will be loaded.
|
||||
*/
|
||||
|
||||
#define HOLODECK_CD 25
|
||||
#define HOLODECK_DMG_CD 500
|
||||
|
||||
/obj/machinery/computer/holodeck
|
||||
name = "holodeck control console"
|
||||
desc = "A computer used to control a nearby holodeck."
|
||||
@@ -26,109 +29,106 @@
|
||||
var/area/holodeck/last_program
|
||||
var/area/offline_program = /area/holodeck/rec_center/offline
|
||||
|
||||
var/list/program_cache = list()
|
||||
var/list/emag_programs = list()
|
||||
var/list/program_cache
|
||||
var/list/emag_programs
|
||||
|
||||
// Splitting this up allows two holodecks of the same size
|
||||
// to use the same source patterns. Y'know, if you want to.
|
||||
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
|
||||
var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
|
||||
|
||||
// set this if you want it to start with some particular program.
|
||||
var/init_program = null
|
||||
// or this to get anything
|
||||
var/random_program = 0
|
||||
|
||||
var/active = 0
|
||||
var/damaged = 0
|
||||
var/active = FALSE
|
||||
var/damaged = FALSE
|
||||
var/list/spawned = list()
|
||||
var/list/effects = list()
|
||||
var/last_change = 0
|
||||
|
||||
|
||||
var/current_cd = 0
|
||||
|
||||
/obj/machinery/computer/holodeck/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/computer/holodeck/LateInitialize()
|
||||
if(ispath(holodeck_type,/area))
|
||||
var/list/possible = get_areas(holodeck_type,subtypes = FALSE)
|
||||
linked = pop(possible)
|
||||
if(ispath(offline_program,/area))
|
||||
var/list/possible = get_areas(offline_program,subtypes = FALSE)
|
||||
offline_program = pop(possible)
|
||||
// the following is necessary for power reasons
|
||||
if(!linked || !offline_program)
|
||||
log_world("No matching holodeck area found")
|
||||
qdel(src)
|
||||
return
|
||||
var/area/AS = get_area(src)
|
||||
if(istype(AS,/area/holodeck))
|
||||
log_world("### MAPPING ERROR")
|
||||
log_world("Holodeck computer cannot be in a holodeck.")
|
||||
log_world("This would cause circular power dependency.")
|
||||
qdel(src) // todo handle constructed computers
|
||||
return //l-lewd...
|
||||
else
|
||||
linked.linked = src // todo detect multiple/constructed computers
|
||||
if(ispath(holodeck_type, /area))
|
||||
linked = locate(holodeck_type) in GLOB.sortedAreas
|
||||
if(ispath(offline_program,/area))
|
||||
offline_program = locate(offline_program) in GLOB.sortedAreas
|
||||
// the following is necessary for power reasons
|
||||
if(!linked || !offline_program)
|
||||
log_world("No matching holodeck area found")
|
||||
qdel(src)
|
||||
return
|
||||
var/area/AS = get_area(src)
|
||||
if(istype(AS, /area/holodeck))
|
||||
log_world("### MAPPING ERROR")
|
||||
log_world("Holodeck computer cannot be in a holodeck.")
|
||||
log_world("This would cause circular power dependency.")
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
linked.linked = src
|
||||
|
||||
program_cache = list()
|
||||
emag_programs = list()
|
||||
for(var/typekey in subtypesof(program_type))
|
||||
var/area/holodeck/A = locate(typekey)
|
||||
if(!A || A == offline_program)
|
||||
continue
|
||||
if(A.contents.len == 0)
|
||||
continue // not loaded
|
||||
if(A.restricted)
|
||||
emag_programs += A
|
||||
else
|
||||
program_cache += A
|
||||
if(typekey == init_program)
|
||||
load_program(A,force=1)
|
||||
if(random_program && program_cache.len && init_program == null)
|
||||
load_program(pick(program_cache),force=1)
|
||||
else if(!program)
|
||||
load_program(offline_program)
|
||||
generate_program_list()
|
||||
load_program(offline_program, FALSE, FALSE)
|
||||
|
||||
/obj/machinery/computer/holodeck/Destroy()
|
||||
emergency_shutdown()
|
||||
if(linked)
|
||||
linked.linked = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/holodeck/power_change()
|
||||
..()
|
||||
. = ..()
|
||||
toggle_power(!stat)
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = 0)
|
||||
if(active == toggleOn) return
|
||||
/obj/machinery/computer/holodeck/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "holodeck", name, 400, 500, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
if(toggleOn)
|
||||
if(last_program && last_program != offline_program)
|
||||
load_program(last_program, delay = 1)
|
||||
active = 1
|
||||
else
|
||||
last_program = program
|
||||
load_program(offline_program,force=1)
|
||||
active = 0
|
||||
/obj/machinery/computer/holodeck/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/emergency_shutdown()
|
||||
last_program = program
|
||||
load_program(offline_program,1)
|
||||
active = 0
|
||||
data["default_programs"] = program_cache
|
||||
if(emagged)
|
||||
data["emagged"] = TRUE
|
||||
data["emag_programs"] = emag_programs
|
||||
data["program"] = program
|
||||
data["can_toggle_safety"] = issilicon(user) || IsAdminGhost(user)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/holodeck/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("load_program")
|
||||
var/program_to_load = text2path(params["type"])
|
||||
if(!ispath(program_to_load))
|
||||
return FALSE
|
||||
var/area/A = locate(program_to_load) in GLOB.sortedAreas
|
||||
if(A)
|
||||
load_program(A)
|
||||
if("safety")
|
||||
emagged = !emagged
|
||||
if(emagged && program && emag_programs[program.name])
|
||||
emergency_shutdown()
|
||||
nerf(emagged)
|
||||
|
||||
/obj/machinery/computer/holodeck/process()
|
||||
if(damaged)
|
||||
if(prob(10))
|
||||
for(var/turf/T in linked)
|
||||
if(prob(5))
|
||||
var/datum/effect_system/spark_spread/s = new
|
||||
s.set_up(2, 1, T)
|
||||
s.start()
|
||||
return
|
||||
if(damaged && prob(10))
|
||||
for(var/turf/T in linked)
|
||||
if(prob(5))
|
||||
do_sparks(2, 1, T)
|
||||
return
|
||||
|
||||
if(!..() || !active)
|
||||
return
|
||||
|
||||
if(!floorcheck())
|
||||
emergency_shutdown()
|
||||
damaged = 1
|
||||
damaged = TRUE
|
||||
for(var/mob/M in urange(10,src))
|
||||
M.show_message("The holodeck overloads!")
|
||||
|
||||
@@ -144,67 +144,24 @@
|
||||
for(var/item in spawned)
|
||||
if(!(get_turf(item) in linked))
|
||||
derez(item, 0)
|
||||
for(var/obj/effect/holodeck_effect/HE in effects)
|
||||
for(var/e in effects)
|
||||
var/obj/effect/holodeck_effect/HE = e
|
||||
HE.tick()
|
||||
|
||||
active_power_usage = 50 + spawned.len * 3 + effects.len * 5
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/floorcheck()
|
||||
for(var/turf/T in linked)
|
||||
if(!T.intact || isspaceturf(T))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/holodeck/Topic(href, list/href_list)
|
||||
if(..())
|
||||
/obj/machinery/computer/holodeck/emag_act(mob/user)
|
||||
if(emagged)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
if(href_list["loadarea"])
|
||||
var/areapath = text2path(href_list["loadarea"])
|
||||
if(!ispath(areapath, /area/holodeck))
|
||||
return
|
||||
var/area/holodeck/area = locate(areapath)
|
||||
if(!istype(area))
|
||||
return
|
||||
if(area == offline_program || (area in program_cache) || (emagged && (area in emag_programs)))
|
||||
load_program(area)
|
||||
else if("safety" in href_list)
|
||||
var/safe = text2num(href_list["safety"])
|
||||
if(!issilicon(usr))
|
||||
return
|
||||
emagged = !safe
|
||||
if(!program)
|
||||
return
|
||||
if(safe && (program in emag_programs))
|
||||
emergency_shutdown()
|
||||
nerf(safe)
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/nerf(active)
|
||||
for(var/obj/item/I in spawned)
|
||||
I.damtype = (active? STAMINA : initial(I.damtype) )
|
||||
for(var/obj/effect/holodeck_effect/HE in effects)
|
||||
HE.safety(active)
|
||||
|
||||
/obj/machinery/computer/holodeck/emag_act(mob/user as mob)
|
||||
if(!emagged)
|
||||
if(!emag_programs.len)
|
||||
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
|
||||
return
|
||||
playsound(loc, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = 1
|
||||
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
|
||||
to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
|
||||
log_game("[key_name(user)] emagged the Holodeck Control Console")
|
||||
updateUsrDialog()
|
||||
nerf(!emagged)
|
||||
|
||||
/obj/machinery/computer/holodeck/Destroy()
|
||||
if(linked)
|
||||
emergency_shutdown()
|
||||
linked.linked = null
|
||||
return ..()
|
||||
if(!LAZYLEN(emag_programs))
|
||||
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
|
||||
return
|
||||
playsound(src, 'sound/effects/sparks4.ogg', 75, 1)
|
||||
emagged = TRUE
|
||||
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
|
||||
to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
|
||||
log_game("[key_name(user)] emagged the Holodeck Control Console")
|
||||
nerf(!emagged)
|
||||
|
||||
/obj/machinery/computer/holodeck/emp_act(severity)
|
||||
emergency_shutdown()
|
||||
@@ -216,4 +173,122 @@
|
||||
|
||||
/obj/machinery/computer/holodeck/blob_act(obj/structure/blob/B)
|
||||
emergency_shutdown()
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/generate_program_list()
|
||||
for(var/typekey in subtypesof(program_type))
|
||||
var/area/holodeck/A = locate(typekey) in GLOB.sortedAreas
|
||||
if(!A || A == offline_program || !A.contents.len)
|
||||
continue
|
||||
var/list/info_this = list()
|
||||
info_this["name"] = A.name
|
||||
info_this["type"] = A.type
|
||||
if(A.restricted)
|
||||
LAZYADD(emag_programs, list(info_this))
|
||||
else
|
||||
LAZYADD(program_cache, list(info_this))
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
|
||||
if(active == toggleOn)
|
||||
return
|
||||
|
||||
if(toggleOn)
|
||||
if(last_program && last_program != offline_program)
|
||||
addtimer(CALLBACK(src, .proc/load_program, last_program, TRUE), 25)
|
||||
active = TRUE
|
||||
else
|
||||
last_program = program
|
||||
load_program(offline_program, TRUE)
|
||||
active = FALSE
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/emergency_shutdown()
|
||||
last_program = program
|
||||
load_program(offline_program, TRUE)
|
||||
active = FALSE
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/floorcheck()
|
||||
for(var/turf/T in linked)
|
||||
if(!T.intact || isspaceturf(T))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/nerf(active)
|
||||
for(var/obj/item/I in spawned)
|
||||
I.damtype = active ? STAMINA : initial(I.damtype)
|
||||
for(var/e in effects)
|
||||
var/obj/effect/holodeck_effect/HE = e
|
||||
HE.safety(active)
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/load_program(area/A, force = FALSE, add_delay = TRUE)
|
||||
if(!is_operational())
|
||||
A = offline_program
|
||||
force = TRUE
|
||||
|
||||
if(program == A)
|
||||
return
|
||||
if(current_cd > world.time && !force)
|
||||
say("ERROR. Recalibrating projection apparatus.")
|
||||
return
|
||||
if(add_delay)
|
||||
current_cd = world.time + HOLODECK_CD
|
||||
if(damaged)
|
||||
current_cd += HOLODECK_DMG_CD
|
||||
active = (A != offline_program)
|
||||
use_power = active + IDLE_POWER_USE
|
||||
|
||||
for(var/e in effects)
|
||||
var/obj/effect/holodeck_effect/HE = e
|
||||
HE.deactivate(src)
|
||||
|
||||
for(var/item in spawned)
|
||||
derez(item, force)
|
||||
|
||||
program = A
|
||||
// note nerfing does not yet work on guns, should
|
||||
// should also remove/limit/filter reagents?
|
||||
// this is an exercise left to others I'm afraid. -Sayu
|
||||
spawned = A.copy_contents_to(linked, 1, nerf_weapons = !emagged)
|
||||
for(var/obj/machinery/M in spawned)
|
||||
M.flags |= NODECONSTRUCT
|
||||
for(var/obj/structure/S in spawned)
|
||||
S.flags |= NODECONSTRUCT
|
||||
effects = list()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/finish_spawn), 30)
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/finish_spawn()
|
||||
var/list/added = list()
|
||||
for(var/obj/effect/holodeck_effect/HE in spawned)
|
||||
effects += HE
|
||||
spawned -= HE
|
||||
var/atom/x = HE.activate(src)
|
||||
if(istype(x) || islist(x))
|
||||
spawned += x // holocarp are not forever
|
||||
added += x
|
||||
for(var/obj/machinery/M in added)
|
||||
M.flags |= NODECONSTRUCT
|
||||
for(var/obj/structure/S in added)
|
||||
S.flags |= NODECONSTRUCT
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/derez(obj/O, silent = TRUE, forced = FALSE)
|
||||
// Emagging a machine creates an anomaly in the derez systems.
|
||||
if(O && emagged && !stat && !forced)
|
||||
if((ismob(O) || ismob(O.loc)) && prob(50))
|
||||
addtimer(CALLBACK(src, .proc/derez, O, silent), 50) // may last a disturbingly long time
|
||||
return
|
||||
|
||||
spawned -= O
|
||||
if(!O)
|
||||
return
|
||||
var/turf/T = get_turf(O)
|
||||
for(var/atom/movable/AM in O) // these should be derezed if they were generated
|
||||
AM.forceMove(T)
|
||||
if(ismob(AM))
|
||||
silent = FALSE // otherwise make sure they are dropped
|
||||
|
||||
if(!silent)
|
||||
visible_message("[O] fades away!")
|
||||
qdel(O)
|
||||
|
||||
#undef HOLODECK_CD
|
||||
#undef HOLODECK_DMG_CD
|
||||
|
||||
@@ -97,3 +97,9 @@
|
||||
|
||||
/obj/effect/holodeck_effect/mobspawner/monkey
|
||||
mobtype = /mob/living/simple_animal/holodeck_monkey
|
||||
|
||||
/obj/effect/holodeck_effect/mobspawner/penguin
|
||||
mobtype = /mob/living/simple_animal/pet/penguin/emperor
|
||||
|
||||
/obj/effect/holodeck_effect/mobspawner/penguin_baby
|
||||
mobtype = /mob/living/simple_animal/pet/penguin/baby
|
||||
|
||||
+220
-220
@@ -1,221 +1,221 @@
|
||||
/*
|
||||
Items, Structures, Machines
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Items
|
||||
//
|
||||
|
||||
/obj/item/weapon/holo
|
||||
damtype = STAMINA
|
||||
|
||||
/obj/item/weapon/holo/esword
|
||||
name = "holographic energy sword"
|
||||
desc = "May the force be with you. Sorta"
|
||||
icon_state = "sword0"
|
||||
force = 3.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
hitsound = "swing_hit"
|
||||
armour_penetration = 50
|
||||
var/active = 0
|
||||
|
||||
/obj/item/weapon/holo/esword/green/New()
|
||||
..()
|
||||
item_color = "green"
|
||||
|
||||
|
||||
/obj/item/weapon/holo/esword/red/New()
|
||||
..()
|
||||
item_color = "red"
|
||||
|
||||
/obj/item/weapon/holo/esword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
|
||||
if(active)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holo/esword/New()
|
||||
item_color = pick("red","blue","green","purple")
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holo/esword/attack_self(mob/living/user as mob)
|
||||
active = !active
|
||||
if (active)
|
||||
force = 30
|
||||
icon_state = "sword[item_color]"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 20, 1)
|
||||
to_chat(user, "<span class='warning'>[src] is now active.</span>")
|
||||
else
|
||||
force = 3
|
||||
icon_state = "sword0"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
hitsound = "swing_hit"
|
||||
playsound(user, 'sound/weapons/saberoff.ogg', 20, 1)
|
||||
to_chat(user, "<span class='warning'>[src] can now be concealed.</span>")
|
||||
return
|
||||
|
||||
//BASKETBALL OBJECTS
|
||||
|
||||
/obj/item/toy/beach_ball/holoball
|
||||
name = "basketball"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "basketball"
|
||||
item_state = "basketball"
|
||||
desc = "Here's your chance, do your dance at the Space Jam."
|
||||
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
|
||||
|
||||
/obj/item/toy/beach_ball/holoball/dodgeball
|
||||
name = "dodgeball"
|
||||
icon_state = "dodgeball"
|
||||
item_state = "dodgeball"
|
||||
desc = "Used for playing the most violent and degrading of childhood games."
|
||||
|
||||
/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if((ishuman(hit_atom)))
|
||||
var/mob/living/carbon/M = hit_atom
|
||||
playsound(src, 'sound/items/dodgeball.ogg', 50, 1)
|
||||
M.apply_damage(10, STAMINA)
|
||||
if(prob(5))
|
||||
M.Weaken(3)
|
||||
visible_message("<span class='danger'>[M] is knocked right off [M.p_their()] feet!</span>")
|
||||
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
|
||||
/obj/structure/holohoop
|
||||
name = "basketball hoop"
|
||||
desc = "Boom, shakalaka!"
|
||||
icon = 'icons/obj/basketball.dmi'
|
||||
icon_state = "hoop"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(get_dist(src,user)<2)
|
||||
if(user.drop_item(src))
|
||||
visible_message("<span class='warning'> [user] dunks [W] into \the [src]!</span>")
|
||||
|
||||
/obj/structure/holohoop/attack_hand(mob/user)
|
||||
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(user.grab_state < GRAB_AGGRESSIVE)
|
||||
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
|
||||
return
|
||||
L.loc = src.loc
|
||||
L.Weaken(5)
|
||||
visible_message("<span class='danger'>[user] dunks [L] into \the [src]!</span>")
|
||||
user.stop_pulling()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if (istype(mover,/obj/item) && mover.throwing)
|
||||
var/obj/item/I = mover
|
||||
if(istype(I, /obj/item/projectile))
|
||||
return
|
||||
if(prob(50))
|
||||
I.forceMove(get_turf(src))
|
||||
visible_message("<span class='warning'>Swish! [I] lands in [src].</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>[I] bounces off of [src]'s rim!</span>")
|
||||
return 0
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Machines
|
||||
//
|
||||
|
||||
/obj/machinery/readybutton
|
||||
name = "ready declaration device"
|
||||
desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!"
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
icon_state = "auth_off"
|
||||
var/ready = 0
|
||||
var/area/currentarea = null
|
||||
var/eventstarted = 0
|
||||
|
||||
anchored = 1.0
|
||||
/*
|
||||
Items, Structures, Machines
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// Items
|
||||
//
|
||||
|
||||
/obj/item/weapon/holo
|
||||
damtype = STAMINA
|
||||
|
||||
/obj/item/weapon/holo/esword
|
||||
name = "holographic energy sword"
|
||||
desc = "May the force be with you. Sorta"
|
||||
icon_state = "sword0"
|
||||
force = 3.0
|
||||
throw_speed = 2
|
||||
throw_range = 5
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
hitsound = "swing_hit"
|
||||
armour_penetration = 50
|
||||
var/active = 0
|
||||
|
||||
/obj/item/weapon/holo/esword/green/New()
|
||||
..()
|
||||
item_color = "green"
|
||||
|
||||
|
||||
/obj/item/weapon/holo/esword/red/New()
|
||||
..()
|
||||
item_color = "red"
|
||||
|
||||
/obj/item/weapon/holo/esword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
if(active)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holo/esword/New()
|
||||
item_color = pick("red","blue","green","purple")
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holo/esword/attack_self(mob/living/user as mob)
|
||||
active = !active
|
||||
if (active)
|
||||
force = 30
|
||||
icon_state = "sword[item_color]"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
hitsound = 'sound/weapons/blade1.ogg'
|
||||
playsound(user, 'sound/weapons/saberon.ogg', 20, 1)
|
||||
to_chat(user, "<span class='warning'>[src] is now active.</span>")
|
||||
else
|
||||
force = 3
|
||||
icon_state = "sword0"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
hitsound = "swing_hit"
|
||||
playsound(user, 'sound/weapons/saberoff.ogg', 20, 1)
|
||||
to_chat(user, "<span class='warning'>[src] can now be concealed.</span>")
|
||||
return
|
||||
|
||||
//BASKETBALL OBJECTS
|
||||
|
||||
/obj/item/toy/beach_ball/holoball
|
||||
name = "basketball"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "basketball"
|
||||
item_state = "basketball"
|
||||
desc = "Here's your chance, do your dance at the Space Jam."
|
||||
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
|
||||
|
||||
/obj/item/toy/beach_ball/holoball/dodgeball
|
||||
name = "dodgeball"
|
||||
icon_state = "dodgeball"
|
||||
item_state = "dodgeball"
|
||||
desc = "Used for playing the most violent and degrading of childhood games."
|
||||
|
||||
/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if((ishuman(hit_atom)))
|
||||
var/mob/living/carbon/M = hit_atom
|
||||
playsound(src, 'sound/items/dodgeball.ogg', 50, 1)
|
||||
M.apply_damage(10, STAMINA)
|
||||
if(prob(5))
|
||||
M.Knockdown(60)
|
||||
visible_message("<span class='danger'>[M] is knocked right off [M.p_their()] feet!</span>")
|
||||
|
||||
//
|
||||
// Structures
|
||||
//
|
||||
|
||||
/obj/structure/holohoop
|
||||
name = "basketball hoop"
|
||||
desc = "Boom, shakalaka!"
|
||||
icon = 'icons/obj/basketball.dmi'
|
||||
icon_state = "hoop"
|
||||
anchored = 1
|
||||
density = 1
|
||||
|
||||
/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(get_dist(src,user)<2)
|
||||
if(user.drop_item(src))
|
||||
visible_message("<span class='warning'> [user] dunks [W] into \the [src]!</span>")
|
||||
|
||||
/obj/structure/holohoop/attack_hand(mob/user)
|
||||
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(user.grab_state < GRAB_AGGRESSIVE)
|
||||
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
|
||||
return
|
||||
L.loc = src.loc
|
||||
L.Knockdown(100)
|
||||
visible_message("<span class='danger'>[user] dunks [L] into \the [src]!</span>")
|
||||
user.stop_pulling()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if (isitem(mover) && mover.throwing)
|
||||
var/obj/item/I = mover
|
||||
if(istype(I, /obj/item/projectile))
|
||||
return
|
||||
if(prob(50))
|
||||
I.forceMove(get_turf(src))
|
||||
visible_message("<span class='warning'>Swish! [I] lands in [src].</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>[I] bounces off of [src]'s rim!</span>")
|
||||
return 0
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Machines
|
||||
//
|
||||
|
||||
/obj/machinery/readybutton
|
||||
name = "ready declaration device"
|
||||
desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!"
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
icon_state = "auth_off"
|
||||
var/ready = 0
|
||||
var/area/currentarea = null
|
||||
var/eventstarted = 0
|
||||
|
||||
anchored = 1.0
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 6
|
||||
power_channel = ENVIRON
|
||||
|
||||
/obj/machinery/readybutton/attack_ai(mob/user as mob)
|
||||
to_chat(user, "The station AI is not to interact with these devices")
|
||||
return
|
||||
|
||||
/obj/machinery/readybutton/attack_paw(mob/user as mob)
|
||||
to_chat(user, "<span class='warning'>You are too primitive to use this device!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
to_chat(user, "The device is a solid button, there's nothing you can do with it!")
|
||||
|
||||
/obj/machinery/readybutton/attack_hand(mob/user as mob)
|
||||
if(user.stat || stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "<span class='warning'>This device is not powered!</span>")
|
||||
return
|
||||
|
||||
currentarea = get_area(src.loc)
|
||||
if(!currentarea)
|
||||
qdel(src)
|
||||
|
||||
if(eventstarted)
|
||||
to_chat(usr, "<span class='warning'>The event has already begun!</span>")
|
||||
return
|
||||
|
||||
ready = !ready
|
||||
|
||||
update_icon()
|
||||
|
||||
var/numbuttons = 0
|
||||
var/numready = 0
|
||||
for(var/obj/machinery/readybutton/button in currentarea)
|
||||
numbuttons++
|
||||
if (button.ready)
|
||||
numready++
|
||||
|
||||
if(numbuttons == numready)
|
||||
begin_event()
|
||||
|
||||
/obj/machinery/readybutton/update_icon()
|
||||
if(ready)
|
||||
icon_state = "auth_on"
|
||||
else
|
||||
icon_state = "auth_off"
|
||||
|
||||
/obj/machinery/readybutton/proc/begin_event()
|
||||
|
||||
eventstarted = 1
|
||||
|
||||
for(var/obj/structure/window/W in currentarea)
|
||||
if(W.flags&NODECONSTRUCT) // Just in case: only holo-windows
|
||||
qdel(W)
|
||||
|
||||
for(var/mob/M in currentarea)
|
||||
to_chat(M, "FIGHT!")
|
||||
|
||||
/obj/machinery/conveyor/holodeck
|
||||
|
||||
/obj/machinery/conveyor/holodeck/attackby(obj/item/I, mob/user, params)
|
||||
if(user.drop_item())
|
||||
I.loc = src.loc
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/paper/trek_diploma
|
||||
name = "paper - Starfleet Academy Diploma"
|
||||
info = {"<h2>Starfleet Academy</h2></br><p>Official Diploma</p></br>"}
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 6
|
||||
power_channel = ENVIRON
|
||||
|
||||
/obj/machinery/readybutton/attack_ai(mob/user as mob)
|
||||
to_chat(user, "The station AI is not to interact with these devices")
|
||||
return
|
||||
|
||||
/obj/machinery/readybutton/attack_paw(mob/user as mob)
|
||||
to_chat(user, "<span class='warning'>You are too primitive to use this device!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
to_chat(user, "The device is a solid button, there's nothing you can do with it!")
|
||||
|
||||
/obj/machinery/readybutton/attack_hand(mob/user as mob)
|
||||
if(user.stat || stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "<span class='warning'>This device is not powered!</span>")
|
||||
return
|
||||
|
||||
currentarea = get_area(src.loc)
|
||||
if(!currentarea)
|
||||
qdel(src)
|
||||
|
||||
if(eventstarted)
|
||||
to_chat(usr, "<span class='warning'>The event has already begun!</span>")
|
||||
return
|
||||
|
||||
ready = !ready
|
||||
|
||||
update_icon()
|
||||
|
||||
var/numbuttons = 0
|
||||
var/numready = 0
|
||||
for(var/obj/machinery/readybutton/button in currentarea)
|
||||
numbuttons++
|
||||
if (button.ready)
|
||||
numready++
|
||||
|
||||
if(numbuttons == numready)
|
||||
begin_event()
|
||||
|
||||
/obj/machinery/readybutton/update_icon()
|
||||
if(ready)
|
||||
icon_state = "auth_on"
|
||||
else
|
||||
icon_state = "auth_off"
|
||||
|
||||
/obj/machinery/readybutton/proc/begin_event()
|
||||
|
||||
eventstarted = 1
|
||||
|
||||
for(var/obj/structure/window/W in currentarea)
|
||||
if(W.flags&NODECONSTRUCT) // Just in case: only holo-windows
|
||||
qdel(W)
|
||||
|
||||
for(var/mob/M in currentarea)
|
||||
to_chat(M, "FIGHT!")
|
||||
|
||||
/obj/machinery/conveyor/holodeck
|
||||
|
||||
/obj/machinery/conveyor/holodeck/attackby(obj/item/I, mob/user, params)
|
||||
if(user.drop_item())
|
||||
I.loc = src.loc
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/paper/trek_diploma
|
||||
name = "paper - Starfleet Academy Diploma"
|
||||
info = {"<h2>Starfleet Academy</h2></br><p>Official Diploma</p></br>"}
|
||||
|
||||
Reference in New Issue
Block a user