Merge branch 'master' into void-but-for-real
This commit is contained in:
+51
-8
@@ -885,6 +885,9 @@
|
||||
VV_DROPDOWN_OPTION(VV_HK_ADD_REAGENT, "Add Reagent")
|
||||
VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EMP, "EMP Pulse")
|
||||
VV_DROPDOWN_OPTION(VV_HK_TRIGGER_EXPLOSION, "Explosion")
|
||||
// VV_DROPDOWN_OPTION(VV_HK_RADIATE, "Radiate")
|
||||
VV_DROPDOWN_OPTION(VV_HK_EDIT_FILTERS, "Edit Filters")
|
||||
// VV_DROPDOWN_OPTION(VV_HK_ADD_AI, "Add AI controller")
|
||||
|
||||
/atom/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
@@ -928,6 +931,9 @@
|
||||
var/newname = input(usr, "What do you want to rename this to?", "Automatic Rename") as null|text
|
||||
if(newname)
|
||||
vv_auto_rename(newname)
|
||||
if(href_list[VV_HK_EDIT_FILTERS] && check_rights(R_VAREDIT))
|
||||
var/client/C = usr.client
|
||||
C?.open_filter_editor(src)
|
||||
|
||||
/atom/vv_get_header()
|
||||
. = ..()
|
||||
@@ -1148,7 +1154,6 @@
|
||||
|
||||
victim.log_message(message, LOG_ATTACK, color="blue")
|
||||
|
||||
// Filter stuff
|
||||
/atom/proc/add_filter(name,priority,list/params)
|
||||
LAZYINITLIST(filter_data)
|
||||
var/list/p = params.Copy()
|
||||
@@ -1164,26 +1169,64 @@
|
||||
var/list/arguments = data.Copy()
|
||||
arguments -= "priority"
|
||||
filters += filter(arglist(arguments))
|
||||
UNSETEMPTY(filter_data)
|
||||
|
||||
/atom/proc/transition_filter(name, time, list/new_params, easing, loop)
|
||||
var/filter = get_filter(name)
|
||||
if(!filter)
|
||||
return
|
||||
|
||||
var/list/old_filter_data = filter_data[name]
|
||||
|
||||
var/list/params = old_filter_data.Copy()
|
||||
for(var/thing in new_params)
|
||||
params[thing] = new_params[thing]
|
||||
|
||||
animate(filter, new_params, time = time, easing = easing, loop = loop)
|
||||
for(var/param in params)
|
||||
filter_data[name][param] = params[param]
|
||||
|
||||
/atom/proc/change_filter_priority(name, new_priority)
|
||||
if(!filter_data || !filter_data[name])
|
||||
return
|
||||
|
||||
filter_data[name]["priority"] = new_priority
|
||||
update_filters()
|
||||
|
||||
/obj/item/update_filters()
|
||||
. = ..()
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/atom/proc/get_filter(name)
|
||||
if(filter_data && filter_data[name])
|
||||
return filters[filter_data.Find(name)]
|
||||
|
||||
/atom/proc/remove_filter(name)
|
||||
if(filter_data && filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
return TRUE
|
||||
/atom/proc/remove_filter(name_or_names)
|
||||
if(!filter_data)
|
||||
return
|
||||
|
||||
var/list/names = islist(name_or_names) ? name_or_names : list(name_or_names)
|
||||
|
||||
for(var/name in names)
|
||||
if(filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
|
||||
/atom/proc/clear_filters()
|
||||
filter_data = null
|
||||
filters = null
|
||||
|
||||
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
|
||||
. |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels)
|
||||
|
||||
///Sets the custom materials for an item.
|
||||
/atom/proc/set_custom_materials(var/list/materials, multiplier = 1)
|
||||
/atom/proc/set_custom_materials(list/materials, multiplier = 1)
|
||||
if(custom_materials) //Only runs if custom materials existed at first. Should usually be the case but check anyways
|
||||
for(var/i in custom_materials)
|
||||
var/datum/material/custom_material = SSmaterials.GetMaterialRef(i)
|
||||
custom_material.on_removed(src, material_flags) //Remove the current materials
|
||||
custom_material.on_removed(src, custom_materials[i], material_flags) //Remove the current materials
|
||||
|
||||
if(!length(materials))
|
||||
custom_materials = null
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
for(var/i in 1 to 3)
|
||||
if(config_tag in saved_dynamic_rules[i])
|
||||
weight_mult -= (repeated_mode_adjust[i]/100)
|
||||
weight_mult = max(0,weight_mult)
|
||||
if(config_tag in costs)
|
||||
cost = costs[config_tag]
|
||||
if(config_tag in requirementses)
|
||||
|
||||
@@ -81,30 +81,43 @@
|
||||
|
||||
///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things
|
||||
/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report.
|
||||
//finalize_monster_hunters() Disabled for now
|
||||
if(!report)
|
||||
report = !CONFIG_GET(flag/no_intercept_report)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
|
||||
|
||||
if(prob(20)) //CIT CHANGE - adds a 20% chance for the security level to be the opposite of what it normally is
|
||||
if(prob(20)) //cit-change
|
||||
flipseclevel = TRUE
|
||||
|
||||
// if(CONFIG_GET(flag/reopen_roundstart_suicide_roles))
|
||||
// var/delay = CONFIG_GET(number/reopen_roundstart_suicide_roles_delay)
|
||||
// if(delay)
|
||||
// delay = (delay SECONDS)
|
||||
// else
|
||||
// delay = (4 MINUTES) //default to 4 minutes if the delay isn't defined.
|
||||
// addtimer(CALLBACK(GLOBAL_PROC, .proc/reopen_roundstart_suicide_roles), delay)
|
||||
|
||||
if(SSdbcore.Connect())
|
||||
var/sql
|
||||
var/list/to_set = list()
|
||||
var/arguments = list()
|
||||
if(SSticker.mode)
|
||||
sql += "game_mode = '[SSticker.mode]'"
|
||||
to_set += "game_mode = :game_mode"
|
||||
arguments["game_mode"] = SSticker.mode
|
||||
if(GLOB.revdata.originmastercommit)
|
||||
if(sql)
|
||||
sql += ", "
|
||||
sql += "commit_hash = '[GLOB.revdata.originmastercommit]'"
|
||||
if(sql)
|
||||
var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]")
|
||||
to_set += "commit_hash = :commit_hash"
|
||||
arguments["commit_hash"] = GLOB.revdata.originmastercommit
|
||||
if(to_set.len)
|
||||
arguments["round_id"] = GLOB.round_id
|
||||
var/datum/db_query/query_round_game_mode = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("round")] SET [to_set.Join(", ")] WHERE id = :round_id",
|
||||
arguments
|
||||
)
|
||||
query_round_game_mode.Execute()
|
||||
qdel(query_round_game_mode)
|
||||
if(report)
|
||||
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
|
||||
generate_station_goals()
|
||||
gamemode_ready = TRUE
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
///Handles late-join antag assignments
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#define DEFAULT_METEOR_LIFETIME 1800
|
||||
#define MAP_EDGE_PAD 5
|
||||
|
||||
GLOBAL_VAR_INIT(meteor_wave_delay, 625) //minimum wait between waves in tenths of seconds
|
||||
//set to at least 100 unless you want evarr ruining every round
|
||||
|
||||
@@ -30,7 +32,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
var/turf/pickedgoal
|
||||
var/max_i = 10//number of tries to spawn meteor.
|
||||
while(!isspaceturf(pickedstart))
|
||||
var/startSide = dir || pick(GLOB.cardinals)
|
||||
var/startSide = (dir ? dir : pick(GLOB.cardinals))
|
||||
var/startZ = pick(SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
pickedstart = spaceDebrisStartLoc(startSide, startZ)
|
||||
pickedgoal = spaceDebrisFinishLoc(startSide, startZ)
|
||||
@@ -46,17 +48,17 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
var/startx
|
||||
switch(startSide)
|
||||
if(NORTH)
|
||||
starty = world.maxy-(TRANSITIONEDGE+2)
|
||||
startx = rand((TRANSITIONEDGE+2), world.maxx-(TRANSITIONEDGE+2))
|
||||
starty = world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
if(EAST)
|
||||
starty = rand((TRANSITIONEDGE+2),world.maxy-(TRANSITIONEDGE+2))
|
||||
startx = world.maxx-(TRANSITIONEDGE+2)
|
||||
starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD),world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
startx = world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
if(SOUTH)
|
||||
starty = (TRANSITIONEDGE+2)
|
||||
startx = rand((TRANSITIONEDGE+2), world.maxx-(TRANSITIONEDGE+2))
|
||||
starty = (TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
if(WEST)
|
||||
starty = rand((TRANSITIONEDGE+2), world.maxy-(TRANSITIONEDGE+2))
|
||||
startx = (TRANSITIONEDGE+2)
|
||||
starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
startx = (TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
. = locate(startx, starty, Z)
|
||||
|
||||
/proc/spaceDebrisFinishLoc(startSide, Z)
|
||||
@@ -64,17 +66,17 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
var/endx
|
||||
switch(startSide)
|
||||
if(NORTH)
|
||||
endy = (TRANSITIONEDGE+1)
|
||||
endx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
|
||||
endy = (TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
endx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
if(EAST)
|
||||
endy = rand((TRANSITIONEDGE+1), world.maxy-(TRANSITIONEDGE+1))
|
||||
endx = (TRANSITIONEDGE+1)
|
||||
endy = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
endx = (TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
if(SOUTH)
|
||||
endy = world.maxy-(TRANSITIONEDGE+1)
|
||||
endx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
|
||||
endy = world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
endx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
if(WEST)
|
||||
endy = rand((TRANSITIONEDGE+1),world.maxy-(TRANSITIONEDGE+1))
|
||||
endx = world.maxx-(TRANSITIONEDGE+1)
|
||||
endy = rand((TRANSITIONEDGE + MAP_EDGE_PAD),world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD))
|
||||
endx = world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)
|
||||
. = locate(endx, endy, Z)
|
||||
|
||||
///////////////////////
|
||||
@@ -82,7 +84,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
//////////////////////
|
||||
|
||||
/obj/effect/meteor
|
||||
name = "the concept of meteor"
|
||||
name = "\proper the concept of meteor"
|
||||
desc = "You should probably run instead of gawking at this."
|
||||
icon = 'icons/obj/meteor.dmi'
|
||||
icon_state = "small"
|
||||
@@ -92,7 +94,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
var/hitpwr = 2 //Level of ex_act to be called on hit.
|
||||
var/dest
|
||||
pass_flags = PASSTABLE
|
||||
var/heavy = 0
|
||||
var/heavy = FALSE
|
||||
var/meteorsound = 'sound/effects/meteorimpact.ogg'
|
||||
var/z_original
|
||||
var/threat = 0 // used for determining which meteors are most interesting
|
||||
@@ -108,12 +110,12 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
|
||||
. = ..() //process movement...
|
||||
|
||||
var/turf/T = get_turf(loc)
|
||||
if(.)//.. if did move, ram the turf we get in
|
||||
var/turf/T = get_turf(loc)
|
||||
ram_turf(T)
|
||||
|
||||
if(prob(10) && !isspaceturf(T) && !istype(T, /turf/closed/mineral) && !istype(T, /turf/open/floor/plating/asteroid))//randomly takes a 'hit' from ramming
|
||||
get_hit()
|
||||
if(prob(10) && !isspaceturf(T) && !istype(T, /turf/closed/mineral) && !istype(T, /turf/open/floor/plating/asteroid))//randomly takes a 'hit' from ramming, and ignore spare ruin aseroids
|
||||
get_hit()
|
||||
|
||||
/obj/effect/meteor/Destroy()
|
||||
if (timerid)
|
||||
@@ -135,24 +137,25 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
/obj/effect/meteor/Bump(atom/A)
|
||||
if(A)
|
||||
ram_turf(get_turf(A))
|
||||
playsound(src.loc, meteorsound, 40, 1)
|
||||
if(!istype(A, /turf/closed/mineral) && !istype(A, /turf/open/floor/plating/asteroid))
|
||||
playsound(src.loc, meteorsound, 40, TRUE)
|
||||
if(!istype(A, /turf/closed/mineral) && !istype(A, /turf/open/floor/plating/asteroid)) // ignore localstation ruins
|
||||
get_hit()
|
||||
|
||||
/obj/effect/meteor/proc/ram_turf(turf/T)
|
||||
//first bust whatever is in the turf
|
||||
for(var/atom/A in T)
|
||||
if(A != src)
|
||||
if(isliving(A))
|
||||
A.visible_message("<span class='warning'>[src] slams into [A].</span>", "<span class='userdanger'>[src] slams into you!.</span>")
|
||||
A.ex_act(hitpwr)
|
||||
for(var/thing in T)
|
||||
if(thing == src)
|
||||
continue
|
||||
if(isliving(thing))
|
||||
var/mob/living/living_thing = thing
|
||||
living_thing.visible_message("<span class='warning'>[src] slams into [living_thing].</span>", "<span class='userdanger'>[src] slams into you!.</span>")
|
||||
living_thing.ex_act(hitpwr)
|
||||
|
||||
//then, ram the turf if it still exists
|
||||
if(T)
|
||||
T.ex_act(hitpwr)
|
||||
|
||||
|
||||
|
||||
//process getting 'hit' by colliding with a dense object
|
||||
//or randomly when ramming turfs
|
||||
/obj/effect/meteor/proc/get_hit()
|
||||
@@ -162,13 +165,10 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
meteor_effect()
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/meteor/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/meteor/examine(mob/user)
|
||||
. = ..()
|
||||
if(!(flags_1 & ADMIN_SPAWNED_1) && isliving(user))
|
||||
SSmedals.UnlockMedal(MEDAL_METEOR, user.client)
|
||||
return ..()
|
||||
user.client.give_award(/datum/award/achievement/misc/meteor_examine, user)
|
||||
|
||||
/obj/effect/meteor/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_MINING)
|
||||
@@ -232,7 +232,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
name = "big meteor"
|
||||
icon_state = "large"
|
||||
hits = 6
|
||||
heavy = 1
|
||||
heavy = TRUE
|
||||
dropamt = 4
|
||||
threat = 10
|
||||
|
||||
@@ -245,7 +245,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
name = "flaming meteor"
|
||||
icon_state = "flaming"
|
||||
hits = 5
|
||||
heavy = 1
|
||||
heavy = TRUE
|
||||
meteorsound = 'sound/effects/bamf.ogg'
|
||||
meteordrop = list(/obj/item/stack/ore/plasma)
|
||||
threat = 20
|
||||
@@ -258,7 +258,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
/obj/effect/meteor/irradiated
|
||||
name = "glowing meteor"
|
||||
icon_state = "glowing"
|
||||
heavy = 1
|
||||
heavy = TRUE
|
||||
meteordrop = list(/obj/item/stack/ore/uranium)
|
||||
threat = 15
|
||||
|
||||
@@ -275,7 +275,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
icon_state = "meateor"
|
||||
desc = "Just... don't think too hard about where this thing came from."
|
||||
hits = 2
|
||||
heavy = 1
|
||||
heavy = TRUE
|
||||
meteorsound = 'sound/effects/blobattack.ogg'
|
||||
meteordrop = list(/obj/item/reagent_containers/food/snacks/meat/slab/human, /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant, /obj/item/organ/heart, /obj/item/organ/lungs, /obj/item/organ/tongue, /obj/item/organ/appendix/)
|
||||
var/meteorgibs = /obj/effect/gibspawner/generic
|
||||
@@ -327,7 +327,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
desc = "Your life briefly passes before your eyes the moment you lay them on this monstrosity."
|
||||
hits = 30
|
||||
hitpwr = 1
|
||||
heavy = 1
|
||||
heavy = TRUE
|
||||
meteorsound = 'sound/effects/bamf.ogg'
|
||||
meteordrop = list(/obj/item/stack/ore/plasma)
|
||||
threat = 50
|
||||
@@ -358,7 +358,7 @@ GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin))
|
||||
icon = 'icons/obj/meteor_spooky.dmi'
|
||||
icon_state = "pumpkin"
|
||||
hits = 10
|
||||
heavy = 1
|
||||
heavy = TRUE
|
||||
dropamt = 1
|
||||
meteordrop = list(/obj/item/clothing/head/hardhat/pumpkinhead, /obj/item/reagent_containers/food/snacks/grown/pumpkin)
|
||||
threat = 100
|
||||
@@ -368,3 +368,4 @@ GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin))
|
||||
meteorsound = pick('sound/hallucinations/im_here1.ogg','sound/hallucinations/im_here2.ogg')
|
||||
//////////////////////////
|
||||
#undef DEFAULT_METEOR_LIFETIME
|
||||
#undef MAP_EDGE_PAD
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define AUTOLATHE_MAIN_MENU 1
|
||||
#define AUTOLATHE_CATEGORY_MENU 2
|
||||
#define AUTOLATHE_SEARCH_MENU 3
|
||||
#define AUTOLATHE_MAIN_MENU 1
|
||||
#define AUTOLATHE_CATEGORY_MENU 2
|
||||
#define AUTOLATHE_SEARCH_MENU 3
|
||||
|
||||
/obj/machinery/autolathe
|
||||
name = "autolathe"
|
||||
@@ -17,7 +17,7 @@
|
||||
var/list/L = list()
|
||||
var/list/LL = list()
|
||||
var/hacked = FALSE
|
||||
var/disabled = 0
|
||||
var/disabled = FALSE
|
||||
var/shocked = FALSE
|
||||
var/hack_wire
|
||||
var/disable_wire
|
||||
@@ -27,13 +27,13 @@
|
||||
var/prod_coeff = 1
|
||||
|
||||
var/datum/design/being_built
|
||||
var/datum/techweb/stored_research
|
||||
var/list/datum/design/matching_designs
|
||||
var/selected_category
|
||||
var/screen = 1
|
||||
var/base_price = 25
|
||||
var/hacked_price = 50
|
||||
|
||||
var/datum/techweb/specialized/autounlocking/stored_research = /datum/techweb/specialized/autounlocking/autolathe
|
||||
var/list/categories = list(
|
||||
"Tools",
|
||||
"Electronics",
|
||||
@@ -46,19 +46,13 @@
|
||||
"Dinnerware",
|
||||
"Imported"
|
||||
)
|
||||
var/list/allowed_materials
|
||||
|
||||
/// Base print speed
|
||||
var/base_print_speed = 10
|
||||
|
||||
/obj/machinery/autolathe/Initialize()
|
||||
var/list/mats = allowed_materials
|
||||
if(!mats)
|
||||
mats = SSmaterials.materialtypes_by_category[MAT_CATEGORY_RIGID]
|
||||
AddComponent(/datum/component/material_container, mats, _show_on_examine=TRUE, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
AddComponent(/datum/component/material_container, SSmaterials.materialtypes_by_category[MAT_CATEGORY_RIGID], 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
|
||||
. = ..()
|
||||
|
||||
wires = new /datum/wires/autolathe(src)
|
||||
stored_research = new stored_research
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/autolathe
|
||||
matching_designs = list()
|
||||
|
||||
/obj/machinery/autolathe/Destroy()
|
||||
@@ -83,7 +77,7 @@
|
||||
if(AUTOLATHE_SEARCH_MENU)
|
||||
dat = search_win(user)
|
||||
|
||||
var/datum/browser/popup = new(user, name, name, 400, 500)
|
||||
var/datum/browser/popup = new(user, "autolathe", name, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
@@ -114,9 +108,9 @@
|
||||
return TRUE
|
||||
|
||||
if(istype(O, /obj/item/disk/design_disk))
|
||||
user.visible_message("[user] begins to load \the [O] in \the [src]...",
|
||||
"You begin to load a design from \the [O]...",
|
||||
"You hear the chatter of a floppy drive.")
|
||||
user.visible_message("<span class='notice'>[user] begins to load \the [O] in \the [src]...</span>",
|
||||
"<span class='notice'>You begin to load a design from \the [O]...</span>",
|
||||
"<span class='hear'>You hear the chatter of a floppy drive.</span>")
|
||||
busy = TRUE
|
||||
var/obj/item/disk/design_disk/D = O
|
||||
if(do_after(user, 14.4, target = src))
|
||||
@@ -128,14 +122,16 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
|
||||
|
||||
/obj/machinery/autolathe/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
|
||||
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
use_power(MINERAL_MATERIAL_AMOUNT / 10)
|
||||
else if(item_inserted.custom_materials?.len && item_inserted.custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)])
|
||||
else if(custom_materials && custom_materials.len && custom_materials[SSmaterials.GetMaterialRef(/datum/material/glass)])
|
||||
flick("autolathe_r",src)//plays glass insertion animation by default otherwise
|
||||
else
|
||||
flick("autolathe_o",src)//plays metal insertion animation
|
||||
|
||||
|
||||
use_power(min(1000, amount_inserted / 100))
|
||||
updateUsrDialog()
|
||||
|
||||
@@ -187,7 +183,7 @@
|
||||
if(materials.materials[i] > 0)
|
||||
list_to_show += i
|
||||
|
||||
used_material = input("Choose [used_material]", "Custom Material") as null|anything in list_to_show
|
||||
used_material = input("Choose [used_material]", "Custom Material") as null|anything in sortList(list_to_show, /proc/cmp_typepaths_asc)
|
||||
if(!used_material)
|
||||
return //Didn't pick any material, so you can't build shit either.
|
||||
custom_materials[used_material] += amount_needed
|
||||
@@ -198,8 +194,8 @@
|
||||
busy = TRUE
|
||||
use_power(power)
|
||||
icon_state = "autolathe_n"
|
||||
var/time = is_stack ? 10 : base_print_speed * coeff * multiplier
|
||||
addtimer(CALLBACK(src, .proc/make_item, power, materials_used, custom_materials, multiplier, coeff, is_stack), time)
|
||||
var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
|
||||
addtimer(CALLBACK(src, .proc/make_item, power, materials_used, custom_materials, multiplier, coeff, is_stack, usr), time)
|
||||
else
|
||||
to_chat(usr, "<span class=\"alert\">Not enough materials for this operation.</span>")
|
||||
|
||||
@@ -218,10 +214,11 @@
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/autolathe/proc/make_item(power, var/list/materials_used, var/list/picked_materials, multiplier, coeff, is_stack)
|
||||
/obj/machinery/autolathe/proc/make_item(power, list/materials_used, list/picked_materials, multiplier, coeff, is_stack, mob/user)
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/atom/A = drop_location()
|
||||
use_power(power)
|
||||
|
||||
materials.use_materials(materials_used)
|
||||
|
||||
if(is_stack)
|
||||
@@ -235,6 +232,11 @@
|
||||
|
||||
if(length(picked_materials))
|
||||
new_item.set_custom_materials(picked_materials, 1 / multiplier) //Ensure we get the non multiplied amount
|
||||
for(var/x in picked_materials)
|
||||
var/datum/material/M = x
|
||||
if(!istype(M, /datum/material/glass) && !istype(M, /datum/material/iron))
|
||||
user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user)
|
||||
|
||||
|
||||
icon_state = "autolathe"
|
||||
busy = FALSE
|
||||
@@ -246,12 +248,10 @@
|
||||
T += MB.rating*75000
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.max_amount = T
|
||||
var/manips = 0
|
||||
var/total_manip_rating = 0
|
||||
T=1.2
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
total_manip_rating += M.rating
|
||||
manips++
|
||||
prod_coeff = STANDARD_PART_LEVEL_LATHE_COEFFICIENT(total_manip_rating / (manips? manips : 1))
|
||||
T -= M.rating*0.2
|
||||
prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
|
||||
|
||||
/obj/machinery/autolathe/examine(mob/user)
|
||||
. += ..()
|
||||
@@ -376,6 +376,7 @@
|
||||
|
||||
return materials.has_materials(required_materials)
|
||||
|
||||
|
||||
/obj/machinery/autolathe/proc/get_design_cost(datum/design/D)
|
||||
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
|
||||
var/dat
|
||||
@@ -416,9 +417,7 @@
|
||||
hacked = state
|
||||
for(var/id in SSresearch.techweb_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
if(D.build_type & stored_research.design_autounlock_skip_types)
|
||||
continue
|
||||
if((D.build_type & stored_research.design_autounlock_buildtypes) && ("hacked" in D.category))
|
||||
if((D.build_type & AUTOLATHE) && ("hacked" in D.category))
|
||||
if(hacked)
|
||||
stored_research.add_design(D)
|
||||
else
|
||||
@@ -428,19 +427,24 @@
|
||||
. = ..()
|
||||
adjust_hacked(TRUE)
|
||||
|
||||
//Called when the object is constructed by an autolathe
|
||||
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
|
||||
/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A)
|
||||
return
|
||||
|
||||
/obj/machinery/autolathe/secure
|
||||
name = "secured autolathe"
|
||||
desc = "It produces items using metal and glass. This model was reprogrammed without some of the more hazardous designs."
|
||||
circuit = /obj/item/circuitboard/machine/autolathe/secure
|
||||
stored_research = /datum/techweb/specialized/autounlocking/autolathe/public
|
||||
base_print_speed = 20
|
||||
|
||||
/obj/machinery/autolathe/secure/Initialize()
|
||||
. = ..()
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/autolathe/public
|
||||
|
||||
/obj/machinery/autolathe/toy
|
||||
name = "autoylathe"
|
||||
desc = "It produces toys using plastic, metal and glass."
|
||||
circuit = /obj/item/circuitboard/machine/autolathe/toy
|
||||
|
||||
stored_research = /datum/techweb/specialized/autounlocking/autolathe/toy
|
||||
categories = list(
|
||||
"Toys",
|
||||
"Figurines",
|
||||
@@ -453,12 +457,8 @@
|
||||
"Misc",
|
||||
"Imported"
|
||||
)
|
||||
allowed_materials = list(
|
||||
/datum/material/iron,
|
||||
/datum/material/glass,
|
||||
/datum/material/plastic
|
||||
)
|
||||
|
||||
/obj/machinery/autolathe/toy/hacked/Initialize()
|
||||
. = ..()
|
||||
adjust_hacked(TRUE)
|
||||
stored_research = new /datum/techweb/specialized/autounlocking/autolathe/toy
|
||||
|
||||
@@ -44,7 +44,8 @@
|
||||
icon_state = "colormate"
|
||||
|
||||
/obj/machinery/gear_painter/Destroy()
|
||||
inserted.forceMove(drop_location())
|
||||
if(inserted) //please i beg you do not drop nulls
|
||||
inserted.forceMove(drop_location())
|
||||
return ..()
|
||||
|
||||
/obj/machinery/gear_painter/attackby(obj/item/I, mob/living/user)
|
||||
|
||||
@@ -3,14 +3,7 @@
|
||||
#define ARCADE_WEIGHT_RARE 1
|
||||
#define ARCADE_RATIO_PLUSH 0.20 // average 1 out of 6 wins is a plush.
|
||||
|
||||
/obj/machinery/computer/arcade
|
||||
name = "random arcade"
|
||||
desc = "random arcade machine"
|
||||
icon_state = "arcade"
|
||||
icon_keyboard = null
|
||||
icon_screen = "invaders"
|
||||
clockwork = TRUE //it'd look weird
|
||||
var/list/prizes = list(
|
||||
GLOBAL_LIST_INIT(arcade_prize_pool, list(
|
||||
/obj/item/toy/balloon = ARCADE_WEIGHT_USELESS,
|
||||
/obj/item/toy/beach_ball = ARCADE_WEIGHT_USELESS,
|
||||
/obj/item/toy/cattoy = ARCADE_WEIGHT_USELESS,
|
||||
@@ -70,9 +63,16 @@
|
||||
/obj/item/clothing/mask/fakemoustache/italian = ARCADE_WEIGHT_RARE,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/ratvar/fake = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/narsie/fake = ARCADE_WEIGHT_TRICK
|
||||
)
|
||||
))
|
||||
|
||||
/obj/machinery/computer/arcade
|
||||
name = "random arcade"
|
||||
desc = "random arcade machine"
|
||||
icon_state = "arcade"
|
||||
icon_keyboard = "no_keyboard"
|
||||
icon_screen = "invaders"
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
var/list/prize_override
|
||||
|
||||
/obj/machinery/computer/arcade/proc/Reset()
|
||||
return
|
||||
@@ -91,44 +91,54 @@
|
||||
var/obj/machinery/computer/arcade/A = new CB.build_path(loc, CB)
|
||||
A.setDir(dir)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
//The below object acts as a spawner with a wide array of possible picks, most being uninspired references to past/current player characters.
|
||||
//Nevertheless, this keeps its ratio constant with the sum of all the others prizes.
|
||||
prizes[/obj/item/toy/plush/random] = counterlist_sum(prizes) * ARCADE_RATIO_PLUSH
|
||||
|
||||
Reset()
|
||||
|
||||
/obj/machinery/computer/arcade/proc/prizevend(mob/user, list/rarity_classes)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "arcade", /datum/mood_event/arcade)
|
||||
/obj/machinery/computer/arcade/proc/prizevend(mob/user, prizes = 1)
|
||||
// if(user.mind?.get_skill_level(/datum/skill/gaming) >= SKILL_LEVEL_LEGENDARY && HAS_TRAIT(user, TRAIT_GAMERGOD))
|
||||
// visible_message("<span class='notice'>[user] inputs an intense cheat code!</span>",
|
||||
// "<span class='notice'>You hear a flurry of buttons being pressed.</span>")
|
||||
// say("CODE ACTIVATED: EXTRA PRIZES.")
|
||||
// prizes *= 2
|
||||
for(var/i = 0, i < prizes, i++)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "arcade", /datum/mood_event/arcade)
|
||||
if(prob(0.0001)) //1 in a million
|
||||
new /obj/item/gun/energy/pulse/prize(src)
|
||||
visible_message("<span class='notice'>[src] dispenses.. woah, a gun! Way past cool.</span>", "<span class='notice'>You hear a chime and a shot.</span>")
|
||||
user.client.give_award(/datum/award/achievement/misc/pulse, user)
|
||||
return
|
||||
|
||||
if(prob(1) && prob(1) && prob(1)) //Proper 1 in a million
|
||||
new /obj/item/gun/energy/pulse/prize(src)
|
||||
SSmedals.UnlockMedal(MEDAL_PULSE, usr.client)
|
||||
var/prizeselect
|
||||
if(prize_override)
|
||||
prizeselect = pickweight(prize_override)
|
||||
else
|
||||
prizeselect = pickweight(GLOB.arcade_prize_pool)
|
||||
var/atom/movable/the_prize = new prizeselect(get_turf(src))
|
||||
playsound(src, 'sound/machines/machine_vend.ogg', 50, TRUE, extrarange = -3)
|
||||
visible_message("<span class='notice'>[src] dispenses [the_prize]!</span>", "<span class='notice'>You hear a chime and a clunk.</span>")
|
||||
|
||||
if(!contents.len)
|
||||
var/list/toy_raffle
|
||||
if(rarity_classes)
|
||||
for(var/A in prizes)
|
||||
if(prizes[A] in rarity_classes)
|
||||
LAZYSET(toy_raffle, A, prizes[A])
|
||||
if(!toy_raffle)
|
||||
toy_raffle = prizes
|
||||
var/prizeselect = pickweight(toy_raffle)
|
||||
new prizeselect(src)
|
||||
|
||||
var/atom/movable/prize = pick(contents)
|
||||
visible_message("<span class='notice'>[src] dispenses [prize]!</span>", "<span class='notice'>You hear a chime and a clunk.</span>")
|
||||
|
||||
prize.forceMove(get_turf(src))
|
||||
|
||||
/obj/machinery/computer/arcade/emp_act(severity)
|
||||
. = ..()
|
||||
var/override = FALSE
|
||||
if(prize_override)
|
||||
override = TRUE
|
||||
|
||||
if(stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF)
|
||||
return
|
||||
|
||||
var/empprize = null
|
||||
var/num_of_prizes = rand(round(severity/50),round(severity/100))
|
||||
var/num_of_prizes = 0
|
||||
switch(severity)
|
||||
if(1)
|
||||
num_of_prizes = rand(1,4)
|
||||
if(2)
|
||||
num_of_prizes = rand(0,2)
|
||||
for(var/i = num_of_prizes; i > 0; i--)
|
||||
empprize = pickweight(prizes)
|
||||
if(override)
|
||||
empprize = pickweight(prize_override)
|
||||
else
|
||||
empprize = pickweight(GLOB.arcade_prize_pool)
|
||||
new empprize(loc)
|
||||
explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes)
|
||||
|
||||
|
||||
@@ -1,130 +1,399 @@
|
||||
// ** BATTLE ** //
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/battle
|
||||
name = "arcade machine"
|
||||
desc = "Does not support Pinball."
|
||||
icon_state = "arcade"
|
||||
circuit = /obj/item/circuitboard/computer/arcade/battle
|
||||
var/enemy_name = "Space Villain"
|
||||
var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc
|
||||
var/player_hp = 30 //Player health/attack points
|
||||
var/player_mp = 10
|
||||
var/enemy_hp = 45 //Enemy health/attack points
|
||||
var/enemy_mp = 20
|
||||
var/gameover = FALSE
|
||||
var/blocked = FALSE //Player cannot attack/heal while set
|
||||
var/turtle = 0
|
||||
|
||||
var/turn_speed = 5 //Measured in deciseconds.
|
||||
var/enemy_name = "Space Villain"
|
||||
///Enemy health/attack points
|
||||
var/enemy_hp = 100
|
||||
var/enemy_mp = 40
|
||||
///Temporary message, for attack messages, etc
|
||||
var/temp = "<br><center><h3>Winners don't use space drugs<center><h3>"
|
||||
///the list of passive skill the enemy currently has. the actual passives are added in the enemy_setup() proc
|
||||
var/list/enemy_passive
|
||||
///if all the enemy's weakpoints have been triggered becomes TRUE
|
||||
var/finishing_move = FALSE
|
||||
///linked to passives, when it's equal or above the max_passive finishing move will become TRUE
|
||||
var/pissed_off = 0
|
||||
///the number of passives the enemy will start with
|
||||
var/max_passive = 3
|
||||
///weapon wielded by the enemy, the shotgun doesn't count.
|
||||
var/chosen_weapon
|
||||
|
||||
///Player health
|
||||
var/player_hp = 85
|
||||
///player magic points
|
||||
var/player_mp = 20
|
||||
///used to remember the last three move of the player before this turn.
|
||||
var/list/last_three_move
|
||||
///if the enemy or player died. restart the game when TRUE
|
||||
var/gameover = FALSE
|
||||
///the player cannot make any move while this is set to TRUE. should only TRUE during enemy turns.
|
||||
var/blocked = FALSE
|
||||
///used to clear the enemy_action proc timer when the game is restarted
|
||||
var/timer_id
|
||||
///weapon used by the enemy, pure fluff.for certain actions
|
||||
var/list/weapons
|
||||
///unique to the emag mode, acts as a time limit where the player dies when it reaches 0.
|
||||
var/bomb_cooldown = 19
|
||||
|
||||
///creates the enemy base stats for a new round along with the enemy passives
|
||||
/obj/machinery/computer/arcade/battle/proc/enemy_setup(player_skill)
|
||||
player_hp = 85
|
||||
player_mp = 20
|
||||
enemy_hp = 100
|
||||
enemy_mp = 40
|
||||
gameover = FALSE
|
||||
blocked = FALSE
|
||||
finishing_move = FALSE
|
||||
pissed_off = 0
|
||||
last_three_move = null
|
||||
|
||||
enemy_passive = list("short_temper" = TRUE, "poisonous" = TRUE, "smart" = TRUE, "shotgun" = TRUE, "magical" = TRUE, "chonker" = TRUE)
|
||||
for(var/i = LAZYLEN(enemy_passive); i > max_passive; i--) //we'll remove passives from the list until we have the number of passive we want
|
||||
var/picked_passive = pick(enemy_passive)
|
||||
LAZYREMOVE(enemy_passive, picked_passive)
|
||||
|
||||
if(LAZYACCESS(enemy_passive, "chonker"))
|
||||
enemy_hp += 20
|
||||
|
||||
if(LAZYACCESS(enemy_passive, "shotgun"))
|
||||
chosen_weapon = "shotgun"
|
||||
else if(weapons)
|
||||
chosen_weapon = pick(weapons)
|
||||
else
|
||||
chosen_weapon = "null gun" //if the weapons list is somehow empty, shouldn't happen but runtimes are sneaky bastards.
|
||||
|
||||
if(player_skill)
|
||||
player_hp += player_skill * 2
|
||||
|
||||
/obj/machinery/computer/arcade/battle/Reset()
|
||||
max_passive = 3
|
||||
var/name_action
|
||||
var/name_part1
|
||||
var/name_part2
|
||||
|
||||
name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ")
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
name_action = pick_list(ARCADE_FILE, "rpg_action_halloween")
|
||||
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_halloween")
|
||||
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_halloween")
|
||||
weapons = strings(ARCADE_FILE, "rpg_weapon_halloween")
|
||||
else if(SSevents.holidays && SSevents.holidays[CHRISTMAS])
|
||||
name_action = pick_list(ARCADE_FILE, "rpg_action_xmas")
|
||||
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_xmas")
|
||||
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_xmas")
|
||||
weapons = strings(ARCADE_FILE, "rpg_weapon_xmas")
|
||||
else if(SSevents.holidays && SSevents.holidays[VALENTINES])
|
||||
name_action = pick_list(ARCADE_FILE, "rpg_action_valentines")
|
||||
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective_valentines")
|
||||
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy_valentines")
|
||||
weapons = strings(ARCADE_FILE, "rpg_weapon_valentines")
|
||||
else
|
||||
name_action = pick_list(ARCADE_FILE, "rpg_action")
|
||||
name_part1 = pick_list(ARCADE_FILE, "rpg_adjective")
|
||||
name_part2 = pick_list(ARCADE_FILE, "rpg_enemy")
|
||||
weapons = strings(ARCADE_FILE, "rpg_weapon")
|
||||
|
||||
name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ")
|
||||
name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers")
|
||||
enemy_name = ("The " + name_part1 + " " + name_part2)
|
||||
name = (name_action + " " + enemy_name)
|
||||
|
||||
enemy_name = replacetext((name_part1 + name_part2), "the ", "")
|
||||
name = (name_action + name_part1 + name_part2)
|
||||
enemy_setup(0) //in the case it's reset we assume the player skill is 0 because the VOID isn't a gamer
|
||||
|
||||
/obj/machinery/computer/arcade/battle/ui_interact(mob/user)
|
||||
. = ..()
|
||||
screen_setup(user)
|
||||
|
||||
///sets up the main screen for the user
|
||||
/obj/machinery/computer/arcade/battle/proc/screen_setup(mob/user)
|
||||
var/dat = "<a href='byond://?src=[REF(src)];close=1'>Close</a>"
|
||||
dat += "<center><h4>[enemy_name]</h4></center>"
|
||||
|
||||
dat += "<br><center><h3>[temp]</h3></center>"
|
||||
dat += "[temp]"
|
||||
dat += "<br><center>Health: [player_hp] | Magic: [player_mp] | Enemy Health: [enemy_hp]</center>"
|
||||
|
||||
if (gameover)
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];newgame=1'>New Game</a>"
|
||||
else
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];attack=1'>Attack</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];heal=1'>Heal</a> | "
|
||||
dat += "<a href='byond://?src=[REF(src)];charge=1'>Recharge Power</a>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];attack=1'>Light attack</a>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];defend=1'>Defend</a>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];counter_attack=1'>Counter attack</a>"
|
||||
dat += "<center><b><a href='byond://?src=[REF(src)];power_attack=1'>Power attack</a>"
|
||||
|
||||
dat += "</b></center>"
|
||||
var/datum/browser/popup = new(user, "arcade", "Space Villain 2000")
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
if(user.client) //mainly here to avoid a runtime when the player gets gibbed when losing the emag mode.
|
||||
var/datum/browser/popup = new(user, "arcade", "Space Villain 2000")
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/arcade/battle/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/gamerSkill = 0
|
||||
// if(usr?.mind)
|
||||
// gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming)
|
||||
|
||||
if (!blocked && !gameover)
|
||||
var/attackamt = rand(5,7) + rand(0, gamerSkill)
|
||||
|
||||
if(finishing_move) //time to bonk that fucker,cuban pete will sometime survive a finishing move.
|
||||
attackamt *= 100
|
||||
|
||||
//light attack suck absolute ass but it doesn't cost any MP so it's pretty good to finish an enemy off
|
||||
if (href_list["attack"])
|
||||
blocked = TRUE
|
||||
var/attackamt = rand(2,6)
|
||||
temp = "You attack for [attackamt] damage!"
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
updateUsrDialog()
|
||||
if(turtle > 0)
|
||||
turtle--
|
||||
|
||||
sleep(turn_speed)
|
||||
temp = "<br><center><h3>you do quick jab for [attackamt] of damage!</h3></center>"
|
||||
enemy_hp -= attackamt
|
||||
arcade_action(usr)
|
||||
arcade_action(usr,"attack",attackamt)
|
||||
|
||||
else if (href_list["heal"])
|
||||
blocked = TRUE
|
||||
var/pointamt = rand(1,3)
|
||||
var/healamt = rand(6,8)
|
||||
temp = "You use [pointamt] magic to heal for [healamt] damage!"
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
updateUsrDialog()
|
||||
turtle++
|
||||
//defend lets you gain back MP and take less damage from non magical attack.
|
||||
else if(href_list["defend"])
|
||||
temp = "<br><center><h3>you take a defensive stance and gain back 10 mp!</h3></center>"
|
||||
player_mp += 10
|
||||
arcade_action(usr,"defend",attackamt)
|
||||
playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3)
|
||||
|
||||
sleep(turn_speed)
|
||||
player_mp -= pointamt
|
||||
player_hp += healamt
|
||||
blocked = TRUE
|
||||
updateUsrDialog()
|
||||
arcade_action(usr)
|
||||
//mainly used to counter short temper and their absurd damage, will deal twice the damage the player took of a non magical attack.
|
||||
else if(href_list["counter_attack"] && player_mp >= 10)
|
||||
temp = "<br><center><h3>you prepare yourself to counter the next attack!</h3></center>"
|
||||
player_mp -= 10
|
||||
arcade_action(usr,"counter_attack",attackamt)
|
||||
playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3)
|
||||
|
||||
else if (href_list["charge"])
|
||||
blocked = TRUE
|
||||
var/chargeamt = rand(4,7)
|
||||
temp = "You regain [chargeamt] points"
|
||||
playsound(loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3)
|
||||
player_mp += chargeamt
|
||||
if(turtle > 0)
|
||||
turtle--
|
||||
else if(href_list["counter_attack"] && player_mp < 10)
|
||||
temp = "<br><center><h3>you don't have the mp necessary to counter attack and defend yourself instead</h3></center>"
|
||||
player_mp += 10
|
||||
arcade_action(usr,"defend",attackamt)
|
||||
playsound(src, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3)
|
||||
|
||||
updateUsrDialog()
|
||||
sleep(turn_speed)
|
||||
arcade_action(usr)
|
||||
//power attack deals twice the amount of damage but is really expensive MP wise, mainly used with combos to get weakpoints.
|
||||
else if (href_list["power_attack"] && player_mp >= 20)
|
||||
temp = "<br><center><h3>You attack [enemy_name] with all your might for [attackamt * 2] damage!</h3></center>"
|
||||
enemy_hp -= attackamt * 2
|
||||
player_mp -= 20
|
||||
arcade_action(usr,"power_attack",attackamt)
|
||||
|
||||
else if(href_list["power_attack"] && player_mp < 20)
|
||||
temp = "<br><center><h3>You don't have the mp necessary for a power attack and settle for a light attack!</h3></center>"
|
||||
enemy_hp -= attackamt
|
||||
arcade_action(usr,"attack",attackamt)
|
||||
|
||||
if (href_list["close"])
|
||||
usr.unset_machine()
|
||||
usr << browse(null, "window=arcade")
|
||||
|
||||
else if (href_list["newgame"]) //Reset everything
|
||||
temp = "New Round"
|
||||
player_hp = initial(player_hp)
|
||||
player_mp = initial(player_mp)
|
||||
enemy_hp = initial(enemy_hp)
|
||||
enemy_mp = initial(enemy_mp)
|
||||
gameover = FALSE
|
||||
turtle = 0
|
||||
temp = "<br><center><h3>New Round<center><h3>"
|
||||
|
||||
if(obj_flags & EMAGGED)
|
||||
Reset()
|
||||
obj_flags &= ~EMAGGED
|
||||
|
||||
enemy_setup(gamerSkill)
|
||||
screen_setup(usr)
|
||||
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user)
|
||||
if ((enemy_mp <= 0) || (enemy_hp <= 0))
|
||||
///happens after a player action and before the enemy turn. the enemy turn will be cancelled if there's a gameover.
|
||||
/obj/machinery/computer/arcade/battle/proc/arcade_action(mob/user,player_stance,attackamt)
|
||||
screen_setup(user)
|
||||
blocked = TRUE
|
||||
if(player_stance == "attack" || player_stance == "power_attack")
|
||||
if(attackamt > 40)
|
||||
playsound(src, 'sound/arcade/boom.ogg', 50, TRUE, extrarange = -3)
|
||||
else
|
||||
playsound(src, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
|
||||
timer_id = addtimer(CALLBACK(src, .proc/enemy_action,player_stance,user),1 SECONDS,TIMER_STOPPABLE)
|
||||
gameover_check(user)
|
||||
|
||||
///the enemy turn, the enemy's action entirely depend on their current passive and a teensy tiny bit of randomness
|
||||
/obj/machinery/computer/arcade/battle/proc/enemy_action(player_stance,mob/user)
|
||||
var/list/list_temp = list()
|
||||
|
||||
switch(LAZYLEN(last_three_move)) //we keep the last three action of the player in a list here
|
||||
if(0 to 2)
|
||||
LAZYADD(last_three_move, player_stance)
|
||||
if(3)
|
||||
for(var/i in 1 to 2)
|
||||
last_three_move[i] = last_three_move[i + 1]
|
||||
last_three_move[3] = player_stance
|
||||
|
||||
if(4 to INFINITY)
|
||||
last_three_move = null //this shouldn't even happen but we empty the list if it somehow goes above 3
|
||||
|
||||
var/enemy_stance
|
||||
var/attack_amount = rand(8,10) //making the attack amount not vary too much so that it's easier to see if the enemy has a shotgun
|
||||
|
||||
if(player_stance == "defend")
|
||||
attack_amount -= 5
|
||||
|
||||
//if emagged, cuban pete will set up a bomb acting up as a timer. when it reaches 0 the player fucking dies
|
||||
if(obj_flags & EMAGGED)
|
||||
switch(bomb_cooldown--)
|
||||
if(18)
|
||||
list_temp += "<br><center><h3>[enemy_name] takes two valve tank and links them together, what's he planning?<center><h3>"
|
||||
if(15)
|
||||
list_temp += "<br><center><h3>[enemy_name] adds a remote control to the tan- ho god is that a bomb?<center><h3>"
|
||||
if(12)
|
||||
list_temp += "<br><center><h3>[enemy_name] throws the bomb next to you, you'r too scared to pick it up. <center><h3>"
|
||||
if(6)
|
||||
list_temp += "<br><center><h3>[enemy_name]'s hand brushes the remote linked to the bomb, your heart skipped a beat. <center><h3>"
|
||||
if(2)
|
||||
list_temp += "<br><center><h3>[enemy_name] is going to press the button! It's now or never! <center><h3>"
|
||||
if(0)
|
||||
player_hp -= attack_amount * 1000 //hey it's a maxcap we might as well go all in
|
||||
|
||||
//yeah I used the shotgun as a passive, you know why? because the shotgun gives +5 attack which is pretty good
|
||||
if(LAZYACCESS(enemy_passive, "shotgun"))
|
||||
if(weakpoint_check("shotgun","defend","defend","power_attack"))
|
||||
list_temp += "<br><center><h3>You manage to disarm [enemy_name] with a surprise power attack and shoot him with his shotgun until it runs out of ammo! <center><h3> "
|
||||
enemy_hp -= 10
|
||||
chosen_weapon = "empty shotgun"
|
||||
else
|
||||
attack_amount += 5
|
||||
|
||||
//heccing chonker passive, only gives more HP at the start of a new game but has one of the hardest weakpoint to trigger.
|
||||
if(LAZYACCESS(enemy_passive, "chonker"))
|
||||
if(weakpoint_check("chonker","power_attack","power_attack","power_attack"))
|
||||
list_temp += "<br><center><h3>After a lot of power attacks you manage to tip over [enemy_name] as they fall over their enormous weight<center><h3> "
|
||||
enemy_hp -= 30
|
||||
|
||||
//smart passive trait, mainly works in tandem with other traits, makes the enemy unable to be counter_attacked
|
||||
if(LAZYACCESS(enemy_passive, "smart"))
|
||||
if(weakpoint_check("smart","defend","defend","attack"))
|
||||
list_temp += "<br><center><h3>[enemy_name] is confused by your illogical strategy!<center><h3> "
|
||||
attack_amount -= 5
|
||||
|
||||
else if(attack_amount >= player_hp)
|
||||
player_hp -= attack_amount
|
||||
list_temp += "<br><center><h3>[enemy_name] figures out you are really close to death and finishes you off with their [chosen_weapon]!<center><h3>"
|
||||
enemy_stance = "attack"
|
||||
|
||||
else if(player_stance == "counter_attack")
|
||||
list_temp += "<br><center><h3>[enemy_name] is not taking your bait. <center><h3> "
|
||||
if(LAZYACCESS(enemy_passive, "short_temper"))
|
||||
list_temp += "However controlling their hatred of you still takes a toll on their mental and physical health!"
|
||||
enemy_hp -= 5
|
||||
enemy_mp -= 5
|
||||
enemy_stance = "defensive"
|
||||
|
||||
//short temper passive trait, gets easily baited into being counter attacked but will bypass your counter when low on HP
|
||||
if(LAZYACCESS(enemy_passive, "short_temper"))
|
||||
if(weakpoint_check("short_temper","counter_attack","counter_attack","counter_attack"))
|
||||
list_temp += "<br><center><h3>[enemy_name] is getting frustrated at all your counter attacks and throws a tantrum!<center><h3>"
|
||||
enemy_hp -= attack_amount
|
||||
|
||||
else if(player_stance == "counter_attack")
|
||||
if(!(LAZYACCESS(enemy_passive, "smart")) && enemy_hp > 30)
|
||||
list_temp += "<br><center><h3>[enemy_name] took the bait and allowed you to counter attack for [attack_amount * 2] damage!<center><h3>"
|
||||
player_hp -= attack_amount
|
||||
enemy_hp -= attack_amount * 2
|
||||
enemy_stance = "attack"
|
||||
|
||||
else if(enemy_hp <= 30) //will break through the counter when low enough on HP even when smart.
|
||||
list_temp += "<br><center><h3>[enemy_name] is getting tired of your tricks and breaks through your counter with their [chosen_weapon]!<center><h3>"
|
||||
player_hp -= attack_amount
|
||||
enemy_stance = "attack"
|
||||
|
||||
else if(!enemy_stance)
|
||||
var/added_temp
|
||||
|
||||
if(rand())
|
||||
added_temp = "you for [attack_amount + 5] damage!"
|
||||
player_hp -= attack_amount + 5
|
||||
enemy_stance = "attack"
|
||||
else
|
||||
added_temp = "the wall, breaking their skull in the process and losing [attack_amount] hp!" //[enemy_name] you have a literal dent in your skull
|
||||
enemy_hp -= attack_amount
|
||||
enemy_stance = "attack"
|
||||
|
||||
list_temp += "<br><center><h3>[enemy_name] grits their teeth and charge right into [added_temp]<center><h3>"
|
||||
|
||||
//in the case none of the previous passive triggered, Mainly here to set an enemy stance for passives that needs it like the magical passive.
|
||||
if(!enemy_stance)
|
||||
enemy_stance = pick("attack","defensive")
|
||||
if(enemy_stance == "attack")
|
||||
player_hp -= attack_amount
|
||||
list_temp += "<br><center><h3>[enemy_name] attacks you for [attack_amount] points of damage with their [chosen_weapon]<center><h3>"
|
||||
if(player_stance == "counter_attack")
|
||||
enemy_hp -= attack_amount * 2
|
||||
list_temp += "<br><center><h3>You counter [enemy_name]'s attack and deal [attack_amount * 2] points of damage!<center><h3>"
|
||||
|
||||
if(enemy_stance == "defensive" && enemy_mp < 15)
|
||||
list_temp += "<br><center><h3>[enemy_name] take some time to get some mp back!<center><h3> "
|
||||
enemy_mp += attack_amount
|
||||
|
||||
else if (enemy_stance == "defensive" && enemy_mp >= 15 && !(LAZYACCESS(enemy_passive, "magical")))
|
||||
list_temp += "<br><center><h3>[enemy_name] quickly heal themselves for 5 hp!<center><h3> "
|
||||
enemy_mp -= 15
|
||||
enemy_hp += 5
|
||||
|
||||
//magical passive trait, recharges MP nearly every turn it's not blasting you with magic.
|
||||
if(LAZYACCESS(enemy_passive, "magical"))
|
||||
if(player_mp >= 50)
|
||||
list_temp += "<br><center><h3>the huge amount of magical energy you have acumulated throws [enemy_name] off balance!<center><h3>"
|
||||
enemy_mp = 0
|
||||
LAZYREMOVE(enemy_passive, "magical")
|
||||
pissed_off++
|
||||
|
||||
else if(LAZYACCESS(enemy_passive, "smart") && player_stance == "counter_attack" && enemy_mp >= 20)
|
||||
list_temp += "<br><center><h3>[enemy_name] blasts you with magic from afar for 10 points of damage before you can counter!<center><h3>"
|
||||
player_hp -= 10
|
||||
enemy_mp -= 20
|
||||
|
||||
else if(enemy_hp >= 20 && enemy_mp >= 40 && enemy_stance == "defensive")
|
||||
list_temp += "<br><center><h3>[enemy_name] Blasts you with magic from afar!<center><h3>"
|
||||
enemy_mp -= 40
|
||||
player_hp -= 30
|
||||
enemy_stance = "attack"
|
||||
|
||||
else if(enemy_hp < 20 && enemy_mp >= 20 && enemy_stance == "defensive") //it's a pretty expensive spell so they can't spam it that much
|
||||
list_temp += "<br><center><h3>[enemy_name] heal themselves with magic and gain back 20 hp!<center><h3>"
|
||||
enemy_hp += 20
|
||||
enemy_mp -= 30
|
||||
else
|
||||
list_temp += "<br><center><h3>[enemy_name]'s magical nature lets them get some mp back!<center><h3>"
|
||||
enemy_mp += attack_amount
|
||||
|
||||
//poisonous passive trait, while it's less damage added than the shotgun it acts up even when the enemy doesn't attack at all.
|
||||
if(LAZYACCESS(enemy_passive, "poisonous"))
|
||||
if(weakpoint_check("poisonous","attack","attack","attack"))
|
||||
list_temp += "<br><center><h3>your flurry of attack throws back the poisonnous gas at [enemy_name] and makes them choke on it!<center><h3> "
|
||||
enemy_hp -= 5
|
||||
else
|
||||
list_temp += "<br><center><h3>the stinky breath of [enemy_name] hurts you for 3 hp!<center><h3> "
|
||||
player_hp -= 3
|
||||
|
||||
//if all passive's weakpoint have been triggered, set finishing_move to TRUE
|
||||
if(pissed_off >= max_passive && !finishing_move)
|
||||
list_temp += "<br><center><h3>You have weakened [enemy_name] enough for them to show their weak point, you will do 10 times as much damage with your next attack!<center><h3> "
|
||||
finishing_move = TRUE
|
||||
|
||||
playsound(src, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
|
||||
temp = list_temp.Join()
|
||||
gameover_check(user)
|
||||
screen_setup(user)
|
||||
blocked = FALSE
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/battle/proc/gameover_check(mob/user)
|
||||
var/xp_gained = 0
|
||||
if(enemy_hp <= 0)
|
||||
if(!gameover)
|
||||
if(timer_id)
|
||||
deltimer(timer_id)
|
||||
timer_id = null
|
||||
if(player_hp <= 0)
|
||||
player_hp = 1 //let's just pretend the enemy didn't kill you so not both the player and enemy look dead.
|
||||
gameover = TRUE
|
||||
temp = "[enemy_name] has fallen! Rejoice!"
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3)
|
||||
blocked = FALSE
|
||||
temp = "<br><center><h3>[enemy_name] has fallen! Rejoice!<center><h3>"
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, TRUE)
|
||||
|
||||
if(obj_flags & EMAGGED)
|
||||
new /obj/effect/spawner/newbomb/timer/syndicate(loc)
|
||||
@@ -133,78 +402,76 @@
|
||||
log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.")
|
||||
Reset()
|
||||
obj_flags &= ~EMAGGED
|
||||
xp_gained += 100
|
||||
else
|
||||
prizevend(user)
|
||||
xp_gained += 50
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("win", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
|
||||
else if ((obj_flags & EMAGGED) && (turtle >= 4))
|
||||
var/boomamt = rand(5,10)
|
||||
temp = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
|
||||
playsound(loc, 'sound/arcade/boom.ogg', 50, TRUE, extrarange = -3)
|
||||
player_hp -= boomamt
|
||||
|
||||
else if ((enemy_mp <= 5) && (prob(70)))
|
||||
var/stealamt = rand(2,3)
|
||||
temp = "[enemy_name] steals [stealamt] of your power!"
|
||||
playsound(loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3)
|
||||
player_mp -= stealamt
|
||||
updateUsrDialog()
|
||||
|
||||
if (player_mp <= 0)
|
||||
gameover = TRUE
|
||||
sleep(turn_speed)
|
||||
temp = "You have been drained! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3)
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.gib()
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "mana", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
else if ((enemy_hp <= 10) && (enemy_mp > 4))
|
||||
temp = "[enemy_name] heals for 4 health!"
|
||||
playsound(loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
enemy_hp += 4
|
||||
enemy_mp -= 4
|
||||
|
||||
else
|
||||
var/attackamt = rand(3,6)
|
||||
temp = "[enemy_name] attacks for [attackamt] damage!"
|
||||
playsound(loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
player_hp -= attackamt
|
||||
|
||||
if ((player_mp <= 0) || (player_hp <= 0))
|
||||
else if(player_hp <= 0)
|
||||
if(timer_id)
|
||||
deltimer(timer_id)
|
||||
timer_id = null
|
||||
gameover = TRUE
|
||||
temp = "You have been crushed! GAME OVER"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3)
|
||||
temp = "<br><center><h3>You have been crushed! GAME OVER<center><h3>"
|
||||
playsound(loc, 'sound/arcade/lose.ogg', 50, TRUE)
|
||||
xp_gained += 10//pity points
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.gib()
|
||||
var/mob/living/living_user = user
|
||||
if (istype(living_user))
|
||||
living_user.gib()
|
||||
SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal")))
|
||||
|
||||
blocked = FALSE
|
||||
return
|
||||
// if(gameover)
|
||||
// user?.mind?.adjust_experience(/datum/skill/gaming, xp_gained+1)//always gain at least 1 point of XP
|
||||
|
||||
|
||||
///used to check if the last three move of the player are the one we want in the right order and if the passive's weakpoint has been triggered yet
|
||||
/obj/machinery/computer/arcade/battle/proc/weakpoint_check(passive,first_move,second_move,third_move)
|
||||
if(LAZYLEN(last_three_move) < 3)
|
||||
return FALSE
|
||||
|
||||
if(last_three_move[1] == first_move && last_three_move[2] == second_move && last_three_move[3] == third_move && LAZYACCESS(enemy_passive, passive))
|
||||
LAZYREMOVE(enemy_passive, passive)
|
||||
pissed_off++
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/battle/Destroy()
|
||||
enemy_passive = null
|
||||
weapons = null
|
||||
last_three_move = null
|
||||
return ..() //well boys we did it, lists are no more
|
||||
|
||||
/obj/machinery/computer/arcade/battle/examine_more(mob/user)
|
||||
to_chat(user, "<span class='notice'>Scribbled on the side of the Arcade Machine you notice some writing...\
|
||||
\nmagical -> >=50 power\
|
||||
\nsmart -> defend, defend, light attack\
|
||||
\nshotgun -> defend, defend, power attack\
|
||||
\nshort temper -> counter, counter, counter\
|
||||
\npoisonous -> light attack, light attack, light attack\
|
||||
\nchonker -> power attack, power attack, power attack</span>")
|
||||
return ..()
|
||||
var/list/msg = list("<span class='notice'><i>You notice some writing scribbled on the side of [src]...</i></span>")
|
||||
msg += "\t<span class='info'>smart -> defend, defend, light attack</span>"
|
||||
msg += "\t<span class='info'>shotgun -> defend, defend, power attack</span>"
|
||||
msg += "\t<span class='info'>short temper -> counter, counter, counter</span>"
|
||||
msg += "\t<span class='info'>poisonous -> light attack, light attack, light attack</span>"
|
||||
msg += "\t<span class='info'>chonker -> power attack, power attack, power attack</span>"
|
||||
return msg
|
||||
|
||||
/obj/machinery/computer/arcade/battle/emag_act(mob/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='warning'>A mesmerizing Rhumba beat starts playing from the arcade machine's speakers!</span>")
|
||||
temp = "If you die in the game, you die for real!"
|
||||
player_hp = 30
|
||||
player_mp = 10
|
||||
enemy_hp = 45
|
||||
enemy_mp = 20
|
||||
temp = "<br><center><h2>If you die in the game, you die for real!<center><h2>"
|
||||
max_passive = 6
|
||||
bomb_cooldown = 18
|
||||
var/gamerSkill = 0
|
||||
// if(usr?.mind)
|
||||
// gamerSkill = usr.mind.get_skill_level(/datum/skill/gaming)
|
||||
enemy_setup(gamerSkill)
|
||||
enemy_hp += 100 //extra HP just to make cuban pete even more bullshit
|
||||
player_hp += 30 //the player will also get a few extra HP in order to have a fucking chance
|
||||
|
||||
screen_setup(user)
|
||||
gameover = FALSE
|
||||
blocked = FALSE
|
||||
|
||||
obj_flags |= EMAGGED
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
visible_message("<span class='notice'>[src] dispenses [itemname]!</span>", "<span class='notice'>You hear a chime and a clunk.</span>")
|
||||
DISABLE_BITFIELD(obj_flags, EMAGGED)
|
||||
else
|
||||
var/dope_prizes = (area >= 480) ? list(ARCADE_WEIGHT_RARE) : (area >= 256) ? list(ARCADE_WEIGHT_RARE, ARCADE_WEIGHT_TRICK) : null
|
||||
var/dope_prizes = (area >= 480) ? 6 : (area >= 256) ? 4 : 2
|
||||
prizevend(user, dope_prizes)
|
||||
|
||||
if(game_status == MINESWEEPER_GAME_WON)
|
||||
@@ -311,12 +311,12 @@
|
||||
var/new_rows = input(user, "How many rows do you want? (Minimum: 4, Maximum: 30)", "Minesweeper Rows") as null|num
|
||||
if(!new_rows || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
return FALSE
|
||||
new_rows = clamp(new_rows + 1, 4, 30)
|
||||
new_rows = clamp(new_rows + 1, 4, 20)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
var/new_columns = input(user, "How many columns do you want? (Minimum: 4, Maximum: 50)", "Minesweeper Squares") as null|num
|
||||
if(!new_columns || !user.canUseTopic(src, !hasSiliconAccessInArea(user)))
|
||||
return FALSE
|
||||
new_columns = clamp(new_columns + 1, 4, 50)
|
||||
new_columns = clamp(new_columns + 1, 4, 30)
|
||||
playsound(loc, 'sound/arcade/minesweeper_menuselect.ogg', 50, FALSE, extrarange = -3)
|
||||
var/grid_area = (new_rows - 1) * (new_columns - 1)
|
||||
var/lower_limit = round(grid_area*0.156)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
icon_state = "arcade"
|
||||
circuit = /obj/item/circuitboard/computer/arcade/amputation
|
||||
|
||||
/obj/machinery/computer/arcade/amputation/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/machinery/computer/arcade/amputation/on_attack_hand(mob/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
var/mob/living/carbon/c_user = user
|
||||
@@ -24,8 +24,13 @@
|
||||
var/obj/item/bodypart/chopchop = c_user.get_bodypart(which_hand)
|
||||
chopchop.dismember()
|
||||
qdel(chopchop)
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3)
|
||||
for(var/i=1; i<=rand(3,5); i++)
|
||||
prizevend(user)
|
||||
// user.mind?.adjust_experience(/datum/skill/gaming, 100)
|
||||
playsound(loc, 'sound/arcade/win.ogg', 50, TRUE)
|
||||
prizevend(user, rand(3,5))
|
||||
else
|
||||
to_chat(c_user, "<span class='notice'>You (wisely) decide against putting your hand in the machine.</span>")
|
||||
|
||||
/obj/machinery/computer/arcade/amputation/festive //dispenses wrapped gifts instead of arcade prizes, also known as the ancap christmas tree
|
||||
name = "Mediborg's Festive Amputation Adventure"
|
||||
desc = "A picture of a blood-soaked medical cyborg wearing a Santa hat flashes on the screen. The mediborg has a speech bubble that says, \"Put your hand in the machine if you aren't a <b>coward!</b>\""
|
||||
prize_override = list(/obj/item/a_gift/anything = 1)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
// *** THE ORION TRAIL ** //
|
||||
|
||||
#define ORION_TRAIL_WINTURN 9
|
||||
@@ -15,6 +13,8 @@
|
||||
#define ORION_TRAIL_COLLISION "Collision"
|
||||
#define ORION_TRAIL_SPACEPORT "Spaceport"
|
||||
#define ORION_TRAIL_BLACKHOLE "BlackHole"
|
||||
#define ORION_TRAIL_OLDSHIP "Old Ship"
|
||||
#define ORION_TRAIL_SEARCH "Old Ship Search"
|
||||
|
||||
#define ORION_STATUS_START 1
|
||||
#define ORION_STATUS_NORMAL 2
|
||||
@@ -44,7 +44,8 @@
|
||||
ORION_TRAIL_LING = 3,
|
||||
ORION_TRAIL_MALFUNCTION = 2,
|
||||
ORION_TRAIL_COLLISION = 1,
|
||||
ORION_TRAIL_SPACEPORT = 2
|
||||
ORION_TRAIL_SPACEPORT = 2,
|
||||
ORION_TRAIL_OLDSHIP = 2
|
||||
)
|
||||
var/list/stops = list()
|
||||
var/list/stopblurbs = list()
|
||||
@@ -55,13 +56,27 @@
|
||||
var/gameStatus = ORION_STATUS_START
|
||||
var/canContinueEvent = 0
|
||||
|
||||
var/obj/item/radio/Radio
|
||||
var/list/gamers = list()
|
||||
var/killed_crew = 0
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/Initialize()
|
||||
. = ..()
|
||||
Radio = new /obj/item/radio(src)
|
||||
Radio.listening = 0
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/Destroy()
|
||||
QDEL_NULL(Radio)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/kobayashi
|
||||
name = "Kobayashi Maru control computer"
|
||||
desc = "A test for cadets"
|
||||
icon = 'icons/obj/machines/particle_accelerator.dmi'
|
||||
icon_state = "control_boxp"
|
||||
events = list("Raiders" = 3, "Interstellar Flux" = 1, "Illness" = 3, "Breakdown" = 2, "Malfunction" = 2, "Collision" = 1, "Spaceport" = 2)
|
||||
prizes = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1)
|
||||
prize_override = list(/obj/item/paper/fluff/holodeck/trek_diploma = 1)
|
||||
settlers = list("Kirk","Worf","Gene")
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/Reset()
|
||||
@@ -96,14 +111,52 @@
|
||||
event = null
|
||||
gameStatus = ORION_STATUS_NORMAL
|
||||
lings_aboard = 0
|
||||
killed_crew = 0
|
||||
|
||||
//spaceport junk
|
||||
spaceport_raided = 0
|
||||
spaceport_freebie = 0
|
||||
last_spaceport_action = ""
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/user)
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/report_player(mob/gamer)
|
||||
if(gamers[gamer] == -2)
|
||||
return // enough harassing them
|
||||
|
||||
if(gamers[gamer] == -1)
|
||||
say("WARNING: Continued antisocial behavior detected: Dispensing self-help literature.")
|
||||
new /obj/item/paper/pamphlet/violent_video_games(drop_location())
|
||||
gamers[gamer]--
|
||||
return
|
||||
|
||||
if(!(gamer in gamers))
|
||||
gamers[gamer] = 0
|
||||
|
||||
gamers[gamer]++ // How many times the player has 'prestiged' (massacred their crew)
|
||||
|
||||
if(gamers[gamer] > 2 && prob(20 * gamers[gamer]))
|
||||
|
||||
Radio.set_frequency(FREQ_SECURITY)
|
||||
Radio.talk_into(src, "SECURITY ALERT: Crewmember [gamer] recorded displaying antisocial tendencies in [get_area(src)]. Please watch for violent behavior.", FREQ_SECURITY)
|
||||
|
||||
Radio.set_frequency(FREQ_MEDICAL)
|
||||
Radio.talk_into(src, "PSYCH ALERT: Crewmember [gamer] recorded displaying antisocial tendencies in [get_area(src)]. Please schedule psych evaluation.", FREQ_MEDICAL)
|
||||
|
||||
gamers[gamer] = -1
|
||||
|
||||
gamer.client.give_award(/datum/award/achievement/misc/gamer, gamer) // PSYCH REPORT NOTE: patient kept rambling about how they did it for an "achievement", recommend continued holding for observation
|
||||
// gamer.mind?.adjust_experience(/datum/skill/gaming, 50) // cheevos make u better
|
||||
|
||||
if(!isnull(GLOB.data_core.general))
|
||||
for(var/datum/data/record/R in GLOB.data_core.general)
|
||||
if(R.fields["name"] == gamer.name)
|
||||
R.fields["m_stat"] = "*Unstable*"
|
||||
return
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/ui_interact(mob/_user)
|
||||
. = ..()
|
||||
if (!isliving(_user))
|
||||
return
|
||||
var/mob/living/user = _user
|
||||
if(fuel <= 0 || food <=0 || settlers.len == 0)
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
@@ -136,6 +189,8 @@
|
||||
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
|
||||
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];menu=1'>May They Rest In Peace</a></P>"
|
||||
// user?.mind?.adjust_experience(/datum/skill/gaming, 10)//learning from your mistakes is the first rule of roguelikes
|
||||
|
||||
else if(event)
|
||||
dat = eventdat
|
||||
else if(gameStatus == ORION_STATUS_NORMAL)
|
||||
@@ -174,20 +229,32 @@
|
||||
return
|
||||
busy = TRUE
|
||||
|
||||
// var/gamerSkillLevel = 0
|
||||
var/gamerSkill = 0
|
||||
var/gamerSkillRands = 0
|
||||
|
||||
// if(usr?.mind)
|
||||
// gamerSkillLevel = usr.mind.get_skill_level(/datum/skill/gaming)
|
||||
// gamerSkill = usr.mind.get_skill_modifier(/datum/skill/gaming, SKILL_PROBS_MODIFIER)
|
||||
// gamerSkillRands = usr.mind.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER)
|
||||
|
||||
|
||||
var/xp_gained = 0
|
||||
if (href_list["continue"]) //Continue your travels
|
||||
if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7)
|
||||
if(turns >= ORION_TRAIL_WINTURN)
|
||||
win(usr)
|
||||
xp_gained += 34
|
||||
else
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
if(turns == 2 && prob(30))
|
||||
if(turns == 2 && prob(30-gamerSkill))
|
||||
event = ORION_TRAIL_COLLISION
|
||||
event()
|
||||
else if(prob(75))
|
||||
else if(prob(75-gamerSkill))
|
||||
event = pickweight(events)
|
||||
if(lings_aboard)
|
||||
if(event == ORION_TRAIL_LING || prob(55))
|
||||
if(event == ORION_TRAIL_LING || prob(55-gamerSkill))
|
||||
event = ORION_TRAIL_LING_ATTACK
|
||||
event()
|
||||
turns += 1
|
||||
@@ -195,15 +262,18 @@
|
||||
var/mob/living/carbon/M = usr //for some vars
|
||||
switch(event)
|
||||
if(ORION_TRAIL_RAIDERS)
|
||||
if(prob(50))
|
||||
if(prob(50-gamerSkill))
|
||||
to_chat(usr, "<span class='userdanger'>You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?</span>")
|
||||
M.hallucination += 30
|
||||
else
|
||||
to_chat(usr, "<span class='userdanger'>Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...</span>")
|
||||
M.take_bodypart_damage(30)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 100, TRUE)
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS
|
||||
var/maxSeverity = 3
|
||||
// if(gamerSkillLevel >= SKILL_LEVEL_EXPERT)
|
||||
// maxSeverity = 2 //part of gitting gud is rng mitigation
|
||||
var/severity = rand(1,maxSeverity) //pray to RNGesus. PRAY, PIGS
|
||||
if(severity == 1)
|
||||
to_chat(M, "<span class='userdanger'>You suddenly feel slightly nauseated.</span>" )
|
||||
if(severity == 2)
|
||||
@@ -215,16 +285,16 @@
|
||||
sleep(30)
|
||||
M.vomit(10, distance = 5)
|
||||
if(ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
if(prob(75-gamerSkill))
|
||||
M.DefaultCombatKnockdown(60)
|
||||
say("A sudden gust of powerful wind slams [M] into the floor!")
|
||||
M.take_bodypart_damage(25)
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, TRUE)
|
||||
else
|
||||
to_chat(M, "<span class='userdanger'>A violent gale blows past you, and you barely manage to stay standing!</span>")
|
||||
if(ORION_TRAIL_COLLISION) //by far the most damaging event
|
||||
if(prob(90))
|
||||
playsound(loc, 'sound/effects/bang.ogg', 100, 1)
|
||||
if(prob(90-gamerSkill))
|
||||
playsound(loc, 'sound/effects/bang.ogg', 100, TRUE)
|
||||
var/turf/open/floor/F
|
||||
for(F in orange(1, src))
|
||||
F.ScrapeAway()
|
||||
@@ -232,15 +302,15 @@
|
||||
if(hull)
|
||||
sleep(10)
|
||||
say("A new floor suddenly appears around [src]. What the hell?")
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, TRUE)
|
||||
var/turf/open/space/T
|
||||
for(T in orange(1, src))
|
||||
T.PlaceOnTop(/turf/open/floor/plating)
|
||||
else
|
||||
say("Something slams into the floor around [src] - luckily, it didn't get through!")
|
||||
playsound(loc, 'sound/effects/bang.ogg', 50, 1)
|
||||
playsound(loc, 'sound/effects/bang.ogg', 50, TRUE)
|
||||
if(ORION_TRAIL_MALFUNCTION)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, TRUE)
|
||||
visible_message("<span class='danger'>[src] malfunctions, randomizing in-game stats!</span>")
|
||||
var/oldfood = food
|
||||
var/oldfuel = fuel
|
||||
@@ -254,7 +324,7 @@
|
||||
audible_message("<span class='danger'>[src] lets out a somehow ominous chime.</span>")
|
||||
food = oldfood
|
||||
fuel = oldfuel
|
||||
playsound(loc, 'sound/machines/chime.ogg', 50, 1)
|
||||
playsound(loc, 'sound/machines/chime.ogg', 50, TRUE)
|
||||
|
||||
else if(href_list["newgame"]) //Reset everything
|
||||
if(gameStatus == ORION_STATUS_START)
|
||||
@@ -266,6 +336,10 @@
|
||||
food = 80
|
||||
fuel = 60
|
||||
settlers = list("Harry","Larry","Bob")
|
||||
else if(href_list["search"]) //search old ship
|
||||
if(event == ORION_TRAIL_OLDSHIP)
|
||||
event = ORION_TRAIL_SEARCH
|
||||
event()
|
||||
else if(href_list["slow"]) //slow down
|
||||
if(event == ORION_TRAIL_FLUX)
|
||||
food -= (alive+lings_aboard)*2
|
||||
@@ -302,11 +376,11 @@
|
||||
event = null
|
||||
else if(href_list["blackhole"]) //keep speed past a black hole
|
||||
if(turns == 7)
|
||||
if(prob(75))
|
||||
if(prob(75-gamerSkill))
|
||||
event = ORION_TRAIL_BLACKHOLE
|
||||
event()
|
||||
if(obj_flags & EMAGGED)
|
||||
playsound(loc, 'sound/effects/supermatter.ogg', 100, 1)
|
||||
playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE)
|
||||
say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!")
|
||||
if(isliving(usr))
|
||||
var/mob/living/L = usr
|
||||
@@ -328,22 +402,29 @@
|
||||
else if(href_list["killcrew"]) //shoot a crewmember
|
||||
if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING)
|
||||
var/sheriff = remove_crewmember() //I shot the sheriff
|
||||
playsound(loc,'sound/weapons/gunshot.ogg', 100, 1)
|
||||
playsound(loc,'sound/weapons/gunshot.ogg', 100, TRUE)
|
||||
killed_crew++
|
||||
|
||||
var/mob/living/user = usr
|
||||
|
||||
if(settlers.len == 0 || alive == 0)
|
||||
say("The last crewmember [sheriff], shot themselves, GAME OVER!")
|
||||
if(obj_flags & EMAGGED)
|
||||
usr.death(0)
|
||||
obj_flags &= EMAGGED
|
||||
user.death(FALSE)
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
|
||||
if(killed_crew >= 4)
|
||||
xp_gained -= 15//no cheating by spamming game overs
|
||||
report_player(usr)
|
||||
else if(obj_flags & EMAGGED)
|
||||
if(usr.name == sheriff)
|
||||
say("The crew of the ship chose to kill [usr.name]!")
|
||||
usr.death(0)
|
||||
user.death(FALSE)
|
||||
|
||||
if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places
|
||||
event = null
|
||||
killed_crew-- // the kill was valid
|
||||
|
||||
//Spaceport specific interactions
|
||||
//they get a header because most of them don't reset event (because it's a shop, you leave when you want to)
|
||||
@@ -356,6 +437,7 @@
|
||||
fuel -= 10
|
||||
food -= 10
|
||||
event()
|
||||
killed_crew-- // I mean not really but you know
|
||||
|
||||
else if(href_list["sellcrew"]) //sell a crewmember
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
@@ -377,15 +459,16 @@
|
||||
else if(href_list["raid_spaceport"])
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided)
|
||||
var/success = min(15 * alive,100) //default crew (4) have a 60% chance
|
||||
var/success = min(15 * alive + gamerSkill,100) //default crew (4) have a 60% chance
|
||||
spaceport_raided = 1
|
||||
|
||||
var/FU = 0
|
||||
var/FO = 0
|
||||
if(prob(success))
|
||||
FU = rand(5,15)
|
||||
FO = rand(5,15)
|
||||
FU = rand(5 + gamerSkillRands,15 + gamerSkillRands)
|
||||
FO = rand(5 + gamerSkillRands,15 + gamerSkillRands)
|
||||
last_spaceport_action = "You successfully raided the spaceport! You gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)"
|
||||
xp_gained += 10
|
||||
else
|
||||
FU = rand(-5,-15)
|
||||
FO = rand(-5,-15)
|
||||
@@ -444,8 +527,7 @@
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
busy = FALSE
|
||||
return
|
||||
|
||||
// usr?.mind?.adjust_experience(/datum/skill/gaming, xp_gained+1)
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/event()
|
||||
eventdat = "<center><h1>[event]</h1></center>"
|
||||
@@ -474,6 +556,38 @@
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];slow=1'>Slow Down</a> <a href='byond://?src=[REF(src)];keepspeed=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
|
||||
if(ORION_TRAIL_OLDSHIP)
|
||||
eventdat += "<br>Your crew spots an old ship floating through space. It might have some supplies, but then again it looks rather unsafe."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];search=1'>Search it</a><a href='byond://?src=[REF(src)];eventclose=1'>Leave it</a></P><P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_SEARCH)
|
||||
switch(rand(100))
|
||||
if(0 to 15)
|
||||
var/rescued = add_crewmember()
|
||||
var/oldfood = rand(1,7)
|
||||
var/oldfuel = rand(4,10)
|
||||
food += oldfood
|
||||
fuel += oldfuel
|
||||
eventdat += "<br>As you look through it you find some supplies and a living person!"
|
||||
eventdat += "<br>[rescued] was rescued from the abandoned ship!"
|
||||
eventdat += "<br>You found [oldfood] <b>Food</b> and [oldfuel] <b>Fuel</b>."
|
||||
if(15 to 35)
|
||||
var/lfuel = rand(4,7)
|
||||
var/deadname = remove_crewmember()
|
||||
fuel -= lfuel
|
||||
eventdat += "<br>[deadname] was lost deep in the wreckage, and your own vessel lost [lfuel] <b>Fuel</b> maneuvering to the the abandoned ship."
|
||||
if(35 to 65)
|
||||
var/oldfood = rand(5,11)
|
||||
food += oldfood
|
||||
engine++
|
||||
eventdat += "<br>You found [oldfood] <b>Food</b> and some parts amongst the wreck."
|
||||
else
|
||||
eventdat += "<br>As you look through the wreck you cannot find much of use."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=[REF(src)];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
eventdat += "A deadly illness has been contracted!"
|
||||
var/deadname = remove_crewmember()
|
||||
@@ -687,7 +801,7 @@
|
||||
|
||||
|
||||
//Add Random/Specific crewmember
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/add_crewmember(var/specific = "")
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/add_crewmember(specific = "")
|
||||
var/newcrew = ""
|
||||
if(specific)
|
||||
newcrew = specific
|
||||
@@ -703,7 +817,7 @@
|
||||
|
||||
|
||||
//Remove Random/Specific crewmember
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/remove_crewmember(var/specific = "", var/dont_remove = "")
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/remove_crewmember(specific = "", dont_remove = "")
|
||||
var/list/safe2remove = settlers
|
||||
var/removed = ""
|
||||
if(dont_remove)
|
||||
@@ -779,14 +893,14 @@
|
||||
to_chat(user, "<span class='warning'>You flip the switch on the underside of [src].</span>")
|
||||
active = 1
|
||||
visible_message("<span class='notice'>[src] softly beeps and whirs to life!</span>")
|
||||
playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1)
|
||||
playsound(loc, 'sound/machines/defib_SaftyOn.ogg', 25, TRUE)
|
||||
say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.")
|
||||
sleep(20)
|
||||
visible_message("<span class='warning'>[src] begins to vibrate...</span>")
|
||||
say("Uh, Port? Having some issues with our reactor, could you check it out? Over.")
|
||||
sleep(30)
|
||||
say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 25, TRUE)
|
||||
sleep(3.6)
|
||||
visible_message("<span class='userdanger'>[src] explodes!</span>")
|
||||
explosion(loc, 2,4,8, flame_range = 16)
|
||||
|
||||
@@ -92,6 +92,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
icon_screen = "tank"
|
||||
icon_keyboard = "atmos_key"
|
||||
circuit = /obj/item/circuitboard/computer/atmos_control
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
|
||||
var/frequency = FREQ_ATMOS_STORAGE
|
||||
var/list/sensors = list(
|
||||
@@ -102,6 +103,20 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank",
|
||||
ATMOS_GAS_MONITOR_SENSOR_AIR = "Mixed Air Tank",
|
||||
ATMOS_GAS_MONITOR_SENSOR_MIX = "Mix Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_BZ = "BZ Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_FREON = "Freon Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_HALON = "Halon Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_HEALIUM = "Healium Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_H2 = "Hydrogen Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_HYPERNOBLIUM = "Hypernoblium Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_MIASMA = "Miasma Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_NO2 = "Nitryl Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_PLUOXIUM = "Pluoxium Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_PROTO_NITRATE = "Proto-Nitrate Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_STIMULUM = "Stimulum Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_TRITIUM = "Tritium Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_H2O = "Water Vapor Tank",
|
||||
// ATMOS_GAS_MONITOR_SENSOR_ZAUKER = "Zauker Tank",
|
||||
ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION = "Distribution Loop",
|
||||
ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE = "Atmos Waste Loop",
|
||||
ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber",
|
||||
@@ -110,7 +125,6 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
var/list/sensor_information = list()
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
|
||||
/obj/machinery/computer/atmos_control/Initialize()
|
||||
. = ..()
|
||||
@@ -165,15 +179,10 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
/obj/machinery/computer/atmos_control/incinerator
|
||||
name = "Incinerator Air Control"
|
||||
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
|
||||
ui_x = 400
|
||||
ui_y = 300
|
||||
|
||||
//Toxins mix sensor only
|
||||
/obj/machinery/computer/atmos_control/toxinsmix
|
||||
name = "Toxins Mixing Air Control"
|
||||
sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber")
|
||||
ui_x = 400
|
||||
ui_y = 300
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
// LARGE TANK CONTROL
|
||||
@@ -184,13 +193,9 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
var/output_tag
|
||||
frequency = FREQ_ATMOS_STORAGE
|
||||
circuit = /obj/item/circuitboard/computer/atmos_control/tank
|
||||
|
||||
var/list/input_info
|
||||
var/list/output_info
|
||||
|
||||
ui_x = 500
|
||||
ui_y = 315
|
||||
|
||||
/obj/machinery/computer/atmos_control/tank/oxygen_tank
|
||||
name = "Oxygen Supply Control"
|
||||
input_tag = ATMOS_GAS_MONITOR_INPUT_O2
|
||||
@@ -236,7 +241,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this
|
||||
/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user)
|
||||
var/list/IO = list()
|
||||
var/datum/radio_frequency/freq = SSradio.return_frequency(FREQ_ATMOS_STORAGE)
|
||||
var/datum/radio_frequency/freq = SSradio.return_frequency(frequency)
|
||||
var/list/devices = freq.devices["_default"]
|
||||
for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices)
|
||||
var/list/text = splittext(U.id_tag, "_")
|
||||
@@ -252,10 +257,11 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
src.output_tag = "[S]_out"
|
||||
name = "[uppertext(S)] Supply Control"
|
||||
var/list/new_devices = freq.devices["4"]
|
||||
sensors.Cut()
|
||||
for(var/obj/machinery/air_sensor/U in new_devices)
|
||||
var/list/text = splittext(U.id_tag, "_")
|
||||
if(text[1] == S)
|
||||
sensors = list("[S]_sensor" = "Tank")
|
||||
sensors = list("[S]_sensor" = "[S] Tank")
|
||||
break
|
||||
|
||||
for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices)
|
||||
@@ -268,13 +274,16 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
|
||||
data["tank"] = TRUE
|
||||
data["inputting"] = input_info ? input_info["power"] : FALSE
|
||||
data["inputRate"] = input_info ? input_info["volume_rate"] : 0
|
||||
data["maxInputRate"] = input_info ? MAX_TRANSFER_RATE : 0
|
||||
data["outputting"] = output_info ? output_info["power"] : FALSE
|
||||
data["outputPressure"] = output_info ? output_info["internal"] : 0
|
||||
|
||||
data["maxOutputPressure"] = output_info ? MAX_OUTPUT_PRESSURE : 0
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/atmos_control/tank/ui_act(action, params)
|
||||
if(..() || !radio_connection)
|
||||
. = ..()
|
||||
|
||||
if(. || !radio_connection)
|
||||
return
|
||||
var/datum/signal/signal = new(list("sigtype" = "command", "user" = usr))
|
||||
switch(action)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#define DEFAULT_MAP_SIZE 15
|
||||
|
||||
/obj/machinery/computer/security
|
||||
name = "security camera console"
|
||||
desc = "Used to access the various cameras on the station."
|
||||
@@ -8,15 +10,19 @@
|
||||
|
||||
var/list/network = list("ss13")
|
||||
var/obj/machinery/camera/active_camera
|
||||
/// The turf where the camera was last updated.
|
||||
var/turf/last_camera_turf
|
||||
var/list/concurrent_users = list()
|
||||
|
||||
// Stuff needed to render the map
|
||||
var/map_name
|
||||
var/const/default_map_size = 15
|
||||
var/obj/screen/cam_screen
|
||||
var/obj/screen/plane_master/lighting/cam_plane_master
|
||||
var/obj/screen/map_view/cam_screen
|
||||
/// All the plane masters that need to be applied.
|
||||
var/list/cam_plane_masters
|
||||
var/obj/screen/background/cam_background
|
||||
|
||||
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_SET_MACHINE //| INTERACT_MACHINE_REQUIRES_SIGHT
|
||||
|
||||
/obj/machinery/computer/security/Initialize()
|
||||
. = ..()
|
||||
// Map name has to start and end with an A-Z character,
|
||||
@@ -33,18 +39,20 @@
|
||||
cam_screen.assigned_map = map_name
|
||||
cam_screen.del_on_map_removal = FALSE
|
||||
cam_screen.screen_loc = "[map_name]:1,1"
|
||||
cam_plane_master = new
|
||||
cam_plane_master.name = "plane_master"
|
||||
cam_plane_master.assigned_map = map_name
|
||||
cam_plane_master.del_on_map_removal = FALSE
|
||||
cam_plane_master.screen_loc = "[map_name]:CENTER"
|
||||
cam_plane_masters = list()
|
||||
for(var/plane in subtypesof(/obj/screen/plane_master))
|
||||
var/obj/screen/instance = new plane()
|
||||
instance.assigned_map = map_name
|
||||
instance.del_on_map_removal = FALSE
|
||||
instance.screen_loc = "[map_name]:CENTER"
|
||||
cam_plane_masters += instance
|
||||
cam_background = new
|
||||
cam_background.assigned_map = map_name
|
||||
cam_background.del_on_map_removal = FALSE
|
||||
|
||||
/obj/machinery/computer/security/Destroy()
|
||||
qdel(cam_screen)
|
||||
qdel(cam_plane_master)
|
||||
QDEL_LIST(cam_plane_masters)
|
||||
qdel(cam_background)
|
||||
return ..()
|
||||
|
||||
@@ -56,9 +64,10 @@
|
||||
/obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui)
|
||||
// Update UI
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
// Show static if can't use the camera
|
||||
if(!active_camera?.can_use())
|
||||
show_camera_static()
|
||||
|
||||
// Update the camera, showing static if necessary and updating data if the location has moved.
|
||||
update_active_camera_screen()
|
||||
|
||||
if(!ui)
|
||||
var/user_ref = REF(user)
|
||||
var/is_living = isliving(user)
|
||||
@@ -72,7 +81,7 @@
|
||||
use_power(active_power_usage)
|
||||
// Register map objects
|
||||
user.client.register_map_obj(cam_screen)
|
||||
for(var/plane in cam_plane_master)
|
||||
for(var/plane in cam_plane_masters)
|
||||
user.client.register_map_obj(plane)
|
||||
user.client.register_map_obj(cam_background)
|
||||
// Open UI
|
||||
@@ -100,6 +109,7 @@
|
||||
data["cameras"] += list(list(
|
||||
name = C.c_tag,
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/security/ui_act(action, params)
|
||||
@@ -110,31 +120,51 @@
|
||||
if(action == "switch_camera")
|
||||
var/c_tag = params["name"]
|
||||
var/list/cameras = get_available_cameras()
|
||||
var/obj/machinery/camera/C = cameras[c_tag]
|
||||
active_camera = C
|
||||
var/obj/machinery/camera/selected_camera = cameras[c_tag]
|
||||
active_camera = selected_camera
|
||||
playsound(src, get_sfx("terminal_type"), 25, FALSE)
|
||||
|
||||
// Show static if can't use the camera
|
||||
if(!active_camera?.can_use())
|
||||
show_camera_static()
|
||||
if(!selected_camera)
|
||||
return TRUE
|
||||
|
||||
var/list/visible_turfs = list()
|
||||
for(var/turf/T in (C.isXRay() \
|
||||
? range(C.view_range, C) \
|
||||
: view(C.view_range, C)))
|
||||
visible_turfs += T
|
||||
|
||||
var/list/bbox = get_bbox_of_atoms(visible_turfs)
|
||||
var/size_x = bbox[3] - bbox[1] + 1
|
||||
var/size_y = bbox[4] - bbox[2] + 1
|
||||
|
||||
cam_screen.vis_contents = visible_turfs
|
||||
cam_background.icon_state = "clear"
|
||||
cam_background.fill_rect(1, 1, size_x, size_y)
|
||||
update_active_camera_screen()
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/security/proc/update_active_camera_screen()
|
||||
// Show static if can't use the camera
|
||||
if(!active_camera?.can_use())
|
||||
show_camera_static()
|
||||
return
|
||||
|
||||
var/list/visible_turfs = list()
|
||||
|
||||
// Is this camera located in or attached to a living thing? If so, assume the camera's loc is the living thing.
|
||||
var/cam_location = isliving(active_camera.loc) ? active_camera.loc : active_camera
|
||||
|
||||
// If we're not forcing an update for some reason and the cameras are in the same location,
|
||||
// we don't need to update anything.
|
||||
// Most security cameras will end here as they're not moving.
|
||||
var/newturf = get_turf(cam_location)
|
||||
if(last_camera_turf == newturf)
|
||||
return
|
||||
|
||||
// Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs.
|
||||
last_camera_turf = get_turf(cam_location)
|
||||
|
||||
var/list/visible_things = active_camera.isXRay() ? range(active_camera.view_range, cam_location) : view(active_camera.view_range, cam_location)
|
||||
|
||||
for(var/turf/visible_turf in visible_things)
|
||||
visible_turfs += visible_turf
|
||||
|
||||
var/list/bbox = get_bbox_of_atoms(visible_turfs)
|
||||
var/size_x = bbox[3] - bbox[1] + 1
|
||||
var/size_y = bbox[4] - bbox[2] + 1
|
||||
|
||||
cam_screen.vis_contents = visible_turfs
|
||||
cam_background.icon_state = "clear"
|
||||
cam_background.fill_rect(1, 1, size_x, size_y)
|
||||
|
||||
/obj/machinery/computer/security/ui_close(mob/user)
|
||||
var/user_ref = REF(user)
|
||||
var/is_living = isliving(user)
|
||||
@@ -151,7 +181,7 @@
|
||||
/obj/machinery/computer/security/proc/show_camera_static()
|
||||
cam_screen.vis_contents.Cut()
|
||||
cam_background.icon_state = "scanline2"
|
||||
cam_background.fill_rect(1, 1, default_map_size, default_map_size)
|
||||
cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE)
|
||||
|
||||
// Returns the list of cameras accessible from this computer
|
||||
/obj/machinery/computer/security/proc/get_available_cameras()
|
||||
@@ -179,7 +209,7 @@
|
||||
name = "security camera monitor"
|
||||
desc = "An old TV hooked into the station's camera network."
|
||||
icon_state = "television"
|
||||
icon_keyboard = null
|
||||
icon_keyboard = "no_keyboard"
|
||||
icon_screen = "detective_tv"
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
@@ -211,7 +241,7 @@
|
||||
|
||||
/obj/machinery/computer/security/qm
|
||||
name = "\improper Quartermaster's camera console"
|
||||
desc = "A console with access to the mining, auxillary base and vault camera networks."
|
||||
desc = "A console with access to the mining, auxiliary base and vault camera networks."
|
||||
network = list("mine", "auxbase", "vault")
|
||||
circuit = null
|
||||
|
||||
@@ -222,17 +252,12 @@
|
||||
desc = "Used for watching an empty arena."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "telescreen"
|
||||
layer = SIGN_LAYER
|
||||
network = list("thunder")
|
||||
density = FALSE
|
||||
circuit = null
|
||||
light_power = 0
|
||||
|
||||
/obj/machinery/computer/security/telescreen/Initialize()
|
||||
. = ..()
|
||||
var/turf/T = get_turf_pixel(src)
|
||||
if(iswallturf(T))
|
||||
plane = ABOVE_WALL_PLANE
|
||||
|
||||
/obj/machinery/computer/security/telescreen/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
if(stat & BROKEN)
|
||||
@@ -246,21 +271,19 @@
|
||||
network = list("thunder")
|
||||
density = FALSE
|
||||
circuit = null
|
||||
//interaction_flags_atom = NONE // interact() is called by BigClick()
|
||||
interaction_flags_atom = NONE // interact() is called by BigClick()
|
||||
var/icon_state_off = "entertainment_blank"
|
||||
var/icon_state_on = "entertainment"
|
||||
|
||||
/* If someone would like to try to get this long-distance viewing thing working, be my guest. I tried everything I could possibly think of and it just refused to operate correctly.
|
||||
|
||||
/obj/machinery/computer/security/telescreen/entertainment/Initialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_CLICK, .proc/BigClick)
|
||||
|
||||
// Bypass clickchain to allow humans to use the telescreen from a distance
|
||||
/obj/machinery/computer/security/telescreen/entertainment/proc/BigClick()
|
||||
interact(usr)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
*/
|
||||
INVOKE_ASYNC(src, /atom.proc/interact, usr)
|
||||
|
||||
/obj/machinery/computer/security/telescreen/entertainment/proc/notify(on)
|
||||
if(on && icon_state == icon_state_off)
|
||||
@@ -279,8 +302,8 @@
|
||||
network = list("rd", "aicore", "aiupload", "minisat", "xeno", "test")
|
||||
|
||||
/obj/machinery/computer/security/telescreen/circuitry
|
||||
name = "circuitry telescreen"
|
||||
desc = "Used for watching the other eggheads from the safety of the circuitry lab."
|
||||
name = "research telescreen"
|
||||
desc = "A telescreen with access to the research division's camera network."
|
||||
network = list("rd")
|
||||
|
||||
/obj/machinery/computer/security/telescreen/ce
|
||||
@@ -324,8 +347,8 @@
|
||||
network = list("prison")
|
||||
|
||||
/obj/machinery/computer/security/telescreen/auxbase
|
||||
name = "auxillary base monitor"
|
||||
desc = "A telescreen that connects to the auxillary base's camera."
|
||||
name = "auxiliary base monitor"
|
||||
desc = "A telescreen that connects to the auxiliary base's camera."
|
||||
network = list("auxbase")
|
||||
|
||||
/obj/machinery/computer/security/telescreen/minisat
|
||||
@@ -346,3 +369,5 @@
|
||||
for(var/i in network)
|
||||
network -= i
|
||||
network += "[idnum][i]"
|
||||
|
||||
#undef DEFAULT_MAP_SIZE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,38 @@
|
||||
/obj/machinery/computer/pod
|
||||
name = "mass driver launch control"
|
||||
desc = "A combined blastdoor and mass driver control unit."
|
||||
// processing_flags = START_PROCESSING_MANUALLY
|
||||
/// Connected mass driver
|
||||
var/obj/machinery/mass_driver/connected = null
|
||||
var/title = "Mass Driver Controls"
|
||||
/// ID of the launch control
|
||||
var/id = 1
|
||||
var/timing = 0
|
||||
/// If the launch timer counts down
|
||||
var/timing = FALSE
|
||||
/// Time before auto launch
|
||||
var/time = 30
|
||||
/// Range in which we search for a mass drivers and poddoors nearby
|
||||
var/range = 4
|
||||
|
||||
/// Countdown timer for the mass driver's delayed launch functionality.
|
||||
COOLDOWN_DECLARE(massdriver_countdown)
|
||||
|
||||
/obj/machinery/computer/pod/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/machinery/mass_driver/M in range(range, src))
|
||||
if(M.id == id)
|
||||
connected = M
|
||||
break
|
||||
|
||||
/obj/machinery/computer/pod/process(delta_time)
|
||||
if(COOLDOWN_FINISHED(src, massdriver_countdown))
|
||||
timing = FALSE
|
||||
// alarm() sleeps, so we want to end processing first and can't rely on return PROCESS_KILL
|
||||
// end_processing()
|
||||
STOP_PROCESSING(SSmachines, src)
|
||||
alarm()
|
||||
|
||||
/**
|
||||
* Initiates launching sequence by checking if all components are functional, opening poddoors, firing mass drivers and then closing poddoors
|
||||
*/
|
||||
/obj/machinery/computer/pod/proc/alarm()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
@@ -39,92 +56,112 @@
|
||||
if(M.id == id)
|
||||
M.close()
|
||||
|
||||
/obj/machinery/computer/pod/ui_interact(mob/user)
|
||||
/obj/machinery/computer/pod/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "MassDriverControl", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/pod/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
// If the cooldown has finished, just display the time. If the cooldown hasn't finished, display the cooldown.
|
||||
var/display_time = COOLDOWN_FINISHED(src, massdriver_countdown) ? time : COOLDOWN_TIMELEFT(src, massdriver_countdown) * 0.1
|
||||
data["connected"] = connected ? TRUE : FALSE
|
||||
data["seconds"] = round(display_time % 60)
|
||||
data["minutes"] = round((display_time - data["seconds"]) / 60)
|
||||
data["timing"] = timing
|
||||
data["power"] = connected ? connected.power : 0.25
|
||||
data["poddoor"] = FALSE
|
||||
for(var/obj/machinery/door/poddoor/door in range(range, src))
|
||||
if(door.id == id)
|
||||
data["poddoor"] = TRUE
|
||||
break
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/pod/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
if(.)
|
||||
return
|
||||
if(!allowed(usr))
|
||||
to_chat(usr, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
|
||||
var/dat = ""
|
||||
if(connected)
|
||||
var/d2
|
||||
if(timing) //door controls do not need timers.
|
||||
d2 = "<A href='?src=[REF(src)];time=0'>Stop Time Launch</A>"
|
||||
else
|
||||
d2 = "<A href='?src=[REF(src)];time=1'>Initiate Time Launch</A>"
|
||||
dat += "<HR>\nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] <A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>"
|
||||
var/temp = ""
|
||||
var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 )
|
||||
for(var/t in L)
|
||||
if(t == connected.power)
|
||||
temp += "[t] "
|
||||
switch(action)
|
||||
if("set_power")
|
||||
if(!connected)
|
||||
return
|
||||
var/value = text2num(params["power"])
|
||||
if(!value)
|
||||
return
|
||||
value = clamp(value, 0.25, 16)
|
||||
connected.power = value
|
||||
return TRUE
|
||||
if("launch")
|
||||
alarm()
|
||||
return TRUE
|
||||
if("time")
|
||||
timing = !timing
|
||||
if(timing)
|
||||
COOLDOWN_START(src, massdriver_countdown, time SECONDS)
|
||||
// begin_processing()
|
||||
START_PROCESSING(SSmachines, src)
|
||||
else
|
||||
temp += "<A href = '?src=[REF(src)];power=[t]'>[t]</A> "
|
||||
dat += "<HR>\nPower Level: [temp]<BR>\n<A href = '?src=[REF(src)];alarm=1'>Firing Sequence</A><BR>\n<A href = '?src=[REF(src)];drive=1'>Test Fire Driver</A><BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
|
||||
else
|
||||
dat += "<BR>\n<A href = '?src=[REF(src)];door=1'>Toggle Outer Door</A><BR>"
|
||||
dat += "<BR><BR><A href='?src=[REF(user)];mach_close=computer'>Close</A>"
|
||||
add_fingerprint(usr)
|
||||
var/datum/browser/popup = new(user, "computer", title, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/pod/process()
|
||||
if(!..())
|
||||
return
|
||||
if(timing)
|
||||
if(time > 0)
|
||||
time = round(time) - 1
|
||||
else
|
||||
alarm()
|
||||
time = 0
|
||||
timing = 0
|
||||
updateDialog()
|
||||
|
||||
|
||||
/obj/machinery/computer/pod/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || hasSiliconAccessInArea(usr))
|
||||
usr.set_machine(src)
|
||||
if(href_list["power"])
|
||||
var/t = text2num(href_list["power"])
|
||||
t = min(max(0.25, t), 16)
|
||||
if(connected)
|
||||
connected.power = t
|
||||
if(href_list["alarm"])
|
||||
alarm()
|
||||
if(href_list["time"])
|
||||
timing = text2num(href_list["time"])
|
||||
if(href_list["tp"])
|
||||
var/tp = text2num(href_list["tp"])
|
||||
time += tp
|
||||
time = min(max(round(time), 0), 120)
|
||||
if(href_list["door"])
|
||||
time = COOLDOWN_TIMELEFT(src, massdriver_countdown) * 0.1
|
||||
COOLDOWN_RESET(src, massdriver_countdown)
|
||||
// end_processing()
|
||||
STOP_PROCESSING(SSmachines, src)
|
||||
return TRUE
|
||||
if("input")
|
||||
var/value = text2num(params["adjust"])
|
||||
if(!value)
|
||||
return
|
||||
value = round(time + value)
|
||||
time = clamp(value, 0, 120)
|
||||
return TRUE
|
||||
if("door")
|
||||
for(var/obj/machinery/door/poddoor/M in range(range, src))
|
||||
if(M.id == id)
|
||||
if(M.density)
|
||||
M.open()
|
||||
else
|
||||
M.close()
|
||||
if(href_list["drive"])
|
||||
return TRUE
|
||||
if("driver_test")
|
||||
for(var/obj/machinery/mass_driver/M in range(range, src))
|
||||
if(M.id == id)
|
||||
M.power = connected.power
|
||||
M.power = connected?.power
|
||||
M.drive()
|
||||
updateUsrDialog()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/pod/old
|
||||
name = "\improper DoorMex control console"
|
||||
title = "Door Controls"
|
||||
icon_state = "oldcomp"
|
||||
icon_screen = "library"
|
||||
icon_keyboard = null
|
||||
icon_keyboard = "no_keyboard"
|
||||
|
||||
// /obj/machinery/computer/pod/old/mass_driver_controller
|
||||
// name = "\improper Mass Driver Controller"
|
||||
// icon = 'icons/obj/airlock_machines.dmi'
|
||||
// icon_state = "airlock_control_standby"
|
||||
// icon_keyboard = "no_keyboard"
|
||||
// density = FALSE
|
||||
|
||||
// /obj/machinery/computer/pod/old/mass_driver_controller/toxinsdriver
|
||||
// id = MASSDRIVER_TOXINS
|
||||
|
||||
// //for maps where pod doors are outside of the standard 4 tile controller detection range (ie Pubbystation)
|
||||
// /obj/machinery/computer/pod/old/mass_driver_controller/toxinsdriver/longrange
|
||||
// range = 6
|
||||
|
||||
// /obj/machinery/computer/pod/old/mass_driver_controller/chapelgun
|
||||
// id = MASSDRIVER_CHAPEL
|
||||
|
||||
// /obj/machinery/computer/pod/old/mass_driver_controller/trash
|
||||
// id = MASSDRIVER_DISPOSALS
|
||||
|
||||
/obj/machinery/computer/pod/old/syndicate
|
||||
name = "\improper ProComp Executive IIc"
|
||||
desc = "The Syndicate operate on a tight budget. Operates external airlocks."
|
||||
title = "External Airlock Controls"
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
|
||||
/obj/machinery/computer/pod/old/swf
|
||||
|
||||
@@ -11,8 +11,24 @@
|
||||
var/id = 1
|
||||
var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess.
|
||||
|
||||
/obj/machinery/mass_driver/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
|
||||
id = "[idnum][id]"
|
||||
// /obj/machinery/mass_driver/chapelgun
|
||||
// name = "holy driver"
|
||||
// id = MASSDRIVER_CHAPEL
|
||||
|
||||
// /obj/machinery/mass_driver/toxins
|
||||
// id = MASSDRIVER_TOXINS
|
||||
|
||||
// /obj/machinery/mass_driver/trash
|
||||
// id = MASSDRIVER_DISPOSALS
|
||||
|
||||
// /obj/machinery/mass_driver/Destroy()
|
||||
// for(var/obj/machinery/computer/pod/control in GLOB.machines)
|
||||
// if(control.id == id)
|
||||
// control.connected = null
|
||||
// return ..()
|
||||
|
||||
/obj/machinery/mass_driver/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
|
||||
id = "[port.id]_[id]"
|
||||
|
||||
/obj/machinery/mass_driver/proc/drive(amount)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
@@ -22,6 +38,8 @@
|
||||
var/atom/target = get_edge_target_turf(src, dir)
|
||||
for(var/atom/movable/O in loc)
|
||||
if(!O.anchored || ismecha(O)) //Mechs need their launch platforms.
|
||||
if(ismob(O) && !isliving(O))
|
||||
continue
|
||||
O_limit++
|
||||
if(O_limit >= 20)
|
||||
audible_message("<span class='notice'>[src] lets out a screech, it doesn't seem to be able to handle the load.</span>")
|
||||
@@ -30,7 +48,6 @@
|
||||
O.throw_at(target, drive_range * power, power)
|
||||
flick("mass_driver1", src)
|
||||
|
||||
|
||||
/obj/machinery/mass_driver/emp_act(severity)
|
||||
. = ..()
|
||||
if (. & EMP_PROTECT_SELF)
|
||||
|
||||
@@ -676,4 +676,3 @@
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/offstation
|
||||
link_on_init = FALSE
|
||||
circuit = /obj/item/circuitboard/machine/mechfab/offstation
|
||||
|
||||
@@ -133,7 +133,6 @@
|
||||
icon_state += "-open"
|
||||
add_radio()
|
||||
add_cabin()
|
||||
add_airtank()
|
||||
spark_system.set_up(2, 0, src)
|
||||
spark_system.attach(src)
|
||||
smoke_system.set_up(3, src)
|
||||
@@ -149,6 +148,11 @@
|
||||
diag_hud_set_mechhealth()
|
||||
diag_hud_set_mechcell()
|
||||
diag_hud_set_mechstat()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/mecha/LateInitialize()
|
||||
. = ..()
|
||||
add_airtank()
|
||||
|
||||
/obj/mecha/get_cell()
|
||||
return cell
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
integrity = round((M.obj_integrity / M.max_integrity) * 100),
|
||||
charge = M.cell ? round(M.cell.percent()) : null,
|
||||
airtank = M.internal_tank ? M.return_pressure() : null,
|
||||
pilot = M.occupant,
|
||||
pilot = list(M.occupant),
|
||||
location = get_area_name(M, TRUE),
|
||||
active_equipment = M.selected,
|
||||
emp_recharging = MT.recharging,
|
||||
@@ -38,7 +38,7 @@
|
||||
if(istype(M, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = M
|
||||
mech_data += list(
|
||||
cargo_space = round((RM.cargo.len / RM.cargo_capacity) * 100)
|
||||
cargo_space = round((LAZYLEN(RM.cargo) / RM.cargo_capacity) * 100)
|
||||
)
|
||||
|
||||
data["mechs"] += list(mech_data)
|
||||
@@ -46,7 +46,8 @@
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/mecha/ui_act(action, params)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
@@ -57,7 +58,7 @@
|
||||
var/message = stripped_input(usr, "Input message", "Transmit message")
|
||||
var/obj/mecha/M = MT.chassis
|
||||
if(trim(message) && M)
|
||||
M.occupant_message(message)
|
||||
to_chat(M.occupant, message)
|
||||
to_chat(usr, "<span class='notice'>Message sent.</span>")
|
||||
. = TRUE
|
||||
if("shock")
|
||||
@@ -67,8 +68,8 @@
|
||||
var/obj/mecha/M = MT.chassis
|
||||
if(M)
|
||||
MT.shock()
|
||||
log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which is currently [M.occupant? "being piloted by [key_name(M.occupant)]." : "without a pilot."] ")
|
||||
message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupant ? "being piloted by [key_name_admin(M.occupant)][ADMIN_FLW(M.occupant)]." : "without a pilot."] ")
|
||||
log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which [M.occupant ? "has the occupants [M.occupant]." : "without a pilot."] ")
|
||||
message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupant ? "occupied by [M.occupant][ADMIN_FLW(M)]." : "without a pilot."] ")
|
||||
. = TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking
|
||||
@@ -85,8 +86,8 @@
|
||||
var/obj/mecha/chassis
|
||||
|
||||
/**
|
||||
* Returns a html formatted string describing attached mech status
|
||||
*/
|
||||
* Returns a html formatted string describing attached mech status
|
||||
*/
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
@@ -101,7 +102,7 @@
|
||||
<b>Active Equipment:</b> [chassis.selected || "None"]"}
|
||||
if(istype(chassis, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = chassis
|
||||
answer += "<br><b>Used Cargo Space:</b> [round((RM.cargo.len / RM.cargo_capacity * 100), 0.01)]%"
|
||||
answer += "<br><b>Used Cargo Space:</b> [round((LAZYLEN(RM.cargo) / RM.cargo_capacity * 100), 0.01)]%"
|
||||
|
||||
return answer
|
||||
|
||||
@@ -125,8 +126,8 @@
|
||||
chassis = M
|
||||
|
||||
/**
|
||||
* Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown
|
||||
*/
|
||||
* Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown
|
||||
*/
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/shock()
|
||||
if(recharging)
|
||||
return
|
||||
@@ -136,8 +137,8 @@
|
||||
recharging = TRUE
|
||||
|
||||
/**
|
||||
* Resets recharge variable, allowing tracker to be EMP pulsed again
|
||||
*/
|
||||
* Resets recharge variable, allowing tracker to be EMP pulsed again
|
||||
*/
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/recharge()
|
||||
recharging = FALSE
|
||||
|
||||
|
||||
@@ -14,8 +14,41 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
grind_results = list(/datum/reagent/silicon = 20)
|
||||
var/build_path = null
|
||||
///determines if the circuit board originated from a vendor off station or not.
|
||||
var/onstation = TRUE
|
||||
|
||||
/obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M)
|
||||
if(LAZYLEN(M.component_parts))
|
||||
// This really shouldn't happen. If it somehow does, print out a stack trace and gracefully handle it.
|
||||
stack_trace("apply_defauly_parts called on machine that already had component_parts: [M]")
|
||||
|
||||
// Move to nullspace so you don't trigger handle_atom_del logic and remove existing parts.
|
||||
for(var/obj/item/part in M.component_parts)
|
||||
part.moveToNullspace(loc)
|
||||
qdel(part)
|
||||
|
||||
// List of components always contains the circuit board used to build it.
|
||||
M.component_parts = list(src)
|
||||
forceMove(M)
|
||||
|
||||
if(M.circuit != src)
|
||||
// This really shouldn't happen. If it somehow does, print out a stack trace and gracefully handle it.
|
||||
stack_trace("apply_default_parts called from a circuit board that does not belong to machine: [M]")
|
||||
|
||||
// Move to nullspace so you don't trigger handle_atom_del logic, remove old circuit, add new circuit.
|
||||
M.circuit.moveToNullspace()
|
||||
qdel(M.circuit)
|
||||
M.circuit = src
|
||||
|
||||
return
|
||||
|
||||
/**
|
||||
* Used to allow the circuitboard to configure a machine in some way, shape or form.
|
||||
*
|
||||
* Arguments:
|
||||
* * machine - The machine to attempt to configure.
|
||||
*/
|
||||
/obj/item/circuitboard/proc/configure_machine(obj/machinery/machine)
|
||||
return
|
||||
|
||||
// Circuitboard/machine
|
||||
@@ -36,8 +69,8 @@ micro-manipulator, console screen, beaker, Microlaser, matter bin, power cells.
|
||||
if(!req_components)
|
||||
return
|
||||
|
||||
M.component_parts = list(src) // List of components always contains a board
|
||||
moveToNullspace()
|
||||
. = ..()
|
||||
moveToNullspace() // thorw ourselves in nullspace
|
||||
|
||||
for(var/comp_path in req_components)
|
||||
var/comp_amt = req_components[comp_path]
|
||||
|
||||
@@ -1,58 +1,22 @@
|
||||
/obj/item/circuitboard/computer/turbine_computer
|
||||
name = "Turbine Computer (Computer Board)"
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
|
||||
/obj/item/circuitboard/computer/launchpad_console
|
||||
name = "Launchpad Control Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/launchpad
|
||||
|
||||
/obj/item/circuitboard/computer/message_monitor
|
||||
name = "Message Monitor (Computer Board)"
|
||||
build_path = /obj/machinery/computer/message_monitor
|
||||
|
||||
/obj/item/circuitboard/computer/security
|
||||
name = "Security Cameras (Computer Board)"
|
||||
build_path = /obj/machinery/computer/security
|
||||
|
||||
/obj/item/circuitboard/computer/security/shuttle
|
||||
name = "Shuttlelinking Security Cameras (Computer Board)"
|
||||
build_path = /obj/machinery/computer/security/shuttle
|
||||
|
||||
/obj/item/circuitboard/computer/xenobiology
|
||||
name = "circuit board (Xenobiology Console)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/xenobio
|
||||
|
||||
/obj/item/circuitboard/computer/base_construction
|
||||
name = "circuit board (Aux Mining Base Construction Console)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/base_construction
|
||||
//Command
|
||||
|
||||
/obj/item/circuitboard/computer/aiupload
|
||||
name = "AI Upload (Computer Board)"
|
||||
icon_state = "command"
|
||||
build_path = /obj/machinery/computer/upload/ai
|
||||
|
||||
/obj/item/circuitboard/computer/borgupload
|
||||
name = "Cyborg Upload (Computer Board)"
|
||||
icon_state = "command"
|
||||
build_path = /obj/machinery/computer/upload/borg
|
||||
|
||||
/obj/item/circuitboard/computer/med_data
|
||||
name = "Medical Records Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/med_data
|
||||
|
||||
/obj/item/circuitboard/computer/pandemic
|
||||
name = "PanD.E.M.I.C. 2200 (Computer Board)"
|
||||
build_path = /obj/machinery/computer/pandemic
|
||||
|
||||
/obj/item/circuitboard/computer/scan_consolenew
|
||||
name = "DNA Machine (Computer Board)"
|
||||
build_path = /obj/machinery/computer/scan_consolenew
|
||||
|
||||
/obj/item/circuitboard/computer/communications
|
||||
name = "Communications (Computer Board)"
|
||||
build_path = /obj/machinery/computer/communications
|
||||
var/lastTimeUsed = 0
|
||||
/obj/item/circuitboard/computer/bsa_control
|
||||
name = "Bluespace Artillery Controls (Computer Board)"
|
||||
build_path = /obj/machinery/computer/bsa_control
|
||||
|
||||
/obj/item/circuitboard/computer/card
|
||||
name = "ID Console (Computer Board)"
|
||||
icon_state = "command"
|
||||
build_path = /obj/machinery/computer/card
|
||||
|
||||
/obj/item/circuitboard/computer/card/centcom
|
||||
@@ -73,266 +37,238 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/circuitboard/computer/card/minor/examine(user)
|
||||
. = ..()
|
||||
. += "Currently set to \"[dept_list[target_dept]]\"."
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Currently set to \"[dept_list[target_dept]]\".</span>")
|
||||
|
||||
|
||||
//obj/item/circuitboard/computer/shield
|
||||
// name = "Shield Control (Computer Board)"
|
||||
// icon_state = "command"
|
||||
// build_path = /obj/machinery/computer/stationshield
|
||||
/obj/item/circuitboard/computer/teleporter
|
||||
name = "Teleporter (Computer Board)"
|
||||
build_path = /obj/machinery/computer/teleporter
|
||||
|
||||
/obj/item/circuitboard/computer/secure_data
|
||||
name = "Security Records Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/secure_data
|
||||
//Engineering
|
||||
|
||||
/obj/item/circuitboard/computer/stationalert
|
||||
name = "Station Alerts (Computer Board)"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/circuitboard/computer/apc_control
|
||||
name = "\improper Power Flow Control Console (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/apc_control
|
||||
|
||||
/obj/item/circuitboard/computer/atmos_alert
|
||||
name = "Atmospheric Alert (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/atmos_alert
|
||||
|
||||
/obj/item/circuitboard/computer/atmos_control
|
||||
name = "Atmospheric Monitor (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/atmos_control
|
||||
|
||||
/obj/item/circuitboard/computer/atmos_control/incinerator
|
||||
name = "Incinerator Air Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/incinerator
|
||||
|
||||
/obj/item/circuitboard/computer/atmos_control/toxinsmix
|
||||
name = "Toxins Mixing Air Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/toxinsmix
|
||||
|
||||
/obj/item/circuitboard/computer/atmos_control/tank
|
||||
name = "Tank Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank
|
||||
|
||||
/obj/item/circuitboard/computer/atmos_alert
|
||||
name = "Atmospheric Alert (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_alert
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/oxygen_tank
|
||||
name = "Oxygen Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/oxygen_tank
|
||||
|
||||
/obj/item/circuitboard/computer/pod
|
||||
name = "Massdriver control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/pod
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/toxin_tank
|
||||
name = "Plasma Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/toxin_tank
|
||||
|
||||
/obj/item/circuitboard/computer/robotics
|
||||
name = "Robotics Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/robotics
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/air_tank
|
||||
name = "Mixed Air Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/air_tank
|
||||
|
||||
/obj/item/circuitboard/computer/cloning
|
||||
name = "Cloning (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cloning
|
||||
var/list/records = list()
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/mix_tank
|
||||
name = "Gas Mix Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/mix_tank
|
||||
|
||||
/obj/item/circuitboard/computer/cloning/prototype
|
||||
name = "Prototype Cloning (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cloning/prototype
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/nitrous_tank
|
||||
name = "Nitrous Oxide Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/nitrous_tank
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/battle
|
||||
name = "Arcade Battle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/battle
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/nitrogen_tank
|
||||
name = "Nitrogen Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/nitrogen_tank
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/orion_trail
|
||||
name = "Orion Trail (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/orion_trail
|
||||
/obj/item/circuitboard/computer/atmos_control/tank/carbon_tank
|
||||
name = "Carbon Dioxide Supply Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/atmos_control/tank/carbon_tank
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/minesweeper
|
||||
name = "Minesweeper (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/minesweeper
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/bz_tank
|
||||
// name = "BZ Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/bz_tank
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/amputation
|
||||
name = "Mediborg's Amputation Adventure (Computer Board)"
|
||||
build_path = /obj/machinery/computer/arcade/amputation
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/freon_tank
|
||||
// name = "Freon Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/freon_tank
|
||||
|
||||
/obj/item/circuitboard/computer/turbine_control
|
||||
name = "Turbine control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/halon_tank
|
||||
// name = "Halon Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/halon_tank
|
||||
|
||||
/obj/item/circuitboard/computer/solar_control
|
||||
name = "Solar Control (Computer Board)" //name fixed 250810
|
||||
build_path = /obj/machinery/power/solar_control
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/healium_tank
|
||||
// name = "Healium Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/healium_tank
|
||||
|
||||
/obj/item/circuitboard/computer/powermonitor
|
||||
name = "Power Monitor (Computer Board)" //name fixed 250810
|
||||
build_path = /obj/machinery/computer/monitor
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/hydrogen_tank
|
||||
// name = "Hydrogen Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/hydrogen_tank
|
||||
|
||||
/obj/item/circuitboard/computer/powermonitor/secret
|
||||
name = "Outdated Power Monitor (Computer Board)" //Variant used on ruins to prevent them from showing up on PDA's.
|
||||
build_path = /obj/machinery/computer/monitor/secret
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/hypernoblium_tank
|
||||
// name = "Hypernoblium Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/hypernoblium_tank
|
||||
|
||||
/obj/item/circuitboard/computer/olddoor
|
||||
name = "DoorMex (Computer Board)"
|
||||
build_path = /obj/machinery/computer/pod/old
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/miasma_tank
|
||||
// name = "Miasma Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/miasma_tank
|
||||
|
||||
/obj/item/circuitboard/computer/syndicatedoor
|
||||
name = "ProComp Executive (Computer Board)"
|
||||
build_path = /obj/machinery/computer/pod/old/syndicate
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/nitryl_tank
|
||||
// name = "Nitryl Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/nitryl_tank
|
||||
|
||||
/obj/item/circuitboard/computer/swfdoor
|
||||
name = "Magix (Computer Board)"
|
||||
build_path = /obj/machinery/computer/pod/old/swf
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/pluoxium_tank
|
||||
// name = "Pluoxium Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/pluoxium_tank
|
||||
|
||||
/obj/item/circuitboard/computer/prisoner
|
||||
name = "Prisoner Management Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/prisoner/management
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/proto_nitrate_tank
|
||||
// name = "Proto-Nitrate Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/proto_nitrate_tank
|
||||
|
||||
/obj/item/circuitboard/computer/gulag_teleporter_console
|
||||
name = "Labor Camp teleporter console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/prisoner/gulag_teleporter_computer
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/stimulum_tank
|
||||
// name = "Stimulum Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/stimulum_tank
|
||||
|
||||
/obj/item/circuitboard/computer/rdconsole/production
|
||||
name = "R&D Console Production Only (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/production
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/tritium_tank
|
||||
// name = "Tritium Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/tritium_tank
|
||||
|
||||
/obj/item/circuitboard/computer/rdconsole
|
||||
name = "R&D Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/water_vapor
|
||||
// name = "Water Vapor Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/water_vapor
|
||||
|
||||
/obj/item/circuitboard/computer/rdconsole/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(build_path == /obj/machinery/computer/rdconsole/core)
|
||||
name = "R&D Console - Robotics (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/robotics
|
||||
to_chat(user, "<span class='notice'>Access protocols successfully updated.</span>")
|
||||
else
|
||||
name = "R&D Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
to_chat(user, "<span class='notice'>Defaulting access protocols.</span>")
|
||||
else
|
||||
return ..()
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/zauker_tank
|
||||
// name = "Zauker Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/zauker_tank
|
||||
|
||||
/obj/item/circuitboard/computer/mecha_control
|
||||
name = "Exosuit Control Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/mecha
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/helium_tank
|
||||
// name = "Helium Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/helium_tank
|
||||
|
||||
/obj/item/circuitboard/computer/rdservercontrol
|
||||
name = "R&D Server Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdservercontrol
|
||||
// /obj/item/circuitboard/computer/atmos_control/tank/antinoblium_tank
|
||||
// name = "Antinoblium Supply Control (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/atmos_control/tank/antinoblium_tank
|
||||
|
||||
/obj/item/circuitboard/computer/crew
|
||||
name = "Crew Monitoring Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/crew
|
||||
/obj/item/circuitboard/computer/auxiliary_base
|
||||
name = "Auxiliary Base Management Console (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/auxillary_base
|
||||
|
||||
/obj/item/circuitboard/computer/mech_bay_power_console
|
||||
name = "Mech Bay Power Control Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/mech_bay_power_console
|
||||
/obj/item/circuitboard/computer/base_construction
|
||||
name = "circuit board (Generic Base Construction Console)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/camera_advanced/base_construction
|
||||
|
||||
/obj/item/circuitboard/computer/cargo
|
||||
name = "Supply Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cargo
|
||||
var/contraband = FALSE
|
||||
// /obj/item/circuitboard/computer/base_construction/aux
|
||||
// name = "circuit board (Aux Mining Base Construction Console)"
|
||||
// icon_state = "engineering"
|
||||
// build_path = /obj/machinery/computer/camera_advanced/base_construction/aux
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/multitool_act(mob/living/user)
|
||||
if(!(obj_flags & EMAGGED))
|
||||
contraband = !contraband
|
||||
to_chat(user, "<span class='notice'>Receiver spectrum set to [contraband ? "Broad" : "Standard"].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The spectrum chip is unresponsive.</span>")
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/emag_act(mob/living/user)
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express
|
||||
name = "Express Supply Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cargo/express
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
|
||||
if (!(obj_flags & EMAGGED))
|
||||
to_chat(user, "<span class='notice'>Routing protocols are already set to: \"factory defaults\".</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You reset the routing protocols to: \"factory defaults\".</span>")
|
||||
obj_flags &= ~EMAGGED
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
|
||||
. = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
|
||||
if(obj_flags & EMAGGED)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You change the routing protocols, allowing the Drop Pod to land anywhere on the station.</span>")
|
||||
obj_flags |= EMAGGED
|
||||
return TRUE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/request
|
||||
name = "Supply Request Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cargo/request
|
||||
|
||||
/obj/item/circuitboard/computer/bounty
|
||||
name = "Nanotrasen Bounty Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/bounty
|
||||
|
||||
/obj/item/circuitboard/computer/operating
|
||||
name = "Operating Computer (Computer Board)"
|
||||
build_path = /obj/machinery/computer/operating
|
||||
|
||||
/obj/item/circuitboard/computer/mining
|
||||
name = "Outpost Status Display (Computer Board)"
|
||||
build_path = /obj/machinery/computer/security/mining
|
||||
|
||||
/obj/item/circuitboard/computer/research
|
||||
name = "Research Monitor (Computer Board)"
|
||||
build_path = /obj/machinery/computer/security/research
|
||||
// /obj/item/circuitboard/computer/base_construction/centcom
|
||||
// name = "circuit board (Centcom Base Construction Console)"
|
||||
// icon_state = "engineering"
|
||||
// build_path = /obj/machinery/computer/camera_advanced/base_construction/centcom
|
||||
|
||||
/obj/item/circuitboard/computer/comm_monitor
|
||||
name = "Telecommunications Monitor (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/telecomms/monitor
|
||||
|
||||
/obj/item/circuitboard/computer/comm_server
|
||||
name = "Telecommunications Server Monitor (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/telecomms/server
|
||||
|
||||
/obj/item/circuitboard/computer/labor_shuttle
|
||||
name = "Labor Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/labor
|
||||
/obj/item/circuitboard/computer/communications
|
||||
name = "Communications (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/communications
|
||||
|
||||
/obj/item/circuitboard/computer/labor_shuttle/one_way
|
||||
name = "Prisoner Shuttle Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/labor/one_way
|
||||
/obj/item/circuitboard/computer/message_monitor
|
||||
name = "Message Monitor (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/message_monitor
|
||||
|
||||
/obj/item/circuitboard/computer/ferry
|
||||
name = "Transport Ferry (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/ferry
|
||||
/obj/item/circuitboard/computer/powermonitor
|
||||
name = "Power Monitor (Computer Board)" //name fixed 250810
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/monitor
|
||||
|
||||
/obj/item/circuitboard/computer/ferry/request
|
||||
name = "Transport Ferry Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/ferry/request
|
||||
/obj/item/circuitboard/computer/powermonitor/secret
|
||||
name = "Outdated Power Monitor (Computer Board)" //Variant used on ruins to prevent them from showing up on PDA's.
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/monitor/secret
|
||||
|
||||
/obj/item/circuitboard/computer/mining_shuttle
|
||||
name = "Mining Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/mining
|
||||
/obj/item/circuitboard/computer/sat_control
|
||||
name = "Satellite Network Control (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/sat_control
|
||||
|
||||
/obj/item/circuitboard/computer/mining_shuttle/common
|
||||
name = "Lavaland Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/mining/common
|
||||
/obj/item/circuitboard/computer/solar_control
|
||||
name = "Solar Control (Computer Board)" //name fixed 250810
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/power/solar_control
|
||||
|
||||
/obj/item/circuitboard/computer/snow_taxi
|
||||
name = "Snow Taxi (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/snow_taxi
|
||||
/obj/item/circuitboard/computer/stationalert
|
||||
name = "Station Alerts (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
|
||||
/obj/item/circuitboard/computer/white_ship
|
||||
name = "White Ship (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship
|
||||
/obj/item/circuitboard/computer/turbine_computer
|
||||
name = "Turbine Computer (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
|
||||
/obj/item/circuitboard/computer/white_ship/pod
|
||||
name = "Salvage Pod (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship/pod
|
||||
/obj/item/circuitboard/computer/turbine_control
|
||||
name = "Turbine control (Computer Board)"
|
||||
icon_state = "engineering"
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
|
||||
/obj/item/circuitboard/computer/white_ship/pod/recall
|
||||
name = "Salvage Pod Recall (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship/pod/recall
|
||||
//Generic
|
||||
|
||||
/obj/item/circuitboard/computer/auxillary_base
|
||||
name = "Auxillary Base Management Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/auxillary_base
|
||||
/obj/item/circuitboard/computer/arcade/amputation
|
||||
name = "Mediborg's Amputation Adventure (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/arcade/amputation
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/battle
|
||||
name = "Arcade Battle (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/arcade/battle
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/orion_trail
|
||||
name = "Orion Trail (Computer Board)"
|
||||
|
||||
build_path = /obj/machinery/computer/arcade/orion_trail
|
||||
|
||||
/obj/item/circuitboard/computer/arcade/minesweeper
|
||||
name = "Minesweeper (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/arcade/minesweeper
|
||||
|
||||
/obj/item/circuitboard/computer/holodeck// Not going to let people get this, but it's just here for future
|
||||
name = "Holodeck Control (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/holodeck
|
||||
|
||||
/obj/item/circuitboard/computer/aifixer
|
||||
name = "AI Integrity Restorer (Computer Board)"
|
||||
build_path = /obj/machinery/computer/aifixer
|
||||
|
||||
/obj/item/circuitboard/computer/slot_machine
|
||||
name = "Slot Machine (Computer Board)"
|
||||
build_path = /obj/machinery/computer/slot_machine
|
||||
|
||||
/obj/item/circuitboard/computer/libraryconsole
|
||||
name = "Library Visitor Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/libraryconsole
|
||||
@@ -350,16 +286,34 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/circuitboard/computer/apc_control
|
||||
name = "\improper Power Flow Control Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/apc_control
|
||||
|
||||
/obj/item/circuitboard/computer/monastery_shuttle
|
||||
name = "Monastery Shuttle (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/shuttle/monastery_shuttle
|
||||
|
||||
/obj/item/circuitboard/computer/olddoor
|
||||
name = "DoorMex (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/pod/old
|
||||
|
||||
/obj/item/circuitboard/computer/pod
|
||||
name = "Massdriver control (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/pod
|
||||
|
||||
/obj/item/circuitboard/computer/slot_machine
|
||||
name = "Slot Machine (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/slot_machine
|
||||
|
||||
/obj/item/circuitboard/computer/swfdoor
|
||||
name = "Magix (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/pod/old/swf
|
||||
|
||||
/obj/item/circuitboard/computer/syndicate_shuttle
|
||||
name = "Syndicate Shuttle (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/shuttle/syndicate
|
||||
var/challenge = FALSE
|
||||
var/moved = FALSE
|
||||
@@ -372,26 +326,296 @@
|
||||
GLOB.syndicate_shuttle_boards -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/circuitboard/computer/bsa_control
|
||||
name = "Bluespace Artillery Controls (Computer Board)"
|
||||
build_path = /obj/machinery/computer/bsa_control
|
||||
/obj/item/circuitboard/computer/syndicatedoor
|
||||
name = "ProComp Executive (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/pod/old/syndicate
|
||||
|
||||
/obj/item/circuitboard/computer/sat_control
|
||||
name = "Satellite Network Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/sat_control
|
||||
/obj/item/circuitboard/computer/white_ship
|
||||
name = "White Ship (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship
|
||||
|
||||
// /obj/item/circuitboard/computer/white_ship/bridge
|
||||
// name = "White Ship Bridge (Computer Board)"
|
||||
// icon_state = "generic"
|
||||
// build_path = /obj/machinery/computer/shuttle/white_ship/bridge
|
||||
|
||||
/obj/item/circuitboard/computer/white_ship/pod
|
||||
name = "Salvage Pod (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship/pod
|
||||
|
||||
/obj/item/circuitboard/computer/white_ship/pod/recall
|
||||
name = "Salvage Pod Recall (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/white_ship/pod/recall
|
||||
|
||||
/obj/item/circuitboard/computer/snow_taxi
|
||||
name = "Snow Taxi (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/snow_taxi
|
||||
|
||||
// /obj/item/circuitboard/computer/bountypad
|
||||
// name = "Bounty Pad (Computer Board)"
|
||||
// build_path = /obj/machinery/computer/piratepad_control/civilian
|
||||
|
||||
/obj/item/circuitboard/computer/security/shuttle
|
||||
name = "Shuttlelinking Security Cameras (Computer Board)"
|
||||
icon_state = "generic"
|
||||
build_path = /obj/machinery/computer/security/shuttle
|
||||
|
||||
//Medical
|
||||
|
||||
/obj/item/circuitboard/computer/crew
|
||||
name = "Crew Monitoring Console (Computer Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/computer/crew
|
||||
|
||||
/obj/item/circuitboard/computer/med_data
|
||||
name = "Medical Records Console (Computer Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/computer/med_data
|
||||
|
||||
/obj/item/circuitboard/computer/operating
|
||||
name = "Operating Computer (Computer Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/computer/operating
|
||||
|
||||
/obj/item/circuitboard/computer/pandemic
|
||||
name = "PanD.E.M.I.C. 2200 (Computer Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/computer/pandemic
|
||||
|
||||
/obj/item/circuitboard/computer/cloning
|
||||
name = "Cloning (Computer Board)"
|
||||
icon_state = "medical"
|
||||
build_path = /obj/machinery/computer/cloning
|
||||
var/list/records = list()
|
||||
|
||||
/obj/item/circuitboard/computer/cloning/prototype
|
||||
name = "Prototype Cloning (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cloning/prototype
|
||||
|
||||
//Science
|
||||
|
||||
/obj/item/circuitboard/computer/aifixer
|
||||
name = "AI Integrity Restorer (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/aifixer
|
||||
|
||||
/obj/item/circuitboard/computer/launchpad_console
|
||||
name = "Launchpad Control Console (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/launchpad
|
||||
|
||||
/obj/item/circuitboard/computer/mech_bay_power_console
|
||||
name = "Mech Bay Power Control Console (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/mech_bay_power_console
|
||||
|
||||
/obj/item/circuitboard/computer/mecha_control
|
||||
name = "Exosuit Control Console (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/mecha
|
||||
|
||||
/obj/item/circuitboard/computer/nanite_chamber_control
|
||||
name = "Nanite Chamber Control (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/nanite_chamber_control
|
||||
|
||||
/obj/item/circuitboard/computer/nanite_cloud_controller
|
||||
name = "Nanite Cloud Control (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/nanite_cloud_controller
|
||||
/obj/item/circuitboard/computer/rdconsole/production
|
||||
name = "R&D Console Production Only (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/rdconsole/production
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle/flight_control
|
||||
name = "Shuttle Flight Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/custom_shuttle
|
||||
/obj/item/circuitboard/computer/rdconsole
|
||||
name = "R&D Console (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
|
||||
/obj/item/circuitboard/computer/rdconsole/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(build_path == /obj/machinery/computer/rdconsole/core)
|
||||
name = "R&D Console - Robotics (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/robotics
|
||||
to_chat(user, "<span class='notice'>Access protocols successfully updated.</span>")
|
||||
else
|
||||
name = "R&D Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
to_chat(user, "<span class='notice'>Defaulting access protocols.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/circuitboard/computer/rdservercontrol
|
||||
name = "R&D Server Control (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/rdservercontrol
|
||||
|
||||
/obj/item/circuitboard/computer/research
|
||||
name = "Research Monitor (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/security/research
|
||||
|
||||
/obj/item/circuitboard/computer/robotics
|
||||
name = "Robotics Control (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/robotics
|
||||
|
||||
/obj/item/circuitboard/computer/teleporter
|
||||
name = "Teleporter (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/teleporter
|
||||
|
||||
/obj/item/circuitboard/computer/xenobiology
|
||||
name = "Xenobiology Console (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/camera_advanced/xenobio
|
||||
|
||||
/obj/item/circuitboard/computer/scan_consolenew
|
||||
name = "DNA Console (Computer Board)"
|
||||
icon_state = "science"
|
||||
build_path = /obj/machinery/computer/scan_consolenew
|
||||
|
||||
// /obj/item/circuitboard/computer/mechpad
|
||||
// name = "Mecha Orbital Pad Console (Computer Board)"
|
||||
// icon_state = "science"
|
||||
// build_path = /obj/machinery/computer/mechpad
|
||||
|
||||
//Security
|
||||
|
||||
/obj/item/circuitboard/computer/labor_shuttle
|
||||
name = "Labor Shuttle (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/shuttle/labor
|
||||
|
||||
/obj/item/circuitboard/computer/labor_shuttle/one_way
|
||||
name = "Prisoner Shuttle Console (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/shuttle/labor/one_way
|
||||
|
||||
/obj/item/circuitboard/computer/gulag_teleporter_console
|
||||
name = "Labor Camp teleporter console (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/prisoner/gulag_teleporter_computer
|
||||
|
||||
/obj/item/circuitboard/computer/prisoner
|
||||
name = "Prisoner Management Console (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/prisoner/management
|
||||
|
||||
/obj/item/circuitboard/computer/secure_data
|
||||
name = "Security Records Console (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/secure_data
|
||||
|
||||
// /obj/item/circuitboard/computer/warrant
|
||||
// name = "Security Warrant Viewer (Computer Board)"
|
||||
// icon_state = "security"
|
||||
// build_path = /obj/machinery/computer/warrant
|
||||
|
||||
/obj/item/circuitboard/computer/security
|
||||
name = "Security Cameras (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/security
|
||||
|
||||
/obj/item/circuitboard/computer/advanced_camera
|
||||
name = "Advanced Camera Console (Computer Board)"
|
||||
icon_state = "security"
|
||||
build_path = /obj/machinery/computer/camera_advanced/syndie
|
||||
|
||||
//Service
|
||||
|
||||
//Supply
|
||||
|
||||
/obj/item/circuitboard/computer/cargo
|
||||
name = "Supply Console (Computer Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/computer/cargo
|
||||
var/contraband = FALSE
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/multitool_act(mob/living/user)
|
||||
. = ..()
|
||||
if(!(obj_flags & EMAGGED))
|
||||
contraband = !contraband
|
||||
to_chat(user, "<span class='notice'>Receiver spectrum set to [contraband ? "Broad" : "Standard"].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>The spectrum chip is unresponsive.</span>")
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/emag_act(mob/living/user)
|
||||
. = ..()
|
||||
if(!(obj_flags & EMAGGED))
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You adjust [src]'s routing and receiver spectrum, unlocking special supplies and contraband.</span>")
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/configure_machine(obj/machinery/computer/cargo/machine)
|
||||
if(!istype(machine))
|
||||
CRASH("Cargo board attempted to configure incorrect machine type: [machine] ([machine?.type])")
|
||||
|
||||
machine.contraband = contraband
|
||||
if (obj_flags & EMAGGED)
|
||||
machine.obj_flags |= EMAGGED
|
||||
else
|
||||
machine.obj_flags &= ~EMAGGED
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express
|
||||
name = "Express Supply Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cargo/express
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/emag_act(mob/living/user)
|
||||
if(!(obj_flags & EMAGGED))
|
||||
contraband = TRUE
|
||||
obj_flags |= EMAGGED
|
||||
to_chat(user, "<span class='notice'>You change the routing protocols, allowing the Drop Pod to land anywhere on the station.</span>")
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/express/multitool_act(mob/living/user)
|
||||
if (!(obj_flags & EMAGGED))
|
||||
contraband = !contraband
|
||||
to_chat(user, "<span class='notice'>Receiver spectrum set to [contraband ? "Broad" : "Standard"].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You reset the destination-routing protocols and receiver spectrum to factory defaults.</span>")
|
||||
contraband = FALSE
|
||||
obj_flags &= ~EMAGGED
|
||||
|
||||
/obj/item/circuitboard/computer/cargo/request
|
||||
name = "Supply Request Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/cargo/request
|
||||
|
||||
/obj/item/circuitboard/computer/bounty
|
||||
name = "Nanotrasen Bounty Console (Computer Board)"
|
||||
build_path = /obj/machinery/computer/bounty
|
||||
|
||||
/obj/item/circuitboard/computer/ferry
|
||||
name = "Transport Ferry (Computer Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/computer/shuttle/ferry
|
||||
|
||||
/obj/item/circuitboard/computer/ferry/request
|
||||
name = "Transport Ferry Console (Computer Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/computer/shuttle/ferry/request
|
||||
|
||||
/obj/item/circuitboard/computer/mining
|
||||
name = "Outpost Status Display (Computer Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/computer/security/mining
|
||||
|
||||
/obj/item/circuitboard/computer/mining_shuttle
|
||||
name = "Mining Shuttle (Computer Board)"
|
||||
icon_state = "supply"
|
||||
build_path = /obj/machinery/computer/shuttle/mining
|
||||
|
||||
/obj/item/circuitboard/computer/mining_shuttle/common
|
||||
name = "Lavaland Shuttle (Computer Board)"
|
||||
build_path = /obj/machinery/computer/shuttle/mining/common
|
||||
|
||||
/obj/item/circuitboard/computer/shuttle/docker
|
||||
name = "Shuttle Navigation Computer (Computer Board)"
|
||||
build_path = /obj/machinery/computer/camera_advanced/shuttle_docker/custom
|
||||
|
||||
// DIY shuttle
|
||||
/obj/item/circuitboard/computer/shuttle/flight_control
|
||||
name = "Shuttle Flight Control (Computer Board)"
|
||||
build_path = /obj/machinery/computer/custom_shuttle
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -122,7 +122,10 @@
|
||||
/obj/item/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
|
||||
src.pai = personality
|
||||
src.add_overlay("pai-null")
|
||||
|
||||
var/list/policies = CONFIG_GET(keyed_list/policyconfig)
|
||||
var/policy = policies[POLICYCONFIG_PAI]
|
||||
if(policy)
|
||||
to_chat(personality, policy)
|
||||
playsound(loc, 'sound/effects/pai_boot.ogg', 50, 1, -1)
|
||||
audible_message("\The [src] plays a cheerful startup noise!")
|
||||
|
||||
|
||||
@@ -180,6 +180,11 @@
|
||||
|
||||
//Called from turf.dm turf/dblclick
|
||||
/obj/item/flamethrower/proc/flame_turf(turflist)
|
||||
var/mob/living/carbon/human/user = loc
|
||||
// no fun for pacifists
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to put others in danger!</span>")
|
||||
return
|
||||
if(!lit || operating)
|
||||
return
|
||||
operating = TRUE
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
w_class = WEIGHT_CLASS_GIGANTIC
|
||||
force = 12
|
||||
total_mass = TOTAL_MASS_NORMAL_ITEM // average toolbox
|
||||
attack_verb = list("robusted")
|
||||
@@ -70,19 +70,19 @@
|
||||
else
|
||||
. += "<span class='his_grace'>[src] is latched closed.</span>"
|
||||
|
||||
/obj/item/his_grace/relaymove(mob/living/user) //Allows changelings, etc. to climb out of Him after they revive, provided He isn't active
|
||||
/obj/item/his_grace/relaymove(mob/living/user, direction) //Allows changelings, etc. to climb out of Him after they revive, provided He isn't active
|
||||
if(!awakened)
|
||||
user.forceMove(get_turf(src))
|
||||
user.visible_message("<span class='warning'>[user] scrambles out of [src]!</span>", "<span class='notice'>You climb out of [src]!</span>")
|
||||
|
||||
/obj/item/his_grace/process()
|
||||
/obj/item/his_grace/process(delta_time)
|
||||
if(!bloodthirst)
|
||||
drowse()
|
||||
return
|
||||
if(bloodthirst < HIS_GRACE_CONSUME_OWNER && !ascended)
|
||||
adjust_bloodthirst(1 + FLOOR(LAZYLEN(contents) * 0.5, 1)) //Maybe adjust this?
|
||||
adjust_bloodthirst((1 + FLOOR(LAZYLEN(contents) * 0.5, 1)) * delta_time) //Maybe adjust this?
|
||||
else
|
||||
adjust_bloodthirst(1) //don't cool off rapidly once we're at the point where His Grace consumes all.
|
||||
adjust_bloodthirst(1 * delta_time) //don't cool off rapidly once we're at the point where His Grace consumes all.
|
||||
var/mob/living/master = get_atom_on_turf(src, /mob/living)
|
||||
if(istype(master) && (src in master.held_items))
|
||||
switch(bloodthirst)
|
||||
@@ -94,7 +94,7 @@
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT)
|
||||
master.DefaultCombatKnockdown(60)
|
||||
master.adjustBruteLoss(master.maxHealth)
|
||||
playsound(master, 'sound/effects/splat.ogg', 100, 0)
|
||||
playsound(master, 'sound/effects/splat.ogg', 100, FALSE)
|
||||
else
|
||||
master.apply_status_effect(STATUS_EFFECT_HISGRACE)
|
||||
return
|
||||
@@ -115,8 +115,8 @@
|
||||
if(!L.stat)
|
||||
L.visible_message("<span class='warning'>[src] lunges at [L]!</span>", "<span class='his_grace big bold'>[src] lunges at you!</span>")
|
||||
do_attack_animation(L, null, src)
|
||||
playsound(L, 'sound/weapons/smash.ogg', 50, 1)
|
||||
playsound(L, 'sound/misc/desceration-01.ogg', 50, 1)
|
||||
playsound(L, 'sound/weapons/smash.ogg', 50, TRUE)
|
||||
playsound(L, 'sound/misc/desceration-01.ogg', 50, TRUE)
|
||||
L.adjustBruteLoss(force)
|
||||
adjust_bloodthirst(-5) //Don't stop attacking they're right there!
|
||||
else
|
||||
@@ -137,6 +137,8 @@
|
||||
move_gracefully()
|
||||
|
||||
/obj/item/his_grace/proc/move_gracefully()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!awakened)
|
||||
return
|
||||
var/static/list/transforms
|
||||
@@ -161,7 +163,7 @@
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<span class='boldwarning'>[src] slowly stops rattling and falls still, His latch snapping shut.</span>")
|
||||
playsound(loc, 'sound/weapons/batonextend.ogg', 100, 1)
|
||||
playsound(loc, 'sound/weapons/batonextend.ogg', 100, TRUE)
|
||||
name = initial(name)
|
||||
desc = initial(desc)
|
||||
icon_state = initial(icon_state)
|
||||
@@ -178,8 +180,8 @@
|
||||
var/victims = 0
|
||||
meal.visible_message("<span class='warning'>[src] swings open and devours [meal]!</span>", "<span class='his_grace big bold'>[src] consumes you!</span>")
|
||||
meal.adjustBruteLoss(200)
|
||||
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
|
||||
playsound(src, 'sound/items/eatfood.ogg', 100, 1)
|
||||
playsound(meal, 'sound/misc/desceration-02.ogg', 75, TRUE)
|
||||
playsound(src, 'sound/items/eatfood.ogg', 100, TRUE)
|
||||
meal.forceMove(src)
|
||||
force_bonus += HIS_GRACE_FORCE_BONUS
|
||||
prev_bloodthirst = bloodthirst
|
||||
@@ -253,3 +255,4 @@
|
||||
if(istype(master))
|
||||
master.visible_message("<span class='his_grace big bold'>Gods will be watching.</span>")
|
||||
name = "[master]'s mythical toolbox of three powers"
|
||||
master.client?.give_award(/datum/award/achievement/misc/ascension, master)
|
||||
|
||||
@@ -328,6 +328,9 @@
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
|
||||
REMOVE_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
|
||||
name = initial(name)
|
||||
if(iscarbon(occupant))
|
||||
to_chat(occupant, "You pop out of the [src], slightly dazed!")
|
||||
occupant.Stun(5 SECONDS)
|
||||
|
||||
/obj/item/pet_carrier/bluespace/return_air()
|
||||
if(!occupant_gas_supply)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
grind_results = list(/datum/reagent/cellulose = 10)
|
||||
var/value = 0
|
||||
|
||||
/obj/item/stack/spacecash/Initialize()
|
||||
/obj/item/stack/spacecash/Initialize(mapload, new_amount, merge = TRUE)
|
||||
. = ..()
|
||||
update_desc()
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
material_type = /datum/material/glass
|
||||
point_value = 1
|
||||
tableVariant = /obj/structure/table/glass
|
||||
matter_amount = 4
|
||||
cost = 500
|
||||
shard_type = /obj/item/shard
|
||||
|
||||
/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user)
|
||||
@@ -69,12 +71,13 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
if (get_amount() < 1 || CC.get_amount() < 5)
|
||||
to_chat(user, "<span class='warning>You need five lengths of coil and one sheet of glass to make wired glass!</span>")
|
||||
return
|
||||
CC.use_tool(src, user, 0, 5, skill_gain_mult = TRIVIAL_USE_TOOL_MULT)
|
||||
CC.use(5)
|
||||
use(1)
|
||||
to_chat(user, "<span class='notice'>You attach wire to the [name].</span>")
|
||||
var/obj/item/stack/light_w/new_tile = new(user.loc)
|
||||
new_tile.add_fingerprint(user)
|
||||
else if(istype(W, /obj/item/stack/rods))
|
||||
return
|
||||
if(istype(W, /obj/item/stack/rods))
|
||||
var/obj/item/stack/rods/V = W
|
||||
if (V.get_amount() >= 1 && get_amount() >= 1)
|
||||
var/obj/item/stack/sheet/rglass/RG = new (get_turf(user))
|
||||
@@ -86,9 +89,8 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one rod and one sheet of glass to make reinforced glass!</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
@@ -164,6 +166,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
|
||||
merge_type = /obj/item/stack/sheet/rglass
|
||||
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10)
|
||||
point_value = 4
|
||||
matter_amount = 6
|
||||
shard_type = /obj/item/shard
|
||||
|
||||
/obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params)
|
||||
@@ -211,6 +214,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \
|
||||
merge_type = /obj/item/stack/sheet/plasmarglass
|
||||
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10)
|
||||
point_value = 23
|
||||
matter_amount = 8
|
||||
shard_type = /obj/item/shard/plasma
|
||||
|
||||
/obj/item/stack/sheet/plasmarglass/get_main_recipes()
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
///What type of wall does this sheet spawn
|
||||
var/walltype
|
||||
|
||||
/obj/item/stack/sheet/Initialize(mapload, new_amount, merge)
|
||||
/obj/item/stack/sheet/Initialize(mapload, new_amount, merge = TRUE)
|
||||
. = ..()
|
||||
pixel_x = rand(-4, 4)
|
||||
pixel_y = rand(-4, 4)
|
||||
|
||||
@@ -8,15 +8,18 @@
|
||||
/*
|
||||
* Stacks
|
||||
*/
|
||||
|
||||
/obj/item/stack
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
gender = PLURAL
|
||||
material_modifier = 0.01
|
||||
// material_modifier = 0.05 //5%, so that a 50 sheet stack has the effect of 5k materials instead of 100k.
|
||||
max_integrity = 100
|
||||
var/list/datum/stack_recipe/recipes
|
||||
var/singular_name
|
||||
var/amount = 1
|
||||
var/max_amount = 50 //also see stack recipes initialisation, param "max_res_amount" must be equal to this max_amount
|
||||
var/is_cyborg = 0 // It's 1 if module is used by a cyborg, and uses its storage
|
||||
var/is_cyborg = FALSE // It's TRUE if module is used by a cyborg, and uses its storage
|
||||
var/datum/robot_energy_storage/source
|
||||
var/cost = 1 // How much energy from storage it costs
|
||||
var/merge_type = null // This path and its children should merge with this stack, defaults to src.type
|
||||
@@ -25,7 +28,6 @@
|
||||
var/list/mats_per_unit //list that tells you how much is in a single unit.
|
||||
///Datum material type that this stack is made of
|
||||
var/material_type
|
||||
max_integrity = 100
|
||||
//NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind()
|
||||
var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack)
|
||||
|
||||
@@ -36,16 +38,8 @@
|
||||
var/absorption_capacity
|
||||
/// How quickly we lower the blood flow on a cut wound we're bandaging. Expected lifetime of this bandage in ticks is thus absorption_capacity/absorption_rate, or until the cut heals, whichever comes first
|
||||
var/absorption_rate
|
||||
|
||||
/obj/item/stack/on_grind()
|
||||
for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists
|
||||
grind_results[grind_results[i]] *= get_amount() //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size
|
||||
|
||||
/obj/item/stack/grind_requirements()
|
||||
if(is_cyborg)
|
||||
to_chat(usr, "<span class='danger'>[src] is electronically synthesized in your chassis and can't be ground up!</span>")
|
||||
return
|
||||
return TRUE
|
||||
/// Amount of matter for RCD
|
||||
var/matter_amount = 0
|
||||
|
||||
/obj/item/stack/Initialize(mapload, new_amount, merge = TRUE)
|
||||
if(new_amount != null)
|
||||
@@ -55,16 +49,19 @@
|
||||
new type(loc, max_amount, FALSE)
|
||||
if(!merge_type)
|
||||
merge_type = type
|
||||
if(custom_materials && custom_materials.len)
|
||||
mats_per_unit = list()
|
||||
var/in_process_mat_list = custom_materials.Copy()
|
||||
|
||||
if(LAZYLEN(mats_per_unit))
|
||||
set_mats_per_unit(mats_per_unit, 1)
|
||||
else if(LAZYLEN(custom_materials))
|
||||
// DO NOT REMOVE! we have to inflate the values first
|
||||
for(var/i in custom_materials)
|
||||
mats_per_unit[SSmaterials.GetMaterialRef(i)] = in_process_mat_list[i]
|
||||
custom_materials[i] *= amount
|
||||
set_mats_per_unit(custom_materials, amount ? 1/amount : 1)
|
||||
|
||||
. = ..()
|
||||
if(merge)
|
||||
for(var/obj/item/stack/S in loc)
|
||||
if(S.merge_type == merge_type)
|
||||
if(can_merge(S))
|
||||
INVOKE_ASYNC(src, .proc/merge, S)
|
||||
var/list/temp_recipes = get_main_recipes()
|
||||
recipes = temp_recipes.Copy()
|
||||
@@ -73,12 +70,48 @@
|
||||
for(var/i in M.categories)
|
||||
switch(i)
|
||||
if(MAT_CATEGORY_BASE_RECIPES)
|
||||
var/list/temp = SSmaterials.base_stack_recipes.Copy()
|
||||
recipes += temp
|
||||
if(MAT_CATEGORY_RIGID)
|
||||
var/list/temp = SSmaterials.rigid_stack_recipes.Copy()
|
||||
recipes += temp
|
||||
update_weight()
|
||||
update_icon()
|
||||
|
||||
/** Sets the amount of materials per unit for this stack.
|
||||
*
|
||||
* Arguments:
|
||||
* - [mats][/list]: The value to set the mats per unit to.
|
||||
* - multiplier: The amount to multiply the mats per unit by. Defaults to 1.
|
||||
*/
|
||||
/obj/item/stack/proc/set_mats_per_unit(list/mats, multiplier=1)
|
||||
mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(mats, multiplier)
|
||||
update_custom_materials()
|
||||
|
||||
/** Updates the custom materials list of this stack.
|
||||
*/
|
||||
/obj/item/stack/proc/update_custom_materials()
|
||||
set_custom_materials(mats_per_unit, amount, is_update=TRUE)
|
||||
|
||||
/**
|
||||
* Override to make things like metalgen accurately set custom materials
|
||||
*/
|
||||
/obj/item/stack/set_custom_materials(list/materials, multiplier=1, is_update=FALSE)
|
||||
return is_update ? ..() : set_mats_per_unit(materials, multiplier / (amount || 1))
|
||||
|
||||
/obj/item/stack/on_grind()
|
||||
. = ..()
|
||||
for(var/i in 1 to length(grind_results)) //This should only call if it's ground, so no need to check if grind_results exists
|
||||
grind_results[grind_results[i]] *= get_amount() //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size
|
||||
|
||||
/obj/item/stack/grind_requirements()
|
||||
if(is_cyborg)
|
||||
to_chat(usr, "<span class='warning'>[src] is electronically synthesized in your chassis and can't be ground up!</span>")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/proc/get_main_recipes()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
return list()//empty list
|
||||
|
||||
/obj/item/stack/proc/update_weight()
|
||||
@@ -99,12 +132,6 @@
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_3"
|
||||
|
||||
|
||||
/obj/item/stack/Destroy()
|
||||
if (usr && usr.machine==src)
|
||||
usr << browse(null, "window=stack")
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/examine(mob/user)
|
||||
. = ..()
|
||||
if (is_cyborg)
|
||||
@@ -126,196 +153,208 @@
|
||||
|
||||
/obj/item/stack/proc/get_amount()
|
||||
if(is_cyborg)
|
||||
. = round(source.energy / cost)
|
||||
. = round(source?.energy / cost)
|
||||
else
|
||||
. = (amount)
|
||||
|
||||
/obj/item/stack/attack_self(mob/user)
|
||||
interact(user)
|
||||
/**
|
||||
* Builds all recipes in a given recipe list and returns an association list containing them
|
||||
*
|
||||
* Arguments:
|
||||
* * recipe_to_iterate - The list of recipes we are using to build recipes
|
||||
*/
|
||||
/obj/item/stack/proc/recursively_build_recipes(list/recipe_to_iterate)
|
||||
var/list/L = list()
|
||||
for(var/recipe in recipe_to_iterate)
|
||||
if(istype(recipe, /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/R = recipe
|
||||
L["[R.title]"] = recursively_build_recipes(R.recipes)
|
||||
if(istype(recipe, /datum/stack_recipe))
|
||||
var/datum/stack_recipe/R = recipe
|
||||
L["[R.title]"] = build_recipe(R)
|
||||
return L
|
||||
|
||||
/obj/item/stack/interact(mob/user, sublist)
|
||||
ui_interact(user, sublist)
|
||||
/**
|
||||
* Returns a list of properties of a given recipe
|
||||
*
|
||||
* Arguments:
|
||||
* * R - The stack recipe we are using to get a list of properties
|
||||
*/
|
||||
/obj/item/stack/proc/build_recipe(datum/stack_recipe/R)
|
||||
return list(
|
||||
"res_amount" = R.res_amount,
|
||||
"max_res_amount" = R.max_res_amount,
|
||||
"req_amount" = R.req_amount,
|
||||
"ref" = "\ref[R]",
|
||||
)
|
||||
|
||||
/obj/item/stack/ui_interact(mob/user, recipes_sublist)
|
||||
/**
|
||||
* Checks if the recipe is valid to be used
|
||||
*
|
||||
* Arguments:
|
||||
* * R - The stack recipe we are checking if it is valid
|
||||
* * recipe_list - The list of recipes we are using to check the given recipe
|
||||
*/
|
||||
/obj/item/stack/proc/is_valid_recipe(datum/stack_recipe/R, list/recipe_list)
|
||||
for(var/S in recipe_list)
|
||||
if(S == R)
|
||||
return TRUE
|
||||
if(istype(S, /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/L = S
|
||||
if(is_valid_recipe(R, L.recipes))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/stack/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
/obj/item/stack/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Stack", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/stack/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["amount"] = get_amount()
|
||||
return data
|
||||
|
||||
/obj/item/stack/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["recipes"] = recursively_build_recipes(recipes)
|
||||
return data
|
||||
|
||||
/obj/item/stack/ui_act(action, params)
|
||||
. = ..()
|
||||
if (!recipes)
|
||||
if(.)
|
||||
return
|
||||
if (!src || get_amount() <= 0)
|
||||
user << browse(null, "window=stack")
|
||||
user.set_machine(src) //for correct work of onclose
|
||||
var/list/recipe_list = recipes
|
||||
if (recipes_sublist && recipe_list[recipes_sublist] && istype(recipe_list[recipes_sublist], /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/srl = recipe_list[recipes_sublist]
|
||||
recipe_list = srl.recipes
|
||||
var/t1 = "Amount Left: [get_amount()]<br>"
|
||||
for(var/i in 1 to length(recipe_list))
|
||||
var/E = recipe_list[i]
|
||||
if (isnull(E))
|
||||
t1 += "<hr>"
|
||||
continue
|
||||
if (i>1 && !isnull(recipe_list[i-1]))
|
||||
t1+="<br>"
|
||||
|
||||
if (istype(E, /datum/stack_recipe_list))
|
||||
var/datum/stack_recipe_list/srl = E
|
||||
t1 += "<a href='?src=[REF(src)];sublist=[i]'>[srl.title]</a>"
|
||||
|
||||
if (istype(E, /datum/stack_recipe))
|
||||
var/datum/stack_recipe/R = E
|
||||
var/max_multiplier = round(get_amount() / R.req_amount)
|
||||
var/title
|
||||
var/can_build = 1
|
||||
can_build = can_build && (max_multiplier>0)
|
||||
|
||||
if (R.res_amount>1)
|
||||
title+= "[R.res_amount]x [R.title]\s"
|
||||
else
|
||||
title+= "[R.title]"
|
||||
title+= " ([R.req_amount] [singular_name]\s)"
|
||||
if (can_build)
|
||||
t1 += text("<A href='?src=[REF(src)];sublist=[recipes_sublist];make=[i];multiplier=1'>[title]</A> ")
|
||||
else
|
||||
t1 += text("[]", title)
|
||||
continue
|
||||
if (R.max_res_amount>1 && max_multiplier>1)
|
||||
max_multiplier = min(max_multiplier, round(R.max_res_amount/R.res_amount))
|
||||
t1 += " |"
|
||||
var/list/multipliers = list(5,10,25)
|
||||
for (var/n in multipliers)
|
||||
if (max_multiplier>=n)
|
||||
t1 += " <A href='?src=[REF(src)];make=[i];multiplier=[n]'>[n*R.res_amount]x</A>"
|
||||
if (!(max_multiplier in multipliers))
|
||||
t1 += " <A href='?src=[REF(src)];make=[i];multiplier=[max_multiplier]'>[max_multiplier*R.res_amount]x</A>"
|
||||
|
||||
var/datum/browser/popup = new(user, "stack", name, 400, 400)
|
||||
popup.set_content(t1)
|
||||
popup.open(0)
|
||||
onclose(user, "stack")
|
||||
|
||||
/obj/item/stack/Topic(href, href_list)
|
||||
..()
|
||||
if (usr.restrained() || usr.stat || usr.get_active_held_item() != src)
|
||||
return
|
||||
if (href_list["sublist"] && !href_list["make"])
|
||||
interact(usr, text2num(href_list["sublist"]))
|
||||
if (href_list["make"])
|
||||
if (get_amount() < 1 && !is_cyborg)
|
||||
qdel(src)
|
||||
|
||||
var/list/recipes_list = recipes
|
||||
if (href_list["sublist"])
|
||||
var/datum/stack_recipe_list/srl = recipes_list[text2num(href_list["sublist"])]
|
||||
recipes_list = srl.recipes
|
||||
var/datum/stack_recipe/R = recipes_list[text2num(href_list["make"])]
|
||||
var/multiplier = text2num(href_list["multiplier"])
|
||||
if (!multiplier ||(multiplier <= 0)) //href protection
|
||||
return
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
if (R.time)
|
||||
var/adjusted_time = 0
|
||||
usr.visible_message("<span class='notice'>[usr] starts building [R.title].</span>", "<span class='notice'>You start building [R.title]...</span>")
|
||||
if(HAS_TRAIT(usr, R.trait_booster))
|
||||
adjusted_time = (R.time * R.trait_modifier)
|
||||
else
|
||||
adjusted_time = R.time
|
||||
if (!do_after(usr, adjusted_time, target = usr))
|
||||
switch(action)
|
||||
if("make")
|
||||
if(get_amount() < 1 && !is_cyborg)
|
||||
qdel(src)
|
||||
return
|
||||
var/datum/stack_recipe/R = locate(params["ref"])
|
||||
if(!is_valid_recipe(R, recipes)) //href exploit protection
|
||||
return
|
||||
var/multiplier = text2num(params["multiplier"])
|
||||
if(!multiplier || (multiplier <= 0)) //href exploit protection
|
||||
return
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
if(R.time)
|
||||
var/adjusted_time = 0
|
||||
usr.visible_message("<span class='notice'>[usr] starts building \a [R.title].</span>", "<span class='notice'>You start building \a [R.title]...</span>")
|
||||
if(HAS_TRAIT(usr, R.trait_booster))
|
||||
adjusted_time = (R.time * R.trait_modifier)
|
||||
else
|
||||
adjusted_time = R.time
|
||||
if(!do_after(usr, adjusted_time, target = usr))
|
||||
return
|
||||
if(!building_checks(R, multiplier))
|
||||
return
|
||||
|
||||
var/obj/O
|
||||
if(R.max_res_amount > 1) //Is it a stack?
|
||||
O = new R.result_type(usr.drop_location(), R.res_amount * multiplier)
|
||||
else if(ispath(R.result_type, /turf))
|
||||
var/turf/T = usr.drop_location()
|
||||
if(!isturf(T))
|
||||
return
|
||||
T.PlaceOnTop(R.result_type, flags = CHANGETURF_INHERIT_AIR)
|
||||
var/obj/O
|
||||
if(R.max_res_amount > 1) //Is it a stack?
|
||||
O = new R.result_type(usr.drop_location(), R.res_amount * multiplier)
|
||||
else if(ispath(R.result_type, /turf))
|
||||
var/turf/T = usr.drop_location()
|
||||
if(!isturf(T))
|
||||
return
|
||||
T.PlaceOnTop(R.result_type, flags = CHANGETURF_INHERIT_AIR)
|
||||
else
|
||||
O = new R.result_type(usr.drop_location())
|
||||
if(O)
|
||||
O.setDir(usr.dir)
|
||||
use(R.req_amount * multiplier)
|
||||
|
||||
if(R.applies_mats && LAZYLEN(mats_per_unit))
|
||||
if(isstack(O))
|
||||
var/obj/item/stack/crafted_stack = O
|
||||
crafted_stack.set_mats_per_unit(mats_per_unit, R.req_amount / R.res_amount)
|
||||
else
|
||||
O.set_custom_materials(mats_per_unit, R.req_amount / R.res_amount)
|
||||
|
||||
if(istype(O, /obj/structure/windoor_assembly))
|
||||
var/obj/structure/windoor_assembly/W = O
|
||||
W.ini_dir = W.dir
|
||||
else if(istype(O, /obj/structure/window))
|
||||
var/obj/structure/window/W = O
|
||||
W.ini_dir = W.dir
|
||||
|
||||
if(QDELETED(O))
|
||||
return //It's a stack and has already been merged
|
||||
|
||||
if(isitem(O))
|
||||
usr.put_in_hands(O)
|
||||
O.add_fingerprint(usr)
|
||||
|
||||
//BubbleWrap - so newly formed boxes are empty
|
||||
if(istype(O, /obj/item/storage))
|
||||
for (var/obj/item/I in O)
|
||||
qdel(I)
|
||||
//BubbleWrap END
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/vv_edit_var(vname, vval)
|
||||
if(vname == NAMEOF(src, amount))
|
||||
add(clamp(vval, 1-amount, max_amount - amount)) //there must always be one.
|
||||
return TRUE
|
||||
else if(vname == NAMEOF(src, max_amount))
|
||||
max_amount = max(vval, 1)
|
||||
add((max_amount < amount) ? (max_amount - amount) : 0) //update icon, weight, ect
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/proc/building_checks(datum/stack_recipe/recipe, multiplier)
|
||||
if (get_amount() < recipe.req_amount*multiplier)
|
||||
if (recipe.req_amount*multiplier>1)
|
||||
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [recipe.req_amount*multiplier] [recipe.title]\s!</span>")
|
||||
else
|
||||
O = new R.result_type(get_turf(usr))
|
||||
if(O)
|
||||
O.setDir(usr.dir)
|
||||
log_craft("[O] crafted by [usr] at [loc_name(O.loc)]")
|
||||
|
||||
use(R.req_amount * multiplier)
|
||||
|
||||
if(R.applies_mats && custom_materials && custom_materials.len)
|
||||
var/list/used_materials = list()
|
||||
for(var/i in custom_materials)
|
||||
used_materials[SSmaterials.GetMaterialRef(i)] = R.req_amount / R.res_amount * (MINERAL_MATERIAL_AMOUNT / custom_materials.len)
|
||||
O.set_custom_materials(used_materials)
|
||||
|
||||
//START: oh fuck i'm so sorry
|
||||
if(istype(O, /obj/structure/windoor_assembly))
|
||||
var/obj/structure/windoor_assembly/W = O
|
||||
W.ini_dir = W.dir
|
||||
else if(istype(O, /obj/structure/window))
|
||||
var/obj/structure/window/W = O
|
||||
W.ini_dir = W.dir
|
||||
//END: oh fuck i'm so sorry
|
||||
|
||||
else if(istype(O, /obj/item/restraints/handcuffs/cable))
|
||||
var/obj/item/cuffs = O
|
||||
cuffs.color = color
|
||||
|
||||
if (QDELETED(O))
|
||||
return //It's a stack and has already been merged
|
||||
|
||||
if (isitem(O))
|
||||
usr.put_in_hands(O)
|
||||
O.add_fingerprint(usr)
|
||||
|
||||
//BubbleWrap - so newly formed boxes are empty
|
||||
if ( istype(O, /obj/item/storage) )
|
||||
for (var/obj/item/I in O)
|
||||
qdel(I)
|
||||
//BubbleWrap END
|
||||
|
||||
/obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier)
|
||||
if (get_amount() < R.req_amount*multiplier)
|
||||
if (R.req_amount*multiplier>1)
|
||||
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [R.req_amount*multiplier] [R.title]\s!</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [R.title]!</span>")
|
||||
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [recipe.title]!</span>")
|
||||
return FALSE
|
||||
var/turf/T = get_turf(usr)
|
||||
var/turf/dest_turf = get_turf(usr)
|
||||
|
||||
var/obj/D = R.result_type
|
||||
if(R.window_checks && !valid_window_location(T, initial(D.dir) == FULLTILE_WINDOW_DIR ? FULLTILE_WINDOW_DIR : usr.dir))
|
||||
to_chat(usr, "<span class='warning'>The [R.title] won't fit here!</span>")
|
||||
return FALSE
|
||||
if(R.one_per_turf && (locate(R.result_type) in T))
|
||||
to_chat(usr, "<span class='warning'>There is another [R.title] here!</span>")
|
||||
return FALSE
|
||||
if(R.on_floor)
|
||||
if(!isfloorturf(T))
|
||||
to_chat(usr, "<span class='warning'>\The [R.title] must be constructed on the floor!</span>")
|
||||
// If we're making a window, we have some special snowflake window checks to do.
|
||||
if(ispath(recipe.result_type, /obj/structure/window))
|
||||
var/obj/structure/window/result_path = recipe.result_type
|
||||
if(!valid_window_location(dest_turf, usr.dir, is_fulltile = initial(result_path.fulltile)))
|
||||
to_chat(usr, "<span class='warning'>The [recipe.title] won't fit here!</span>")
|
||||
return FALSE
|
||||
for(var/obj/AM in T)
|
||||
if(istype(AM,/obj/structure/grille))
|
||||
|
||||
if(recipe.one_per_turf && (locate(recipe.result_type) in dest_turf))
|
||||
to_chat(usr, "<span class='warning'>There is another [recipe.title] here!</span>")
|
||||
return FALSE
|
||||
|
||||
if(recipe.on_floor)
|
||||
if(!isfloorturf(dest_turf))
|
||||
to_chat(usr, "<span class='warning'>\The [recipe.title] must be constructed on the floor!</span>")
|
||||
return FALSE
|
||||
|
||||
for(var/obj/object in dest_turf)
|
||||
if(istype(object, /obj/structure/grille))
|
||||
continue
|
||||
if(istype(AM,/obj/structure/table))
|
||||
if(istype(object, /obj/structure/table))
|
||||
continue
|
||||
if(istype(AM,/obj/structure/window))
|
||||
var/obj/structure/window/W = AM
|
||||
if(!W.fulltile)
|
||||
if(istype(object, /obj/structure/window))
|
||||
var/obj/structure/window/window_structure = object
|
||||
if(!window_structure.fulltile)
|
||||
continue
|
||||
if(AM.density)
|
||||
to_chat(usr, "<span class='warning'>Theres a [AM.name] here. You cant make a [R.title] here!</span>")
|
||||
if(object.density)
|
||||
to_chat(usr, "<span class='warning'>There is \a [object.name] here. You cant make \a [recipe.title] here!</span>")
|
||||
return FALSE
|
||||
if(R.placement_checks)
|
||||
switch(R.placement_checks)
|
||||
if(recipe.placement_checks)
|
||||
switch(recipe.placement_checks)
|
||||
if(STACK_CHECK_CARDINALS)
|
||||
var/turf/step
|
||||
for(var/direction in GLOB.cardinals)
|
||||
step = get_step(T, direction)
|
||||
if(locate(R.result_type) in step)
|
||||
to_chat(usr, "<span class='warning'>\The [R.title] must not be built directly adjacent to another!</span>")
|
||||
step = get_step(dest_turf, direction)
|
||||
if(locate(recipe.result_type) in step)
|
||||
to_chat(usr, "<span class='warning'>\The [recipe.title] must not be built directly adjacent to another!</span>")
|
||||
return FALSE
|
||||
if(STACK_CHECK_ADJACENT)
|
||||
if(locate(R.result_type) in range(1, T))
|
||||
to_chat(usr, "<span class='warning'>\The [R.title] must be constructed at least one tile away from others of its type!</span>")
|
||||
if(locate(recipe.result_type) in range(1, dest_turf))
|
||||
to_chat(usr, "<span class='warning'>\The [recipe.title] must be constructed at least one tile away from others of its type!</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -330,10 +369,7 @@
|
||||
if(check && zero_amount())
|
||||
return TRUE
|
||||
if(length(mats_per_unit))
|
||||
var/temp_materials = custom_materials.Copy()
|
||||
for(var/i in mats_per_unit)
|
||||
temp_materials[i] = mats_per_unit[i] * src.amount
|
||||
set_custom_materials(temp_materials)
|
||||
update_custom_materials()
|
||||
update_icon()
|
||||
update_weight()
|
||||
return TRUE
|
||||
@@ -357,22 +393,36 @@
|
||||
return source.energy < cost
|
||||
if(amount < 1)
|
||||
qdel(src)
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/stack/proc/add(amount)
|
||||
/** Adds some number of units to this stack.
|
||||
*
|
||||
* Arguments:
|
||||
* - _amount: The number of units to add to this stack.
|
||||
*/
|
||||
/obj/item/stack/proc/add(_amount)
|
||||
if (is_cyborg)
|
||||
source.add_charge(amount * cost)
|
||||
source.add_charge(_amount * cost)
|
||||
else
|
||||
src.amount += amount
|
||||
amount += _amount
|
||||
if(length(mats_per_unit))
|
||||
var/temp_materials = custom_materials.Copy()
|
||||
for(var/i in mats_per_unit)
|
||||
temp_materials[i] = mats_per_unit[i] * src.amount
|
||||
set_custom_materials(temp_materials)
|
||||
update_custom_materials()
|
||||
update_icon()
|
||||
update_weight()
|
||||
|
||||
/** Checks whether this stack can merge itself into another stack.
|
||||
*
|
||||
* Arguments:
|
||||
* - [check][/obj/item/stack]: The stack to check for mergeability.
|
||||
*/
|
||||
/obj/item/stack/proc/can_merge(obj/item/stack/check)
|
||||
if(!istype(check, merge_type))
|
||||
return FALSE
|
||||
if(!check.is_cyborg && (mats_per_unit != check.mats_per_unit)) // Cyborg stacks don't have materials. This lets them recycle sheets and floor tiles.
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
|
||||
if(QDELETED(S) || QDELETED(src) || S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
|
||||
return
|
||||
@@ -388,50 +438,53 @@
|
||||
S.add(transfer)
|
||||
return transfer
|
||||
|
||||
/obj/item/stack/Crossed(obj/o)
|
||||
if(istype(o, merge_type) && !o.throwing)
|
||||
merge(o)
|
||||
/obj/item/stack/Crossed(atom/movable/crossing)
|
||||
if(!crossing.throwing && can_merge(crossing))
|
||||
merge(crossing)
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
if(istype(AM, merge_type))
|
||||
merge(AM)
|
||||
/obj/item/stack/hitby(atom/movable/hitting, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
|
||||
if(can_merge(hitting))
|
||||
merge(hitting)
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/stack/on_attack_hand(mob/user)
|
||||
if(user.get_inactive_held_item() == src)
|
||||
if(zero_amount())
|
||||
return
|
||||
return change_stack(user,1)
|
||||
return split_stack(user, 1)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/stack/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups
|
||||
return
|
||||
if(is_cyborg)
|
||||
if(is_cyborg || !user.canUseTopic(src, BE_CLOSE, TRUE, FALSE) || zero_amount()) //, !iscyborg(user)
|
||||
return
|
||||
else
|
||||
if(zero_amount())
|
||||
return
|
||||
//get amount from user
|
||||
var/max = get_amount()
|
||||
var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max])") as null|num)
|
||||
max = get_amount()
|
||||
stackmaterial = min(max, stackmaterial)
|
||||
if(stackmaterial == null || stackmaterial <= 0 || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
|
||||
return TRUE
|
||||
else
|
||||
change_stack(user, stackmaterial)
|
||||
to_chat(user, "<span class='notice'>You take [stackmaterial] sheets out of the stack</span>")
|
||||
return TRUE
|
||||
//get amount from user
|
||||
var/max = get_amount()
|
||||
var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max])") as null|num)
|
||||
max = get_amount()
|
||||
stackmaterial = min(max, stackmaterial)
|
||||
if(stackmaterial == null || stackmaterial <= 0 || !user.canUseTopic(src, BE_CLOSE, TRUE, FALSE)) //, !iscyborg(user)
|
||||
return
|
||||
split_stack(user, stackmaterial)
|
||||
to_chat(user, "<span class='notice'>You take [stackmaterial] sheets out of the stack.</span>")
|
||||
|
||||
/obj/item/stack/proc/change_stack(mob/user, amount)
|
||||
/** Splits the stack into two stacks.
|
||||
*
|
||||
* Arguments:
|
||||
* - [user][/mob]: The mob splitting the stack.
|
||||
* - amount: The number of units to split from this stack.
|
||||
*/
|
||||
/obj/item/stack/proc/split_stack(mob/user, amount)
|
||||
if(!use(amount, TRUE, FALSE))
|
||||
return FALSE
|
||||
return null
|
||||
var/obj/item/stack/F = new type(user? user : drop_location(), amount, FALSE)
|
||||
. = F
|
||||
F.set_mats_per_unit(mats_per_unit, 1) // Required for greyscale sheets and tiles.
|
||||
F.copy_evidences(src)
|
||||
if(user)
|
||||
if(!user.put_in_hands(F, merge_stacks = FALSE))
|
||||
@@ -441,7 +494,7 @@
|
||||
zero_amount()
|
||||
|
||||
/obj/item/stack/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, merge_type))
|
||||
if(can_merge(W))
|
||||
var/obj/item/stack/S = W
|
||||
if(merge(S))
|
||||
to_chat(user, "<span class='notice'>Your [S.name] stack now contains [S.get_amount()] [S.singular_name]\s.</span>")
|
||||
@@ -455,8 +508,8 @@
|
||||
fingerprints = from.fingerprints.Copy()
|
||||
if(from.fingerprintshidden)
|
||||
fingerprintshidden = from.fingerprintshidden.Copy()
|
||||
if(from.fingerprintslast)
|
||||
fingerprintslast = from.fingerprintslast
|
||||
fingerprintslast = from.fingerprintslast
|
||||
//TODO bloody overlay
|
||||
|
||||
/obj/item/stack/microwave_act(obj/machinery/microwave/M)
|
||||
if(istype(M) && M.dirty < 100)
|
||||
@@ -474,15 +527,12 @@
|
||||
var/time = 0
|
||||
var/one_per_turf = FALSE
|
||||
var/on_floor = FALSE
|
||||
var/window_checks = FALSE
|
||||
var/placement_checks = FALSE
|
||||
var/applies_mats = FALSE
|
||||
var/trait_booster = null
|
||||
var/trait_modifier = 1
|
||||
|
||||
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1)
|
||||
|
||||
|
||||
src.title = title
|
||||
src.result_type = result_type
|
||||
src.req_amount = req_amount
|
||||
@@ -491,7 +541,6 @@
|
||||
src.time = time
|
||||
src.one_per_turf = one_per_turf
|
||||
src.on_floor = on_floor
|
||||
src.window_checks = window_checks
|
||||
src.placement_checks = placement_checks
|
||||
src.applies_mats = applies_mats
|
||||
src.trait_booster = trait_booster
|
||||
|
||||
@@ -1143,9 +1143,9 @@
|
||||
desc = "A box containing a gift for worthy golems."
|
||||
|
||||
/obj/item/storage/box/rndboards/PopulateContents()
|
||||
new /obj/item/circuitboard/machine/protolathe/offstation(src)
|
||||
new /obj/item/circuitboard/machine/protolathe(src)
|
||||
new /obj/item/circuitboard/machine/destructive_analyzer(src)
|
||||
new /obj/item/circuitboard/machine/circuit_imprinter/offstation(src)
|
||||
new /obj/item/circuitboard/machine/circuit_imprinter(src)
|
||||
new /obj/item/circuitboard/computer/rdconsole(src)
|
||||
|
||||
/obj/item/storage/box/silver_sulf
|
||||
|
||||
@@ -164,11 +164,15 @@
|
||||
/obj/item/storage/secure/briefcase/hos/mws_pack_hos/PopulateContents()
|
||||
new /obj/item/gun/ballistic/revolver/mws(src)
|
||||
new /obj/item/ammo_box/magazine/mws_mag(src)
|
||||
new /obj/item/ammo_box/magazine/mws_mag(src)
|
||||
new /obj/item/ammo_casing/mws_batt/lethal(src)
|
||||
new /obj/item/ammo_casing/mws_batt/lethal(src)
|
||||
new /obj/item/ammo_casing/mws_batt/lethal(src)
|
||||
new /obj/item/ammo_casing/mws_batt/stun(src)
|
||||
new /obj/item/ammo_casing/mws_batt/stun(src)
|
||||
new /obj/item/ammo_casing/mws_batt/stun(src)
|
||||
new /obj/item/ammo_casing/mws_batt/ion(src)
|
||||
new /obj/item/ammo_casing/mws_batt/taser(src)
|
||||
|
||||
/obj/item/storage/secure/briefcase/hos/multiphase_box
|
||||
name = "\improper X-01 Multiphase energy gun box"
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
/obj/item/tank
|
||||
name = "tank"
|
||||
icon = 'icons/obj/tank.dmi'
|
||||
icon_state = "generic"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tanks_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tanks_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = ITEM_SLOT_BACK
|
||||
// worn_icon = 'icons/mob/clothing/back.dmi' //since these can also get thrown into suit storage slots. if something goes on the belt, set this to null.
|
||||
hitsound = 'sound/weapons/smash.ogg'
|
||||
pressure_resistance = ONE_ATMOSPHERE * 5
|
||||
force = 5
|
||||
@@ -18,6 +20,8 @@
|
||||
var/distribute_pressure = ONE_ATMOSPHERE
|
||||
var/integrity = 3
|
||||
var/volume = 70
|
||||
/// Icon state when in a tank holder. Null makes it incompatible with tank holder.
|
||||
var/tank_holder_icon_state = "holder_generic"
|
||||
|
||||
/obj/item/tank/ui_action_click(mob/user)
|
||||
toggle_internals(user)
|
||||
@@ -84,18 +88,23 @@
|
||||
|
||||
/obj/item/tank/Destroy()
|
||||
if(air_contents)
|
||||
qdel(air_contents)
|
||||
QDEL_NULL(air_contents)
|
||||
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
// /obj/item/tank/ComponentInitialize()
|
||||
// . = ..()
|
||||
// if(tank_holder_icon_state)
|
||||
// AddComponent(/datum/component/container_item/tank_holder, tank_holder_icon_state)
|
||||
|
||||
/obj/item/tank/examine(mob/user)
|
||||
var/obj/icon = src
|
||||
. = ..()
|
||||
if(istype(src.loc, /obj/item/assembly))
|
||||
icon = src.loc
|
||||
if(!in_range(src, user) && !isobserver(user))
|
||||
if (icon == src)
|
||||
if(icon == src)
|
||||
. += "<span class='notice'>If you want any more information you'll need to get closer.</span>"
|
||||
return
|
||||
|
||||
@@ -140,14 +149,14 @@
|
||||
if(T)
|
||||
T.assume_air(air_contents)
|
||||
air_update_turf()
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/tank/suicide_act(mob/user)
|
||||
var/mob/living/carbon/human/H = user
|
||||
user.visible_message("<span class='suicide'>[user] is putting [src]'s valve to [user.p_their()] lips! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
playsound(loc, 'sound/effects/spray.ogg', 10, 1, -3)
|
||||
if (!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000)
|
||||
playsound(loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
||||
if(!QDELETED(H) && air_contents && air_contents.return_pressure() >= 1000)
|
||||
for(var/obj/item/W in H)
|
||||
H.dropItemToGround(W)
|
||||
if(prob(50))
|
||||
@@ -159,12 +168,10 @@
|
||||
H.spawn_gibs()
|
||||
H.spill_organs()
|
||||
H.spread_bodyparts()
|
||||
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/tank/attack_ghost(mob/dead/observer/O)
|
||||
. = ..()
|
||||
atmosanalyzer_scan(air_contents, O, src, FALSE)
|
||||
return MANUAL_SUICIDE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There isn't enough pressure in [src] to commit suicide with...</span>")
|
||||
return SHAME
|
||||
|
||||
/obj/item/tank/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
@@ -182,27 +189,30 @@
|
||||
ui = new(user, src, "Tank", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/tank/ui_static_data(mob/user)
|
||||
. = list (
|
||||
"defaultReleasePressure" = round(TANK_DEFAULT_RELEASE_PRESSURE),
|
||||
"minReleasePressure" = round(TANK_MIN_RELEASE_PRESSURE),
|
||||
"maxReleasePressure" = round(TANK_MAX_RELEASE_PRESSURE),
|
||||
"leakPressure" = round(TANK_LEAK_PRESSURE),
|
||||
"fragmentPressure" = round(TANK_FRAGMENT_PRESSURE)
|
||||
)
|
||||
|
||||
/obj/item/tank/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
|
||||
data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0)
|
||||
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
|
||||
data["minReleasePressure"] = round(TANK_MIN_RELEASE_PRESSURE)
|
||||
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
|
||||
. = list(
|
||||
"tankPressure" = round(air_contents.return_pressure()),
|
||||
"releasePressure" = round(distribute_pressure)
|
||||
)
|
||||
|
||||
var/mob/living/carbon/C = user
|
||||
if(!istype(C))
|
||||
C = loc.loc
|
||||
if(!istype(C))
|
||||
return data
|
||||
|
||||
if(C.internal == src)
|
||||
data["connected"] = TRUE
|
||||
|
||||
return data
|
||||
if(istype(C) && C.internal == src)
|
||||
.["connected"] = TRUE
|
||||
|
||||
/obj/item/tank/ui_act(action, params)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("pressure")
|
||||
@@ -228,6 +238,9 @@
|
||||
/obj/item/tank/return_air()
|
||||
return air_contents
|
||||
|
||||
// /obj/item/tank/return_analyzable_air()
|
||||
// return air_contents
|
||||
|
||||
/obj/item/tank/assume_air(datum/gas_mixture/giver)
|
||||
air_contents.merge(giver)
|
||||
|
||||
@@ -239,10 +252,9 @@
|
||||
return null
|
||||
|
||||
var/tank_pressure = air_contents.return_pressure()
|
||||
if(tank_pressure < distribute_pressure)
|
||||
distribute_pressure = tank_pressure
|
||||
var/actual_distribute_pressure = clamp(tank_pressure, 0, distribute_pressure)
|
||||
|
||||
var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature())
|
||||
var/moles_needed = actual_distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature())
|
||||
|
||||
return remove_air(moles_needed)
|
||||
|
||||
@@ -267,7 +279,7 @@
|
||||
//Give the gas a chance to build up more pressure through reacting
|
||||
air_contents.react(src)
|
||||
air_contents.react(src)
|
||||
//Citadel Edit: removing extra react for "balance"
|
||||
|
||||
pressure = air_contents.return_pressure()
|
||||
var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE
|
||||
var/turf/epicenter = get_turf(loc)
|
||||
@@ -285,7 +297,7 @@
|
||||
if(!T)
|
||||
return
|
||||
T.assume_air(air_contents)
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, 1, -3)
|
||||
playsound(src.loc, 'sound/effects/spray.ogg', 10, TRUE, -3)
|
||||
qdel(src)
|
||||
else
|
||||
integrity--
|
||||
|
||||
@@ -24,9 +24,9 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
*/
|
||||
/obj/item/banhammer/attack(mob/M, mob/user)
|
||||
if(user.zone_selected == BODY_ZONE_HEAD)
|
||||
M.visible_message("<span class='danger'>[user] are stroking the head of [M] with a bangammer</span>", "<span class='userdanger'>[user] are stroking the head with a bangammer</span>", "you hear a bangammer stroking a head");
|
||||
M.visible_message("<span class='danger'>[user] are stroking the head of [M] with a bangammer.</span>", "<span class='userdanger'>[user] are stroking your head with a bangammer.</span>", "<span class='hear'>You hear a bangammer stroking a head.</span>") // see above comment
|
||||
else
|
||||
M.visible_message("<span class='danger'>[M] has been banned FOR NO REISIN by [user]</span>", "<span class='userdanger'>You have been banned FOR NO REISIN by [user]</span>", "you hear a banhammer banning someone")
|
||||
M.visible_message("<span class='danger'>[M] has been banned FOR NO REISIN by [user]!</span>", "<span class='userdanger'>You have been banned FOR NO REISIN by [user]!</span>", "<span class='hear'>You hear a banhammer banning someone.</span>")
|
||||
playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much
|
||||
if(user.a_intent != INTENT_HELP)
|
||||
return ..(M, user)
|
||||
@@ -89,7 +89,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
|
||||
desc = "<b><i>THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!</i></b>\nActivate it in your hand to point to the nearest victim."
|
||||
flags_1 = CONDUCT_1
|
||||
item_flags = DROPDEL
|
||||
item_flags = DROPDEL //WOW BRO YOU LOST AN ARM, GUESS WHAT YOU DONT GET YOUR SWORD ANYMORE //I CANT BELIEVE SPOOKYDONUT WOULD BREAK THE REQUIREMENTS
|
||||
slot_flags = null
|
||||
block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY
|
||||
light_range = 3
|
||||
@@ -130,8 +130,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/claymore/highlander/dropped(mob/living/user)
|
||||
. = ..()
|
||||
user.unignore_slowdown(HIGHLANDER)
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //If this ever happens, it's because you lost an arm
|
||||
|
||||
/obj/item/claymore/highlander/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -141,8 +139,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/claymore/highlander/attack(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
if(!QDELETED(target) && iscarbon(target) && target.stat == DEAD && target.mind && target.mind.special_role == "highlander")
|
||||
user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES
|
||||
if(!QDELETED(target) && target.stat == DEAD && target.mind && target.mind.special_role == "highlander")
|
||||
user.fully_heal(admin_revive = FALSE) //STEAL THE LIFE OF OUR FALLEN FOES
|
||||
add_notch(user)
|
||||
target.visible_message("<span class='warning'>[target] crumbles to dust beneath [user]'s blows!</span>", "<span class='userdanger'>As you fall, your body crumbles to dust!</span>")
|
||||
target.dust()
|
||||
@@ -150,9 +148,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/claymore/highlander/attack_self(mob/living/user)
|
||||
var/closest_victim
|
||||
var/closest_distance = 255
|
||||
for(var/mob/living/carbon/human/H in GLOB.player_list - user)
|
||||
if(H.client && H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance))
|
||||
closest_victim = H
|
||||
for(var/mob/living/carbon/human/scot in GLOB.player_list - user)
|
||||
if(scot.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance))
|
||||
closest_victim = scot
|
||||
for(var/mob/living/silicon/robot/siliscot in GLOB.player_list - user)
|
||||
if(siliscot.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance))
|
||||
closest_victim = siliscot
|
||||
|
||||
if(!closest_victim)
|
||||
to_chat(user, "<span class='warning'>[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.</span>")
|
||||
return
|
||||
@@ -161,7 +163,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/claymore/highlander/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if((attack_type & ATTACK_TYPE_PROJECTILE) && is_energy_reflectable_projectile(object))
|
||||
return BLOCK_SUCCESS | BLOCK_SHOULD_REDIRECT | BLOCK_PHYSICAL_EXTERNAL | BLOCK_REDIRECTED
|
||||
return ..()
|
||||
return ..() //YOU THINK YOUR PUNY LASERS CAN STOP ME?
|
||||
|
||||
/obj/item/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE
|
||||
notches++
|
||||
@@ -214,7 +216,22 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
remove_atom_colour(ADMIN_COLOUR_PRIORITY)
|
||||
|
||||
name = new_name
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, TRUE)
|
||||
|
||||
/obj/item/claymore/highlander/robot //BLOODTHIRSTY BORGS NOW COME IN PLAID
|
||||
icon = 'icons/obj/items_cyborg.dmi'
|
||||
icon_state = "claymore_cyborg"
|
||||
var/mob/living/silicon/robot/robot
|
||||
|
||||
/obj/item/claymore/highlander/robot/Initialize()
|
||||
var/obj/item/robot_module/kiltkit = loc
|
||||
robot = kiltkit.loc
|
||||
if(!istype(robot))
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/claymore/highlander/robot/process()
|
||||
loc.layer = LARGE_MOB_LAYER
|
||||
|
||||
/obj/item/katana
|
||||
name = "katana"
|
||||
@@ -227,7 +244,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK
|
||||
force = 40
|
||||
throwforce = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
block_chance = 50
|
||||
@@ -417,7 +434,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
desc = "A misnomer of sorts, this is effectively a blunt katana made from steelwood, a dense organic wood derived from steelcaps. Why steelwood? Druids can use it. Duh."
|
||||
icon_state = "bokken_steel"
|
||||
item_state = "bokken_steel"
|
||||
force = 12
|
||||
force = 12
|
||||
stamina_damage_increment = 3
|
||||
|
||||
/obj/item/melee/bokken/waki
|
||||
@@ -427,7 +444,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
item_state = "wakibokken"
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 6
|
||||
force = 6
|
||||
stamina_damage_increment = 4
|
||||
block_parry_data = /datum/block_parry_data/bokken/waki
|
||||
default_parry_data = /datum/block_parry_data/bokken/waki
|
||||
@@ -442,7 +459,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 7.5
|
||||
parry_efficiency_to_counterattack = 120
|
||||
parry_efficiency_considered_successful = 65
|
||||
parry_efficiency_considered_successful = 65
|
||||
parry_efficiency_perfect = 120
|
||||
parry_efficiency_perfect_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 30,
|
||||
@@ -455,10 +472,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/datum/block_parry_data/bokken/waki/quick_parry //For the parry spammer in you
|
||||
parry_stamina_cost = 2 // Slam that parry button
|
||||
parry_time_active = 2.5
|
||||
parry_time_perfect = 1
|
||||
parry_time_perfect = 1
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_failed_stagger_duration = 1 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS
|
||||
|
||||
/datum/block_parry_data/bokken/waki/quick_parry/proj
|
||||
parry_efficiency_perfect_override = list()
|
||||
@@ -468,7 +485,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
desc = "A misnomer of sorts, this is effectively a blunt wakizashi made from steelwood, a dense organic wood derived from steelcaps. Why steelwood? Druids can use it. Duh."
|
||||
icon_state = "wakibokken_steel"
|
||||
item_state = "wakibokken_steel"
|
||||
force = 8
|
||||
force = 8
|
||||
stamina_damage_increment = 2
|
||||
|
||||
/obj/item/melee/bokken/debug
|
||||
@@ -575,7 +592,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
user.put_in_hands(S)
|
||||
to_chat(user, "<span class='notice'>You fasten the glass shard to the top of the rod with the cable.</span>")
|
||||
|
||||
else if(istype(I, /obj/item/assembly/igniter) && !HAS_TRAIT(I, TRAIT_NODROP))
|
||||
else if(istype(I, /obj/item/assembly/igniter) && !(HAS_TRAIT(I, TRAIT_NODROP)))
|
||||
var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod
|
||||
|
||||
remove_item_from_storage(user)
|
||||
@@ -598,13 +615,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
force = 2
|
||||
throwforce = 10 //This is never used on mobs since this has a 100% embed chance.
|
||||
throwforce = 10 //10 + 2 (WEIGHT_CLASS_SMALL) * 4 (EMBEDDED_IMPACT_PAIN_MULTIPLIER) = 18 damage on hit due to guaranteed embedding
|
||||
throw_speed = 4
|
||||
embedding = list("pain_mult" = 4, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
|
||||
armour_penetration = 40
|
||||
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
sharpness = SHARP_EDGED
|
||||
sharpness = SHARP_POINTY
|
||||
custom_materials = list(/datum/material/iron=500, /datum/material/glass=500)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
@@ -639,27 +656,23 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
attack_verb = list("stubbed", "poked")
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/extended = 0
|
||||
var/extended_force = 20
|
||||
var/extended_throwforce = 23
|
||||
var/extended_icon_state = "switchblade_ext"
|
||||
var/retracted_icon_state = "switchblade"
|
||||
|
||||
/obj/item/switchblade/attack_self(mob/user)
|
||||
extended = !extended
|
||||
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1)
|
||||
playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, TRUE)
|
||||
if(extended)
|
||||
force = extended_force
|
||||
force = 20
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throwforce = extended_throwforce
|
||||
icon_state = extended_icon_state
|
||||
throwforce = 23
|
||||
icon_state = "switchblade_ext"
|
||||
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = SHARP_EDGED
|
||||
else
|
||||
force = initial(force)
|
||||
force = 3
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = initial(throwforce)
|
||||
icon_state = retracted_icon_state
|
||||
throwforce = 5
|
||||
icon_state = "switchblade"
|
||||
attack_verb = list("stubbed", "poked")
|
||||
hitsound = 'sound/weapons/genhit.ogg'
|
||||
sharpness = SHARP_NONE
|
||||
@@ -750,6 +763,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
user.visible_message("<span class='suicide'>[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane!</span>")
|
||||
return (OXYLOSS)
|
||||
|
||||
// /obj/item/ectoplasm/angelic
|
||||
// icon = 'icons/obj/wizard.dmi'
|
||||
// icon_state = "angelplasm"
|
||||
|
||||
/obj/item/mounted_chainsaw
|
||||
name = "mounted chainsaw"
|
||||
desc = "A chainsaw that has replaced your arm."
|
||||
@@ -758,7 +775,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
item_flags = ABSTRACT | DROPDEL
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 24
|
||||
throwforce = 0
|
||||
throw_range = 0
|
||||
@@ -801,7 +818,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/statuebust/Initialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/art, impressiveness)
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 1000)), 0)
|
||||
// AddComponent(/datum/component/beauty, 1000)
|
||||
|
||||
// /obj/item/statuebust/hippocratic
|
||||
// name = "hippocrates bust"
|
||||
// desc = "A bust of the famous Greek physician Hippocrates of Kos, often referred to as the father of western medicine."
|
||||
// icon_state = "hippocratic"
|
||||
// impressiveness = 50
|
||||
|
||||
/obj/item/tailclub
|
||||
name = "tail club"
|
||||
@@ -825,8 +848,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
icon_state = "catwhip"
|
||||
|
||||
/obj/item/melee/skateboard
|
||||
name = "improvised skateboard"
|
||||
desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon."
|
||||
name = "skateboard"
|
||||
desc = "A skateboard. It can be placed on its wheels and ridden, or used as a radical weapon."
|
||||
icon_state = "skateboard"
|
||||
item_state = "skateboard"
|
||||
force = 12
|
||||
@@ -839,17 +862,22 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/melee/skateboard/attack_self(mob/user)
|
||||
if(!user.canUseTopic(src, TRUE, FALSE, TRUE))
|
||||
return
|
||||
var/obj/vehicle/ridden/scooter/skateboard/S = new board_item_type(get_turf(user))
|
||||
var/obj/vehicle/ridden/scooter/skateboard/S = new board_item_type(get_turf(user))//this probably has fucky interactions with telekinesis but for the record it wasn't my fault
|
||||
S.buckle_mob(user)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/melee/skateboard/improvised
|
||||
name = "improvised skateboard"
|
||||
desc = "A jury-rigged skateboard. It can be placed on its wheels and ridden, or used as a radical weapon."
|
||||
// board_item_type = /obj/vehicle/ridden/scooter/skateboard/improvised
|
||||
|
||||
/obj/item/melee/skateboard/pro
|
||||
name = "skateboard"
|
||||
desc = "A RaDSTORMz brand professional skateboard. It looks sturdy and well made."
|
||||
desc = "An EightO brand professional skateboard. It looks sturdy and well made."
|
||||
icon_state = "skateboard2"
|
||||
item_state = "skateboard2"
|
||||
board_item_type = /obj/vehicle/ridden/scooter/skateboard/pro
|
||||
custom_premium_price = 500
|
||||
custom_premium_price = PAYCHECK_HARD * 5
|
||||
|
||||
/obj/item/melee/skateboard/hoverboard
|
||||
name = "hoverboard"
|
||||
@@ -857,10 +885,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
icon_state = "hoverboard_red"
|
||||
item_state = "hoverboard_red"
|
||||
board_item_type = /obj/vehicle/ridden/scooter/skateboard/hoverboard
|
||||
custom_premium_price = 2015
|
||||
custom_premium_price = PAYCHECK_COMMAND * 5.4 //If I can't make it a meme I'll make it RAD
|
||||
|
||||
/obj/item/melee/skateboard/hoverboard/admin
|
||||
name = "\improper Board Of Directors"
|
||||
name = "Board Of Directors"
|
||||
desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too."
|
||||
icon_state = "hoverboard_nt"
|
||||
item_state = "hoverboard_nt"
|
||||
@@ -879,11 +907,19 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
throwforce = 12
|
||||
attack_verb = list("beat", "smacked")
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 3.5)
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
var/homerun_ready = 0
|
||||
var/homerun_able = 0
|
||||
total_mass = 2.7 //a regular wooden major league baseball bat weighs somewhere between 2 to 3.4 pounds, according to google
|
||||
|
||||
/obj/item/melee/baseball_bat/Initialize()
|
||||
. = ..()
|
||||
if(prob(1))
|
||||
name = "cricket bat"
|
||||
desc = "You've got red on you."
|
||||
icon_state = "baseball_bat_brit"
|
||||
item_state = "baseball_bat_brit"
|
||||
|
||||
/obj/item/melee/baseball_bat/chaplain
|
||||
name = "blessed baseball bat"
|
||||
desc = "There ain't a cult in the league that can withstand a swatter."
|
||||
@@ -908,11 +944,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
..()
|
||||
return
|
||||
if(homerun_ready)
|
||||
to_chat(user, "<span class='notice'>You're already ready to do a home run!</span>")
|
||||
to_chat(user, "<span class='warning'>You're already ready to do a home run!</span>")
|
||||
..()
|
||||
return
|
||||
to_chat(user, "<span class='warning'>You begin gathering strength...</span>")
|
||||
playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1)
|
||||
playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, TRUE)
|
||||
if(do_after(user, 90, target = src))
|
||||
to_chat(user, "<span class='userdanger'>You gather power! Time for a home run!</span>")
|
||||
homerun_ready = 1
|
||||
@@ -920,12 +956,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
return
|
||||
var/atom/throw_target = get_edge_target_turf(target, user.dir)
|
||||
if(homerun_ready)
|
||||
user.visible_message("<span class='userdanger'>It's a home run!</span>")
|
||||
target.throw_at(throw_target, rand(8,10), 14, user)
|
||||
target.ex_act(EXPLODE_HEAVY)
|
||||
playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1)
|
||||
playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, TRUE)
|
||||
homerun_ready = 0
|
||||
return
|
||||
else if(!target.anchored)
|
||||
@@ -956,7 +994,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/melee/flyswatter
|
||||
name = "flyswatter"
|
||||
desc = "Useful for killing insects of all sizes."
|
||||
desc = "Useful for killing pests of all sizes."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "flyswatter"
|
||||
item_state = "flyswatter"
|
||||
@@ -969,7 +1007,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
//Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc.
|
||||
var/list/strong_against
|
||||
var/list/spider_panic
|
||||
|
||||
/obj/item/melee/flyswatter/Initialize()
|
||||
. = ..()
|
||||
@@ -977,13 +1014,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/mob/living/simple_animal/hostile/poison/bees/,
|
||||
/mob/living/simple_animal/butterfly,
|
||||
/mob/living/simple_animal/cockroach,
|
||||
/obj/item/queen_bee
|
||||
))
|
||||
spider_panic = typecacheof(list(
|
||||
/mob/living/simple_animal/banana_spider,
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider,
|
||||
/obj/item/queen_bee,
|
||||
/obj/structure/spider/spiderling
|
||||
))
|
||||
|
||||
|
||||
/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag)
|
||||
. = ..()
|
||||
if(proximity_flag)
|
||||
@@ -993,11 +1028,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
if(istype(target, /mob/living/))
|
||||
var/mob/living/bug = target
|
||||
bug.death(1)
|
||||
if(is_type_in_typecache(target, spider_panic))
|
||||
to_chat(user, "<span class='warning'>You easily land a critical blow on the [target].</span>")
|
||||
if(istype(target, /mob/living/))
|
||||
var/mob/living/bug = target
|
||||
bug.adjustBruteLoss(35) //What kinda mad man would go into melee with a spider?!
|
||||
else
|
||||
qdel(target)
|
||||
|
||||
@@ -1007,7 +1037,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
icon_state = "madeyoulook"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
item_flags = DROPDEL | ABSTRACT
|
||||
item_flags = DROPDEL | ABSTRACT // | HAND_ITEM
|
||||
attack_verb = list("bopped")
|
||||
|
||||
/obj/item/circlegame/Initialize()
|
||||
@@ -1030,6 +1060,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/// Stage 1: The mistake is made
|
||||
/obj/item/circlegame/proc/ownerExamined(mob/living/owner, mob/living/sucker)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!istype(sucker) || !in_range(owner, sucker))
|
||||
return
|
||||
addtimer(CALLBACK(src, .proc/waitASecond, owner, sucker), 4)
|
||||
@@ -1076,6 +1108,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
to_chat(owner, "<span class='warning'>[sucker] looks down at your [src.name] before trying to avert [sucker.p_their()] eyes, but it's too late!</span>")
|
||||
to_chat(sucker, "<span class='danger'><b>[owner] sees the fear in your eyes as you try to look away from [owner.p_their()] [src.name]!</b></span>")
|
||||
|
||||
owner.face_atom(sucker)
|
||||
if(owner.client)
|
||||
owner.client.give_award(/datum/award/achievement/misc/gottem, owner) // then everybody clapped
|
||||
|
||||
playsound(get_turf(owner), 'sound/effects/hit_punch.ogg', 50, TRUE, -1)
|
||||
owner.do_attack_animation(sucker)
|
||||
|
||||
@@ -1103,7 +1139,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
item_state = "nothing"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
item_flags = DROPDEL | ABSTRACT
|
||||
item_flags = DROPDEL | ABSTRACT // | HAND_ITEM
|
||||
attack_verb = list("slapped")
|
||||
hitsound = 'sound/effects/snap.ogg'
|
||||
|
||||
@@ -1112,16 +1148,12 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
var/mob/living/carbon/human/L = M
|
||||
if(L && L.dna && L.dna.species)
|
||||
L.dna.species.stop_wagging_tail(M)
|
||||
if(user.a_intent != INTENT_HARM && ((user.zone_selected == BODY_ZONE_PRECISE_MOUTH) || (user.zone_selected == BODY_ZONE_PRECISE_EYES) || (user.zone_selected == BODY_ZONE_HEAD)))
|
||||
user.do_attack_animation(M)
|
||||
playsound(M, 'sound/weapons/slap.ogg', 50, 1, -1)
|
||||
user.visible_message("<span class='danger'>[user] slaps [M]!</span>",
|
||||
"<span class='notice'>You slap [M]!</span>",\
|
||||
"You hear a slap.")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
user.do_attack_animation(M)
|
||||
playsound(M, 'sound/weapons/slap.ogg', 50, TRUE, -1)
|
||||
user.visible_message("<span class='danger'>[user] slaps [M]!</span>",
|
||||
"<span class='notice'>You slap [M]!</span>",\
|
||||
"<span class='hear'>You hear a slap.</span>")
|
||||
return
|
||||
/obj/item/proc/can_trigger_gun(mob/living/user)
|
||||
if(!user.can_use_guns(src))
|
||||
return FALSE
|
||||
@@ -1138,6 +1170,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
force = 0
|
||||
throwforce = 5
|
||||
reach = 2
|
||||
var/min_reach = 2
|
||||
|
||||
/obj/item/extendohand/acme
|
||||
name = "\improper ACME Extendo-Hand"
|
||||
@@ -1145,13 +1178,26 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/extendohand/attack(atom/M, mob/living/carbon/human/user)
|
||||
var/dist = get_dist(M, user)
|
||||
if(dist < reach)
|
||||
if(dist < min_reach)
|
||||
to_chat(user, "<span class='warning'>[M] is too close to use [src] on.</span>")
|
||||
return
|
||||
M.attack_hand(user)
|
||||
|
||||
//HF blade
|
||||
// /obj/item/gohei
|
||||
// name = "gohei"
|
||||
// desc = "A wooden stick with white streamers at the end. Originally used by shrine maidens to purify things. Now used by the station's valued weeaboos."
|
||||
// force = 5
|
||||
// throwforce = 5
|
||||
// hitsound = "swing_hit"
|
||||
// attack_verb_continuous = list("whacks", "thwacks", "wallops", "socks")
|
||||
// attack_verb_simple = list("whack", "thwack", "wallop", "sock")
|
||||
// icon = 'icons/obj/items_and_weapons.dmi'
|
||||
// icon_state = "gohei"
|
||||
// inhand_icon_state = "gohei"
|
||||
// lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi'
|
||||
// righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi'
|
||||
|
||||
//HF blade
|
||||
/obj/item/vibro_weapon
|
||||
icon_state = "hfrequency0"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
@@ -1160,6 +1206,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
desc = "A potent weapon capable of cutting through nearly anything. Wielding it in two hands will allow you to deflect gunfire."
|
||||
armour_penetration = 100
|
||||
block_chance = 40
|
||||
force = 20
|
||||
throwforce = 20
|
||||
throw_speed = 4
|
||||
sharpness = SHARP_EDGED
|
||||
@@ -1182,10 +1229,14 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/vibro_weapon/proc/on_wield(obj/item/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
wielded = TRUE
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/vibro_weapon/proc/on_unwield(obj/item/source, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
wielded = FALSE
|
||||
|
||||
/obj/item/vibro_weapon/update_icon_state()
|
||||
|
||||
@@ -344,11 +344,6 @@
|
||||
if(resistance_flags & ON_FIRE)
|
||||
. += GLOB.fire_overlay
|
||||
|
||||
//Called when the object is constructed by an autolathe
|
||||
//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes
|
||||
/obj/proc/autolathe_crafted(obj/machinery/autolathe/A)
|
||||
return
|
||||
|
||||
/obj/proc/rnd_crafted(obj/machinery/rnd/production/P)
|
||||
return
|
||||
|
||||
|
||||
@@ -345,7 +345,7 @@
|
||||
name = initial(I.name)
|
||||
icon = initial(I.icon)
|
||||
icon_state = initial(I.icon_state)
|
||||
/* Selling people in jars is currently disabled.
|
||||
|
||||
/obj/structure/displaycase/forsale
|
||||
name = "vend-a-tray"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
@@ -354,9 +354,9 @@
|
||||
density = FALSE
|
||||
max_integrity = 100
|
||||
req_access = null
|
||||
showpiece_type = /obj/item/reagent_containers/food
|
||||
start_showpiece_type = /obj/item/reagent_containers/food
|
||||
alert = FALSE //No, we're not calling the fire department because someone stole your cookie.
|
||||
glass_fix = FALSE //Fixable with tools instead.
|
||||
// glass_fix = FALSE //Fixable with tools instead.
|
||||
///The price of the item being sold. Altered by grab intent ID use.
|
||||
var/sale_price = 20
|
||||
///The Account which will receive payment for purchases. Set by the first ID to swipe the tray.
|
||||
@@ -437,7 +437,7 @@
|
||||
payments_acc.adjust_money(sale_price)
|
||||
usr.put_in_hands(showpiece)
|
||||
to_chat(usr, "<span class='notice'>You purchase [showpiece] for [sale_price] credits.</span>")
|
||||
playsound(src, 'sound/effects/cashregister.ogg', 40, TRUE)
|
||||
// playsound(src, 'sound/effects/cashregister.ogg', 40, TRUE)
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
flick("laserbox_vend", src)
|
||||
showpiece = null
|
||||
@@ -553,4 +553,3 @@
|
||||
/obj/structure/displaycase/forsale/kitchen
|
||||
desc = "A display case with an ID-card swiper. Use your ID to purchase the contents. Meant for the bartender and chef."
|
||||
req_one_access = list(ACCESS_KITCHEN, ACCESS_BAR)
|
||||
*/
|
||||
|
||||
@@ -73,9 +73,14 @@
|
||||
icon_state = "breaker_drop"
|
||||
|
||||
/obj/structure/femur_breaker/proc/damage_leg(mob/living/carbon/human/H)
|
||||
H.emote("scream")
|
||||
H.apply_damage(150, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
|
||||
H.adjustBruteLoss(rand(5,20) + (max(0, H.health))) //Make absolutely sure they end up in crit, so that they can succumb if they wish.
|
||||
var/where_we_snappin_boys = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
H.emote("scream")
|
||||
H.apply_damage(150, BRUTE, where_we_snappin_boys)
|
||||
var/obj/item/bodypart/cracka = H.get_bodypart(where_we_snappin_boys)
|
||||
if(cracka)
|
||||
var/datum/wound/blunt/critical/cracka_lackin = new
|
||||
cracka_lackin.apply_wound(cracka)
|
||||
H.adjustBruteLoss(rand(5,20) + (max(0, H.health))) //Make absolutely sure they end up in crit, so that they can succumb if they wish.
|
||||
|
||||
/obj/structure/femur_breaker/proc/raise_slat()
|
||||
slat_status = BREAKER_SLAT_RAISED
|
||||
|
||||
@@ -52,12 +52,12 @@ GLOBAL_LIST_INIT(tendrils, list())
|
||||
last_tendril = FALSE
|
||||
|
||||
if(last_tendril && !(flags_1 & ADMIN_SPAWNED_1))
|
||||
if(SSmedals.hub_enabled)
|
||||
if(SSachievements.achievements_enabled)
|
||||
for(var/mob/living/L in view(7,src))
|
||||
if(L.stat || !L.client)
|
||||
continue
|
||||
SSmedals.UnlockMedal("[BOSS_MEDAL_TENDRIL] [ALL_KILL_MEDAL]", L.client)
|
||||
SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1)
|
||||
L.client.give_award(/datum/award/achievement/boss/tendril_exterminator, L)
|
||||
L.client.give_award(/datum/award/score/tendril_score, L) //Progresses score by one
|
||||
GLOB.tendrils -= src
|
||||
QDEL_NULL(emitted_light)
|
||||
QDEL_NULL(gps)
|
||||
|
||||
@@ -4,6 +4,11 @@ SAFES
|
||||
FLOOR SAFES
|
||||
*/
|
||||
|
||||
/// Chance for a sound clue
|
||||
#define SOUND_CHANCE 10
|
||||
/// Explosion number threshold for opening safe
|
||||
#define BROKEN_THRESHOLD 3
|
||||
|
||||
//SAFES
|
||||
/obj/structure/safe
|
||||
name = "safe"
|
||||
@@ -14,31 +19,36 @@ FLOOR SAFES
|
||||
density = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT
|
||||
var/open = FALSE //is the safe open?
|
||||
var/tumbler_1_pos //the tumbler position- from 0 to 72
|
||||
var/tumbler_1_open //the tumbler position to open at- 0 to 72
|
||||
var/tumbler_2_pos
|
||||
var/tumbler_2_open
|
||||
var/dial = 0 //where is the dial pointing?
|
||||
var/space = 0 //the combined w_class of everything in the safe
|
||||
var/maxspace = 24 //the maximum combined w_class of stuff in the safe
|
||||
var/explosion_count = 0 //Tough, but breakable
|
||||
|
||||
/obj/structure/safe/New()
|
||||
..()
|
||||
tumbler_1_pos = rand(0, 71)
|
||||
tumbler_1_open = rand(0, 71)
|
||||
|
||||
tumbler_2_pos = rand(0, 71)
|
||||
tumbler_2_open = rand(0, 71)
|
||||
|
||||
/// The maximum combined w_class of stuff in the safe
|
||||
var/maxspace = 24
|
||||
/// The amount of tumblers that will be generated
|
||||
var/number_of_tumblers = 2
|
||||
/// Whether the safe is open or not
|
||||
var/open = FALSE
|
||||
/// Whether the safe is locked or not
|
||||
var/locked = TRUE
|
||||
/// The position the dial is pointing to
|
||||
var/dial = 0
|
||||
/// The list of tumbler dial positions that need to be hit
|
||||
var/list/tumblers = list()
|
||||
/// The index in the tumblers list of the tumbler dial position that needs to be hit
|
||||
var/current_tumbler_index = 1
|
||||
/// The combined w_class of everything in the safe
|
||||
var/space = 0
|
||||
/// Tough, but breakable if explosion counts reaches set value
|
||||
var/explosion_count = 0
|
||||
|
||||
/obj/structure/safe/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
// Combination generation
|
||||
for(var/i in 1 to number_of_tumblers)
|
||||
tumblers.Add(rand(0, 99))
|
||||
|
||||
if(!mapload)
|
||||
return
|
||||
|
||||
// Put as many items on our turf inside as possible
|
||||
for(var/obj/item/I in loc)
|
||||
if(space >= maxspace)
|
||||
return
|
||||
@@ -46,141 +56,36 @@ FLOOR SAFES
|
||||
space += I.w_class
|
||||
I.forceMove(src)
|
||||
|
||||
|
||||
/obj/structure/safe/proc/check_unlocked(mob/user, canhear)
|
||||
if(explosion_count > 2)
|
||||
return 1
|
||||
if(user && canhear)
|
||||
if(tumbler_1_pos == tumbler_1_open)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("tonk", "krunk", "plunk")] from [src].</span>")
|
||||
if(tumbler_2_pos == tumbler_2_open)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("tink", "krink", "plink")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_1_open && tumbler_2_pos == tumbler_2_open)
|
||||
if(user)
|
||||
visible_message("<i><b>[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!</b></i>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/safe/proc/decrement(num)
|
||||
num -= 1
|
||||
if(num < 0)
|
||||
num = 71
|
||||
return num
|
||||
|
||||
/obj/structure/safe/proc/increment(num)
|
||||
num += 1
|
||||
if(num > 71)
|
||||
num = 0
|
||||
return num
|
||||
|
||||
/obj/structure/safe/update_icon_state()
|
||||
if(open)
|
||||
icon_state = "[initial(icon_state)]-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/structure/safe/ui_interact(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = "<center>"
|
||||
dat += "<a href='?src=[REF(src)];open=1'>[open ? "Close" : "Open"] [src]</a> | <a href='?src=[REF(src)];decrement=1'>-</a> [dial] <a href='?src=[REF(src)];increment=1'>+</a>"
|
||||
if(open)
|
||||
dat += "<table>"
|
||||
for(var/i = contents.len, i>=1, i--)
|
||||
var/obj/item/P = contents[i]
|
||||
dat += "<tr><td><a href='?src=[REF(src)];retrieve=[REF(P)]'>[P.name]</a></td></tr>"
|
||||
dat += "</table></center>"
|
||||
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[name]</title></head><body>[dat]</body></html>", "window=safe;size=350x300")
|
||||
|
||||
/obj/structure/safe/Topic(href, href_list)
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
if(!user.canUseTopic(src))
|
||||
return
|
||||
|
||||
var/canhear = FALSE
|
||||
if(user.is_holding_item_of_type(/obj/item/clothing/neck/stethoscope))
|
||||
canhear = TRUE
|
||||
|
||||
if(href_list["open"])
|
||||
if(check_unlocked())
|
||||
to_chat(user, "<span class='notice'>You [open ? "close" : "open"] [src].</span>")
|
||||
open = !open
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't [open ? "close" : "open"] [src], the lock is engaged!</span>")
|
||||
return
|
||||
|
||||
if(href_list["decrement"])
|
||||
dial = decrement(dial)
|
||||
if(dial == tumbler_1_pos + 1 || dial == tumbler_1_pos - 71)
|
||||
tumbler_1_pos = decrement(tumbler_1_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_2_pos + 37 || tumbler_1_pos == tumbler_2_pos - 35)
|
||||
tumbler_2_pos = decrement(tumbler_2_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
|
||||
check_unlocked(user, canhear)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["increment"])
|
||||
dial = increment(dial)
|
||||
if(dial == tumbler_1_pos - 1 || dial == tumbler_1_pos + 71)
|
||||
tumbler_1_pos = increment(tumbler_1_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("clack", "scrape", "clank")] from [src].</span>")
|
||||
if(tumbler_1_pos == tumbler_2_pos - 37 || tumbler_1_pos == tumbler_2_pos + 35)
|
||||
tumbler_2_pos = increment(tumbler_2_pos)
|
||||
if(canhear)
|
||||
to_chat(user, "<span class='italics'>You hear a [pick("click", "chink", "clink")] from [src].</span>")
|
||||
check_unlocked(user, canhear)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["retrieve"])
|
||||
user << browse("", "window=safe") // Close the menu
|
||||
|
||||
var/obj/item/P = locate(href_list["retrieve"]) in src
|
||||
if(open)
|
||||
if(P && in_range(src, user))
|
||||
user.put_in_hands(P)
|
||||
space -= P.w_class
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
/obj/structure/safe/attackby(obj/item/I, mob/user, params)
|
||||
if(open)
|
||||
. = 1 //no afterattack
|
||||
. = TRUE //no afterattack
|
||||
if(I.w_class + space <= maxspace)
|
||||
space += I.w_class
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
to_chat(user, "<span class='warning'>\The [I] is stuck to your hand, you cannot put it in the safe!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You put [I] in [src].</span>")
|
||||
updateUsrDialog()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[I] won't fit in [src].</span>")
|
||||
else
|
||||
if(istype(I, /obj/item/clothing/neck/stethoscope))
|
||||
attack_hand(user)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>[I] won't fit in [src].</span>")
|
||||
to_chat(user, "<span class='warning'>You can't put [I] into the safe while it is closed!</span>")
|
||||
return
|
||||
else if(istype(I, /obj/item/clothing/neck/stethoscope))
|
||||
to_chat(user, "<span class='warning'>Hold [I] in one of your hands while you manipulate the dial!</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/safe/handle_atom_del(atom/A)
|
||||
updateUsrDialog()
|
||||
|
||||
/obj/structure/safe/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/obj/structure/safe/ex_act(severity, target)
|
||||
if(((severity == 2 && target == src) || severity == 1) && explosion_count < 3)
|
||||
if(((severity == 2 && target == src) || severity == 1) && explosion_count < BROKEN_THRESHOLD)
|
||||
explosion_count++
|
||||
switch(explosion_count)
|
||||
if(1)
|
||||
@@ -190,6 +95,144 @@ FLOOR SAFES
|
||||
if(3)
|
||||
desc = initial(desc) + "\nThe lock seems to be broken."
|
||||
|
||||
/obj/structure/safe/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/safe),
|
||||
)
|
||||
|
||||
/obj/structure/safe/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/obj/structure/safe/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Safe", name)
|
||||
ui.open()
|
||||
|
||||
/obj/structure/safe/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["dial"] = dial
|
||||
data["open"] = open
|
||||
data["locked"] = locked
|
||||
data["broken"] = check_broken()
|
||||
|
||||
if(open)
|
||||
var/list/contents_names = list()
|
||||
data["contents"] = contents_names
|
||||
for(var/obj/O in contents)
|
||||
contents_names[++contents_names.len] = list("name" = O.name, "sprite" = O.icon_state)
|
||||
user << browse_rsc(icon(O.icon, O.icon_state), "[O.icon_state].png")
|
||||
|
||||
return data
|
||||
|
||||
/obj/structure/safe/ui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(!ishuman(usr))
|
||||
return
|
||||
var/mob/living/carbon/human/user = usr
|
||||
if(!user.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
|
||||
var/canhear = FALSE
|
||||
if(user.is_holding_item_of_type(/obj/item/clothing/neck/stethoscope))
|
||||
canhear = TRUE
|
||||
|
||||
switch(action)
|
||||
if("open")
|
||||
if(!check_unlocked() && !open && !broken)
|
||||
to_chat(user, "<span class='warning'>You cannot open [src], as its lock is engaged!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You [open ? "close" : "open"] [src].</span>")
|
||||
open = !open
|
||||
update_icon()
|
||||
return TRUE
|
||||
if("turnright")
|
||||
if(open)
|
||||
return
|
||||
if(broken)
|
||||
to_chat(user, "<span class='warning'>The dial will not turn, as the mechanism is destroyed!</span>")
|
||||
return
|
||||
var/ticks = text2num(params["num"])
|
||||
for(var/i = 1 to ticks)
|
||||
dial = WRAP(dial - 1, 0, 100)
|
||||
|
||||
var/invalid_turn = current_tumbler_index % 2 == 0 || current_tumbler_index > number_of_tumblers
|
||||
if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset
|
||||
current_tumbler_index = 1
|
||||
|
||||
if(!invalid_turn && dial == tumblers[current_tumbler_index])
|
||||
notify_user(user, canhear, list("tink", "krink", "plink"), ticks, i)
|
||||
current_tumbler_index++
|
||||
else
|
||||
notify_user(user, canhear, list("clack", "scrape", "clank"), ticks, i)
|
||||
check_unlocked()
|
||||
return TRUE
|
||||
if("turnleft")
|
||||
if(open)
|
||||
return
|
||||
if(broken)
|
||||
to_chat(user, "<span class='warning'>The dial will not turn, as the mechanism is destroyed!</span>")
|
||||
return
|
||||
var/ticks = text2num(params["num"])
|
||||
for(var/i = 1 to ticks)
|
||||
dial = WRAP(dial + 1, 0, 100)
|
||||
|
||||
var/invalid_turn = current_tumbler_index % 2 != 0 || current_tumbler_index > number_of_tumblers
|
||||
if(invalid_turn) // The moment you turn the wrong way or go too far, the tumblers reset
|
||||
current_tumbler_index = 1
|
||||
|
||||
if(!invalid_turn && dial == tumblers[current_tumbler_index])
|
||||
notify_user(user, canhear, list("tonk", "krunk", "plunk"), ticks, i)
|
||||
current_tumbler_index++
|
||||
else
|
||||
notify_user(user, canhear, list("click", "chink", "clink"), ticks, i)
|
||||
check_unlocked()
|
||||
return TRUE
|
||||
if("retrieve")
|
||||
if(!open)
|
||||
return
|
||||
var/index = text2num(params["index"])
|
||||
if(!index)
|
||||
return
|
||||
var/obj/item/I = contents[index]
|
||||
if(!I || !in_range(src, user))
|
||||
return
|
||||
user.put_in_hands(I)
|
||||
space -= I.w_class
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Checks if safe is considered in a broken state for force-opening the safe
|
||||
*/
|
||||
/obj/structure/safe/proc/check_broken()
|
||||
return broken || explosion_count >= BROKEN_THRESHOLD
|
||||
|
||||
/**
|
||||
* Called every dial turn to determine whether the safe should unlock or not.
|
||||
*/
|
||||
/obj/structure/safe/proc/check_unlocked()
|
||||
if(check_broken())
|
||||
return TRUE
|
||||
if(current_tumbler_index > number_of_tumblers)
|
||||
locked = FALSE
|
||||
visible_message("<span class='boldnotice'>[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!</span>")
|
||||
return TRUE
|
||||
locked = TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Called every dial turn to provide feedback if possible.
|
||||
*/
|
||||
/obj/structure/safe/proc/notify_user(user, canhear, sounds, total_ticks, current_tick)
|
||||
if(!canhear)
|
||||
return
|
||||
if(current_tick == 2)
|
||||
to_chat(user, "<span class='italics'>The sounds from [src] are too fast and blend together.</span>")
|
||||
if(total_ticks == 1 || prob(SOUND_CHANCE))
|
||||
to_chat(user, "<span class='italics'>You hear a [pick(sounds)] from [src].</span>")
|
||||
|
||||
//FLOOR SAFES
|
||||
/obj/structure/safe/floor
|
||||
@@ -199,13 +242,11 @@ FLOOR SAFES
|
||||
level = 1 //underfloor
|
||||
layer = LOW_OBJ_LAYER
|
||||
|
||||
|
||||
/obj/structure/safe/floor/Initialize(mapload)
|
||||
. = ..()
|
||||
if(mapload)
|
||||
var/turf/T = loc
|
||||
hide(T.intact)
|
||||
|
||||
|
||||
/obj/structure/safe/floor/hide(var/intact)
|
||||
invisibility = intact ? INVISIBILITY_MAXIMUM : 0
|
||||
#undef SOUND_CHANCE
|
||||
#undef BROKEN_THRESHOLD
|
||||
|
||||
@@ -47,14 +47,19 @@
|
||||
if(open)
|
||||
GM.visible_message("<span class='danger'>[user] starts to give [GM] a swirlie!</span>", "<span class='userdanger'>[user] starts to give you a swirlie...</span>")
|
||||
swirlie = GM
|
||||
if(do_after(user, 30, 0, target = src))
|
||||
GM.visible_message("<span class='danger'>[user] gives [GM] a swirlie!</span>", "<span class='userdanger'>[user] gives you a swirlie!</span>", "<span class='italics'>You hear a toilet flushing.</span>")
|
||||
var/was_alive = (swirlie.stat != DEAD)
|
||||
if(do_after(user, 3 SECONDS, target = src))
|
||||
GM.visible_message("<span class='danger'>[user] gives [GM] a swirlie!</span>", "<span class='userdanger'>[user] gives you a swirlie!</span>", "<span class='hear'>You hear a toilet flushing.</span>")
|
||||
if(iscarbon(GM))
|
||||
var/mob/living/carbon/C = GM
|
||||
if(!C.internal)
|
||||
log_combat(user, C, "swirlied (oxy)")
|
||||
C.adjustOxyLoss(5)
|
||||
else
|
||||
log_combat(user, GM, "swirlied (oxy)")
|
||||
GM.adjustOxyLoss(5)
|
||||
if(was_alive && swirlie.stat == DEAD && swirlie.client)
|
||||
swirlie.client.give_award(/datum/award/achievement/misc/swirlie, swirlie) // just like space high school all over again!
|
||||
swirlie = null
|
||||
else
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
|
||||
|
||||
@@ -584,6 +584,9 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup)
|
||||
/obj/structure/window/plasma/reinforced/unanchored
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/window/plasma/reinforced/BlockSuperconductivity()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/window/reinforced/tinted
|
||||
name = "tinted window"
|
||||
icon_state = "twindow"
|
||||
|
||||
@@ -872,20 +872,18 @@
|
||||
/turf/closed/mineral/strong/gets_drilled(mob/user)
|
||||
if(!ishuman(user))
|
||||
return // see attackby
|
||||
/*
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!(H.mind.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_MASTER))
|
||||
return
|
||||
*/
|
||||
// if(!(H.mind?.get_skill_level(/datum/skill/mining) >= SKILL_LEVEL_MASTER))
|
||||
// return
|
||||
drop_ores()
|
||||
// H.client.give_award(/datum/award/achievement/skill/legendary_miner, H)
|
||||
H.client.give_award(/datum/award/achievement/skill/legendary_miner, H)
|
||||
var/flags = NONE
|
||||
if(defer_change) // TODO: make the defer change var a var for any changeturf flag
|
||||
flags = CHANGETURF_DEFER_CHANGE
|
||||
ScrapeAway(flags=flags)
|
||||
addtimer(CALLBACK(src, .proc/AfterChange), 1, TIMER_UNIQUE)
|
||||
playsound(src, 'sound/effects/break_stone.ogg', 50, TRUE) //beautiful destruction
|
||||
// H.mind.adjust_experience(/datum/skill/mining, 100) //yay!
|
||||
// H.mind?.adjust_experience(/datum/skill/mining, 100) //yay!
|
||||
|
||||
/turf/closed/mineral/strong/proc/drop_ores()
|
||||
if(prob(10))
|
||||
|
||||
Reference in New Issue
Block a user