Merge remote-tracking branch 'upstream/master' into cool-ipcs
This commit is contained in:
@@ -17,11 +17,15 @@
|
||||
var/countdown_colour
|
||||
var/obj/effect/countdown/anomaly/countdown
|
||||
|
||||
/obj/effect/anomaly/Initialize(mapload, new_lifespan)
|
||||
/// chance we drop a core when neutralized
|
||||
var/core_drop_chance = 100
|
||||
|
||||
/obj/effect/anomaly/Initialize(mapload, new_lifespan, core_drop_chance = 100)
|
||||
. = ..()
|
||||
GLOB.poi_list |= src
|
||||
START_PROCESSING(SSobj, src)
|
||||
impact_area = get_area(src)
|
||||
src.core_drop_chance = core_drop_chance
|
||||
|
||||
if (!impact_area)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
@@ -54,6 +58,8 @@
|
||||
GLOB.poi_list.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(countdown)
|
||||
if(aSignal)
|
||||
QDEL_NULL(aSignal)
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomaly/proc/anomalyEffect()
|
||||
@@ -70,12 +76,12 @@
|
||||
/obj/effect/anomaly/proc/anomalyNeutralize()
|
||||
new /obj/effect/particle_effect/smoke/bad(loc)
|
||||
|
||||
for(var/atom/movable/O in src)
|
||||
O.forceMove(drop_location())
|
||||
if(prob(core_drop_chance))
|
||||
aSignal.forceMove(drop_location())
|
||||
aSignal = null
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/anomaly/attackby(obj/item/I, mob/user, params)
|
||||
if(I.tool_behaviour == TOOL_ANALYZER) //revert if runtimed
|
||||
to_chat(user, "<span class='notice'>Analyzing... [src]'s unstable field is fluctuating along frequency [format_frequency(aSignal.frequency)], code [aSignal.code].</span>")
|
||||
@@ -285,7 +291,7 @@
|
||||
S.rabid = TRUE
|
||||
S.amount_grown = SLIME_EVOLUTION_THRESHOLD
|
||||
S.Evolve()
|
||||
offer_control(S)
|
||||
offer_control(S,POLL_IGNORE_SENTIENCE_POTION)
|
||||
|
||||
/////////////////////
|
||||
|
||||
|
||||
@@ -46,4 +46,5 @@
|
||||
var/turf/T = loc
|
||||
if(!istype(T)) //you know this will happen somehow
|
||||
CRASH("Turf decal initialized in an object/nullspace")
|
||||
T.AddElement(/datum/element/decal, icon, icon_state, turn(dir, -dir2angle(T.dir)), CLEAN_GOD, color, null, null, alpha)
|
||||
var/turn_dir = 180 - dir2angle(T.dir) //Turning a dir by 0 results in a roulette of random dirs.
|
||||
T.AddElement(/datum/element/decal, icon, icon_state, turn_dir ? turn(dir, turn_dir) : dir, CLEAN_GOD, color, null, null, alpha)
|
||||
|
||||
@@ -242,7 +242,6 @@ RLD
|
||||
|
||||
var/datum/browser/popup = new(user, "rcd_access", "Access Control", 900, 500, src)
|
||||
popup.set_content(t1)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/item/construction/rcd/Topic(href, href_list)
|
||||
|
||||
@@ -28,39 +28,37 @@
|
||||
/// triggered on wield of two handed item
|
||||
/obj/item/broom/proc/on_wield(obj/item/source, mob/user)
|
||||
to_chat(user, "<span class='notice'>You brace the [src] against the ground in a firm sweeping stance.</span>")
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/sweep)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_PRE_MOVE, .proc/sweep)
|
||||
|
||||
/// triggered on unwield of two handed item
|
||||
/obj/item/broom/proc/on_unwield(obj/item/source, mob/user)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_PRE_MOVE)
|
||||
|
||||
/obj/item/broom/afterattack(atom/A, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
sweep(user, A, FALSE)
|
||||
sweep(user, A)
|
||||
|
||||
/obj/item/broom/proc/sweep(mob/user, atom/A, moving = TRUE)
|
||||
var/turf/target
|
||||
if (!moving)
|
||||
if (isturf(A))
|
||||
target = A
|
||||
else
|
||||
target = A.loc
|
||||
else
|
||||
target = user.loc
|
||||
if (!isturf(target))
|
||||
/obj/item/broom/proc/sweep(datum/source, atom/newLoc)
|
||||
if(!ismob(source) || !isturf(newLoc) || (get_dist(source, newLoc) > 1))
|
||||
return
|
||||
if (locate(/obj/structure/table) in target.contents)
|
||||
var/turf/target = newLoc
|
||||
var/atom/movable/AM
|
||||
var/sweep_dir = get_dir(source, target)
|
||||
if(!sweep_dir)
|
||||
return
|
||||
for(var/i in target.contents)
|
||||
AM = i
|
||||
if(AM.density) // eh good enough heuristic check
|
||||
return
|
||||
var/i = 0
|
||||
for(var/obj/item/garbage in target.contents)
|
||||
if(!garbage.anchored)
|
||||
garbage.Move(get_step(target, user.dir), user.dir)
|
||||
i++
|
||||
if(i >= 20)
|
||||
step(garbage, sweep_dir)
|
||||
if(++i > 20)
|
||||
break
|
||||
if(i >= 1)
|
||||
if(i)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1)
|
||||
|
||||
/obj/item/broom/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) //bless you whoever fixes this copypasta
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
var/ignores_timeout = FALSE
|
||||
var/response_timer_id = null
|
||||
var/approval_time = 600
|
||||
var/allow_unicode = FALSE
|
||||
|
||||
var/static/regex/standard_station_regex
|
||||
|
||||
@@ -48,6 +49,9 @@
|
||||
|
||||
if(!new_name)
|
||||
return
|
||||
if(!allow_unicode && (length(new_name) != length_char(new_name)))
|
||||
to_chat(user, "Unicode is not allowed. Adminhelp if you want to use it so badly.")
|
||||
return
|
||||
log_game("[key_name(user)] has proposed to name the station as \
|
||||
[new_name]")
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@
|
||||
|
||||
/obj/item/circuitboard/machine/thermomachine/examine()
|
||||
. = ..()
|
||||
. += "<span class='notice'>It is set to layer [pipe_layer].</span>"
|
||||
. += "<span class='notice'>It is set to layer [pipe_layer]. Use a Multitool on the circuit to change this.</span>"
|
||||
|
||||
/obj/item/circuitboard/machine/thermomachine/heater
|
||||
name = "Heater (Machine Board)"
|
||||
@@ -1146,3 +1146,8 @@
|
||||
build_path = /obj/machinery/atmospherics/components/unary/shuttle/heater
|
||||
req_components = list(/obj/item/stock_parts/micro_laser = 2,
|
||||
/obj/item/stock_parts/matter_bin = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/explosive_compressor
|
||||
name = "Explosive Compressor (Machine Board)"
|
||||
build_path = /obj/machinery/research/explosive_compressor
|
||||
req_components = list(/obj/item/stock_parts/matter_bin = 3)
|
||||
|
||||
@@ -735,7 +735,11 @@
|
||||
if(isobj(target))
|
||||
if(actually_paints)
|
||||
var/list/hsl = rgb2hsl(hex2num(copytext(paint_color,2,4)),hex2num(copytext(paint_color,4,6)),hex2num(copytext(paint_color,6,8)))
|
||||
if(hsl[3] < 0.25 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
|
||||
var/static/whitelisted = typecacheof(list(/obj/structure/window,
|
||||
/obj/effect/decal/cleanable/crayon,
|
||||
/obj/machinery/door/window)
|
||||
)
|
||||
if(hsl[3] < 0.25 && !whitelisted[target]) //Colors too dark are rejected
|
||||
to_chat(usr, "<span class='warning'>A color that dark on an object like this? Surely not...</span>")
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -394,8 +394,6 @@
|
||||
to_chat(user, "<span class='warning'>[src] are recharging!</span>")
|
||||
return
|
||||
|
||||
user.stop_pulling() //User has hands full, and we don't care about anyone else pulling on it, their problem. CLEAR!!
|
||||
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
do_disarm(M, user)
|
||||
return
|
||||
@@ -447,8 +445,7 @@
|
||||
if(do_after(user, isnull(defib?.disarm_shock_time)? disarm_shock_time : defib.disarm_shock_time, target = M))
|
||||
M.visible_message("<span class='danger'>[user] zaps [M] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] zaps [M] with [src]!</span>")
|
||||
M.adjustStaminaLoss(50)
|
||||
M.DefaultCombatKnockdown(100)
|
||||
M.DefaultCombatKnockdown(140)
|
||||
M.updatehealth() //forces health update before next life tick
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
M.emote("gasp")
|
||||
|
||||
@@ -266,7 +266,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda)
|
||||
assets.send(user)
|
||||
|
||||
var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/goonchat)
|
||||
var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/chat)
|
||||
emoji_s.send(user) //Already sent by chat but no harm doing this
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
@@ -590,7 +590,7 @@ Code:
|
||||
var/static/list/emoji_icon_states
|
||||
var/static/emoji_table
|
||||
if(!emoji_table)
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/goonchat)
|
||||
var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat)
|
||||
var/list/collate = list("<br><table>")
|
||||
for(var/emoji in sortList(icon_states(icon('icons/emoji.dmi'))))
|
||||
var/tag = sheet.icon_tag("emoji-[emoji]")
|
||||
|
||||
207
code/game/objects/items/devices/portable_chem_mixer.dm
Normal file
207
code/game/objects/items/devices/portable_chem_mixer.dm
Normal file
@@ -0,0 +1,207 @@
|
||||
/obj/item/storage/portable_chem_mixer
|
||||
name = "Portable Chemical Mixer"
|
||||
desc = "A portable device that dispenses and mixes chemicals. All necessary reagents need to be supplied with beakers. A label indicates that a screwdriver is required to open it for refills. This device can be worn on a belt. The letters 'S&T' are imprinted on the side."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "portablechemicalmixer_open"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
custom_price = 2000
|
||||
custom_premium_price = 2000
|
||||
|
||||
var/obj/item/reagent_containers/beaker = null ///Creating an empty slot for a beaker that can be added to dispense into
|
||||
var/amount = 30 ///The amount of reagent that is to be dispensed currently
|
||||
|
||||
var/list/dispensable_reagents = list() ///List in which all currently dispensable reagents go
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_combined_w_class = 200
|
||||
STR.max_items = 50
|
||||
STR.insert_preposition = "in"
|
||||
STR.can_hold = typecacheof(list(
|
||||
/obj/item/reagent_containers/glass/beaker,
|
||||
))
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/Destroy()
|
||||
QDEL_NULL(beaker)
|
||||
return ..()
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/ex_act(severity, target)
|
||||
if(severity < 3)
|
||||
..()
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/attackby(obj/item/I, mob/user, params)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked)
|
||||
if (!locked)
|
||||
update_contents()
|
||||
if (locked)
|
||||
replace_beaker(user)
|
||||
update_icon()
|
||||
I.play_tool_sound(src, 50)
|
||||
return
|
||||
|
||||
else if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container() && locked)
|
||||
var/obj/item/reagent_containers/B = I
|
||||
. = TRUE //no afterattack
|
||||
if(!user.transferItemToLoc(B, src))
|
||||
return
|
||||
replace_beaker(user, B)
|
||||
update_icon()
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Updates the contents of the portable chemical mixer
|
||||
*
|
||||
* A list of dispensable reagents is created by iterating through each source beaker in the portable chemical beaker and reading its contents
|
||||
*/
|
||||
/obj/item/storage/portable_chem_mixer/proc/update_contents()
|
||||
dispensable_reagents.Cut()
|
||||
|
||||
for (var/obj/item/reagent_containers/glass/beaker/B in contents)
|
||||
var/key = B.reagents.get_master_reagent_id()
|
||||
if (!(key in dispensable_reagents))
|
||||
dispensable_reagents[key] = list()
|
||||
dispensable_reagents[key]["reagents"] = list()
|
||||
dispensable_reagents[key]["reagents"] += B.reagents
|
||||
|
||||
return
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/update_icon_state()
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (!locked)
|
||||
icon_state = "portablechemicalmixer_open"
|
||||
else if (beaker)
|
||||
icon_state = "portablechemicalmixer_full"
|
||||
else
|
||||
icon_state = "portablechemicalmixer_empty"
|
||||
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/AltClick(mob/living/user)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (!locked)
|
||||
return ..()
|
||||
if(!can_interact(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
replace_beaker(user)
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
* Replaces the beaker of the portable chemical mixer with another beaker, or simply adds the new beaker if none is in currently
|
||||
*
|
||||
* Checks if a valid user and a valid new beaker exist and attempts to replace the current beaker in the portable chemical mixer with the one in hand. Simply places the new beaker in if no beaker is currently loaded
|
||||
* Arguments:
|
||||
* * mob/living/user - The user who is trying to exchange beakers
|
||||
* * obj/item/reagent_containers/new_beaker - The new beaker that the user wants to put into the device
|
||||
*/
|
||||
/obj/item/storage/portable_chem_mixer/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(beaker)
|
||||
user.put_in_hands(beaker)
|
||||
beaker = null
|
||||
if(new_beaker)
|
||||
beaker = new_beaker
|
||||
return TRUE
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/attack_hand(mob/user)
|
||||
if (loc != user)
|
||||
return ..()
|
||||
if(SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED))
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/attack_self(mob/user)
|
||||
if(loc == user)
|
||||
var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED)
|
||||
if (locked)
|
||||
ui_interact(user)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The portable chemical mixer is currently open and its contents can be accessed.</span>")
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/MouseDrop(obj/over_object)
|
||||
. = ..()
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
if(!M.incapacitated() && istype(over_object, /obj/screen/inventory/hand))
|
||||
var/obj/screen/inventory/hand/H = over_object
|
||||
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PortableChemMixer", name)
|
||||
if(user.hallucinating())
|
||||
// to not ruin the immersion by constantly changing the fake chemicals
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["amount"] = amount
|
||||
data["isBeakerLoaded"] = beaker ? 1 : 0
|
||||
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
|
||||
data["beakerMaxVolume"] = beaker ? beaker.volume : null
|
||||
data["beakerTransferAmounts"] = beaker ? beaker.possible_transfer_amounts : null
|
||||
var/chemicals[0]
|
||||
var/is_hallucinating = user.hallucinating()
|
||||
if(user.hallucinating())
|
||||
is_hallucinating = TRUE
|
||||
for(var/re in dispensable_reagents)
|
||||
var/value = dispensable_reagents[re]
|
||||
var/datum/reagent/temp = GLOB.chemical_reagents_list[re]
|
||||
if(temp)
|
||||
var/chemname = temp.name
|
||||
var/total_volume = 0
|
||||
for (var/datum/reagents/rs in value["reagents"])
|
||||
total_volume += rs.total_volume
|
||||
if(is_hallucinating && prob(5))
|
||||
chemname = "[pick_list_replacements("hallucination.json", "chemicals")]"
|
||||
chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name), "volume" = total_volume )))
|
||||
data["chemicals"] = chemicals
|
||||
var/beakerContents[0]
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
beakerContents.Add(list(list("name" = R.name, "id" = ckey(R.name), "volume" = R.volume))) // list in a list because Byond merges the first list...
|
||||
data["beakerContents"] = beakerContents
|
||||
return data
|
||||
|
||||
/obj/item/storage/portable_chem_mixer/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("amount")
|
||||
var/target = text2num(params["target"])
|
||||
amount = target
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
var/reagent_name = params["reagent"]
|
||||
var/datum/reagent/reagent = GLOB.name2reagent[reagent_name]
|
||||
var/entry = dispensable_reagents[reagent]
|
||||
if(beaker)
|
||||
var/datum/reagents/R = beaker.reagents
|
||||
var/actual = min(amount, 1000, R.maximum_volume - R.total_volume)
|
||||
// todo: add check if we have enough reagent left
|
||||
for (var/datum/reagents/source in entry["reagents"])
|
||||
var/to_transfer = min(source.total_volume, actual)
|
||||
source.trans_to(beaker, to_transfer)
|
||||
actual -= to_transfer
|
||||
if (actual <= 0)
|
||||
break
|
||||
. = TRUE
|
||||
if("remove")
|
||||
var/amount = text2num(params["amount"])
|
||||
beaker.reagents.remove_all(amount)
|
||||
. = TRUE
|
||||
if("eject")
|
||||
replace_beaker(usr)
|
||||
update_icon()
|
||||
. = TRUE
|
||||
@@ -16,9 +16,6 @@
|
||||
var/on = TRUE
|
||||
var/shock_cooldown = FALSE
|
||||
|
||||
var/ui_x = 260
|
||||
var/ui_y = 137
|
||||
|
||||
/obj/item/electropack/suicide_act(mob/living/carbon/user)
|
||||
user.visible_message("<span class='suicide'>[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (FIRELOSS)
|
||||
@@ -201,17 +198,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/electropack/shockcollar/ui_interact(mob/user) //note to src: use tgooey
|
||||
var/dat = {"
|
||||
<TT>
|
||||
<B>Frequency/Code</B> for shock collar:<BR>
|
||||
Frequency:
|
||||
[format_frequency(src.frequency)]
|
||||
<A href='byond://?src=[REF(src)];set=freq'>Set</A><BR>
|
||||
Code:
|
||||
[src.code]
|
||||
<A href='byond://?src=[REF(src)];set=code'>Set</A><BR>
|
||||
</TT>"}
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
/obj/item/electropack/ui_act(action, params)
|
||||
if(action == "power") // DO. NOT.
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -729,10 +729,10 @@ GENETICS SCANNER
|
||||
to_chat(user, "<span class='notice'>[target] is empty!</span>")
|
||||
|
||||
if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected
|
||||
var/fusion_power = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = fusionpower2text(fusion_power)
|
||||
var/instability = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = instability2text(instability)
|
||||
to_chat(user, "<span class='boldnotice'>Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.</span>")
|
||||
to_chat(user, "<span class='notice'>Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.</span>")
|
||||
to_chat(user, "<span class='notice'>Instability of the last fusion reaction: [instability]\n This indicates it was [tier].</span>")
|
||||
return
|
||||
|
||||
/obj/item/analyzer/proc/scan_turf(mob/user, turf/location)
|
||||
@@ -783,10 +783,10 @@ GENETICS SCANNER
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)</span>")
|
||||
|
||||
if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected
|
||||
var/fusion_power = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = fusionpower2text(fusion_power)
|
||||
var/instability = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = instability2text(instability)
|
||||
to_chat(user, "<span class='boldnotice'>Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.</span>")
|
||||
to_chat(user, "<span class='notice'>Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.</span>")
|
||||
to_chat(user, "<span class='notice'>Instability of the last fusion reaction: [instability]\n This indicates it was [tier].</span>")
|
||||
|
||||
/obj/item/analyzer/ranged
|
||||
desc = "A hand-held scanner which uses advanced spectroscopy and infrared readings to analyze gases as a distance. Alt-Click to use the built in barometer function."
|
||||
@@ -992,4 +992,4 @@ GENETICS SCANNER
|
||||
#undef SCANMODE_CHEMICAL
|
||||
#undef SCANMODE_WOUND
|
||||
#undef SCANNER_CONDENSED
|
||||
#undef SCANNER_VERBOSE
|
||||
#undef SCANNER_VERBOSE
|
||||
|
||||
@@ -289,3 +289,9 @@
|
||||
. = TRUE
|
||||
|
||||
update_icon()
|
||||
|
||||
/**
|
||||
* Returns if this is ready to be detonated. Checks if both tanks are in place.
|
||||
*/
|
||||
/obj/item/transfer_valve/proc/ready()
|
||||
return tank_one && tank_two
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
wound_bonus = -110
|
||||
bare_wound_bonus = 20
|
||||
block_parry_data = /datum/block_parry_data/dual_esword
|
||||
block_chance = 60
|
||||
var/hacked = FALSE
|
||||
/// Can this reflect all energy projectiles?
|
||||
var/can_reflect = TRUE
|
||||
@@ -38,7 +39,8 @@
|
||||
var/wielded = FALSE // track wielded status on item
|
||||
var/slowdown_wielded = 0
|
||||
|
||||
/datum/block_parry_data/dual_esword
|
||||
/datum/block_parry_data/dual_esword // please run at the man going apeshit with his funny doublesword
|
||||
can_block_directions = BLOCK_DIR_NORTH | BLOCK_DIR_NORTHEAST | BLOCK_DIR_NORTHWEST | BLOCK_DIR_WEST | BLOCK_DIR_EAST
|
||||
block_damage_absorption = 2
|
||||
block_damage_multiplier = 0.15
|
||||
block_damage_multiplier_override = list(
|
||||
@@ -50,10 +52,10 @@
|
||||
block_lock_sprinting = TRUE
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
block_projectile_mitigation = 75
|
||||
block_projectile_mitigation = 85
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 6
|
||||
)
|
||||
|
||||
parry_time_windup = 0
|
||||
|
||||
@@ -234,6 +234,9 @@
|
||||
/obj/item/melee/rapier/attack(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
visible_message("<span class='warning'>[user] gently taps [target] with [src].</span>",null,null,COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "slept", src)
|
||||
var/mob/living/carbon/H = target
|
||||
H.Dizzy(10)
|
||||
H.adjustStaminaLoss(30)
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
/obj/item/choice_beacon/box/plushie/generate_display_names()
|
||||
var/list/plushie_list = list()
|
||||
//plushie set 1: just subtypes of /obj/item/toy/plush
|
||||
var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox)
|
||||
var/list/plushies_set_one = subtypesof(/obj/item/toy/plush) - list(/obj/item/toy/plush/narplush, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random_snowflake, /obj/item/toy/plush/plushling, /obj/item/toy/plush/random) //don't allow these special ones (you can still get narplush/hugbox)
|
||||
for(var/V in plushies_set_one)
|
||||
var/atom/A = V
|
||||
plushie_list[initial(A.name)] = A
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
return
|
||||
log_game("[key_name(user)] activated a hidden grenade in [src].")
|
||||
grenade.preprime(user, msg = FALSE, volume = 10)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushpet", /datum/mood_event/plushpet)
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushpet", /datum/mood_event/plushpet)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You try to pet [src], but it has no stuffing. Aww...</span>")
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plush_nostuffing", /datum/mood_event/plush_nostuffing)
|
||||
@@ -688,18 +688,6 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
icon_state = "scrubpuppy"
|
||||
item_state = "scrubpuppy"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/meddrake
|
||||
name = "MediDrake Plushie"
|
||||
desc = "An adorable stuffed toy of a Medidrake."
|
||||
icon_state = "meddrake"
|
||||
item_state = "meddrake"
|
||||
|
||||
/obj/item/toy/plush/borgplushie/secdrake
|
||||
name = "SecDrake Plushie"
|
||||
desc = "An adorable stuffed toy of a Secdrake."
|
||||
icon_state = "secdrake"
|
||||
item_state = "secdrake"
|
||||
|
||||
/obj/item/toy/plush/aiplush
|
||||
name = "AI plushie"
|
||||
desc = "A little stuffed toy AI core... it appears to be malfunctioning."
|
||||
@@ -766,8 +754,8 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
attack_verb = list("headbutt", "scritched", "bit")
|
||||
squeak_override = list('modular_citadel/sound/voice/nya.ogg' = 1)
|
||||
can_random_spawn = FALSE
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/toy/plush/hairball
|
||||
name = "Hairball"
|
||||
desc = "A bundle of undigested fibers and scales. Yuck."
|
||||
@@ -777,3 +765,78 @@ GLOBAL_LIST_INIT(valid_plushie_paths, valid_plushie_paths())
|
||||
squeak_override = list('sound/misc/splort.ogg'=1)
|
||||
attack_verb = list("sploshed", "splorted", "slushed")
|
||||
can_random_spawn = FALSE
|
||||
|
||||
/obj/item/toy/plush/plushling
|
||||
name = "peculiar plushie"
|
||||
desc = "An adorable stuffed toy- wait, did it just move?"
|
||||
can_random_spawn = FALSE
|
||||
var/absorb_cooldown = 100 //ticks cooldown between absorbs
|
||||
var/next_absorb = 0 //When can it absorb another plushie
|
||||
var/check_interval = 20
|
||||
var/next_check = 0
|
||||
|
||||
//Overrides parent proc
|
||||
/obj/item/toy/plush/plushling/attack_self(mob/user)
|
||||
if(!user) //hmmmmm
|
||||
return
|
||||
to_chat(user, "<span class='warning'>You try to pet the plushie, but recoil as it bites your hand instead! OW!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plush_bite", /datum/mood_event/plush_bite)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H)
|
||||
return //Type safety.
|
||||
H.apply_damage(5, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
|
||||
addtimer(CALLBACK(H, /mob/living/carbon/human.proc/dropItemToGround, src, TRUE), 1)
|
||||
|
||||
/obj/item/toy/plush/plushling/New()
|
||||
var/initial_state = pick("plushie_lizard", "plushie_snake", "plushie_slime", "fox")
|
||||
icon_state = initial_state
|
||||
item_state = initial_state
|
||||
START_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/plush/plushling/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/toy/plush/plushling/process()
|
||||
if(world.time < next_absorb || world.time < next_check)
|
||||
return
|
||||
next_check = world.time + check_interval
|
||||
var/obj/item/toy/plush/target
|
||||
for(var/obj/item/toy/plush/possible_target in loc) //First, it tries to get anything in its same location, be it a tile or a backpack
|
||||
if(possible_target == src || istype(possible_target, /obj/item/toy/plush/plushling))
|
||||
continue
|
||||
target = possible_target
|
||||
break
|
||||
if(!target)
|
||||
if(!isturf(loc))
|
||||
return
|
||||
for(var/obj/item/toy/plush/P in oview(1, src)) //If that doesn't work, it hunts for plushies adjacent to its own tile
|
||||
if(istype(P, /obj/item/toy/plush/plushling)) //These do not hunt their own kind
|
||||
continue
|
||||
src.throw_at(P, 1, 2)
|
||||
visible_message("<span class='danger'>[src] leaps at [P]!</span>")
|
||||
break
|
||||
return
|
||||
if(istype(target, /obj/item/toy/plush/plushling)) //These do not consume their own.
|
||||
return
|
||||
next_absorb = world.time + absorb_cooldown
|
||||
plushie_absorb(target)
|
||||
|
||||
/obj/item/toy/plush/plushling/proc/plushie_absorb(obj/item/toy/plush/victim)
|
||||
if(!victim)
|
||||
return
|
||||
visible_message("<span class='warning'>[src] gruesomely mutilliates [victim], leaving nothing more than dust!</span>")
|
||||
name = victim.name
|
||||
desc = victim.desc + " Wait, did it just move..?"
|
||||
icon_state = victim.icon_state
|
||||
item_state = victim.item_state
|
||||
squeak_override = victim.squeak_override
|
||||
attack_verb = victim.attack_verb
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(victim))
|
||||
qdel(victim)
|
||||
|
||||
/obj/item/toy/plush/plushling/love(obj/item/toy/plush/Kisser, mob/living/user) //You shouldn't have come here, poor plush.
|
||||
if(!Kisser)
|
||||
return
|
||||
plushie_absorb(Kisser)
|
||||
|
||||
@@ -117,6 +117,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \
|
||||
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
|
||||
// new/datum/stack_recipe("diamond brick", /obj/item/ingot/diamond, 6, time = 100), \ not yet
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/get_main_recipes()
|
||||
@@ -145,6 +146,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \
|
||||
new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
|
||||
new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("uranium ingot", /obj/item/ingot/uranium, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium/get_main_recipes()
|
||||
@@ -177,6 +179,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
|
||||
new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
|
||||
new/datum/stack_recipe("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
|
||||
// new/datum/stack_recipe("plasma ingot", /obj/item/ingot/plasma, 6, time = 100), \ no
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/get_main_recipes()
|
||||
@@ -221,6 +224,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
|
||||
new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
|
||||
new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("gold ingot", /obj/item/ingot/gold, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold/get_main_recipes()
|
||||
@@ -252,6 +256,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("silver ingot", /obj/item/ingot/silver, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver/get_main_recipes()
|
||||
@@ -278,6 +283,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \
|
||||
GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
|
||||
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("hilarious ingot", /obj/item/ingot/bananium, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium/get_main_recipes()
|
||||
@@ -306,6 +312,7 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
|
||||
GLOBAL_LIST_INIT(titanium_recipes, list ( \
|
||||
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \
|
||||
new/datum/stack_recipe("titanic ingot", /obj/item/ingot/titanium, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/get_main_recipes()
|
||||
@@ -353,6 +360,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \
|
||||
*/
|
||||
GLOBAL_LIST_INIT(adamantine_recipes, list(
|
||||
new /datum/stack_recipe("incomplete servant golem shell", /obj/item/golem_shell/servant, req_amount=1, res_amount=1),
|
||||
new/datum/stack_recipe("adamant ingot", /obj/item/ingot/adamantine, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine
|
||||
|
||||
@@ -121,6 +121,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
|
||||
new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \
|
||||
new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("iron ingot", /obj/item/ingot/iron, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/metal
|
||||
@@ -556,6 +557,9 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \
|
||||
new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("anvil", /obj/structure/anvil/obtainable/narsie, 4, time = 40, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("runic ingot", /obj/item/ingot/cult, 2, time = 100), \
|
||||
new/datum/stack_recipe("rune smith's hammer", /obj/item/melee/smith/hammer/narsie, 6), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/runed_metal
|
||||
@@ -618,6 +622,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass anvil", /obj/structure/anvil/obtainable/ratvar, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("brass furnace", /obj/structure/furnace/infinite/ratvar, 10, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("sender - mech sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
@@ -629,6 +635,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
|
||||
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
|
||||
null, \
|
||||
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \
|
||||
new/datum/stack_recipe("brass smith's hammer", /obj/item/melee/smith/hammer/ratvar, 6), \
|
||||
new/datum/stack_recipe("brass ingot", /obj/item/ingot/ratvar, 6, time = 100), \
|
||||
))
|
||||
|
||||
/obj/item/stack/tile/brass
|
||||
@@ -684,7 +692,10 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
|
||||
new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
new /datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \
|
||||
new/datum/stack_recipe("bronze anvil",/obj/structure/anvil/obtainable/bronze, 20, time = 110, one_per_turf = TRUE, on_floor = TRUE), \
|
||||
null,
|
||||
new/datum/stack_recipe("bronze ingot", /obj/item/ingot/bronze, 6, time = 100), \
|
||||
new/datum/stack_recipe("bronze floor tiles", /obj/item/stack/tile/bronze, 1, 4, 20), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/bronze
|
||||
|
||||
@@ -815,3 +815,18 @@
|
||||
attack_verb = list("bashed", "slashes", "prods", "pokes")
|
||||
fitting_swords = list(/obj/item/melee/rapier)
|
||||
starting_sword = /obj/item/melee/rapier
|
||||
|
||||
/obj/item/storage/belt/sabre/twin
|
||||
name = "twin sheath"
|
||||
desc = "Two sheaths. One is capable of holding a katana (or bokken) and the other a wakizashi. You could put two wakizashis in if you really wanted to. Now you can really roleplay as a samurai."
|
||||
icon_state = "twinsheath"
|
||||
item_state = "quiver" //this'll do.
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
fitting_swords = list(/obj/item/melee/smith/wakizashi, /obj/item/melee/smith/twohand/katana, /obj/item/melee/bokken)
|
||||
starting_sword = null
|
||||
|
||||
/obj/item/storage/belt/sabre/twin/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_items = 2
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY + WEIGHT_CLASS_NORMAL //katana and waki.
|
||||
|
||||
@@ -237,6 +237,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
resistance_flags = FIRE_PROOF
|
||||
total_mass = TOTAL_MASS_MEDIEVAL_WEAPON
|
||||
|
||||
/obj/item/katana/lavaland
|
||||
desc = "Woefully underpowered in Lavaland."
|
||||
block_chance = 30
|
||||
force = 25 //Like a fireaxe but one handed and can block!
|
||||
|
||||
/obj/item/katana/cursed
|
||||
slot_flags = null
|
||||
|
||||
|
||||
@@ -143,10 +143,18 @@
|
||||
var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10)
|
||||
take_damage(amt, BRUTE)
|
||||
|
||||
#define BLACKLISTED_OBJECTS list(/obj/machinery/power/apc, /obj/machinery/airalarm, /obj/machinery/power/smes, /obj/structure/cable)
|
||||
|
||||
/obj/attack_slime(mob/living/simple_animal/slime/user)
|
||||
if(!user.is_adult)
|
||||
return
|
||||
attack_generic(user, rand(10, 15), "melee", 1)
|
||||
if(src.type in BLACKLISTED_OBJECTS)
|
||||
return
|
||||
if(istype(src, /obj/machinery/atmospherics))
|
||||
return
|
||||
attack_generic(user, rand(10, 15), BRUTE, "melee", 1)
|
||||
|
||||
#undef BLACKLISTED_OBJECTS
|
||||
|
||||
/obj/mech_melee_attack(obj/mecha/M)
|
||||
M.do_attack_animation(src)
|
||||
|
||||
@@ -304,18 +304,20 @@
|
||||
/obj/proc/reskin_obj(mob/M)
|
||||
if(!LAZYLEN(unique_reskin))
|
||||
return
|
||||
var/dat = "<b>Reskin options for [name]:</b>\n"
|
||||
for(var/V in unique_reskin)
|
||||
var/output = icon2html(src, M, unique_reskin[V])
|
||||
dat += "[V]: <span class='reallybig'>[output]</span>\n"
|
||||
to_chat(M, dat)
|
||||
|
||||
var/choice = input(M, always_reskinnable ? "Choose the a reskin for [src]" : "Warning, you can only reskin [src] once!","Reskin Object") as null|anything in unique_reskin
|
||||
if(QDELETED(src) || !choice || (current_skin && !always_reskinnable) || M.incapacitated() || !in_range(M,src) || !unique_reskin[choice] || unique_reskin[choice] == current_skin)
|
||||
return
|
||||
current_skin = choice
|
||||
var/list/skins = list()
|
||||
for(var/S in unique_reskin)
|
||||
skins[S] = image(icon = icon, icon_state = unique_reskin[S])
|
||||
var/choice = show_radial_menu(M, src, skins, custom_check = CALLBACK(src, .proc/check_skinnable, M), radius = 40, require_near = TRUE)
|
||||
if(!choice)
|
||||
return FALSE
|
||||
icon_state = unique_reskin[choice]
|
||||
to_chat(M, "[src] is now skinned as '[choice]'.")
|
||||
current_skin = choice
|
||||
return
|
||||
|
||||
/obj/proc/check_skinnable(/mob/M)
|
||||
if(current_skin || !always_reskinnable)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/update_overlays()
|
||||
. = ..()
|
||||
|
||||
@@ -4,25 +4,6 @@
|
||||
req_access = list(ACCESS_ALL_PERSONAL_LOCKERS)
|
||||
var/registered_name = null
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/examine(mob/user)
|
||||
. = ..()
|
||||
if(registered_name)
|
||||
. += "<span class='notice'>The display reads, \"Owned by [registered_name]\".</span>"
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/check_access(obj/item/I)
|
||||
. = ..()
|
||||
if(!I || !istype(I))
|
||||
return
|
||||
if(istype(I,/obj/item/modular_computer/tablet))
|
||||
var/obj/item/modular_computer/tablet/ourTablet = I
|
||||
var/obj/item/computer_hardware/card_slot/card_slot = ourTablet.all_components[MC_CARD]
|
||||
if(card_slot)
|
||||
return registered_name == card_slot.stored_card.registered_name || registered_name == card_slot.stored_card2.registered_name
|
||||
var/obj/item/card/id/ID = I.GetID()
|
||||
if(ID && registered_name == ID.registered_name)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/PopulateContents()
|
||||
..()
|
||||
if(prob(50))
|
||||
@@ -54,15 +35,24 @@
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params)
|
||||
var/obj/item/card/id/I = W.GetID()
|
||||
if(!I || !istype(I))
|
||||
return ..()
|
||||
if(!can_lock(user, FALSE)) //Can't do anything if there isn't a lock!
|
||||
return
|
||||
if(I.registered_name && !registered_name)
|
||||
to_chat(user, "<span class='notice'>You claim [src].</span>")
|
||||
registered_name = I.registered_name
|
||||
if(istype(I))
|
||||
if(broken)
|
||||
to_chat(user, "<span class='danger'>It appears to be broken.</span>")
|
||||
return
|
||||
if(!I || !I.registered_name)
|
||||
return
|
||||
if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name)))
|
||||
//they can open all lockers, or nobody owns this, or they own this locker
|
||||
locked = !locked
|
||||
update_icon()
|
||||
|
||||
if(!registered_name)
|
||||
registered_name = I.registered_name
|
||||
desc = "Owned by [I.registered_name]."
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Access Denied.</span>")
|
||||
else
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/personal/handle_lock_addition() //If lock construction is successful we don't care what access the electronics had, so we override it
|
||||
if(..())
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
max_mobs = 3
|
||||
max_integrity = 250
|
||||
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
|
||||
var/loot_type = /obj/structure/closet/crate/necropolis/tendril/all
|
||||
|
||||
move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it
|
||||
anchored = TRUE
|
||||
@@ -41,7 +42,7 @@ GLOBAL_LIST_INIT(tendrils, list())
|
||||
|
||||
/obj/structure/spawner/lavaland/deconstruct(disassembled)
|
||||
new /obj/effect/collapse(loc)
|
||||
new /obj/structure/closet/crate/necropolis/tendril(loc)
|
||||
new loot_type(loc)
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user