mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-05 14:17:12 +01:00
858da9f19a
## About The Pull Request We do two major things here. First, instead of having every turf need to ask all the turfs in "front" of it for its blast resistance, we have blast resistance carry back in a cache, so they only need to ask the one directly in front of them. Much faster, such wow The other thing we do is totally remove the idea of "building" a turf's explosion resistance. Instead, a turf's full resistance is stored on it at all times. We use an element to manage objects that want to block explosives, and that's it simple as. As an optimization, turfs handle block differently, using a system where we imply that a turf's own block is just the initial of their explosive_resistance, unless proven otherwise This also saves a significant amount of time To be honest with you, I did this mostly cause I wanted to well make explosions faster This doesn't really fufil that. They are faster, but not by much The bulk of explosion cost comes from actually exploding things, rather then figuring out what/how to delete. This code is much faster for larger blastwave sizes, because calculating protection is constant. We save maybe 60% of propogate_blastwave, but unfortunately propogate_blastwave for one maxcap on the top left of icebox's chapel is only 28ms, so while 11ms is good, it's not everything I could want when the cost of explosion/fire is 555ms. I'm happy about it still tho, because doing things like this means I can expand on how explosive blocking works without needing to make things seriously expensive in here. Also it's faster for meme admin explosions and mega burgers ## Why It's Good For The Game Speeds up explosives slightly, opens the door to better blast resistance projection
272 lines
8.6 KiB
Plaintext
272 lines
8.6 KiB
Plaintext
//Every time you got lost looking for keycards, incriment: 1
|
|
//**************
|
|
//*****Keys*******************
|
|
//************** ** **
|
|
/obj/item/keycard
|
|
name = "security keycard"
|
|
desc = "This feels like it belongs to a door."
|
|
icon = 'icons/obj/puzzle_small.dmi'
|
|
icon_state = "keycard"
|
|
force = 0
|
|
throwforce = 0
|
|
w_class = WEIGHT_CLASS_TINY
|
|
throw_speed = 1
|
|
throw_range = 7
|
|
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
|
var/puzzle_id = null
|
|
|
|
//Two test keys for use alongside the two test doors.
|
|
/obj/item/keycard/yellow
|
|
name = "yellow keycard"
|
|
desc = "A yellow keycard. How fantastic. Looks like it belongs to a high security door."
|
|
color = "#f0da12"
|
|
puzzle_id = "yellow"
|
|
|
|
/obj/item/keycard/blue
|
|
name = "blue keycard"
|
|
desc = "A blue keycard. How terrific. Looks like it belongs to a high security door."
|
|
color = "#3bbbdb"
|
|
puzzle_id = "blue"
|
|
|
|
//***************
|
|
//*****Doors*****
|
|
//***************
|
|
|
|
/obj/machinery/door/puzzle
|
|
name = "locked door"
|
|
desc = "This door only opens under certain conditions. It looks virtually indestructible."
|
|
icon = 'icons/obj/doors/puzzledoor/default.dmi'
|
|
icon_state = "door_closed"
|
|
explosion_block = 3
|
|
heat_proof = TRUE
|
|
max_integrity = 600
|
|
armor_type = /datum/armor/door_puzzle
|
|
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
|
move_resist = MOVE_FORCE_OVERPOWERING
|
|
damage_deflection = 70
|
|
/// Make sure that the puzzle has the same puzzle_id as the keycard door!
|
|
var/puzzle_id = null
|
|
/// Message that occurs when the door is opened
|
|
var/open_message = "The door beeps, and slides opens."
|
|
|
|
//Standard Expressions to make keycard doors basically un-cheeseable
|
|
/datum/armor/door_puzzle
|
|
melee = 100
|
|
bullet = 100
|
|
laser = 100
|
|
energy = 100
|
|
bomb = 100
|
|
bio = 100
|
|
fire = 100
|
|
acid = 100
|
|
|
|
/obj/machinery/door/puzzle/Bumped(atom/movable/AM)
|
|
return !density && ..()
|
|
|
|
/obj/machinery/door/puzzle/emp_act(severity)
|
|
return
|
|
|
|
/obj/machinery/door/puzzle/ex_act(severity, target)
|
|
return FALSE
|
|
|
|
/obj/machinery/door/puzzle/try_to_activate_door(mob/user, access_bypass = FALSE)
|
|
add_fingerprint(user)
|
|
if(operating)
|
|
return
|
|
|
|
/obj/machinery/door/puzzle/proc/try_puzzle_open(try_id)
|
|
if(puzzle_id && puzzle_id != try_id)
|
|
return FALSE
|
|
if(!density)
|
|
visible_message(span_warning("The door can't seem to be closed."))
|
|
return TRUE
|
|
if(open_message)
|
|
visible_message(span_notice(open_message))
|
|
open()
|
|
return TRUE
|
|
|
|
/obj/machinery/door/puzzle/keycard
|
|
desc = "This door only opens when a keycard is swiped. It looks virtually indestructible."
|
|
|
|
/obj/machinery/door/puzzle/keycard/attackby(obj/item/attacking_item, mob/user, params)
|
|
. = ..()
|
|
if(!istype(attacking_item, /obj/item/keycard))
|
|
return
|
|
var/obj/item/keycard/key = attacking_item
|
|
if(!try_puzzle_open(key.puzzle_id))
|
|
to_chat(user, span_notice("[src] buzzes. This must not be the right key."))
|
|
|
|
//Test doors. Gives admins a few doors to use quickly should they so choose for events.
|
|
/obj/machinery/door/puzzle/keycard/yellow_required
|
|
name = "blue airlock"
|
|
desc = "It looks like it requires a yellow keycard."
|
|
puzzle_id = "yellow"
|
|
|
|
/obj/machinery/door/puzzle/keycard/blue_required
|
|
name = "blue airlock"
|
|
desc = "It looks like it requires a blue keycard."
|
|
puzzle_id = "blue"
|
|
|
|
/obj/machinery/door/puzzle/light
|
|
desc = "This door only opens when a linked mechanism is powered. It looks virtually indestructible."
|
|
|
|
/obj/machinery/door/puzzle/light/Initialize(mapload)
|
|
. = ..()
|
|
RegisterSignal(SSdcs, COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED, PROC_REF(check_mechanism))
|
|
|
|
/obj/machinery/door/puzzle/light/proc/check_mechanism(datum/source, try_id)
|
|
SIGNAL_HANDLER
|
|
|
|
INVOKE_ASYNC(src, PROC_REF(try_puzzle_open), try_id)
|
|
|
|
//*************************
|
|
//***Box Pushing Puzzles***
|
|
//*************************
|
|
//We're working off a subtype of pressureplates, which should work just a BIT better now.
|
|
/obj/structure/holobox
|
|
name = "holobox"
|
|
desc = "A hard-light box, containing a secure decryption key."
|
|
icon = 'icons/obj/puzzle_small.dmi'
|
|
icon_state = "laserbox"
|
|
density = TRUE
|
|
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
|
|
|
//Uses the pressure_plate settings for a pretty basic custom pattern that waits for a specific item to trigger. Easy enough to retool for mapping purposes or subtypes.
|
|
/obj/item/pressure_plate/hologrid
|
|
name = "hologrid"
|
|
desc = "A high power, electronic input port for a holobox, which can unlock the hologrid's storage compartment. Safe to stand on."
|
|
icon = 'icons/obj/puzzle_small.dmi'
|
|
icon_state = "lasergrid"
|
|
anchored = TRUE
|
|
trigger_mob = FALSE
|
|
trigger_item = TRUE
|
|
specific_item = /obj/structure/holobox
|
|
removable_signaller = FALSE //Being a pressure plate subtype, this can also use signals.
|
|
roundstart_signaller_freq = FREQ_HOLOGRID_SOLUTION //Frequency is kept on it's own default channel however.
|
|
active = TRUE
|
|
trigger_delay = 10
|
|
protected = TRUE
|
|
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
|
undertile_pressureplate = FALSE
|
|
var/reward = /obj/item/food/cookie
|
|
var/claimed = FALSE
|
|
|
|
/obj/item/pressure_plate/hologrid/Initialize(mapload)
|
|
. = ..()
|
|
if(undertile_pressureplate)
|
|
AddElement(/datum/element/undertile, tile_overlay = tile_overlay, use_anchor = FALSE) //we remove use_anchor here, so it ALWAYS stays anchored
|
|
|
|
/obj/item/pressure_plate/hologrid/examine(mob/user)
|
|
. = ..()
|
|
if(claimed)
|
|
. += span_notice("This one appears to be spent already.")
|
|
|
|
/obj/item/pressure_plate/hologrid/trigger()
|
|
if(!claimed)
|
|
new reward(loc)
|
|
flick("lasergrid_a",src)
|
|
icon_state = "lasergrid_full"
|
|
claimed = TRUE
|
|
|
|
/obj/item/pressure_plate/hologrid/on_entered(datum/source, atom/movable/AM)
|
|
. = ..()
|
|
if(trigger_item && istype(AM, specific_item) && !claimed)
|
|
AM.set_anchored(TRUE)
|
|
flick("laserbox_burn", AM)
|
|
trigger()
|
|
QDEL_IN(AM, 15)
|
|
|
|
//Light puzzle
|
|
/obj/structure/light_puzzle
|
|
name = "light mechanism"
|
|
desc = "It's a mechanism that seems to power something when all the lights are lit up. It looks virtually indestructible."
|
|
icon = 'icons/obj/puzzle_small.dmi'
|
|
icon_state = "light_puzzle"
|
|
anchored = TRUE
|
|
explosion_block = 3
|
|
armor_type = /datum/armor/structure_light_puzzle
|
|
resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF
|
|
light_range = MINIMUM_USEFUL_LIGHT_RANGE
|
|
light_power = 3
|
|
light_color = LIGHT_COLOR_ORANGE
|
|
var/powered = FALSE
|
|
var/puzzle_id = null
|
|
var/list/light_list = list(
|
|
0, 0, 0,
|
|
0, 0, 0,
|
|
0, 0, 0
|
|
)
|
|
/// Banned combinations of the list in decimal
|
|
var/static/list/banned_combinations = list(-1, 47, 95, 203, 311, 325, 422, 473, 488, 500, 511)
|
|
|
|
/datum/armor/structure_light_puzzle
|
|
melee = 100
|
|
bullet = 100
|
|
laser = 100
|
|
energy = 100
|
|
bomb = 100
|
|
bio = 100
|
|
fire = 100
|
|
acid = 100
|
|
|
|
/obj/structure/light_puzzle/Initialize(mapload)
|
|
AddElement(/datum/element/blocks_explosives)
|
|
. = ..()
|
|
var/generated_board = -1
|
|
while(generated_board in banned_combinations)
|
|
generated_board = rand(0, 510)
|
|
for(var/i in 0 to 8)
|
|
var/position = !!(generated_board & (1<<i))
|
|
light_list[i+1] = position
|
|
update_icon(UPDATE_OVERLAYS)
|
|
|
|
/obj/structure/light_puzzle/update_overlays()
|
|
. = ..()
|
|
for(var/i in 1 to 9)
|
|
if(!light_list[i])
|
|
continue
|
|
var/mutable_appearance/lit_image = mutable_appearance('icons/obj/puzzle_small.dmi', "light_lit")
|
|
var/mutable_appearance/emissive_image = emissive_appearance('icons/obj/puzzle_small.dmi', "light_lit", src)
|
|
lit_image.pixel_x = 8 * ((i % 3 || 3 ) - 1)
|
|
lit_image.pixel_y = -8 * (ROUND_UP(i / 3) - 1)
|
|
emissive_image.pixel_x = lit_image.pixel_x
|
|
emissive_image.pixel_y = lit_image.pixel_y
|
|
. += lit_image
|
|
. += emissive_image
|
|
|
|
/obj/structure/light_puzzle/attack_hand(mob/living/user, list/modifiers)
|
|
if(!modifiers || powered)
|
|
return ..()
|
|
var/light_clicked
|
|
var/x_clicked = text2num(modifiers[ICON_X])
|
|
var/y_clicked = text2num(modifiers[ICON_Y])
|
|
if(x_clicked <= 4 || x_clicked >= 29 || y_clicked <= 4 || y_clicked >= 29)
|
|
return ..()
|
|
x_clicked = ROUND_UP((x_clicked - 4) / 8)
|
|
y_clicked = (-(ROUND_UP((y_clicked - 4) / 8) - 4) - 1) * 3
|
|
light_clicked = x_clicked + y_clicked
|
|
switch_light(light_clicked)
|
|
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
|
|
|
|
/obj/structure/light_puzzle/proc/switch_light(light)
|
|
var/list/updating_lights = list()
|
|
updating_lights += light
|
|
if(light % 3 != 0)
|
|
updating_lights += light + 1
|
|
if(light % 3 != 1)
|
|
updating_lights += light - 1
|
|
if(light + 3 <= 9)
|
|
updating_lights += light + 3
|
|
if(light - 3 > 0)
|
|
updating_lights += light - 3
|
|
for(var/updating_light in updating_lights)
|
|
light_list[updating_light] = !light_list[updating_light]
|
|
update_icon(UPDATE_OVERLAYS)
|
|
for(var/checking_light in light_list)
|
|
if(!checking_light)
|
|
return
|
|
visible_message(span_boldnotice("[src] becomes fully charged!"))
|
|
powered = TRUE
|
|
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED, puzzle_id)
|
|
playsound(src, 'sound/machines/synth_yes.ogg', 100, TRUE)
|