Merge branch 'malf-dynamic' into super-special-awesome-dynamic
This commit is contained in:
+1
-1
@@ -829,7 +829,7 @@ Proc for attack log creation, because really why not
|
||||
return filters[filter_data.Find(name)]
|
||||
|
||||
/atom/movable/proc/remove_filter(name)
|
||||
if(filter_data[name])
|
||||
if(filter_data && filter_data[name])
|
||||
filter_data -= name
|
||||
update_filters()
|
||||
return TRUE
|
||||
@@ -27,7 +27,6 @@
|
||||
glide_size = 8
|
||||
appearance_flags = TILE_BOUND|PIXEL_SCALE
|
||||
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
|
||||
var/floating = FALSE
|
||||
var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc.
|
||||
var/atom/movable/pulling
|
||||
var/grab_state = 0
|
||||
@@ -422,6 +421,9 @@
|
||||
var/atom/movable/AM = item
|
||||
AM.onTransitZ(old_z,new_z)
|
||||
|
||||
/atom/movable/proc/setMovetype(newval)
|
||||
movement_type = newval
|
||||
|
||||
//Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
//And when an object or action applies a force on src, see newtonian_move() below
|
||||
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
@@ -518,6 +520,8 @@
|
||||
TT.thrower = thrower
|
||||
TT.diagonals_first = diagonals_first
|
||||
TT.callback = callback
|
||||
if(!QDELETED(thrower))
|
||||
TT.target_zone = thrower.zone_selected
|
||||
|
||||
var/dist_x = abs(target.x - src.x)
|
||||
var/dist_y = abs(target.y - src.y)
|
||||
@@ -684,14 +688,14 @@
|
||||
/atom/movable/proc/float(on)
|
||||
if(throwing)
|
||||
return
|
||||
if(on && !floating)
|
||||
if(on && !(movement_type & FLOATING))
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
floating = TRUE
|
||||
else if (!on && floating)
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if (!on && (movement_type & FLOATING))
|
||||
animate(src, pixel_y = initial(pixel_y), time = 10)
|
||||
floating = FALSE
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
|
||||
/* Language procs */
|
||||
/atom/movable/proc/get_language_holder(shadow=TRUE)
|
||||
|
||||
@@ -267,6 +267,7 @@
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
wreckage = /obj/structure/mecha_wreckage/honker/dark
|
||||
max_equip = 3
|
||||
spawn_tracked = FALSE
|
||||
|
||||
/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
|
||||
@@ -111,6 +111,10 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
..()
|
||||
pop_per_requirement = CONFIG_GET(number/dynamic_pop_per_requirement)
|
||||
GLOB.dynamic_high_pop_limit = CONFIG_GET(number/dynamic_high_pop_limit)
|
||||
GLOB.dynamic_latejoin_delay_min = CONFIG_GET(number/dynamic_latejoin_delay_min)*600
|
||||
GLOB.dynamic_latejoin_delay_max = CONFIG_GET(number/dynamic_latejoin_delay_max)*600
|
||||
GLOB.dynamic_midround_delay_min = CONFIG_GET(number/dynamic_midround_delay_min)*600
|
||||
GLOB.dynamic_midround_delay_max = CONFIG_GET(number/dynamic_midround_delay_max)*600
|
||||
|
||||
/datum/game_mode/dynamic/admin_panel()
|
||||
var/list/dat = list("<html><head><title>Game Mode Panel</title></head><body><h1><B>Game Mode Panel</B></h1>")
|
||||
@@ -221,7 +225,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
|
||||
. += G.get_report()
|
||||
|
||||
print_command_report(., "Central Command Status Summary", announce=FALSE)
|
||||
priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", 'sound/ai/intercept.ogg')
|
||||
priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", "intercept")
|
||||
if(GLOB.security_level < SEC_LEVEL_BLUE)
|
||||
set_security_level(SEC_LEVEL_BLUE)
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
|
||||
/datum/dynamic_ruleset/midround/malf
|
||||
name = "Malfunctioning AI"
|
||||
config_tag = "malf_ai"
|
||||
config_tag = "midround_malf_ai"
|
||||
antag_datum = /datum/antagonist/traitor
|
||||
antag_flag = ROLE_MALF
|
||||
enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer")
|
||||
@@ -263,7 +263,7 @@
|
||||
M.mind.special_role = antag_flag
|
||||
M.mind.add_antag_datum(AI)
|
||||
if(prob(ion_announce))
|
||||
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/ai/ionstorm.ogg')
|
||||
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm")
|
||||
if(prob(removeDontImproveChance))
|
||||
M.replace_random_law(generate_ion_law(), list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
|
||||
else
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
antag_datum = /datum/antagonist/traitor/
|
||||
minimum_required_age = 0
|
||||
protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster", "Cyborg")
|
||||
restricted_roles = list("Cyborg")
|
||||
restricted_roles = list("Cyborg", "AI")
|
||||
required_candidates = 1
|
||||
weight = 5
|
||||
cost = 10
|
||||
@@ -41,6 +41,61 @@
|
||||
log_game("DYNAMIC: Checking if we can turn someone into a traitor.")
|
||||
mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor)
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// //
|
||||
// MALF AI //
|
||||
// //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/delayed/malf_ai
|
||||
name = "Malfunctioning AI"
|
||||
config_tag = "malf_ai"
|
||||
antag_datum = /datum/antagonist/traitor
|
||||
antag_flag = ROLE_MALF
|
||||
enemy_roles = list("Security Officer", "Warden","Detective","Head of Security", "Captain", "Scientist", "Chemist", "Research Director", "Chief Engineer")
|
||||
exclusive_roles = list("AI")
|
||||
required_enemies = list(4,4,4,4,4,4,2,2,2,0)
|
||||
required_candidates = 1
|
||||
weight = 1
|
||||
cost = 35
|
||||
requirements = list(101,101,80,70,60,60,50,50,40,40)
|
||||
high_population_requirement = 35
|
||||
required_type = /mob/living/silicon/ai
|
||||
var/autotraitor_cooldown = 450 // 15 minutes (ticks once per 2 sec)
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/delayed/malf_ai/trim_candidates()
|
||||
..()
|
||||
candidates = candidates[CURRENT_LIVING_PLAYERS]
|
||||
for(var/mob/living/player in candidates)
|
||||
if(!isAI(player))
|
||||
candidates -= player
|
||||
continue
|
||||
if(is_centcom_level(player.z))
|
||||
candidates -= player
|
||||
continue
|
||||
if(player.mind && (player.mind.special_role || player.mind.antag_datums?.len > 0))
|
||||
candidates -= player
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/delayed/malf_ai/execute()
|
||||
if(!candidates || !candidates.len)
|
||||
return FALSE
|
||||
var/mob/living/silicon/ai/M = pick(candidates)
|
||||
candidates -= M
|
||||
assigned += M.mind
|
||||
var/datum/antagonist/traitor/AI = new
|
||||
M.mind.special_role = antag_flag
|
||||
M.mind.add_antag_datum(AI)
|
||||
return TRUE
|
||||
|
||||
/datum/dynamic_ruleset/roundstart/delayed/malf_ai/rule_process()
|
||||
if (autotraitor_cooldown > 0)
|
||||
autotraitor_cooldown--
|
||||
else
|
||||
autotraitor_cooldown = 450 // 15 minutes
|
||||
message_admins("Checking if we can turn someone into a traitor.")
|
||||
log_game("DYNAMIC: Checking if we can turn someone into a traitor.")
|
||||
mode.picking_specific_rule(/datum/dynamic_ruleset/midround/autotraitor)
|
||||
|
||||
//////////////////////////////////////////
|
||||
// //
|
||||
// BLOOD BROTHERS //
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/proc/power_failure()
|
||||
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
|
||||
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff")
|
||||
for(var/obj/machinery/power/smes/S in GLOB.machines)
|
||||
if(istype(get_area(S), /area/ai_monitored/turret_protected) || !is_station_level(S.z))
|
||||
continue
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/proc/power_restore()
|
||||
|
||||
priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
|
||||
priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", "poweron")
|
||||
for(var/obj/machinery/power/apc/C in GLOB.machines)
|
||||
if(C.cell && is_station_level(C.z))
|
||||
C.cell.charge = C.cell.maxcharge
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
/proc/power_restore_quick()
|
||||
|
||||
priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
|
||||
priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", "poweron")
|
||||
for(var/obj/machinery/power/smes/S in GLOB.machines)
|
||||
if(!is_station_level(S.z))
|
||||
continue
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
/datum/game_mode/extended/announced/send_intercept(report = 0)
|
||||
if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart
|
||||
return ..()
|
||||
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", 'sound/ai/commandreport.ogg')
|
||||
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport")
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
|
||||
/datum/game_mode/proc/send_intercept()
|
||||
if(flipseclevel && !(config_tag == "extended"))//CIT CHANGE - lets the security level be flipped roundstart
|
||||
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", 'sound/ai/commandreport.ogg')
|
||||
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport")
|
||||
return
|
||||
var/intercepttext = "<b><i>Central Command Status Summary</i></b><hr>"
|
||||
intercepttext += "<b>Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \
|
||||
@@ -288,7 +288,7 @@
|
||||
intercepttext += G.get_report()
|
||||
|
||||
print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE)
|
||||
priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", 'sound/ai/intercept.ogg')
|
||||
priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", "intercept")
|
||||
if(GLOB.security_level < SEC_LEVEL_BLUE)
|
||||
set_security_level(SEC_LEVEL_BLUE)
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
/obj/machinery/computer/ratvar_act()
|
||||
if(!clockwork)
|
||||
clockwork = TRUE
|
||||
icon_screen = "ratvar[rand(1, 4)]"
|
||||
icon_keyboard = "ratvar_key[rand(1, 6)]"
|
||||
icon_state = "ratvarcomputer[rand(1, 4)]"
|
||||
icon_screen = "ratvar[rand(1, 3)]"
|
||||
icon_keyboard = "ratvar_key[rand(1, 2)]"
|
||||
icon_state = "ratvarcomputer"
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/narsie_act()
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#define ARCADE_WEIGHT_TRICK 4
|
||||
#define ARCADE_WEIGHT_USELESS 2
|
||||
#define ARCADE_WEIGHT_RARE 1
|
||||
#define ARCADE_WEIGHT_PLUSH 65
|
||||
|
||||
#define ARCADE_RATIO_PLUSH 0.20 // average 1 out of 6 wins is a plush.
|
||||
|
||||
/obj/machinery/computer/arcade
|
||||
name = "random arcade"
|
||||
@@ -27,7 +26,6 @@
|
||||
/obj/item/toy/katana = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/toy/minimeteor = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/toy/nuke = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/toy/plush/random = ARCADE_WEIGHT_PLUSH,
|
||||
/obj/item/toy/redbutton = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/toy/spinningtoy = ARCADE_WEIGHT_TRICK,
|
||||
/obj/item/toy/sword = ARCADE_WEIGHT_TRICK,
|
||||
@@ -88,8 +86,12 @@
|
||||
/obj/item/circuitboard/computer/arcade/amputation = 2)
|
||||
var/thegame = pickweight(gameodds)
|
||||
var/obj/item/circuitboard/CB = new thegame()
|
||||
new CB.build_path(loc, CB)
|
||||
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)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
network += lowertext(i)
|
||||
|
||||
/obj/machinery/computer/security/check_eye(mob/user)
|
||||
if( (stat & (NOPOWER|BROKEN)) || user.incapacitated() || user.eye_blind )
|
||||
if(CHECK_BITFIELD(stat, NOPOWER|BROKEN) || is_blind(user) || !in_view_range(user, src) || !user.canUseTopic(src, !issilicon(user), FALSE))
|
||||
user.unset_machine()
|
||||
return
|
||||
if(!(user in watchers))
|
||||
@@ -30,14 +30,6 @@
|
||||
if(!C.can_use())
|
||||
user.unset_machine()
|
||||
return
|
||||
if(!issilicon(user))
|
||||
if(!Adjacent(user))
|
||||
user.unset_machine()
|
||||
return
|
||||
else if(iscyborg(user))
|
||||
var/list/viewing = viewers(src)
|
||||
if(!viewing.Find(user))
|
||||
user.unset_machine()
|
||||
|
||||
/obj/machinery/computer/security/on_unset_machine(mob/user)
|
||||
watchers.Remove(user)
|
||||
@@ -97,36 +89,22 @@
|
||||
user.unset_machine()
|
||||
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
|
||||
return
|
||||
if(C)
|
||||
var/camera_fail = 0
|
||||
if(!C.can_use() || user.machine != src || user.eye_blind || user.incapacitated())
|
||||
camera_fail = 1
|
||||
else if(iscyborg(user))
|
||||
var/list/viewing = viewers(src)
|
||||
if(!viewing.Find(user))
|
||||
camera_fail = 1
|
||||
else if(!issilicon(user))
|
||||
if(!Adjacent(user))
|
||||
camera_fail = 1
|
||||
|
||||
if(camera_fail)
|
||||
user.unset_machine()
|
||||
return 0
|
||||
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/A = user
|
||||
A.eyeobj.setLoc(get_turf(C))
|
||||
A.client.eye = A.eyeobj
|
||||
else
|
||||
user.reset_perspective(C)
|
||||
user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
|
||||
user.clear_fullscreen("flash", 5)
|
||||
watchers[user] = C
|
||||
use_power(50)
|
||||
addtimer(CALLBACK(src, .proc/use_camera_console, user), 5)
|
||||
else
|
||||
if(!C || !C.can_use() || CHECK_BITFIELD(stat, NOPOWER|BROKEN) || is_blind(user) || !in_view_range(user, src) || !user.canUseTopic(src, !issilicon(user), FALSE))
|
||||
user.unset_machine()
|
||||
return FALSE
|
||||
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/A = user
|
||||
A.eyeobj.setLoc(get_turf(C))
|
||||
A.client.eye = A.eyeobj
|
||||
else
|
||||
user.reset_perspective(C)
|
||||
user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
|
||||
user.clear_fullscreen("flash", 5)
|
||||
watchers[user] = C
|
||||
use_power(50)
|
||||
addtimer(CALLBACK(src, .proc/use_camera_console, user), 5)
|
||||
|
||||
//returns the list of cameras accessible from this computer
|
||||
/obj/machinery/computer/security/proc/get_available_cameras()
|
||||
|
||||
@@ -298,13 +298,15 @@
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
|
||||
say("Initiating scan...")
|
||||
|
||||
var/prev_locked = scanner.locked
|
||||
scanner.locked = TRUE
|
||||
spawn(20)
|
||||
src.scan_occupant(scanner.occupant)
|
||||
|
||||
loading = 0
|
||||
src.updateUsrDialog()
|
||||
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
|
||||
scanner.locked = prev_locked
|
||||
|
||||
|
||||
//No locking an open scanner.
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
Nuke_request(input, usr)
|
||||
to_chat(usr, "<span class='notice'>Request sent.</span>")
|
||||
usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY)
|
||||
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/ai/commandreport.ogg')
|
||||
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested","commandreport")
|
||||
CM.lastTimeUsed = world.time
|
||||
|
||||
|
||||
|
||||
@@ -484,7 +484,7 @@
|
||||
var/counter = 1
|
||||
while(active2.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
|
||||
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
|
||||
|
||||
else if(href_list["del_c"])
|
||||
if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
|
||||
|
||||
@@ -455,7 +455,7 @@ What a mess.*/
|
||||
var/counter = 1
|
||||
while(active2.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
|
||||
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
|
||||
|
||||
if("Delete Record (ALL)")
|
||||
if(active1)
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
say("Processing hub calibration to target...")
|
||||
|
||||
calibrating = 1
|
||||
power_station.update_icon()
|
||||
spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration
|
||||
calibrating = 0
|
||||
if(check_hub_connection())
|
||||
@@ -97,6 +98,7 @@
|
||||
say("Calibration complete.")
|
||||
else
|
||||
say("Error: Unable to detect hub.")
|
||||
power_station.update_icon()
|
||||
updateDialog()
|
||||
|
||||
updateDialog()
|
||||
|
||||
@@ -74,7 +74,8 @@
|
||||
to_chat(user, "<span class='notice'>You start adding [I] to [src]...</span>")
|
||||
if(do_after(user, 50, target=src))
|
||||
W.use(5)
|
||||
new /turf/closed/wall/mineral/wood/nonmetal(get_turf(src))
|
||||
var/turf/T = get_turf(src)
|
||||
T.PlaceOnTop(/turf/closed/wall/mineral/wood/nonmetal)
|
||||
qdel(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -24,6 +24,8 @@ Possible to do for anyone motivated enough:
|
||||
* Holopad
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_EMPTY(network_holopads)
|
||||
|
||||
#define HOLOPAD_PASSIVE_POWER_USAGE 1
|
||||
#define HOLOGRAM_POWER_USAGE 2
|
||||
|
||||
@@ -55,7 +57,6 @@ Possible to do for anyone motivated enough:
|
||||
var/record_user //user that inititiated the recording
|
||||
var/obj/effect/overlay/holo_pad_hologram/replay_holo //replay hologram
|
||||
var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging
|
||||
var/static/list/holopads = list()
|
||||
var/obj/effect/overlay/holoray/ray
|
||||
var/ringing = FALSE
|
||||
var/offset = FALSE
|
||||
@@ -96,7 +97,7 @@ Possible to do for anyone motivated enough:
|
||||
/obj/machinery/holopad/Initialize()
|
||||
. = ..()
|
||||
if(on_network)
|
||||
holopads += src
|
||||
GLOB.network_holopads += src
|
||||
|
||||
/obj/machinery/holopad/Destroy()
|
||||
if(outgoing_call)
|
||||
@@ -116,7 +117,7 @@ Possible to do for anyone motivated enough:
|
||||
|
||||
QDEL_NULL(disk)
|
||||
|
||||
holopads -= src
|
||||
GLOB.network_holopads -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/holopad/power_change()
|
||||
@@ -260,7 +261,7 @@ Possible to do for anyone motivated enough:
|
||||
temp += "<A href='?src=[REF(src)];mainmenu=1'>Main Menu</A>"
|
||||
if(usr.loc == loc)
|
||||
var/list/callnames = list()
|
||||
for(var/I in holopads)
|
||||
for(var/I in GLOB.network_holopads)
|
||||
var/area/A = get_area(I)
|
||||
if(A)
|
||||
LAZYADD(callnames[A], I)
|
||||
@@ -474,7 +475,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner]
|
||||
if(!h || h.HC) //Holocalls can't change source.
|
||||
return FALSE
|
||||
for(var/pad in holopads)
|
||||
for(var/pad in GLOB.network_holopads)
|
||||
var/obj/machinery/holopad/another = pad
|
||||
if(another == src)
|
||||
continue
|
||||
|
||||
@@ -562,6 +562,7 @@
|
||||
//Shooting Code:
|
||||
A.preparePixelProjectile(target, T)
|
||||
A.firer = src
|
||||
A.fired_from = src
|
||||
A.fire()
|
||||
return A
|
||||
|
||||
|
||||
@@ -209,5 +209,7 @@
|
||||
icon_state = "controller-o"
|
||||
else if(stat & (BROKEN|NOPOWER))
|
||||
icon_state = "controller-p"
|
||||
else if(teleporter_console && teleporter_console.calibrating)
|
||||
icon_state = "controller-c"
|
||||
else
|
||||
icon_state = "controller"
|
||||
|
||||
@@ -3,3 +3,9 @@
|
||||
internal_damage_threshold = 50
|
||||
armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
|
||||
var/spawn_tracked = TRUE
|
||||
|
||||
/obj/mecha/combat/Initialize()
|
||||
. = ..()
|
||||
if(spawn_tracked)
|
||||
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
@@ -19,7 +19,3 @@
|
||||
/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
defense_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/Initialize()
|
||||
. = ..()
|
||||
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax/dark
|
||||
max_equip = 4
|
||||
spawn_tracked = FALSE
|
||||
|
||||
/obj/mecha/combat/gygax/dark/loaded/Initialize()
|
||||
. = ..()
|
||||
@@ -48,7 +49,6 @@
|
||||
return
|
||||
cell = new /obj/item/stock_parts/cell/hyper(src)
|
||||
|
||||
|
||||
/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
overload_action.Grant(user, src)
|
||||
@@ -65,7 +65,3 @@
|
||||
/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/Initialize()
|
||||
. = ..()
|
||||
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
|
||||
@@ -152,8 +152,4 @@
|
||||
var/color=""
|
||||
for (var/i=0;i<6;i++)
|
||||
color = color+pick(colors)
|
||||
return color
|
||||
|
||||
/obj/mecha/combat/Initialize()
|
||||
. = ..()
|
||||
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
return color
|
||||
@@ -16,6 +16,7 @@
|
||||
force = 45
|
||||
max_equip = 4
|
||||
bumpsmash = 1
|
||||
spawn_tracked = FALSE
|
||||
|
||||
/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
breach_time = 100 //ten seconds till all goes to shit
|
||||
recharge_rate = 100
|
||||
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
|
||||
spawn_tracked = FALSE
|
||||
|
||||
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
|
||||
internals_action.Grant(user, src)
|
||||
|
||||
@@ -27,7 +27,3 @@
|
||||
..()
|
||||
switch_damtype_action.Remove(user)
|
||||
phasing_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/Initialize()
|
||||
. = ..()
|
||||
trackers += new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
stepsound = null
|
||||
turnsound = null
|
||||
opacity = 0
|
||||
spawn_tracked = FALSE
|
||||
|
||||
/obj/mecha/combat/reticence/loaded/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -1025,7 +1025,7 @@
|
||||
|
||||
/obj/mecha/log_message(message as text, message_type=LOG_GAME, color=null, log_globally)
|
||||
log.len++
|
||||
log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss")]","date","year"="[GLOB.year_integer+540]","message"="[color?"<font color='[color]'>":null][message][color?"</font>":null]")
|
||||
log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss")]","date","year"="[GLOB.year_integer]","message"="[color?"<font color='[color]'>":null][message][color?"</font>":null]")
|
||||
..()
|
||||
return log.len
|
||||
|
||||
@@ -1034,9 +1034,6 @@
|
||||
last_entry["message"] += "<br>[red?"<font color='red'>":null][message][red?"</font>":null]"
|
||||
return
|
||||
|
||||
GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY"))
|
||||
GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
|
||||
|
||||
///////////////////////
|
||||
///// Power stuff /////
|
||||
///////////////////////
|
||||
|
||||
@@ -89,7 +89,6 @@
|
||||
buckled_mob.clear_alert("buckled")
|
||||
buckled_mobs -= buckled_mob
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, src, force)
|
||||
|
||||
post_unbuckle_mob(.)
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
if(!victim.client || !istype(victim))
|
||||
return
|
||||
to_chat(victim, "<span class='notice'>You feel fast!</span>")
|
||||
ADD_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
|
||||
victim.add_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
|
||||
sleep(duration)
|
||||
REMOVE_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
|
||||
victim.remove_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB)
|
||||
to_chat(victim, "<span class='notice'>You slow down.</span>")
|
||||
|
||||
@@ -97,9 +97,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
// non-clothing items
|
||||
var/datum/dog_fashion/dog_fashion = null
|
||||
|
||||
var/datum/rpg_loot/rpg_loot = null
|
||||
|
||||
|
||||
//Tooltip vars
|
||||
var/force_string //string form of an item's force. Edit this var only to set a custom force string
|
||||
var/last_force_string_check = 0
|
||||
@@ -124,7 +121,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
actions_types = null
|
||||
|
||||
if(GLOB.rpg_loot_items)
|
||||
rpg_loot = new(src)
|
||||
AddComponent(/datum/component/fantasy)
|
||||
|
||||
if(force_string)
|
||||
item_flags |= FORCE_STRING_OVERRIDE
|
||||
@@ -149,7 +146,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
m.temporarilyRemoveItemFromInventory(src, TRUE)
|
||||
for(var/X in actions)
|
||||
qdel(X)
|
||||
QDEL_NULL(rpg_loot)
|
||||
return ..()
|
||||
|
||||
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
|
||||
|
||||
@@ -439,6 +439,9 @@ RLD
|
||||
|
||||
/obj/item/construction/rcd/proc/rcd_create(atom/A, mob/user)
|
||||
var/list/rcd_results = A.rcd_vals(user, src)
|
||||
var/turf/the_turf = get_turf(A)
|
||||
var/turf_coords = "[COORD(the_turf)]"
|
||||
investigate_log("[user] is attempting to use [src] on [A] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
|
||||
if(!rcd_results)
|
||||
return FALSE
|
||||
if(do_after(user, rcd_results["delay"] * delay_mod, target = A))
|
||||
@@ -447,7 +450,7 @@ RLD
|
||||
if(A.rcd_act(user, src, rcd_results["mode"]))
|
||||
useResource(rcd_results["cost"], user)
|
||||
activate()
|
||||
investigate_log("[user] used [src] on [cached] (now [A]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
|
||||
investigate_log("[user] used [src] on [cached] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
|
||||
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
|
||||
var/prox_check = TRUE //If the emag requires you to be in range
|
||||
var/uses = 15
|
||||
|
||||
/obj/item/card/emag/bluespace
|
||||
name = "bluespace cryptographic sequencer"
|
||||
@@ -110,6 +111,37 @@
|
||||
user.visible_message("<span class='warning'>[src] fizzles and sparks. It seems like it's out of charges.</span>")
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 100, 1)
|
||||
|
||||
/obj/item/card/emag/examine(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>It has <b>[uses ? uses : "no"]</b> charges left.</span>")
|
||||
|
||||
/obj/item/card/emag/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/emagrecharge))
|
||||
var/obj/item/emagrecharge/ER = W
|
||||
if(ER.uses)
|
||||
uses += ER.uses
|
||||
to_chat(user, "<span class='notice'>You have added [ER.uses] charges to [src]. It now has [uses] charges.</span>")
|
||||
playsound(src, "sparks", 100, 1)
|
||||
ER.uses = 0
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[ER] has no charges left.</span>")
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/emagrecharge
|
||||
name = "electromagnet charging device"
|
||||
desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "cell_mini"
|
||||
item_flags = NOBLUDGEON
|
||||
var/uses = 5 //Dictates how many charges the device adds to compatible items
|
||||
|
||||
/obj/item/emagrecharge/examine(mob/user)
|
||||
. = ..()
|
||||
if(uses)
|
||||
to_chat(user, "<span class='notice'>It can add up to [uses] charges to compatible devices</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>It has a small, red, blinking light coming from inside of it. It's spent.</span>")
|
||||
|
||||
/obj/item/card/emagfake
|
||||
desc = "It's a card with a magnetic strip attached to some circuitry. Closer inspection shows that this card is a poorly made replica, with a \"DonkCo\" logo stamped on the back."
|
||||
@@ -451,3 +483,58 @@ update_label("John Doe", "Clowny")
|
||||
name = "APC Access ID"
|
||||
desc = "A special ID card that allows access to APC terminals."
|
||||
access = list(ACCESS_ENGINE_EQUIP)
|
||||
|
||||
//Polychromatic Knight Badge
|
||||
|
||||
/obj/item/card/id/knight
|
||||
var/id_color = "#00FF00" //defaults to green
|
||||
name = "knight badge"
|
||||
icon_state = "knight"
|
||||
desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
|
||||
|
||||
/obj/item/card/id/knight/update_label(newname, newjob)
|
||||
if(newname || newjob)
|
||||
name = "[(!newname) ? "knight badge" : "[newname]'s Knight Badge"][(!newjob) ? "" : " ([newjob])"]"
|
||||
return
|
||||
|
||||
name = "[(!registered_name) ? "knight badge" : "[registered_name]'s Knight Badge"][(!assignment) ? "" : " ([assignment])"]"
|
||||
|
||||
/obj/item/card/id/knight/update_icon()
|
||||
var/mutable_appearance/id_overlay = mutable_appearance(icon, "knight_overlay")
|
||||
|
||||
if(id_color)
|
||||
id_overlay.color = id_color
|
||||
cut_overlays()
|
||||
|
||||
add_overlay(id_overlay)
|
||||
|
||||
/obj/item/card/id/knight/AltClick(mob/living/user)
|
||||
. = ..()
|
||||
if(!in_range(src, user)) //Basic checks to prevent abuse
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(alert("Are you sure you want to recolor your id?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",id_color) as color|null
|
||||
if(!in_range(src, user) || !energy_color_input)
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
id_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
|
||||
/obj/item/card/id/knight/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/card/id/knight/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/obj/item/card/id/knight/blue
|
||||
id_color = "#0000FF"
|
||||
|
||||
/obj/item/card/id/knight/captain
|
||||
id_color = "#FFD700"
|
||||
@@ -274,7 +274,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
dat += text("<br><a href='?src=[REF(src)];choice=UpdateInfo'>[id ? "Update PDA Info" : ""]</A><br><br>")
|
||||
|
||||
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss")]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
|
||||
dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer+540]"
|
||||
dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]"
|
||||
|
||||
dat += "<br><br>"
|
||||
|
||||
|
||||
@@ -89,30 +89,23 @@
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Anomalous error. Summon a coder.</span>")
|
||||
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/victim = target
|
||||
if(istype(victim, /mob/living/carbon/human))
|
||||
if(user.zone_selected == "groin") // pp smol. There's probably a smarter way to do this but im retarded. If you have a simpler method let me know.
|
||||
var/list/organs = victim.getorganszone("groin")
|
||||
for(var/internal_organ in organs)
|
||||
if(istype(internal_organ, /obj/item/organ/genital/penis))
|
||||
var/obj/item/organ/genital/penis/O = internal_organ
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
|
||||
victim.visible_message("<span class='warning'>[user] is preparing to shrink [victim]\'s [O.name] with their bluespace compression kit!</span>")
|
||||
if(do_mob(user, victim, 40) && charges > 0 && O.length > 0)
|
||||
victim.visible_message("<span class='warning'>[user] has shrunk [victim]\'s [O.name]!</span>")
|
||||
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
|
||||
sparks()
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
|
||||
charges -= 1
|
||||
O.length -= 5
|
||||
if(O.length < 1)
|
||||
victim.visible_message("<span class='warning'>[user]\'s [O.name] vanishes!</span>")
|
||||
qdel(O) // no pp for you
|
||||
else
|
||||
O.update_size()
|
||||
O.update_appearance()
|
||||
|
||||
else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_GROIN)
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
|
||||
if(!P)
|
||||
return
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
|
||||
H.visible_message("<span class='warning'>[user] is preparing to shrink [H]\'s [P.name] with their bluespace compression kit!</span>")
|
||||
if(do_mob(user, H, 40) && charges > 0 && P.length > 0)
|
||||
H.visible_message("<span class='warning'>[user] has shrunk [H]\'s [P.name]!</span>")
|
||||
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
|
||||
sparks()
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
|
||||
charges -= 1
|
||||
var/p_name = P.name
|
||||
P.modify_size(-5)
|
||||
if(QDELETED(P))
|
||||
H.visible_message("<span class='warning'>[H]\'s [p_name] vanishes!</span>")
|
||||
|
||||
|
||||
/obj/item/compressionkit/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "sleeper"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/mob/living/carbon/patient = null
|
||||
var/mob/living/silicon/robot/hound = null
|
||||
var/mob/living/carbon/patient
|
||||
var/inject_amount = 10
|
||||
var/min_health = -100
|
||||
var/cleaning = FALSE
|
||||
@@ -61,8 +60,18 @@
|
||||
/obj/item/dogborg/sleeper/Exit(atom/movable/O)
|
||||
return 0
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/get_host()
|
||||
if(!loc)
|
||||
return
|
||||
if(iscyborg(loc))
|
||||
return loc
|
||||
else if(iscyborg(loc.loc))
|
||||
return loc.loc //cursed cyborg code
|
||||
|
||||
/obj/item/dogborg/sleeper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
|
||||
hound = loc
|
||||
var/mob/living/silicon/robot/hound = get_host()
|
||||
if(!hound)
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(!iscarbon(target))
|
||||
@@ -82,7 +91,8 @@
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
|
||||
if(patient) return //If you try to eat two people at once, you can only eat one.
|
||||
if(patient)
|
||||
return //If you try to eat two people at once, you can only eat one.
|
||||
|
||||
else //If you don't have someone in you, proceed.
|
||||
if(!isjellyperson(target) && ("toxin" in injection_chems))
|
||||
@@ -94,14 +104,17 @@
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
target.ExtinguishMob() //The tongue already puts out fire stacks but being put into the sleeper shouldn't allow you to keep burning.
|
||||
update_gut()
|
||||
update_gut(hound)
|
||||
user.visible_message("<span class='warning'>[voracious ? "[hound]'s [src.name] lights up and expands as [target] slips inside into their [src.name]." : "[hound]'s sleeper indicator lights up as [target] is scooped up into [hound.p_their()] [src]."]</span>", \
|
||||
"<span class='notice'>Your [voracious ? "[src.name] lights up as [target] slips into" : "sleeper indicator light shines brightly as [target] is scooped inside"] your [src]. Life support functions engaged.</span>")
|
||||
message_admins("[key_name(hound)] has sleeper'd [key_name(patient)] as a dogborg. [ADMIN_JMP(src)]")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 100, 1)
|
||||
|
||||
/obj/item/dogborg/sleeper/container_resist(mob/living/user)
|
||||
hound = loc
|
||||
var/mob/living/silicon/robot/hound = get_host()
|
||||
if(!hound)
|
||||
go_out(user)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
@@ -113,55 +126,41 @@
|
||||
"<span class='notice'>[voracious ? "You start struggling inside of [src]'s tight, flexible confines," : "You start pounding against the metallic walls of [src],"] trying to trigger the release... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a [voracious ? "couple of thumps" : "loud banging noise"] coming from within [hound].</span>")
|
||||
if(do_after(user, breakout_time, target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [hound.name]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [hound.name]!</span>")
|
||||
go_out()
|
||||
go_out(user, hound)
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/go_out(var/target)
|
||||
hound = loc
|
||||
hound.setClickCooldown(50)
|
||||
var/voracious = TRUE
|
||||
if(!hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
else
|
||||
for(var/mob/M in contents)
|
||||
if(!M.client || !(M.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
if(length(contents) > 0)
|
||||
hound.visible_message("<span class='warning'>[voracious ? "[hound] empties out [hound.p_their()] contents via [hound.p_their()] release port." : "[hound]'s underside slides open with an audible clunk before [hound.p_their()] [src] flips over, carelessly dumping its contents onto the ground below [hound.p_them()] before closing right back up again."]</span>", \
|
||||
"<span class='notice'>[voracious ? "You empty your contents via your release port." : "You open your sleeper hatch, quickly releasing all of the contents within before closing it again."]</span>")
|
||||
if(target)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/person = target
|
||||
person.forceMove(get_turf(src))
|
||||
person.reset_perspective()
|
||||
else
|
||||
var/obj/T = target
|
||||
T.loc = hound.loc
|
||||
/obj/item/dogborg/sleeper/proc/go_out(atom/movable/target, mob/living/silicon/robot/hound)
|
||||
var/voracious = hound ? TRUE : FALSE
|
||||
var/list/targets = target && hound ? list(target) : contents
|
||||
if(hound)
|
||||
hound.setClickCooldown(50)
|
||||
if(!hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
else
|
||||
for(var/C in contents)
|
||||
if(iscarbon(C))
|
||||
var/mob/living/carbon/person = C
|
||||
person.forceMove(get_turf(src))
|
||||
person.reset_perspective()
|
||||
else
|
||||
var/obj/T = C
|
||||
T.loc = hound.loc
|
||||
items_preserved.Cut()
|
||||
update_gut()
|
||||
cleaning = FALSE
|
||||
for(var/mob/M in targets)
|
||||
if(!M.client || !(M.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
|
||||
voracious = FALSE
|
||||
if(length(targets))
|
||||
if(hound)
|
||||
hound.visible_message("<span class='warning'>[voracious ? "[hound] empties out [hound.p_their()] contents via [hound.p_their()] release port." : "[hound]'s underside slides open with an audible clunk before [hound.p_their()] [src] flips over, carelessly dumping its contents onto the ground below [hound.p_them()] before closing right back up again."]</span>", \
|
||||
"<span class='notice'>[voracious ? "You empty your contents via your release port." : "You open your sleeper hatch, quickly releasing all of the contents within before closing it again."]</span>")
|
||||
for(var/a in contents)
|
||||
var/atom/movable/AM = a
|
||||
AM.forceMove(get_turf(src))
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
M.reset_perspective()
|
||||
playsound(loc, voracious ? 'sound/effects/splat.ogg' : 'sound/effects/bin_close.ogg', 50, 1)
|
||||
|
||||
else //You clicked eject with nothing in you, let's just reset stuff to be sure.
|
||||
items_preserved.Cut()
|
||||
cleaning = FALSE
|
||||
update_gut()
|
||||
items_preserved.Cut()
|
||||
cleaning = FALSE
|
||||
if(hound)
|
||||
update_gut(hound)
|
||||
|
||||
|
||||
/obj/item/dogborg/sleeper/attack_self(mob/user)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(. || !iscyborg(user))
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
@@ -219,30 +218,31 @@
|
||||
return data
|
||||
|
||||
/obj/item/dogborg/sleeper/ui_act(action, params)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(. || !iscyborg(usr))
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("eject")
|
||||
go_out()
|
||||
go_out(null, usr)
|
||||
. = TRUE
|
||||
if("inject")
|
||||
var/chem = params["chem"]
|
||||
if(!patient)
|
||||
return
|
||||
inject_chem(chem)
|
||||
inject_chem(chem, usr)
|
||||
. = TRUE
|
||||
if("cleaning")
|
||||
if(!contents)
|
||||
to_chat(src, "Your [src] is already cleaned.")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(patient, "<span class='danger'>[hound.name]'s [src] fills with caustic enzymes around you!</span>")
|
||||
to_chat(patient, "<span class='danger'>[usr.name]'s [src] fills with caustic enzymes around you!</span>")
|
||||
to_chat(src, "<span class='danger'>Cleaning process enabled.</span>")
|
||||
clean_cycle()
|
||||
clean_cycle(usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/update_gut()
|
||||
/obj/item/dogborg/sleeper/proc/update_gut(mob/living/silicon/robot/hound)
|
||||
//Well, we HAD one, what happened to them?
|
||||
var/prociconupdate = FALSE
|
||||
var/currentenvy = hound.sleeper_nv
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
//Update icon and return new patient
|
||||
hound.update_icons()
|
||||
return(C)
|
||||
return
|
||||
|
||||
//Cleaning looks better with red on, even with nobody in it
|
||||
if(cleaning && !patient)
|
||||
@@ -307,8 +307,10 @@
|
||||
hound.update_icons()
|
||||
|
||||
//Gurgleborg process
|
||||
/obj/item/dogborg/sleeper/proc/clean_cycle()
|
||||
/obj/item/dogborg/sleeper/proc/clean_cycle(mob/living/silicon/robot/hound)
|
||||
//Sanity
|
||||
if(!hound)
|
||||
return
|
||||
for(var/I in items_preserved)
|
||||
if(!(I in contents))
|
||||
items_preserved -= I
|
||||
@@ -320,13 +322,12 @@
|
||||
if(cleaning_cycles)
|
||||
cleaning_cycles--
|
||||
cleaning = TRUE
|
||||
for(var/mob/living/carbon/human/T in (touchable_items))
|
||||
if((T.status_flags & GODMODE) || !T.digestable)
|
||||
items_preserved += T
|
||||
for(var/mob/living/carbon/C in (touchable_items))
|
||||
if((C.status_flags & GODMODE) || !C.digestable)
|
||||
items_preserved += C
|
||||
else
|
||||
T.adjustBruteLoss(2)
|
||||
T.adjustFireLoss(3)
|
||||
update_gut()
|
||||
C.adjustBruteLoss(2)
|
||||
C.adjustFireLoss(3)
|
||||
if(contents)
|
||||
var/atom/target = pick(touchable_items)
|
||||
if(iscarbon(target)) //Handle the target being a mob
|
||||
@@ -359,7 +360,6 @@
|
||||
if(!T.dropItemToGround(W))
|
||||
qdel(W)
|
||||
qdel(T)
|
||||
update_gut()
|
||||
//Handle the target being anything but a mob
|
||||
else if(isobj(target))
|
||||
var/obj/T = target
|
||||
@@ -374,12 +374,10 @@
|
||||
cleaning_cycles = initial(cleaning_cycles)
|
||||
cleaning = FALSE
|
||||
to_chat(hound, "<span class='notice'>Your [src] chimes it ends its self-cleaning cycle.</span>")//Belly is entirely empty
|
||||
update_gut()
|
||||
|
||||
if(!length(contents))
|
||||
to_chat(hound, "<span class='notice'>Your [src] is now clean. Ending self-cleaning cycle.</span>")
|
||||
cleaning = FALSE
|
||||
update_gut()
|
||||
|
||||
//sound effects
|
||||
if(prob(50))
|
||||
@@ -397,13 +395,17 @@
|
||||
else if(H in contents)
|
||||
H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
|
||||
|
||||
update_gut(hound)
|
||||
|
||||
if(cleaning)
|
||||
addtimer(CALLBACK(src, .proc/clean_cycle), 50)
|
||||
addtimer(CALLBACK(src, .proc/clean_cycle, hound), 50)
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/CheckAccepted(obj/item/I)
|
||||
return is_type_in_typecache(I, important_items)
|
||||
|
||||
/obj/item/dogborg/sleeper/proc/inject_chem(chem)
|
||||
/obj/item/dogborg/sleeper/proc/inject_chem(chem, mob/living/silicon/robot/hound)
|
||||
if(!hound)
|
||||
return
|
||||
if(hound.cell.charge <= 800) //This is so borgs don't kill themselves with it. Remember, 750 charge used every injection.
|
||||
to_chat(hound, "<span class='notice'>You don't have enough power to synthesize fluids.</span>")
|
||||
return
|
||||
@@ -438,40 +440,27 @@
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/dogborg/sleeper/K9/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)
|
||||
hound = loc
|
||||
/obj/item/dogborg/sleeper/K9/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
|
||||
var/mob/living/silicon/robot/hound = get_host()
|
||||
if(!hound || !istype(target) || !proximity || target.anchored)
|
||||
return
|
||||
if (!target.devourable)
|
||||
to_chat(user, "The target registers an error code. Unable to insert into [src].")
|
||||
return
|
||||
if(target)
|
||||
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
|
||||
return
|
||||
if(target.buckled)
|
||||
to_chat(user,"<span class='warning'>[target] is buckled and can not be put into your [src].</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [target] into their [src].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
if(do_after(user, 30, target = target) && !patient && !target.buckled)
|
||||
target.forceMove(src)
|
||||
target.reset_perspective(src)
|
||||
update_gut(hound)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [target] slips inside.</span>", "<span class='notice'>Your mobile brig groans lightly as [target] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
|
||||
|
||||
if(!istype(target))
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(target.anchored)
|
||||
return
|
||||
if(isobj(target))
|
||||
to_chat(user, "You are above putting such trash inside of yourself.")
|
||||
return
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/brigman = target
|
||||
if (!brigman.devourable)
|
||||
to_chat(user, "The target registers an error code. Unable to insert into [src].")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
|
||||
return
|
||||
if(brigman.buckled)
|
||||
to_chat(user,"<span class='warning'>[brigman] is buckled and can not be put into your [src].</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [brigman] into their [src].</span>", "<span class='notice'>You start ingesting [brigman] into your [src.name]...</span>")
|
||||
if(do_after(user, 30, target = brigman) && !patient && !brigman.buckled)
|
||||
if(!in_range(src, brigman)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
brigman.forceMove(src)
|
||||
brigman.reset_perspective(src)
|
||||
update_gut()
|
||||
user.visible_message("<span class='warning'>[hound.name]'s mobile brig clunks in series as [brigman] slips inside.</span>", "<span class='notice'>Your mobile brig groans lightly as [brigman] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/dogborg/sleeper/compactor //Janihound gut.
|
||||
name = "garbage processor"
|
||||
@@ -489,31 +478,25 @@
|
||||
else
|
||||
. = ..()
|
||||
|
||||
/obj/item/dogborg/sleeper/compactor/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS
|
||||
hound = loc
|
||||
var/obj/item/target_obj = target
|
||||
if(!istype(target))
|
||||
return
|
||||
if(!proximity)
|
||||
return
|
||||
if(target.anchored)
|
||||
/obj/item/dogborg/sleeper/compactor/afterattack(atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS
|
||||
var/mob/living/silicon/robot/hound = get_host()
|
||||
if(!hound || !istype(target) || !proximity || target.anchored)
|
||||
return
|
||||
if(length(contents) > (max_item_count - 1))
|
||||
to_chat(user,"<span class='warning'>Your [src] is full. Eject or process contents to continue.</span>")
|
||||
return
|
||||
if(isobj(target))
|
||||
if(CheckAccepted(target))
|
||||
to_chat(user,"<span class='warning'>\The [target] registers an error code to your [src]</span>")
|
||||
if(isitem(target))
|
||||
var/obj/item/I = target
|
||||
if(CheckAccepted(I))
|
||||
to_chat(user,"<span class='warning'>[I] registers an error code to your [src]</span>")
|
||||
return
|
||||
if(target_obj.w_class > WEIGHT_CLASS_NORMAL)
|
||||
to_chat(user,"<span class='warning'>\The [target] is too large to fit into your [src]</span>")
|
||||
if(I.w_class > WEIGHT_CLASS_NORMAL)
|
||||
to_chat(user,"<span class='warning'>[I] is too large to fit into your [src]</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [I] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
|
||||
if(do_after(user, 15, target = target) && length(contents) < max_item_count)
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them. This still applies to items, don't magically eat things I picked up already.
|
||||
target.forceMove(src)
|
||||
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [target] slips inside.</span>")
|
||||
I.forceMove(src)
|
||||
I.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [I] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [I] slips inside.</span>")
|
||||
playsound(hound, 'sound/machines/disposalflush.ogg', 50, 1)
|
||||
if(length(contents) > 11) //grow that tum after a certain junk amount
|
||||
hound.sleeper_r = 1
|
||||
@@ -523,9 +506,9 @@
|
||||
hound.update_icons()
|
||||
return
|
||||
|
||||
else if(iscarbon(target))
|
||||
var/mob/living/carbon/trashman = target
|
||||
if (!trashman.devourable)
|
||||
if(iscarbon(target) || issilicon(target))
|
||||
var/mob/living/trashman = target
|
||||
if(!trashman.devourable)
|
||||
to_chat(user, "<span class='warning'>[target] registers an error code to your [src]</span>")
|
||||
return
|
||||
if(patient)
|
||||
@@ -536,34 +519,8 @@
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashman] into their [src].</span>", "<span class='notice'>You start ingesting [trashman] into your [src.name]...</span>")
|
||||
if(do_after(user, 30, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
|
||||
if(!in_range(src, trashman)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
trashman.forceMove(src)
|
||||
trashman.reset_perspective(src)
|
||||
update_gut()
|
||||
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
|
||||
return
|
||||
else if(issilicon(target))
|
||||
var/mob/living/silicon/trashbot = target
|
||||
if (!trashbot.devourable)
|
||||
to_chat(user, "<span class='warning'>[target] registers an error code to your [src]</span>")
|
||||
return
|
||||
if(patient)
|
||||
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
|
||||
return
|
||||
if(trashbot.buckled)
|
||||
to_chat(user,"<span class='warning'>[trashbot] is buckled and can not be put into your [src].</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashbot] into their [src].</span>", "<span class='notice'>You start ingesting [trashbot] into your [src.name]...</span>")
|
||||
if(do_after(user, 30, target = trashbot) && !patient && !trashbot.buckled && length(contents) < max_item_count)
|
||||
if(!in_range(src, trashbot)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
trashbot.forceMove(src)
|
||||
trashbot.reset_perspective(src)
|
||||
update_gut()
|
||||
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashbot] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashbot] slips inside.</span>")
|
||||
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/obj/item/multitool/chaplain/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
|
||||
|
||||
/obj/item/multitool/examine(mob/user)
|
||||
..()
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
|
||||
/obj/item/nullrod/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
|
||||
|
||||
/obj/item/nullrod/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god!</span>")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/obj/item/implant/storage/removed(source, silent = FALSE, special = 0)
|
||||
if(!special)
|
||||
qdel(pocket)
|
||||
QDEL_NULL(pocket)
|
||||
else
|
||||
pocket?.moveToNullspace()
|
||||
return ..()
|
||||
@@ -29,7 +29,7 @@
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(.)
|
||||
if(pocket)
|
||||
if(!QDELETED(pocket))
|
||||
pocket.forceMove(target)
|
||||
else
|
||||
pocket = new(target)
|
||||
@@ -41,7 +41,6 @@
|
||||
desc = "A tiny yet spacious pocket, usually found implanted inside sneaky syndicate agents and nowhere else."
|
||||
component_type = /datum/component/storage/concrete/implant
|
||||
resistance_flags = INDESTRUCTIBLE //A bomb!
|
||||
item_flags = DROPDEL
|
||||
|
||||
/obj/item/implanter/storage
|
||||
name = "implanter (storage)"
|
||||
|
||||
@@ -233,3 +233,152 @@
|
||||
desc = "An extremely sharp blade made out of hard light. Packs quite a punch."
|
||||
icon_state = "lightblade"
|
||||
item_state = "lightblade"
|
||||
|
||||
/*/////////////////////////////////////////////////////////////////////////
|
||||
///////////// The TRUE Energy Sword ///////////////////////////
|
||||
*//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx
|
||||
name = "non-eutactic blade"
|
||||
desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
|
||||
icon_state = "cxsword_hilt"
|
||||
item_state = "cxsword"
|
||||
force = 3
|
||||
force_on = 21
|
||||
throwforce = 5
|
||||
throwforce_on = 20
|
||||
hitsound = "swing_hit" //it starts deactivated
|
||||
hitsound_on = 'sound/weapons/nebhit.ogg'
|
||||
attack_verb_off = list("tapped", "poked")
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
sharpness = IS_SHARP
|
||||
embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
|
||||
armour_penetration = 10
|
||||
block_chance = 35
|
||||
light_color = "#37FFF7"
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
|
||||
active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
|
||||
if(active) //also I'd need to rip out the iconstate changing bits
|
||||
force = force_on
|
||||
throwforce = throwforce_on
|
||||
hitsound = hitsound_on
|
||||
throw_speed = 4
|
||||
if(attack_verb_on.len)
|
||||
attack_verb = attack_verb_on
|
||||
w_class = w_class_on
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_light(brightness_on)
|
||||
update_icon()
|
||||
else
|
||||
force = initial(force)
|
||||
throwforce = initial(throwforce)
|
||||
hitsound = initial(hitsound)
|
||||
throw_speed = initial(throw_speed)
|
||||
if(attack_verb_off.len)
|
||||
attack_verb = attack_verb_off
|
||||
w_class = initial(w_class)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_light(0)
|
||||
update_icon()
|
||||
transform_messages(user, supress_message_text)
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
|
||||
playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
|
||||
if(!supress_message_text)
|
||||
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/update_icon()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
|
||||
var/mutable_appearance/gem_overlay = mutable_appearance(icon, "cxsword_gem")
|
||||
|
||||
if(light_color)
|
||||
blade_overlay.color = light_color
|
||||
gem_overlay.color = light_color
|
||||
|
||||
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
|
||||
|
||||
add_overlay(gem_overlay)
|
||||
|
||||
if(active)
|
||||
add_overlay(blade_overlay)
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
|
||||
if(!in_range(src, user)) //Basic checks to prevent abuse
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
|
||||
if(energy_color_input)
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
update_light()
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(isinhands)
|
||||
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
|
||||
blade_inhand.color = light_color
|
||||
. += blade_inhand
|
||||
|
||||
//Broken version. Not a toy, but not as strong.
|
||||
/obj/item/melee/transforming/energy/sword/cx/broken
|
||||
name = "misaligned non-eutactic blade"
|
||||
desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. This one seems to have a damaged handle and misaligned components, causing the blade to be unstable at best"
|
||||
force_on = 15 //As strong a survival knife/bone dagger
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params)
|
||||
if(istype(W, /obj/item/melee/transforming/energy/sword/cx))
|
||||
if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
|
||||
to_chat(user, "<span class='warning'>\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You combine the two light swords, making a single supermassive blade! You're cool.</span>")
|
||||
new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
//////// Tatortot NEB /////////////// (same stats as regular esword)
|
||||
/obj/item/melee/transforming/energy/sword/cx/traitor
|
||||
name = "\improper Dragon's Tooth Sword"
|
||||
desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \
|
||||
which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
|
||||
It appears to have a wooden grip and a shaved down guard."
|
||||
icon_state = "cxsword_hilt_traitor"
|
||||
force_on = 30
|
||||
armour_penetration = 50
|
||||
embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10)
|
||||
block_chance = 50
|
||||
hitsound_on = 'sound/weapons/blade1.ogg'
|
||||
light_color = "#37F0FF"
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
|
||||
playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
|
||||
if(!supress_message_text)
|
||||
to_chat(user, "<span class='notice'>[src] [active ? "is now active":"can now be concealed"].</span>")
|
||||
|
||||
@@ -366,10 +366,10 @@
|
||||
/obj/item/toy/plush/random
|
||||
name = "Illegal plushie"
|
||||
desc = "Something fucked up"
|
||||
var/blacklisted_plushes = list(/obj/item/toy/plush/carpplushie/dehy_carp, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random)
|
||||
|
||||
/obj/item/toy/plush/random/Initialize()
|
||||
..()
|
||||
var/newtype = pick(subtypesof(/obj/item/toy/plush))
|
||||
var/newtype = pick(subtypesof(/obj/item/toy/plush) - typecacheof(blacklisted_plushes))
|
||||
new newtype(loc)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
if(M.get_ear_protection() == FALSE)
|
||||
M.confused += 6
|
||||
audible_message("<font color='red' size='7'>HUMAN HARM</font>")
|
||||
playsound(get_turf(src), 'sound/ai/harmalarm.ogg', 70, 3)
|
||||
playsound(get_turf(src), 'sound/effects/harmalarm.ogg', 70, 3)
|
||||
cooldown = world.time + 200
|
||||
log_game("[key_name(user)] used a Cyborg Harm Alarm in [AREACOORD(user)]")
|
||||
if(iscyborg(user))
|
||||
@@ -430,7 +430,7 @@
|
||||
A.BB.nodamage = FALSE
|
||||
A.BB.speed = 0.5
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
|
||||
A.fire_casing(target, user, params, 0, 0, null, 0)
|
||||
A.fire_casing(target, user, params, 0, 0, null, 0, src)
|
||||
user.visible_message("<span class='warning'>[user] blasts a flying lollipop at [target]!</span>")
|
||||
check_amount()
|
||||
|
||||
@@ -446,7 +446,7 @@
|
||||
A.BB.speed = 0.5
|
||||
A.BB.color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
|
||||
playsound(src.loc, 'sound/weapons/bulletflyby3.ogg', 50, 1)
|
||||
A.fire_casing(target, user, params, 0, 0, null, 0)
|
||||
A.fire_casing(target, user, params, 0, 0, null, 0, src)
|
||||
user.visible_message("<span class='warning'>[user] shoots a high-velocity gumball at [target]!</span>")
|
||||
check_amount()
|
||||
|
||||
@@ -746,3 +746,73 @@
|
||||
..()
|
||||
hud = new /obj/item/clothing/glasses/hud/security(src)
|
||||
return
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Grippers oh god oh fuck
|
||||
***********************************************************************/
|
||||
|
||||
/obj/item/weapon/gripper
|
||||
name = "circuit gripper"
|
||||
desc = "A simple grasping tool for inserting circuitboards into machinary."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gripper"
|
||||
|
||||
item_flags = NOBLUDGEON
|
||||
|
||||
//Has a list of items that it can hold.
|
||||
var/list/can_hold = list(
|
||||
/obj/item/circuitboard
|
||||
)
|
||||
|
||||
var/obj/item/wrapped = null // Item currently being held.
|
||||
|
||||
/obj/item/weapon/gripper/attack_self()
|
||||
if(wrapped)
|
||||
wrapped.forceMove(get_turf(wrapped))
|
||||
wrapped = null
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params)
|
||||
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
if(!wrapped)
|
||||
for(var/obj/item/thing in src.contents)
|
||||
wrapped = thing
|
||||
break
|
||||
|
||||
if(wrapped) //Already have an item.
|
||||
//Temporary put wrapped into user so target's attackby() checks pass.
|
||||
wrapped.loc = user
|
||||
|
||||
//Pass the attack on to the target. This might delete/relocate wrapped.
|
||||
var/resolved = target.attackby(wrapped,user)
|
||||
if(!resolved && wrapped && target)
|
||||
wrapped.afterattack(target,user,1)
|
||||
//If wrapped was neither deleted nor put into target, put it back into the gripper.
|
||||
if(wrapped && user && (wrapped.loc == user))
|
||||
wrapped.loc = src
|
||||
else
|
||||
wrapped = null
|
||||
return
|
||||
|
||||
else if(istype(target,/obj/item))
|
||||
|
||||
var/obj/item/I = target
|
||||
|
||||
var/grab = 0
|
||||
for(var/typepath in can_hold)
|
||||
if(istype(I,typepath))
|
||||
grab = 1
|
||||
break
|
||||
|
||||
//We can grab the item, finally.
|
||||
if(grab)
|
||||
to_chat(user, "You collect \the [I].")
|
||||
I.loc = src
|
||||
wrapped = I
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Your gripper cannot hold \the [target].</span>")
|
||||
|
||||
@@ -89,32 +89,36 @@
|
||||
R.speed = initial(R.speed)
|
||||
|
||||
/obj/item/borg/upgrade/disablercooler
|
||||
name = "cyborg rapid disabler cooling module"
|
||||
desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate."
|
||||
name = "cyborg rapid energy blaster cooling module"
|
||||
desc = "Used to cool a mounted energy-based firearm, increasing the potential current in it and thus its recharge rate."
|
||||
icon_state = "cyborg_upgrade3"
|
||||
require_module = 1
|
||||
|
||||
/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.module.modules
|
||||
if(!T)
|
||||
to_chat(user, "<span class='notice'>There's no disabler in this unit!</span>")
|
||||
var/successflag
|
||||
for(var/obj/item/gun/energy/T in R.module.modules)
|
||||
if(T.charge_delay <= 2)
|
||||
successflag = successflag || 2
|
||||
continue
|
||||
T.charge_delay = max(2, T.charge_delay - 4)
|
||||
successflag = 1
|
||||
if(!successflag)
|
||||
to_chat(user, "<span class='notice'>There's no energy-based firearm in this unit!</span>")
|
||||
return FALSE
|
||||
if(T.charge_delay <= 2)
|
||||
if(successflag == 2)
|
||||
to_chat(R, "<span class='notice'>A cooling unit is already installed!</span>")
|
||||
to_chat(user, "<span class='notice'>There's no room for another cooling unit!</span>")
|
||||
return FALSE
|
||||
|
||||
T.charge_delay = max(2 , T.charge_delay - 4)
|
||||
|
||||
/obj/item/borg/upgrade/disablercooler/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
if (.)
|
||||
var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.module.modules
|
||||
if(!T)
|
||||
return FALSE
|
||||
T.charge_delay = initial(T.charge_delay)
|
||||
for(var/obj/item/gun/energy/T in R.module.modules)
|
||||
T.charge_delay = initial(T.charge_delay)
|
||||
return .
|
||||
return FALSE
|
||||
|
||||
/obj/item/borg/upgrade/thrusters
|
||||
name = "ion thruster upgrade"
|
||||
@@ -598,10 +602,10 @@
|
||||
R.update_transform()
|
||||
|
||||
/obj/item/borg/upgrade/rped
|
||||
name = "engineering cyborg RPED"
|
||||
name = "engineering cyborg BSRPED"
|
||||
desc = "A rapid part exchange device for the engineering cyborg."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "borgrped"
|
||||
icon_state = "borg_BS_RPED"
|
||||
require_module = TRUE
|
||||
module_type = list(/obj/item/robot_module/engineering)
|
||||
|
||||
@@ -609,14 +613,21 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
|
||||
var/obj/item/storage/part_replacer/bluespace/cyborg/BSRPED = locate() in R
|
||||
var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R
|
||||
if(RPED)
|
||||
to_chat(user, "<span class='warning'>This unit is already equipped with a RPED module.</span>")
|
||||
if(!RPED)
|
||||
RPED = locate() in R.module
|
||||
if(!BSRPED)
|
||||
BSRPED = locate() in R.module //There's gotta be a smarter way to do this.
|
||||
if(BSRPED)
|
||||
to_chat(user, "<span class='warning'>This unit is already equipped with a BSRPED module.</span>")
|
||||
return FALSE
|
||||
|
||||
RPED = new(R.module)
|
||||
R.module.basic_modules += RPED
|
||||
R.module.add_module(RPED, FALSE, TRUE)
|
||||
BSRPED = new(R.module)
|
||||
SEND_SIGNAL(RPED, COMSIG_TRY_STORAGE_QUICK_EMPTY)
|
||||
qdel(RPED)
|
||||
R.module.basic_modules += BSRPED
|
||||
R.module.add_module(BSRPED, FALSE, TRUE)
|
||||
|
||||
/obj/item/borg/upgrade/rped/deactivate(mob/living/silicon/robot/R, user = usr)
|
||||
. = ..()
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
STR.max_combined_w_class = 30
|
||||
STR.max_items = 30
|
||||
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear))
|
||||
STR.limited_random_access = TRUE
|
||||
STR.limited_random_access_stack_position = 3
|
||||
|
||||
/obj/item/storage/bag/trash/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting!</span>")
|
||||
@@ -88,6 +90,7 @@
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 60
|
||||
STR.max_items = 60
|
||||
STR.limited_random_access_stack_position = 5
|
||||
|
||||
/obj/item/storage/bag/trash/bluespace/cyborg
|
||||
insertable = FALSE
|
||||
|
||||
@@ -1144,7 +1144,7 @@
|
||||
if(can_expire)
|
||||
expiration_date = rand(expiration_date_min, expiration_date_max)
|
||||
desc += "\n<span_clas='notice'>An expiry date is listed on it. It reads: [expiration_date]</span>"
|
||||
var/spess_current_year = GLOB.year_integer + 540
|
||||
var/spess_current_year = GLOB.year_integer
|
||||
if(expiration_date < spess_current_year)
|
||||
var/gross_risk = min(round(spess_current_year - expiration_date * 0.1), 1)
|
||||
var/toxic_risk = min(round(spess_current_year - expiration_date * 0.01), 1)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#define STUNBATON_CHARGE_LENIENCY 0.3
|
||||
#define STUNBATON_DEPLETION_RATE 0.006
|
||||
|
||||
/obj/item/melee/baton
|
||||
name = "stunbaton"
|
||||
@@ -76,7 +77,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/item/melee/baton/process()
|
||||
deductcharge(hitcost * 0.004, FALSE, FALSE)
|
||||
deductcharge(round(hitcost * STUNBATON_DEPLETION_RATE), FALSE, FALSE)
|
||||
|
||||
/obj/item/melee/baton/update_icon()
|
||||
if(status)
|
||||
@@ -250,4 +251,5 @@
|
||||
sparkler?.activate()
|
||||
. = ..()
|
||||
|
||||
#undef STUNBATON_CHARGE_LENIENCY
|
||||
#undef STUNBATON_CHARGE_LENIENCY
|
||||
#undef STUNBATON_DEPLETION_RATE
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/obj/item/tank/jetpack/New()
|
||||
..()
|
||||
if(gas_type)
|
||||
air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)
|
||||
air_contents.gases[gas_type] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))
|
||||
|
||||
ion_trail = new
|
||||
ion_trail.set_up(src)
|
||||
@@ -37,42 +37,50 @@
|
||||
return
|
||||
|
||||
if(!on)
|
||||
turn_on()
|
||||
turn_on(user)
|
||||
to_chat(user, "<span class='notice'>You turn the jetpack on.</span>")
|
||||
else
|
||||
turn_off()
|
||||
turn_off(user)
|
||||
to_chat(user, "<span class='notice'>You turn the jetpack off.</span>")
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
/obj/item/tank/jetpack/proc/turn_on()
|
||||
/obj/item/tank/jetpack/proc/turn_on(mob/user)
|
||||
on = TRUE
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
ion_trail.start()
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/move_react)
|
||||
if(full_speed)
|
||||
user.add_movespeed_modifier(MOVESPEED_ID_JETPACK, priority=100, multiplicative_slowdown=-2, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
|
||||
|
||||
/obj/item/tank/jetpack/proc/turn_off()
|
||||
/obj/item/tank/jetpack/proc/turn_off(mob/user)
|
||||
on = FALSE
|
||||
stabilizers = FALSE
|
||||
icon_state = initial(icon_state)
|
||||
ion_trail.stop()
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
user.remove_movespeed_modifier(MOVESPEED_ID_JETPACK)
|
||||
|
||||
/obj/item/tank/jetpack/proc/move_react(mob/user)
|
||||
allow_thrust(0.01, user)
|
||||
|
||||
/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
|
||||
if(!on)
|
||||
return
|
||||
if((num < 0.005 || air_contents.total_moles() < num))
|
||||
turn_off()
|
||||
turn_off(user)
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(num)
|
||||
if(removed.total_moles() < 0.005)
|
||||
turn_off()
|
||||
turn_off(user)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
T.assume_air(removed)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank/jetpack/suicide_act(mob/user)
|
||||
if (istype(user, /mob/living/carbon/human/))
|
||||
@@ -96,22 +104,22 @@
|
||||
if(!on)
|
||||
return
|
||||
if((num < 0.005 || air_contents.total_moles() < num))
|
||||
turn_off()
|
||||
turn_off(user)
|
||||
return
|
||||
if(rand(0,250) == 0)
|
||||
to_chat(user, "<span class='notice'>You feel your jetpack's engines cut out.</span>")
|
||||
turn_off()
|
||||
turn_off(user)
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/removed = air_contents.remove(num)
|
||||
if(removed.total_moles() < 0.005)
|
||||
turn_off()
|
||||
turn_off(user)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
T.assume_air(removed)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/tank/jetpack/void
|
||||
name = "void jetpack (oxygen)"
|
||||
@@ -178,6 +186,7 @@
|
||||
full_speed = FALSE
|
||||
var/datum/gas_mixture/temp_air_contents
|
||||
var/obj/item/tank/internals/tank = null
|
||||
var/mob/living/carbon/human/cur_user
|
||||
|
||||
/obj/item/tank/jetpack/suit/New()
|
||||
..()
|
||||
@@ -198,28 +207,30 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/tank/jetpack/suit/turn_on()
|
||||
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
|
||||
/obj/item/tank/jetpack/suit/turn_on(mob/user)
|
||||
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc) || loc.loc != user)
|
||||
return
|
||||
var/mob/living/carbon/human/H = loc.loc
|
||||
var/mob/living/carbon/human/H = user
|
||||
tank = H.s_store
|
||||
air_contents = tank.air_contents
|
||||
START_PROCESSING(SSobj, src)
|
||||
cur_user = user
|
||||
..()
|
||||
|
||||
/obj/item/tank/jetpack/suit/turn_off()
|
||||
/obj/item/tank/jetpack/suit/turn_off(mob/user)
|
||||
tank = null
|
||||
air_contents = temp_air_contents
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
cur_user = null
|
||||
..()
|
||||
|
||||
/obj/item/tank/jetpack/suit/process()
|
||||
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
|
||||
turn_off()
|
||||
turn_off(cur_user)
|
||||
return
|
||||
var/mob/living/carbon/human/H = loc.loc
|
||||
if(!tank || tank != H.s_store)
|
||||
turn_off()
|
||||
turn_off(cur_user)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
item_state = "teleprod"
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
|
||||
/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user)//handles making things teleport when hit
|
||||
. = ..()
|
||||
if(!. || !istype(M) || M.anchored)
|
||||
if(!. || L.anchored)
|
||||
return
|
||||
do_teleport(M, get_turf(M), 15, channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
do_teleport(L, get_turf(L), 15, channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
|
||||
/obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user)
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
|
||||
@@ -276,6 +276,106 @@
|
||||
/obj/item/toy/sword/getweight()
|
||||
return (active ? total_mass_on : total_mass) || w_class *1.25
|
||||
|
||||
/obj/item/toy/sword/cx
|
||||
name = "\improper DX Non-Euplastic LightSword"
|
||||
desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "cxsword_hilt"
|
||||
item_state = "cxsword"
|
||||
active = FALSE
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("poked", "jabbed", "hit")
|
||||
light_color = "#37FFF7"
|
||||
var/light_brightness = 3
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/toy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/sword/cx/attack_self(mob/user)
|
||||
active = !( active )
|
||||
|
||||
if (active)
|
||||
to_chat(user, "<span class='notice'>You activate the holographic blade with a press of a button.</span>")
|
||||
playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
attack_verb = list("slashed", "stabbed", "ravaged")
|
||||
set_light(light_brightness)
|
||||
update_icon()
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You deactivate the holographic blade with a press of a button.</span>")
|
||||
playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("poked", "jabbed", "hit")
|
||||
set_light(0)
|
||||
update_icon()
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/toy/sword/cx/update_icon()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
|
||||
var/mutable_appearance/gem_overlay = mutable_appearance(icon, "cxsword_gem")
|
||||
|
||||
if(light_color)
|
||||
blade_overlay.color = light_color
|
||||
gem_overlay.color = light_color
|
||||
|
||||
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
|
||||
|
||||
add_overlay(gem_overlay)
|
||||
|
||||
if(active)
|
||||
add_overlay(blade_overlay)
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
/obj/item/toy/sword/cx/AltClick(mob/living/user)
|
||||
if(!in_range(src, user)) //Basic checks to prevent abuse
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
|
||||
if(energy_color_input)
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
update_light()
|
||||
|
||||
/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
|
||||
. = ..()
|
||||
if(active)
|
||||
if(isinhands)
|
||||
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
|
||||
blade_inhand.color = light_color
|
||||
. += blade_inhand
|
||||
|
||||
/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
|
||||
if(istype(W, /obj/item/toy/sword/cx))
|
||||
if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
|
||||
to_chat(user, "<span class='warning'>\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You combine the two plastic swords, making a single supermassive toy! You're fake-cool.</span>")
|
||||
new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc)
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/sword/cx/examine(mob/user)
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/*
|
||||
* Foam armblade
|
||||
*/
|
||||
@@ -337,6 +437,30 @@
|
||||
/obj/item/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles
|
||||
return FALSE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy
|
||||
name = "\improper DX Hyper-Euplastic LightSword"
|
||||
desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up."
|
||||
force = 0
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
force_unwielded = 0
|
||||
force_wielded = 0
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
slowdown_wielded = 0
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
||||
return FALSE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles
|
||||
return FALSE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
|
||||
name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
|
||||
desc = "A custom-built toy with fancy rainbow lights built-in."
|
||||
hacked = TRUE
|
||||
|
||||
/obj/item/toy/katana
|
||||
name = "replica katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* Spears
|
||||
* CHAINSAWS
|
||||
* Bone Axe and Spear
|
||||
* And more
|
||||
*/
|
||||
|
||||
/*##################################################################
|
||||
@@ -464,6 +465,116 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// HYPEREUTACTIC Blades /////////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic
|
||||
icon = 'icons/obj/1x2.dmi'
|
||||
icon_state = "hypereutactic"
|
||||
lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
|
||||
item_state = "hypereutactic"
|
||||
inhand_x_dimension = 64
|
||||
inhand_y_dimension = 64
|
||||
name = "hypereutactic blade"
|
||||
desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
|
||||
force = 7
|
||||
force_unwielded = 7
|
||||
force_wielded = 40
|
||||
wieldsound = 'sound/weapons/nebon.ogg'
|
||||
unwieldsound = 'sound/weapons/neboff.ogg'
|
||||
hitsound_on = 'sound/weapons/nebhit.ogg'
|
||||
slowdown_wielded = 1
|
||||
armour_penetration = 60
|
||||
light_color = "#37FFF7"
|
||||
rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
|
||||
spinnable = FALSE
|
||||
total_mass_on = 4
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/chaplain
|
||||
name = "\improper divine lightblade"
|
||||
desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
|
||||
force = 5
|
||||
force_unwielded = 5
|
||||
force_wielded = 20
|
||||
block_chance = 50
|
||||
armour_penetration = 0
|
||||
var/chaplain_spawnable = TRUE
|
||||
obj_flags = UNIQUE_RENAME
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
|
||||
return FALSE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
|
||||
altafterattack(A, user, TRUE, params)
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) //does right click memes
|
||||
if(istype(user))
|
||||
user.visible_message("<span class='notice'>[user] points the tip of [src] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/update_icon()
|
||||
var/mutable_appearance/blade_overlay = mutable_appearance(icon, "hypereutactic_blade")
|
||||
var/mutable_appearance/gem_overlay = mutable_appearance(icon, "hypereutactic_gem")
|
||||
|
||||
if(light_color)
|
||||
blade_overlay.color = light_color
|
||||
gem_overlay.color = light_color
|
||||
|
||||
cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
|
||||
|
||||
add_overlay(gem_overlay)
|
||||
|
||||
if(wielded)
|
||||
add_overlay(blade_overlay)
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_hands()
|
||||
|
||||
clean_blood()
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user)
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
|
||||
return
|
||||
if(user.incapacitated() || !istype(user))
|
||||
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
|
||||
return
|
||||
if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
|
||||
var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
|
||||
if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
|
||||
return
|
||||
light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
|
||||
update_icon()
|
||||
update_light()
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file)
|
||||
. = ..()
|
||||
if(isinhands)
|
||||
var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
|
||||
gem_inhand.color = light_color
|
||||
. += gem_inhand
|
||||
if(wielded)
|
||||
var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
|
||||
blade_inhand.color = light_color
|
||||
. += blade_inhand
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/examine(mob/user)
|
||||
..()
|
||||
if(!hacked)
|
||||
to_chat(user, "<span class='notice'>Alt-click to recolor it.</span>")
|
||||
|
||||
/obj/item/twohanded/dualsaber/hypereutactic/rainbow_process()
|
||||
. = ..()
|
||||
update_icon()
|
||||
update_light()
|
||||
|
||||
//spears
|
||||
/obj/item/twohanded/spear
|
||||
icon_state = "spearglass0"
|
||||
|
||||
@@ -528,7 +528,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
/obj/item/melee/baseball_bat/chaplain/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE)
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
|
||||
|
||||
/obj/item/melee/baseball_bat/homerun
|
||||
name = "home run bat"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/structure/sign/barsign // All Signs are 64 by 32 pixels, they take two tiles
|
||||
/obj/structure/sign/barsign // All Signs are 64 by 64 pixels, though most of them are made to fit 64 x 32 and only take the two lowermost tiles.
|
||||
name = "Bar Sign"
|
||||
desc = "A bar sign with no writing on it."
|
||||
icon = 'icons/obj/barsigns.dmi'
|
||||
|
||||
@@ -495,7 +495,25 @@
|
||||
icon_state = "sofamiddle"
|
||||
icon = 'icons/obj/sofa.dmi'
|
||||
buildstackamount = 1
|
||||
item_chair = null
|
||||
var/mutable_appearance/armrest
|
||||
|
||||
/obj/structure/chair/sofa/Initialize()
|
||||
armrest = mutable_appearance(icon, "[icon_state]_armrest")
|
||||
return ..()
|
||||
|
||||
/obj/structure/chair/sofa/post_buckle_mob(mob/living/M)
|
||||
. = ..()
|
||||
update_armrest()
|
||||
|
||||
/obj/structure/chair/sofa/proc/update_armrest()
|
||||
if(has_buckled_mobs())
|
||||
add_overlay(armrest)
|
||||
else
|
||||
cut_overlay(armrest)
|
||||
|
||||
/obj/structure/chair/sofa/post_unbuckle_mob()
|
||||
. = ..()
|
||||
update_armrest()
|
||||
|
||||
/obj/structure/chair/sofa/left
|
||||
icon_state = "sofaend_left"
|
||||
@@ -504,4 +522,7 @@
|
||||
icon_state = "sofaend_right"
|
||||
|
||||
/obj/structure/chair/sofa/corner
|
||||
icon_state = "sofacorner"
|
||||
icon_state = "sofacorner"
|
||||
|
||||
/obj/structure/chair/sofa/corner/handle_layer() //only the armrest/back of this chair should cover the mob.
|
||||
return
|
||||
@@ -614,3 +614,6 @@
|
||||
user.resting = FALSE
|
||||
togglelock(user)
|
||||
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
|
||||
|
||||
/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return ..() && opened
|
||||
|
||||
@@ -300,18 +300,9 @@
|
||||
throw_speed = 2
|
||||
throw_range = 4
|
||||
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/equipped(mob/living/user)
|
||||
var/image/I = image(icon = 'icons/obj/flora/plants.dmi' , icon_state = src.icon_state, loc = user)
|
||||
I.copy_overlays(src)
|
||||
I.override = 1
|
||||
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
..()
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/dropped(mob/living/user)
|
||||
..()
|
||||
user.remove_alt_appearance("sneaking_mission")
|
||||
/obj/item/twohanded/required/kirbyplants/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/tactical)
|
||||
|
||||
/obj/item/twohanded/required/kirbyplants/random
|
||||
icon = 'icons/obj/flora/_flora.dmi'
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
var/mob/M = AM
|
||||
if(M.mind in immune_minds)
|
||||
return
|
||||
if(M.anti_magic_check())
|
||||
flare()
|
||||
if(charges <= 0)
|
||||
return
|
||||
flare()
|
||||
|
||||
Reference in New Issue
Block a user