mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into bring_colossus_back_2016
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
"a" = (/turf/closed/indestructible/riveted/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"b" = (/obj/effect/decal/cleanable/blood/tracks,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"c" = (/obj/effect/decal/cleanable/cobweb,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"d" = (/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"e" = (/obj/effect/gibspawner/human,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"f" = (/obj/effect/decal/cleanable/blood/gibs/limb,/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"g" = (/obj/effect/light_emitter{set_cap = 3; set_luminosity = 7},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"h" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"i" = (/obj/effect/decal/cleanable/blood/old,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"j" = (/obj/effect/decal/cleanable/blood/old,/obj/effect/decal/remains/human,/obj/effect/light_emitter{set_cap = 3; set_luminosity = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"k" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHWEST)"; icon_state = "tracks"; dir = 10},/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"l" = (/obj/effect/light_emitter{set_cap = 3; set_luminosity = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"m" = (/obj/effect/gibspawner/generic,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"n" = (/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"o" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHEAST)"; icon_state = "tracks"; dir = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"p" = (/obj/effect/light_emitter,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"q" = (/obj/effect/decal/cleanable/blood/old,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"r" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHWEST)"; icon_state = "tracks"; dir = 9},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"s" = (/obj/effect/decal/cleanable/blood/gibs/limb,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"t" = (/obj/effect/decal/cleanable/ash,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"u" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHWEST)"; icon_state = "tracks"; dir = 10},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"v" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHEAST)"; icon_state = "tracks"; dir = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"w" = (/obj/effect/gibspawner/human,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHEAST)"; icon_state = "tracks"; dir = 6},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"x" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (WEST)"; icon_state = "tracks"; dir = 8},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"y" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (WEST)"; icon_state = "tracks"; dir = 8},/obj/effect/light_emitter{set_cap = 3; set_luminosity = 7},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"z" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHWEST)"; icon_state = "tracks"; dir = 9},/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"A" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHEAST)"; icon_state = "tracks"; dir = 6},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"B" = (/mob/living/simple_animal/hostile/megafauna/hierophant,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"C" = (/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (WEST)"; icon_state = "tracks"; dir = 8},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"D" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"E" = (/obj/effect/decal/cleanable/blood/gibs/up,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"F" = (/obj/effect/decal/cleanable/blood/old,/obj/effect/decal/remains/human,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"G" = (/obj/effect/decal/cleanable/blood/gibs/core,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"H" = (/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHWEST)"; icon_state = "tracks"; dir = 10},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"I" = (/obj/effect/gibspawner/human,/obj/effect/light_emitter{set_cap = 3; set_luminosity = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
"J" = (/obj/effect/decal/cleanable/blood/gibs/down,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
|
||||
|
||||
(1,1,1) = {"
|
||||
aaaaaaaaaaaabaaaaaaaaaaaa
|
||||
acdddddddddddddddddddddda
|
||||
adeddfddddddgdddhhhdiddda
|
||||
addjddddddddkhhddddddldda
|
||||
adddadddaaaaaaaaadddaddda
|
||||
addddmhdhddddddddddmddnda
|
||||
adddddgdddddddddddgddodda
|
||||
addddddddkdopddfdddbdddda
|
||||
adqdadddddadddaddddbaddda
|
||||
adddadddddrdddddddddaddda
|
||||
adstadddadudhhdvadhwabdda
|
||||
adddadrxxmddddduddddaddda
|
||||
xxyoazApddddBddddpddadyxC
|
||||
addbabddddddddtdddddaddda
|
||||
addbabddadDdEdddadddafdda
|
||||
adddabddddddndddddqdaddda
|
||||
adddabddddadddadddddadnda
|
||||
adqedbddsdddpddddddddddda
|
||||
addddAgddddeddddddgFdddGa
|
||||
addddmdddddHdehddxdedddda
|
||||
adddadddaaaaaaaaadddaddda
|
||||
addlddddddddrdddddAddIdda
|
||||
adddddJdddddgdddqddddddda
|
||||
adnddddddFddbdddddddnddda
|
||||
aaaaaaaaaaaabaaaaaaaaaaaa
|
||||
"}
|
||||
@@ -35087,6 +35087,7 @@
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/portable_atmospherics/canister/water_vapor,
|
||||
/mob/living/simple_animal/hostile/lizard{
|
||||
name = "Wags-His-Tail";
|
||||
real_name = "Wags-His-Tail"
|
||||
|
||||
@@ -7375,13 +7375,9 @@
|
||||
/turf/closed/wall/mineral/titanium/overspace,
|
||||
/area/shuttle/pod_1)
|
||||
"apG" = (
|
||||
/turf/open/space,
|
||||
/turf/closed/wall/shuttle{
|
||||
dir = 2;
|
||||
icon_state = "swall_f10";
|
||||
layer = 2
|
||||
},
|
||||
/area/shuttle/pod_1)
|
||||
/obj/machinery/portable_atmospherics/canister/water_vapor,
|
||||
/turf/open/floor/plasteel,
|
||||
/area/janitor)
|
||||
"apH" = (
|
||||
/obj/structure/grille,
|
||||
/obj/structure/window/shuttle,
|
||||
@@ -91946,7 +91942,7 @@ aLY
|
||||
aLY
|
||||
bBx
|
||||
bCv
|
||||
bDL
|
||||
apG
|
||||
bFk
|
||||
bDs
|
||||
bCv
|
||||
|
||||
@@ -51,6 +51,6 @@
|
||||
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
|
||||
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
|
||||
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)]"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoordjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
|
||||
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
|
||||
|
||||
@@ -498,6 +498,7 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define COLOSSUS_SCORE "Colossus Killed"
|
||||
#define BUBBLEGUM_SCORE "Bubblegum Killed"
|
||||
#define DRAKE_SCORE "Drakes Killed"
|
||||
#define BIRD_SCORE "Hierophants Killed"
|
||||
#define BOSS_SCORE "Bosses Killed"
|
||||
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
|
||||
|
||||
@@ -527,4 +528,4 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
|
||||
// Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it.
|
||||
#define MAX_NTNET_LOGS 300
|
||||
#define MIN_NTNET_LOGS 10
|
||||
#define MIN_NTNET_LOGS 10
|
||||
|
||||
@@ -121,15 +121,16 @@ var/const/tk_maxrange = 15
|
||||
focus_object(target, user)
|
||||
return
|
||||
|
||||
if(focus.anchored)
|
||||
if(focus.anchored || !isturf(focus.loc))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(target == focus)
|
||||
target.attack_self_tk(user)
|
||||
return // todo: something like attack_self not laden with assumptions inherent to attack_self
|
||||
|
||||
|
||||
if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
|
||||
if(!isturf(target) && istype(focus,/obj/item) && target.Adjacent(focus))
|
||||
var/obj/item/I = focus
|
||||
var/resolved = target.attackby(I, user, params)
|
||||
if(!resolved && target && I)
|
||||
@@ -139,7 +140,6 @@ var/const/tk_maxrange = 15
|
||||
focus.throw_at(target, 10, 1,user)
|
||||
last_throw = world.time
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
return
|
||||
|
||||
/proc/tkMaxRangeCheck(mob/user, atom/target, atom/focus)
|
||||
var/d = get_dist(user, target)
|
||||
@@ -155,7 +155,7 @@ var/const/tk_maxrange = 15
|
||||
|
||||
|
||||
/obj/item/tk_grab/proc/focus_object(obj/target, mob/living/user)
|
||||
if(!istype(target,/obj))
|
||||
if(!isobj(target))
|
||||
return//Cant throw non objects atm might let it do mobs later
|
||||
if(target.anchored || !isturf(target.loc))
|
||||
qdel(src)
|
||||
|
||||
@@ -58,15 +58,20 @@ var/datum/subsystem/vote/SSvote
|
||||
greatest_votes = votes
|
||||
//default-vote for everyone who didn't vote
|
||||
if(!config.vote_no_default && choices.len)
|
||||
var/non_voters = (clients.len - total_votes)
|
||||
if(non_voters > 0)
|
||||
var/list/non_voters = directory.Copy()
|
||||
non_voters -= voted
|
||||
for (var/non_voter_ckey in non_voters)
|
||||
var/client/C = non_voters[non_voter_ckey]
|
||||
if (!C || C.is_afk())
|
||||
non_voters -= non_voter_ckey
|
||||
if(non_voters.len > 0)
|
||||
if(mode == "restart")
|
||||
choices["Continue Playing"] += non_voters
|
||||
choices["Continue Playing"] += non_voters.len
|
||||
if(choices["Continue Playing"] >= greatest_votes)
|
||||
greatest_votes = choices["Continue Playing"]
|
||||
else if(mode == "gamemode")
|
||||
if(master_mode in choices)
|
||||
choices[master_mode] += non_voters
|
||||
choices[master_mode] += non_voters.len
|
||||
if(choices[master_mode] >= greatest_votes)
|
||||
greatest_votes = choices[master_mode]
|
||||
//get all options with that many votes and return them in a list
|
||||
|
||||
@@ -189,6 +189,40 @@
|
||||
/datum/action/item_action/toggle_helmet_light
|
||||
name = "Toggle Helmet Light"
|
||||
|
||||
/datum/action/item_action/toggle_unfriendly_fire
|
||||
name = "Toggle Friendly Fire \[ON\]"
|
||||
desc = "Toggles if the staff causes friendly fire."
|
||||
button_icon_state = "vortex_ff_on"
|
||||
|
||||
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
|
||||
if(..())
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon()
|
||||
if(istype(target, /obj/item/weapon/hierophant_staff))
|
||||
var/obj/item/weapon/hierophant_staff/H = target
|
||||
if(H.friendly_fire_check)
|
||||
button_icon_state = "vortex_ff_off"
|
||||
name = "Toggle Friendly Fire \[OFF\]"
|
||||
button.name = name
|
||||
else
|
||||
button_icon_state = "vortex_ff_on"
|
||||
name = "Toggle Friendly Fire \[ON\]"
|
||||
button.name = name
|
||||
..()
|
||||
|
||||
/datum/action/item_action/vortex_recall
|
||||
name = "Vortex Recall"
|
||||
desc = "Recall yourself, and anyone nearby, to an attuned hierophant rune at any time.<br>If no such rune exists, will produce a rune at your location."
|
||||
button_icon_state = "vortex_recall"
|
||||
|
||||
/datum/action/item_action/vortex_recall/IsAvailable()
|
||||
if(istype(target, /obj/item/weapon/hierophant_staff))
|
||||
var/obj/item/weapon/hierophant_staff/H = target
|
||||
if(H.teleporting)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/item_action/clock
|
||||
background_icon_state = "bg_clock"
|
||||
buttontooltipstyle = "clockcult"
|
||||
|
||||
@@ -4,10 +4,15 @@ var/global/list/internal_byond_list_vars = list("contents" = TRUE, "verbs" = TRU
|
||||
|
||||
/datum
|
||||
var/var_edited = 0 //Warrenty void if seal is broken
|
||||
var/datum/reagents/reagents = null
|
||||
var/fingerprintslast = null
|
||||
|
||||
/datum/proc/on_varedit(modified_var) //called whenever a var is edited
|
||||
var_edited = 1
|
||||
|
||||
/datum/proc/on_reagent_change()
|
||||
return
|
||||
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
set category = "Debug"
|
||||
set name = "View Variables"
|
||||
@@ -397,6 +402,7 @@ body
|
||||
html += "[html_encode(name)] = /list ([L.len])"
|
||||
|
||||
if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500))
|
||||
name = "[name]" //Needs to be a string or it will go out of bounds in the internal_byond_list_vars array
|
||||
html += "<ul>"
|
||||
var/index = 1
|
||||
for(var/entry in L)
|
||||
|
||||
+2
-2
@@ -261,12 +261,12 @@ mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutat
|
||||
/mob/proc/domutcheck()
|
||||
return
|
||||
|
||||
/mob/living/carbon/domutcheck()
|
||||
/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
|
||||
if(!has_dna())
|
||||
return
|
||||
|
||||
for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations)
|
||||
if(ismob(A.check_block(src)))
|
||||
if(ismob(A.check_block(src, force_powers)))
|
||||
return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
|
||||
|
||||
update_mutations_overlay()
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
/datum/proc/freon_gas_act()
|
||||
return
|
||||
return 0
|
||||
|
||||
/datum/proc/water_vapor_gas_act() // We get it
|
||||
return 0 // You vape
|
||||
+1
-1
@@ -238,7 +238,7 @@
|
||||
|
||||
enslaved_to = creator
|
||||
|
||||
current.faction = creator.faction
|
||||
current.faction = creator.faction.Copy()
|
||||
|
||||
if(special_role)
|
||||
message_admins("[key_name_admin(current)](<A HREF='?_src_=holder;adminmoreinfo=\ref[current]'>?</A>) has been created by [key_name_admin(creator)](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>), an antagonist.")
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
if(hex2num(getblock(se_string, dna_block)) >= lowest_value)
|
||||
return 1
|
||||
|
||||
/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner)
|
||||
/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner, force_powers=0)
|
||||
if(check_block_string(owner.dna.struc_enzymes))
|
||||
if(prob(get_chance))
|
||||
if(prob(get_chance)||force_powers)
|
||||
. = on_acquiring(owner)
|
||||
else
|
||||
. = on_losing(owner)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
* */
|
||||
|
||||
/datum/recipe
|
||||
var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice
|
||||
var/list/reagents_list // example: = list("berryjuice" = 5) // do not list same reagent twice
|
||||
var/list/items // example: =list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo
|
||||
var/result //example: = /obj/item/weapon/reagent_containers/food/snacks/donut
|
||||
var/time = 100 // 1/10 part of second
|
||||
@@ -49,7 +49,7 @@
|
||||
. = -1
|
||||
else
|
||||
return 0
|
||||
if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len)
|
||||
if ((reagents_list?(reagents_list.len):(0)) < avail_reagents.reagent_list.len)
|
||||
return -1
|
||||
return .
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
. = possible_recipes[1]
|
||||
for (var/datum/recipe/recipe in possible_recipes)
|
||||
var/N_i = (recipe.items)?(recipe.items.len):0
|
||||
var/N_r = (recipe.reagents)?(recipe.reagents.len):0
|
||||
var/N_r = (recipe.reagents_list)?(recipe.reagents_list.len):0
|
||||
if (N_i > i_count || (N_i== i_count && N_r > r_count ))
|
||||
r_count = N_r
|
||||
i_count = N_i
|
||||
|
||||
@@ -126,6 +126,14 @@
|
||||
// Generates nothing but atmos runtimes and salt
|
||||
cost = 0
|
||||
|
||||
/datum/map_template/ruin/lavaland/hierophant
|
||||
name = "Hierophant's Arena"
|
||||
id = "hierophant"
|
||||
description = "A huge fucking bird priest awaits you in this arena."
|
||||
suffix = "lavaland_surface_hierophant.dmm"
|
||||
cost = 0
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/ufo_crash
|
||||
name = "UFO Crash"
|
||||
id = "ufo-crash"
|
||||
|
||||
@@ -348,9 +348,9 @@
|
||||
if(L.&& L.client)
|
||||
L.client.played = 0
|
||||
|
||||
/proc/has_gravity(atom/AT, turf/T)
|
||||
if(!T)
|
||||
T = get_turf(AT)
|
||||
/atom/proc/has_gravity(turf/T)
|
||||
if(!T || !isturf(T))
|
||||
T = get_turf(src)
|
||||
var/area/A = get_area(T)
|
||||
if(istype(T, /turf/open/space)) // Turf never has gravity
|
||||
return 0
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
var/flags = 0
|
||||
var/list/fingerprints
|
||||
var/list/fingerprintshidden
|
||||
var/fingerprintslast = null
|
||||
var/list/blood_DNA
|
||||
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
|
||||
|
||||
///Chemistry.
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
//This atom's HUD (med/sec, etc) images. Associative list.
|
||||
var/list/image/hud_list = null
|
||||
//HUD images that this atom can provide.
|
||||
@@ -102,8 +98,6 @@
|
||||
/atom/proc/check_eye(mob/user)
|
||||
return
|
||||
|
||||
/atom/proc/on_reagent_change()
|
||||
return
|
||||
|
||||
/atom/proc/Bumped(AM as mob|obj)
|
||||
return
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(active)
|
||||
user << "<span class='notice'>Our muscles tense and strengthen.</span>"
|
||||
else
|
||||
user.status_flags -= GOTTAGOFAST
|
||||
user.status_flags &= ~GOTTAGOFAST
|
||||
user << "<span class='notice'>Our muscles relax.</span>"
|
||||
if(stacks >= 10)
|
||||
user << "<span class='danger'>We collapse in exhaustion.</span>"
|
||||
@@ -29,7 +29,7 @@
|
||||
active = !active
|
||||
user << "<span class='notice'>Our muscles relax without the energy to strengthen them.</span>"
|
||||
user.Weaken(2)
|
||||
user.status_flags -= GOTTAGOFAST
|
||||
user.status_flags &= ~GOTTAGOFAST
|
||||
break
|
||||
|
||||
stacks++
|
||||
|
||||
@@ -90,10 +90,11 @@ This file's folder contains:
|
||||
whim without hesitation.</span>")
|
||||
ticker.mode.servants_of_ratvar += M.mind
|
||||
ticker.mode.update_servant_icons_added(M.mind)
|
||||
all_clockwork_mobs += M
|
||||
M.faction |= "ratvar"
|
||||
M.mind.special_role = "Servant of Ratvar"
|
||||
M.languages_spoken |= RATVAR
|
||||
M.languages_understood |= RATVAR
|
||||
all_clockwork_mobs += M
|
||||
M.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
|
||||
M.attack_log += "\[[time_stamp()]\] <span class='brass'>Has been converted to the cult of Ratvar!</span>"
|
||||
if(issilicon(M))
|
||||
@@ -152,6 +153,7 @@ This file's folder contains:
|
||||
ticker.mode.servants_of_ratvar -= M.mind
|
||||
ticker.mode.update_servant_icons_removed(M.mind)
|
||||
all_clockwork_mobs -= M
|
||||
M.faction -= "ratvar"
|
||||
M.mind.memory = "" //Not sure if there's a better way to do this
|
||||
M.mind.special_role = null
|
||||
M.languages_spoken &= ~RATVAR
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
user.Dizzy(30)
|
||||
user.Weaken(5)
|
||||
else
|
||||
user << "<span class='cultlarge'>\"Putting on things you don't own is bad, you know.\"</span>"
|
||||
user << "<span class='cultlarge'>\"Trying to use things you don't own is bad, you know.\"</span>"
|
||||
user << "<span class='userdanger'>The armor squeezes at your body!</span>"
|
||||
user.emote("scream")
|
||||
user.adjustBruteLoss(25)
|
||||
@@ -239,7 +239,7 @@
|
||||
user.Dizzy(30)
|
||||
user.Weaken(5)
|
||||
else
|
||||
user << "<span class='cultlarge'>\"Putting on things you don't own is bad, you know.\"</span>"
|
||||
user << "<span class='cultlarge'>\"Trying to use things you don't own is bad, you know.\"</span>"
|
||||
user << "<span class='userdanger'>The robes squeeze at your body!</span>"
|
||||
user.emote("scream")
|
||||
user.adjustBruteLoss(25)
|
||||
|
||||
@@ -101,6 +101,8 @@ This file contains the arcane tome files.
|
||||
text += "<font color='red'><b>Blood Boil</b></font><br>When invoked, this rune will do a massive amount of damage to all non-cultist viewers, but it will also emit a small explosion upon invocation. \
|
||||
It requires three invokers.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Drain Life</b></font><br>This rune will drain the life of every living creature above the rune, healing the invoker for each creature drained by it.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Manifest Spirit</b></font><br>This rune allows you to summon spirits as humanoid fighters. When invoked, a spirit above the rune will be brought to life as a human, wearing nothing, that seeks only to serve you and the Geometer. \
|
||||
However, the spirit's link to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, all summoned spirits will dissipate, dropping their items to the ground. You may manifest \
|
||||
multiple spirits with one rune, but you will rapidly take damage in doing so.<br><br>"
|
||||
@@ -111,7 +113,7 @@ This file contains the arcane tome files.
|
||||
|
||||
text += "<font color='red'><b>Talisman of Teleportation</b></font><br>The talisman form of the Teleport rune will transport the invoker to a selected Teleport rune once.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Construction</b></font><br>This talisman is the main way of creating construct shells. To use it, one must strike 30 sheets of metal with the talisman. The sheets will then be twisted into a construct shell, ready to recieve a soul to occupy it.<br><br>"
|
||||
text += "<font color='red'><b>Talisman of Construction</b></font><br>This talisman is the main way of creating construct shells. To use it, one must strike 25 sheets of metal with the talisman. The sheets will then be twisted into a construct shell, ready to recieve a soul to occupy it.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Tome Summoning</b></font><br>This talisman will produce a single tome at your feet.<br><br>"
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
/obj/effect/rune/malformed/New()
|
||||
..()
|
||||
icon_state = "[rand(1,6)]"
|
||||
icon_state = "[rand(1,7)]"
|
||||
color = rgb(rand(0,255), rand(0,255), rand(0,255))
|
||||
|
||||
/obj/effect/rune/malformed/invoke(var/list/invokers)
|
||||
@@ -372,7 +372,7 @@ var/list/teleport_runes = list()
|
||||
|
||||
/obj/effect/rune/sacrifice/New()
|
||||
..()
|
||||
icon_state = "[rand(1,6)]"
|
||||
icon_state = "[rand(1,7)]"
|
||||
|
||||
/obj/effect/rune/sacrifice/invoke(var/list/invokers)
|
||||
if(rune_in_use)
|
||||
@@ -675,7 +675,7 @@ var/list/teleport_runes = list()
|
||||
cultist_name = "Astral Communion"
|
||||
cultist_desc = "severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active."
|
||||
invocation = "Fwe'sh mah erl nyag r'ya!"
|
||||
icon_state = "6"
|
||||
icon_state = "7"
|
||||
color = rgb(126, 23, 23)
|
||||
rune_in_use = 0 //One at a time, please!
|
||||
construct_invoke = 0
|
||||
@@ -692,7 +692,7 @@ var/list/teleport_runes = list()
|
||||
log_game("Astral Communion rune failed - more than one user")
|
||||
return list()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!user in T.contents)
|
||||
if(!(user in T))
|
||||
user << "<span class='cultitalic'>You must be standing on top of [src]!</span>"
|
||||
log_game("Astral Communion rune failed - user not standing on rune")
|
||||
return list()
|
||||
@@ -714,8 +714,8 @@ var/list/teleport_runes = list()
|
||||
affecting = null //In case it's assigned to a number or something
|
||||
rune_in_use = 0
|
||||
return
|
||||
affecting.apply_damage(1, BRUTE)
|
||||
if(!(user in T.contents))
|
||||
affecting.apply_damage(0.1, BRUTE)
|
||||
if(!(user in T))
|
||||
user.visible_message("<span class='warning'>A spectral tendril wraps around [user] and pulls them back to the rune!</span>")
|
||||
Beam(user,icon_state="drainbeam",icon='icons/effects/effects.dmi',time=2)
|
||||
user.forceMove(get_turf(src)) //NO ESCAPE :^)
|
||||
@@ -728,19 +728,17 @@ var/list/teleport_runes = list()
|
||||
affecting = null
|
||||
return
|
||||
if(user.stat == UNCONSCIOUS)
|
||||
if(prob(10))
|
||||
if(prob(1))
|
||||
var/mob/dead/observer/G = user.get_ghost()
|
||||
if(G)
|
||||
G << "<span class='cultitalic'>You feel the link between you and your body weakening... you must hurry!</span>"
|
||||
G << "<span class='cultitalic'>You feel the link between you and your body weakening... you must hurry!</span>"
|
||||
if(user.stat == DEAD)
|
||||
user.color = initial(user.color)
|
||||
rune_in_use = 0
|
||||
affecting = null
|
||||
var/mob/dead/observer/G = user.get_ghost()
|
||||
if(G)
|
||||
G << "<span class='cultitalic'><b>You suddenly feel your physical form pass on. [src]'s exertion has killed you!</b></span>"
|
||||
G << "<span class='cultitalic'><b>You suddenly feel your physical form pass on. [src]'s exertion has killed you!</b></span>"
|
||||
return
|
||||
sleep(10)
|
||||
sleep(1)
|
||||
rune_in_use = 0
|
||||
|
||||
|
||||
@@ -869,6 +867,44 @@ var/list/teleport_runes = list()
|
||||
explosion(T, -1, 0, 1, 5)
|
||||
|
||||
|
||||
//Deals brute damage to all targets on the rune and heals the invoker for each target drained.
|
||||
/obj/effect/rune/leeching
|
||||
cultist_name = "Drain Life"
|
||||
cultist_desc = "drains the life of all targets on the rune, restoring life to the user."
|
||||
invocation = "Yu'gular faras desdae. Umathar uf'kal thenar!"
|
||||
icon_state = "3"
|
||||
color = rgb(159, 28, 52)
|
||||
|
||||
/obj/effect/rune/leeching/can_invoke(mob/living/user)
|
||||
if(world.time <= user.next_move)
|
||||
return list()
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/potential_targets = list()
|
||||
for(var/mob/living/carbon/M in T.contents - user)
|
||||
if(M.stat != DEAD)
|
||||
potential_targets += M
|
||||
if(!potential_targets.len)
|
||||
user << "<span class='cultitalic'>There must be at least one valid target on the rune!</span>"
|
||||
log_game("Leeching rune failed - no valid targets")
|
||||
return list()
|
||||
return ..()
|
||||
|
||||
/obj/effect/rune/leeching/invoke(var/list/invokers)
|
||||
var/mob/living/user = invokers[1]
|
||||
user.changeNext_move(CLICK_CD_CLICK_ABILITY)
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/living/carbon/M in T.contents - user)
|
||||
if(M.stat != DEAD)
|
||||
var/drained_amount = rand(10,20)
|
||||
M.apply_damage(drained_amount, BRUTE, "chest")
|
||||
user.adjustBruteLoss(-drained_amount)
|
||||
M << "<span class='cultitalic'>You feel extremely weak.</span>"
|
||||
user.Beam(T,icon_state="drainbeam",icon='icons/effects/effects.dmi',time=5)
|
||||
user.visible_message("<span class='warning'>Blood flows from the rune into [user]!</span>", \
|
||||
"<span class='cult'>Blood flows into you, healing your wounds and revitalizing your spirit.</span>")
|
||||
|
||||
|
||||
//Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost.
|
||||
/obj/effect/rune/manifest
|
||||
cultist_name = "Manifest Spirit"
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
dat += "Please choose the chant to be imbued into the fabric of reality.<BR>"
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];rune=newtome'>N'ath reth sh'yro eth d'raggathnor!</A> - Summons an arcane tome, used to scribe runes and communicate with other cultists.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=metal'>Ar'Tee ess!</A> - Provides 5 runed metal.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=metal'>Bar'tea eas!</A> - Provides 5 runed metal.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=teleport'>Sas'so c'arta forbici!</A> - Allows you to move to a selected teleportation rune.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=emp'>Ta'gh fara'qha fel d'amar det!</A> - Allows you to destroy technology in a short range.<BR>"
|
||||
dat += "<A href='?src=\ref[src];rune=runestun'>Fuu ma'jin!</A> - Allows you to stun a person by attacking them with the talisman.<BR>"
|
||||
@@ -81,7 +81,8 @@
|
||||
if(istype(src, /obj/item/weapon/paper/talisman/supply/weak))
|
||||
usr.visible_message("<span class='cultitalic'>Lesser supply talismans lack the strength to materialize runed metal!</span>")
|
||||
return
|
||||
new /obj/item/stack/sheet/runed_metal(get_turf(usr),5)
|
||||
var/obj/item/stack/sheet/runed_metal/R = new(usr,5)
|
||||
usr.put_in_hands(R)
|
||||
if("teleport")
|
||||
var/obj/item/weapon/paper/talisman/teleport/T = new(usr)
|
||||
usr.put_in_hands(T)
|
||||
@@ -319,12 +320,13 @@
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets.
|
||||
//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets, or converts plasteel into runed metal up to 25 times
|
||||
/obj/item/weapon/paper/talisman/construction
|
||||
cultist_name = "Talisman of Construction"
|
||||
cultist_desc = "Use this talisman on at least twenty-five metal sheets to create an empty construct shell"
|
||||
invocation = "Ethra p'ni dedol!"
|
||||
color = "#000000" // black
|
||||
uses = 25
|
||||
|
||||
/obj/item/weapon/paper/talisman/construction/attack_self(mob/living/user)
|
||||
if(iscultist(user))
|
||||
@@ -335,8 +337,10 @@
|
||||
|
||||
/obj/item/weapon/paper/talisman/construction/attack(obj/M,mob/living/user)
|
||||
if(iscultist(user))
|
||||
user << "<span class='cultitalic'>This talisman will only work on a stack of metal sheets!</span>"
|
||||
user << "<span class='cultitalic'>This talisman will only work on a stack of metal or plasteel sheets!</span>"
|
||||
log_game("Construct talisman failed - not a valid target")
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/paper/talisman/construction/afterattack(obj/item/stack/sheet/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
@@ -347,15 +351,20 @@
|
||||
new /obj/structure/constructshell(T)
|
||||
user << "<span class='warning'>The talisman clings to the metal and twists it into a construct shell!</span>"
|
||||
user << sound('sound/effects/magic.ogg',0,1,25)
|
||||
invoke(user, 1)
|
||||
qdel(src)
|
||||
if(istype(target, /obj/item/stack/sheet/plasteel))
|
||||
var/quantity = target.amount
|
||||
var/turf/T = get_turf(target)
|
||||
new /obj/item/stack/sheet/runed_metal(T,quantity)
|
||||
target.use(quantity)
|
||||
user << "<span class='warning'>The talisman clings to the plasteel, transforming it into runed metal!</span>"
|
||||
user << sound('sound/effects/magic.ogg',0,1,25)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>You need more metal to produce a construct shell!</span>"
|
||||
if(istype(target, /obj/item/stack/sheet/plasteel))
|
||||
var/quantity = min(target.amount, uses)
|
||||
uses -= quantity
|
||||
new /obj/item/stack/sheet/runed_metal(T,quantity)
|
||||
target.use(quantity)
|
||||
user << "<span class='warning'>The talisman clings to the plasteel, transforming it into runed metal!</span>"
|
||||
user << sound('sound/effects/magic.ogg',0,1,25)
|
||||
invoke(user, 1)
|
||||
if(uses <= 0)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='warning'>The talisman must be used on metal or plasteel!</span>"
|
||||
|
||||
|
||||
@@ -397,18 +397,6 @@
|
||||
item_path = /obj/item/weapon/twohanded/singularityhammer
|
||||
log_name = "SI"
|
||||
|
||||
/datum/spellbook_entry/item/cursed_heart
|
||||
name = "Cursed Heart"
|
||||
desc = "A heart that has been revived by dark magicks, the user must \
|
||||
concentrate to ensure the heart beats, but every beat heals them. It \
|
||||
must beat every 6 seconds. The heart is fickle, and will not work for a \
|
||||
lich."
|
||||
item_path = /obj/item/organ/heart/cursed/wizard
|
||||
log_name = "CH"
|
||||
cost = 1
|
||||
category = "Defensive"
|
||||
|
||||
|
||||
/datum/spellbook_entry/item/battlemage
|
||||
name = "Battlemage Armour"
|
||||
desc = "An ensorcelled suit of armour, protected by a powerful shield. The shield can completly negate sixteen attacks before being permanently depleted."
|
||||
|
||||
@@ -163,9 +163,11 @@
|
||||
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
|
||||
|
||||
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
|
||||
|
||||
if(efficiency > 2)
|
||||
for(var/A in bad_se_blocks)
|
||||
setblock(H.dna.struc_enzymes, A, construct_block(0,2))
|
||||
var/list/unclean_mutations = (not_good_mutations|bad_mutations)
|
||||
H.dna.remove_mutation_group(unclean_mutations)
|
||||
if(efficiency > 5 && prob(20))
|
||||
randmutvg(H)
|
||||
if(efficiency < 3 && prob(50))
|
||||
@@ -197,7 +199,6 @@
|
||||
beginning to regenerate in a cloning pod. You will \
|
||||
become conscious when it is complete.</span>"
|
||||
|
||||
H.hardset_dna(ui, H.dna.struc_enzymes, H.real_name, null, mrace, features)
|
||||
if(H)
|
||||
H.faction |= factions
|
||||
|
||||
@@ -343,7 +344,7 @@
|
||||
occupant.forceMove(T)
|
||||
icon_state = "pod_0"
|
||||
eject_wait = FALSE //If it's still set somehow.
|
||||
occupant.domutcheck() //Waiting until they're out before possible monkeyizing.
|
||||
occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/clonepod/proc/malfunction()
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
occupant_status += "</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [viable_occupant.health]%;' class='progressFill good'></div></div><div class='statusValue'>[viable_occupant.health] %</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Radiation Level:</div><div class='progressBar'><div style='width: [viable_occupant.radiation]%;' class='progressFill bad'></div></div><div class='statusValue'>[viable_occupant.radiation] %</div></div>"
|
||||
var/rejuvenators = viable_occupant.reagents.get_reagent_amount("epinephrine")
|
||||
var/rejuvenators = viable_occupant.reagents.get_reagent_amount("potass_iodide")
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Rejuvenators:</div><div class='progressBar'><div style='width: [round((rejuvenators / REJUVENATORS_MAX) * 100)]%;' class='progressFill highlight'></div></div><div class='statusValue'>[rejuvenators] units</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Unique Enzymes :</div><div class='statusValue'><span class='highlight'>[viable_occupant.dna.unique_enzymes]</span></div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Last Operation:</div><div class='statusValue'>[last_change ? last_change : "----"]</div></div>"
|
||||
@@ -350,9 +350,9 @@
|
||||
current_screen = href_list["text"]
|
||||
if("rejuv")
|
||||
if(viable_occupant && viable_occupant.reagents)
|
||||
var/epinephrine_amount = viable_occupant.reagents.get_reagent_amount("epinephrine")
|
||||
var/can_add = max(min(REJUVENATORS_MAX - epinephrine_amount, REJUVENATORS_INJECT), 0)
|
||||
viable_occupant.reagents.add_reagent("epinephrine", can_add)
|
||||
var/potassiodide_amount = viable_occupant.reagents.get_reagent_amount("potass_iodide")
|
||||
var/can_add = max(min(REJUVENATORS_MAX - potassiodide_amount, REJUVENATORS_INJECT), 0)
|
||||
viable_occupant.reagents.add_reagent("potass_iodide", can_add)
|
||||
if("setbufferlabel")
|
||||
var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null)
|
||||
if(num && text)
|
||||
|
||||
@@ -313,11 +313,6 @@ Class Procs:
|
||||
if(!user.IsAdvancedToolUser() && !IsAdminGhost(user))
|
||||
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
||||
return 1
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(prob(H.getBrainLoss()))
|
||||
user << "<span class='warning'>You momentarily forget how to use [src]!</span>"
|
||||
return 1
|
||||
if(!is_interactable())
|
||||
return 1
|
||||
if(set_machine)
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
return resources
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
|
||||
if(D.reagents.len) // No reagents storage - no reagent designs.
|
||||
if(D.reagents_list.len) // No reagents storage - no reagent designs.
|
||||
return 0
|
||||
if(materials.has_materials(get_resources_w_coeff(D)))
|
||||
return 1
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
density = 0
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
layer = WALL_OBJ_LAYER
|
||||
mouse_opacity = 0
|
||||
var/amount = 3
|
||||
animate_movement = 0
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
processing = 0
|
||||
var/turf/T = get_turf(holder)
|
||||
if(T != oldposition)
|
||||
if(!has_gravity(T))
|
||||
if(!T.has_gravity())
|
||||
var/obj/effect/particle_effect/ion_trails/I = PoolOrNew(effect_type, oldposition)
|
||||
I.setDir(holder.dir)
|
||||
flick("ion_fade", I)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
opacity = 0
|
||||
layer = FLY_LAYER
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
animate_movement = 0
|
||||
@@ -25,6 +26,8 @@
|
||||
var/step = alpha / frames
|
||||
for(var/i = 0, i < frames, i++)
|
||||
alpha -= step
|
||||
if(alpha < 160)
|
||||
opacity = 0 //if we were blocking view, we aren't now because we're fading out
|
||||
stoplag()
|
||||
|
||||
/obj/effect/particle_effect/smoke/New()
|
||||
|
||||
@@ -144,6 +144,9 @@
|
||||
appearance = mimiced_atom.appearance
|
||||
setDir(mimiced_atom.dir)
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/effect/overlay/temp/decoy/fading/New(loc, atom/mimiced_atom)
|
||||
..()
|
||||
animate(src, alpha = 0, time = duration)
|
||||
|
||||
/obj/effect/overlay/temp/cult
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
/obj/item/weapon/wirecutters = 1,
|
||||
/obj/item/weapon/wrench = 4,
|
||||
/obj/item/weapon/relic = 3,
|
||||
/obj/item/weaponcrafting/reciever = 1,
|
||||
/obj/item/weaponcrafting/reciever = 2,
|
||||
/obj/item/clothing/head/cone = 2,
|
||||
/obj/item/weapon/grenade/smokebomb = 2,
|
||||
/obj/item/device/geiger_counter = 3,
|
||||
@@ -157,7 +157,7 @@
|
||||
/obj/item/clothing/gloves/color/random = 8,
|
||||
/obj/item/clothing/shoes/laceup = 1,
|
||||
/obj/item/weapon/storage/secure/briefcase = 3,
|
||||
"" = 4
|
||||
"" = 3
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/crate_spawner
|
||||
|
||||
@@ -337,6 +337,7 @@
|
||||
if(!can_claim_for_gang(user, target))
|
||||
return
|
||||
tag_for_gang(user, target)
|
||||
affected_turfs += target
|
||||
else
|
||||
switch(paint_mode)
|
||||
if(PAINT_NORMAL)
|
||||
|
||||
@@ -704,38 +704,31 @@
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/wildcard/New()
|
||||
..()
|
||||
for(var/i in 1 to 6)
|
||||
//Pick common ingredients
|
||||
for(var/i in 1 to 7)
|
||||
var/randomFood = pick(/obj/item/weapon/reagent_containers/food/snacks/grown/chili,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/potato,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/potato,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/chocolatebar,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/banana,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/corn)
|
||||
new randomFood(src)
|
||||
//Pick one random rare ingredient
|
||||
var/randomRareFood = pick(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/corn,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle)
|
||||
new randomRareFood(src)
|
||||
new randomFood(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/fiesta
|
||||
item_state = "fiesta"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/fiesta/New()
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/tortilla(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/tortilla(src)
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/corn(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/chili(src)
|
||||
|
||||
@@ -746,32 +739,80 @@
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/bottle/wine(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/vegetarian
|
||||
item_state = "vegetarian"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/vegetarian/New()
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/potato(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/apple(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/corn(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/american
|
||||
item_state = "american"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/american/New()
|
||||
..()
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/potato(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/corn(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/fruity
|
||||
item_state = "fruity"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/fruity/New()
|
||||
..()
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/apple(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/sweets
|
||||
item_state = "sweets"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/sweets/New()
|
||||
..()
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cherries(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/apple(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/delights
|
||||
item_state = "delights"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/delights/New()
|
||||
..()
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/grains
|
||||
item_state = "grains"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/grains/New()
|
||||
..()
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(src)
|
||||
new /obj/item/weapon/reagent_containers/food/condiment/sugar(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cherries(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/icecream(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/oat(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/wheat(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod(src)
|
||||
new /obj/item/weapon/reagent_containers/honeycomb(src)
|
||||
new /obj/item/seeds/poppy(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/carnivore
|
||||
item_state = "carnivore"
|
||||
@@ -780,22 +821,22 @@
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/spidereggs(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/carpmeat(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/exotic
|
||||
item_state = "exotic"
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/exotic/New()
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/food/condiment/soysauce(src)
|
||||
for(var/i in 1 to 2)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/soydope(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/carpmeat(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage(src)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/grown/chili(src)
|
||||
|
||||
/obj/item/weapon/storage/box/ingredients/New()
|
||||
..()
|
||||
|
||||
@@ -175,12 +175,13 @@
|
||||
desc = "An improvised stun baton."
|
||||
icon_state = "stunprod_nocell"
|
||||
item_state = "prod"
|
||||
w_class = 4
|
||||
force = 3
|
||||
throwforce = 5
|
||||
stunforce = 5
|
||||
hitcost = 2500
|
||||
hitcost = 2000
|
||||
throw_hit_chance = 10
|
||||
slot_flags = null
|
||||
slot_flags = SLOT_BACK
|
||||
var/obj/item/device/assembly/igniter/sparkler = 0
|
||||
|
||||
/obj/item/weapon/melee/baton/cattleprod/New()
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/obj/item/weapon/melee/baton/cattleprod/teleprod
|
||||
name = "teleprod"
|
||||
desc = "A prod with a bluespace crystal on the end. The crystal doesn't look too fun to touch."
|
||||
w_class = 3
|
||||
icon_state = "teleprod_nocell"
|
||||
item_state = "teleprod"
|
||||
origin_tech = "combat=2;bluespace=4;materials=3"
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/weapon/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
|
||||
..()
|
||||
|
||||
@@ -107,6 +107,11 @@
|
||||
unwield(M)
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot != slot_l_hand && slot != slot_r_hand && wielded)
|
||||
unwield(user)
|
||||
|
||||
///////////OFFHAND///////////////
|
||||
/obj/item/weapon/twohanded/offhand
|
||||
name = "offhand"
|
||||
@@ -152,9 +157,6 @@
|
||||
else
|
||||
unwield(user)
|
||||
|
||||
|
||||
/obj/item/weapon/twohanded/
|
||||
|
||||
/*
|
||||
* Fireaxe
|
||||
*/
|
||||
|
||||
@@ -470,7 +470,7 @@ var/highlander_claymores = 0
|
||||
playsound(get_turf(src), 'sound/weapons/HOMERUN.ogg', 100, 1)
|
||||
homerun_ready = 0
|
||||
return
|
||||
else
|
||||
else if(!target.anchored)
|
||||
target.throw_at(throw_target, rand(1,2), 7, user)
|
||||
|
||||
/obj/item/weapon/melee/baseball_bat/ablative
|
||||
|
||||
@@ -31,8 +31,11 @@
|
||||
|
||||
/mob/living/rad_act(amount, silent = 0)
|
||||
if(amount)
|
||||
var/message = silent ? null : "Your clothes feel warm."
|
||||
var/blocked = run_armor_check(null, "rad", message, message)
|
||||
var/blocked = getarmor(null, "rad")
|
||||
|
||||
if(!silent)
|
||||
src << "Your skin feels warm."
|
||||
|
||||
apply_effect(amount, IRRADIATE, blocked)
|
||||
for(var/obj/I in src) //Radiation is also applied to items held by the mob
|
||||
I.rad_act(amount)
|
||||
|
||||
@@ -38,7 +38,7 @@ LINEN BINS
|
||||
|
||||
/obj/item/weapon/bedsheet/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/wirecutters) || I.is_sharp())
|
||||
var/obj/item/stack/sheet/cloth/C = new (loc, 3)
|
||||
var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3)
|
||||
transfer_fingerprints_to(C)
|
||||
C.add_fingerprint(user)
|
||||
qdel(src)
|
||||
|
||||
@@ -27,13 +27,17 @@
|
||||
if ("small")
|
||||
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
|
||||
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
|
||||
if ("aid")
|
||||
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
|
||||
new /obj/item/weapon/storage/firstaid/o2(src)
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
|
||||
if ("tank")
|
||||
new /obj/item/weapon/tank/internals/air(src)
|
||||
new /obj/item/clothing/mask/breath(src)
|
||||
|
||||
if ("both")
|
||||
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
check_break(M)
|
||||
|
||||
/obj/structure/table/glass/proc/check_break(mob/living/M)
|
||||
if(has_gravity(M) && M.mob_size > MOB_SIZE_SMALL)
|
||||
if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL)
|
||||
table_shatter(M)
|
||||
|
||||
/obj/structure/table/glass/proc/table_shatter(mob/M)
|
||||
|
||||
+27
-2
@@ -72,7 +72,30 @@
|
||||
for(var/obj/I in contents)
|
||||
if(!I.is_frozen) //let it go
|
||||
I.make_frozen_visual(I)
|
||||
for(var/mob/living/L in contents)
|
||||
if(L.bodytemperature >= 10)
|
||||
L.bodytemperature -= 10
|
||||
if(L.bodytemperature <= 50)
|
||||
L.apply_status_effect(/datum/status_effect/freon)
|
||||
MakeSlippery(TURF_WET_PERMAFROST, 5)
|
||||
return 1
|
||||
|
||||
/turf/open/water_vapor_gas_act()
|
||||
MakeSlippery(min_wet_time = 10, wet_time_to_add = 5)
|
||||
|
||||
for(var/mob/living/simple_animal/slime/M in src)
|
||||
M.apply_water()
|
||||
|
||||
clean_blood()
|
||||
for(var/obj/effect/O in src)
|
||||
if(is_cleanable(O))
|
||||
qdel(O)
|
||||
|
||||
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in src)
|
||||
if(hotspot && !istype(src, /turf/open/space))
|
||||
air.temperature = max(min(air.temperature-2000,air.temperature/2),0)
|
||||
qdel(hotspot)
|
||||
return 1
|
||||
|
||||
/turf/open/handle_fall(mob/faller, forced)
|
||||
faller.lying = pick(90, 270)
|
||||
@@ -95,8 +118,8 @@
|
||||
return 0
|
||||
if(!(lube&SLIDE_ICE))
|
||||
C << "<span class='notice'>You slipped[ O ? " on the [O.name]" : ""]!</span>"
|
||||
|
||||
C.attack_log += "\[[time_stamp()]\] <font color='orange'>Slipped[O ? " on the [O.name]" : ""][(lube&SLIDE)? " (LUBE)" : ""]!</font>"
|
||||
if(!C.slipping)
|
||||
C.attack_log += "\[[time_stamp()]\] <font color='orange'>Slipped[O ? " on the [O.name]" : ""][(lube&SLIDE)? " (LUBE)" : ""]!</font>"
|
||||
if(!(lube&SLIDE_ICE))
|
||||
playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3)
|
||||
|
||||
@@ -119,8 +142,10 @@
|
||||
step(C, olddir)
|
||||
C.spin(1,1)
|
||||
else if(lube&SLIDE_ICE)
|
||||
C.slipping = TRUE
|
||||
spawn(1)
|
||||
step(C, olddir)
|
||||
C.slipping = FALSE
|
||||
return 1
|
||||
|
||||
/turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost, 5 = Slide
|
||||
|
||||
@@ -239,8 +239,8 @@
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
/turf/open/floor/plating/lava/Entered(atom/movable/AM)
|
||||
burn_stuff()
|
||||
START_PROCESSING(SSobj, src)
|
||||
if(burn_stuff(AM))
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/turf/open/floor/plating/lava/process()
|
||||
if(!burn_stuff())
|
||||
@@ -257,9 +257,12 @@
|
||||
|
||||
/turf/open/floor/plating/lava/TakeTemperature(temp)
|
||||
|
||||
/turf/open/floor/plating/lava/proc/burn_stuff()
|
||||
/turf/open/floor/plating/lava/proc/burn_stuff(AM)
|
||||
. = 0
|
||||
for(var/thing in contents)
|
||||
var/thing_to_check = src
|
||||
if (AM)
|
||||
thing_to_check = list(AM)
|
||||
for(var/thing in thing_to_check)
|
||||
if(isobj(thing))
|
||||
var/obj/O = thing
|
||||
if(O.burn_state == LAVA_PROOF || O.throwing)
|
||||
|
||||
@@ -6,7 +6,6 @@ What are the archived variables for?
|
||||
#define MINIMUM_HEAT_CAPACITY 0.0003
|
||||
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
|
||||
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
|
||||
|
||||
var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
|
||||
|
||||
var/list/gaslist_cache = null
|
||||
@@ -181,13 +180,16 @@ var/list/gaslist_cache = null
|
||||
//world << "post [temperature], [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]]
|
||||
*/
|
||||
if(holder)
|
||||
if(cached_gases["freon"] && cached_gases["o2"])
|
||||
if(cached_gases["freon"][MOLES] >= 3)
|
||||
if(return_temperature() < 50)
|
||||
holder.freon_gas_act()
|
||||
cached_gases["freon"][MOLES] -= 3
|
||||
cached_gases["o2"][MOLES] += 3
|
||||
temperature += 1
|
||||
if(cached_gases["freon"])
|
||||
if(cached_gases["freon"][MOLES] >= MOLES_PLASMA_VISIBLE)
|
||||
if(holder.freon_gas_act())
|
||||
cached_gases["freon"][MOLES] -= MOLES_PLASMA_VISIBLE
|
||||
|
||||
if(cached_gases["water_vapor"])
|
||||
if(cached_gases["water_vapor"][MOLES] >= MOLES_PLASMA_VISIBLE)
|
||||
if(holder.water_vapor_gas_act())
|
||||
cached_gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE
|
||||
|
||||
fuel_burnt = 0
|
||||
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
|
||||
//world << "pre [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]"
|
||||
@@ -342,7 +344,6 @@ var/list/gaslist_cache = null
|
||||
amount = min(amount, sum) //Can not take more air than tile has!
|
||||
if(amount <= 0)
|
||||
return null
|
||||
|
||||
var/list/cached_gases = gases
|
||||
var/datum/gas_mixture/removed = new
|
||||
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
|
||||
@@ -370,6 +371,7 @@ var/list/gaslist_cache = null
|
||||
removed.add_gas(id)
|
||||
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio)
|
||||
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
|
||||
|
||||
garbage_collect()
|
||||
|
||||
return removed
|
||||
@@ -394,6 +396,7 @@ var/list/gaslist_cache = null
|
||||
for(var/id in sample_gases)
|
||||
assert_gas(id)
|
||||
cached_gases[id][MOLES] = sample_gases[id][MOLES]
|
||||
|
||||
//remove all gases not in the sample
|
||||
cached_gases &= sample_gases
|
||||
|
||||
|
||||
@@ -51,12 +51,19 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
|
||||
gas_overlay = "plasma"
|
||||
moles_visible = MOLES_PLASMA_VISIBLE
|
||||
|
||||
/datum/gas/water_vapor
|
||||
id = "water_vapor"
|
||||
specific_heat = 40
|
||||
name = "Water Vapor"
|
||||
gas_overlay = "water_vapor"
|
||||
moles_visible = MOLES_PLASMA_VISIBLE
|
||||
|
||||
/datum/gas/freon
|
||||
id = "freon"
|
||||
specific_heat = 1000
|
||||
specific_heat = 2000
|
||||
name = "Freon"
|
||||
gas_overlay = "freon"
|
||||
moles_visible = 3
|
||||
moles_visible = MOLES_PLASMA_VISIBLE
|
||||
|
||||
/datum/gas/nitrous_oxide
|
||||
id = "n2o"
|
||||
@@ -84,7 +91,7 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
|
||||
icon = 'icons/effects/tile_effects.dmi'
|
||||
mouse_opacity = 0
|
||||
layer = FLY_LAYER
|
||||
appearance_flags = RESET_COLOR|TILE_BOUND
|
||||
appearance_flags = TILE_BOUND
|
||||
|
||||
/obj/effect/overlay/gas/New(state)
|
||||
. = ..()
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
"n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
|
||||
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5),
|
||||
"freon" = new/datum/tlv(-1, -1, 0.2, 0.5),
|
||||
"water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
|
||||
)
|
||||
|
||||
/obj/machinery/airalarm/server // No checks here.
|
||||
@@ -91,6 +92,7 @@
|
||||
"n2o" = new/datum/tlv(-1, -1, -1, -1),
|
||||
"bz" = new/datum/tlv(-1, -1, -1, -1),
|
||||
"freon" = new/datum/tlv(-1, -1, -1, -1),
|
||||
"water_vapor" = new/datum/tlv(-1, -1, -1, -1)
|
||||
)
|
||||
|
||||
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
|
||||
@@ -104,6 +106,7 @@
|
||||
"n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
|
||||
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
|
||||
"freon" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
|
||||
"water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
|
||||
)
|
||||
|
||||
//all air alarms in area are connected via magic
|
||||
@@ -228,16 +231,17 @@
|
||||
if(!info || info["frequency"] != frequency)
|
||||
continue
|
||||
data["scrubbers"] += list(list(
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"scrubbing" = info["scrubbing"],
|
||||
"widenet" = info["widenet"],
|
||||
"filter_co2" = info["filter_co2"],
|
||||
"filter_toxins" = info["filter_toxins"],
|
||||
"filter_n2o" = info["filter_n2o"],
|
||||
"filter_bz" = info["filter_bz"],
|
||||
"filter_freon" = info["filter_freon"]
|
||||
"id_tag" = id_tag,
|
||||
"long_name" = sanitize(long_name),
|
||||
"power" = info["power"],
|
||||
"scrubbing" = info["scrubbing"],
|
||||
"widenet" = info["widenet"],
|
||||
"filter_co2" = info["filter_co2"],
|
||||
"filter_toxins" = info["filter_toxins"],
|
||||
"filter_n2o" = info["filter_n2o"],
|
||||
"filter_bz" = info["filter_bz"],
|
||||
"filter_freon" = info["filter_freon"],
|
||||
"filter_water_vapor" = info["filter_water_vapor"]
|
||||
))
|
||||
data["mode"] = mode
|
||||
data["modes"] = list()
|
||||
@@ -293,7 +297,7 @@
|
||||
if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN))
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("power", "co2_scrub", "tox_scrub", "n2o_scrub", "bz_scrub", "freon_scrub", "widenet", "scrubbing")
|
||||
if("power", "co2_scrub", "tox_scrub", "n2o_scrub", "bz_scrub", "freon_scrub","water_vapor_scrub", "widenet", "scrubbing")
|
||||
send_signal(device_id, list("[action]" = text2num(params["val"])))
|
||||
. = TRUE
|
||||
if("excheck")
|
||||
@@ -410,8 +414,9 @@
|
||||
"co2_scrub" = 1,
|
||||
"tox_scrub" = 0,
|
||||
"n2o_scrub" = 0,
|
||||
"bz_scrub" = 1,
|
||||
"freon_scrub"= 1,
|
||||
"bz_scrub" = 0,
|
||||
"freon_scrub"= 0,
|
||||
"water_vapor_scrub"= 0,
|
||||
"scrubbing" = 1,
|
||||
"widenet" = 0,
|
||||
))
|
||||
@@ -430,6 +435,7 @@
|
||||
"n2o_scrub" = 1,
|
||||
"bz_scrub" = 1,
|
||||
"freon_scrub"= 1,
|
||||
"water_vapor_scrub"= 1,
|
||||
"scrubbing" = 1,
|
||||
"widenet" = 1,
|
||||
))
|
||||
@@ -460,7 +466,8 @@
|
||||
"tox_scrub" = 0,
|
||||
"n2o_scrub" = 0,
|
||||
"bz_scrub" = 0,
|
||||
"freon_scrub"= 1,
|
||||
"freon_scrub"= 0,
|
||||
"water_vapor_scrub"= 0,
|
||||
"scrubbing" = 1,
|
||||
"widenet" = 0,
|
||||
))
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
var/scrub_Toxins = 0
|
||||
var/scrub_N2O = 0
|
||||
var/scrub_BZ = 0
|
||||
var/scrub_Freon = 1
|
||||
var/scrub_Freon = 0
|
||||
var/scrub_WaterVapor = 0
|
||||
|
||||
|
||||
var/volume_rate = 200
|
||||
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
|
||||
@@ -72,6 +74,8 @@
|
||||
amount += idle_power_usage
|
||||
if(scrub_Freon)
|
||||
amount += idle_power_usage
|
||||
if(scrub_WaterVapor)
|
||||
amount += idle_power_usage
|
||||
else //scrubbing == SIPHONING
|
||||
amount = active_power_usage
|
||||
|
||||
@@ -122,7 +126,8 @@
|
||||
"filter_toxins" = scrub_Toxins,
|
||||
"filter_n2o" = scrub_N2O,
|
||||
"filter_bz" = scrub_BZ,
|
||||
"filter_Freon" = scrub_Freon,
|
||||
"filter_freon" = scrub_Freon,
|
||||
"filter_water_vapor" = scrub_WaterVapor,
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
@@ -218,6 +223,11 @@
|
||||
filtered_out.gases["freon"][MOLES] = removed_gases["freon"][MOLES]
|
||||
removed.gases["freon"][MOLES] = 0
|
||||
|
||||
if(scrub_WaterVapor && removed_gases["water_vapor"])
|
||||
filtered_out.assert_gas("water_vapor")
|
||||
filtered_out.gases["water_vapor"][MOLES] = removed_gases["water_vapor"][MOLES]
|
||||
removed.gases["water_vapor"][MOLES] = 0
|
||||
|
||||
removed.garbage_collect()
|
||||
|
||||
//Remix the resulting gases
|
||||
@@ -303,6 +313,11 @@
|
||||
if("toggle_freon_scrub" in signal.data)
|
||||
scrub_Freon = !scrub_Freon
|
||||
|
||||
if("water_vapor_scrub" in signal.data)
|
||||
scrub_WaterVapor = text2num(signal.data["water_vapor_scrub"])
|
||||
if("toggle_water_vapor_scrub" in signal.data)
|
||||
scrub_WaterVapor = !scrub_WaterVapor
|
||||
|
||||
if("init" in signal.data)
|
||||
name = signal.data["init"]
|
||||
return
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
"n2o" = /obj/machinery/portable_atmospherics/canister/nitrous_oxide,
|
||||
"bz" = /obj/machinery/portable_atmospherics/canister/bz,
|
||||
"air" = /obj/machinery/portable_atmospherics/canister/air,
|
||||
"freon" = /obj/machinery/portable_atmospherics/canister/freon,
|
||||
"water vapor" = /obj/machinery/portable_atmospherics/canister/water_vapor,
|
||||
"caution" = /obj/machinery/portable_atmospherics/canister,
|
||||
)
|
||||
|
||||
@@ -85,7 +87,14 @@
|
||||
desc = "Freon. Great for the atmosphere!"
|
||||
icon_state = "freon"
|
||||
gas_type = "freon"
|
||||
starter_temp = 2.7
|
||||
starter_temp = 120
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/water_vapor
|
||||
name = "water vapor canister"
|
||||
desc = "Water Vapor. We get it, you vape."
|
||||
icon_state = "water_vapor"
|
||||
gas_type = "water_vapor"
|
||||
filled = 1
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture)
|
||||
..()
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
var/volume_rate = 1000
|
||||
volume = 1000
|
||||
|
||||
var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon")
|
||||
var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon", "water_vapor")
|
||||
|
||||
/obj/machinery/portable_atmospherics/scrubber/Destroy()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
@@ -153,8 +153,6 @@
|
||||
dangerous = TRUE
|
||||
|
||||
/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
|
||||
var/static/list/uplink_items = get_uplink_items()
|
||||
|
||||
var/crate_value = 50
|
||||
while(crate_value)
|
||||
var/category = pick(uplink_items)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
icon_state = "[magboot_state][magpulse]"
|
||||
user << "<span class='notice'>You [magpulse ? "enable" : "disable"] the mag-pulse traction system.</span>"
|
||||
user.update_inv_shoes() //so our mob-overlays update
|
||||
user.update_gravity(user.mob_has_gravity())
|
||||
user.update_gravity(user.has_gravity())
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
|
||||
@@ -100,11 +100,11 @@
|
||||
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
|
||||
if(prob(75))
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
|
||||
if(prob(50))
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
|
||||
shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
|
||||
|
||||
if(SPIDER_GIFT)
|
||||
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
|
||||
|
||||
@@ -214,10 +214,14 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/burn()
|
||||
SSobj.burning -= src
|
||||
boom()
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/proc/boom(mob/user)
|
||||
user << "<span class='danger'>The crate's anti-tamper system activates!</span>"
|
||||
if(user)
|
||||
user << "<span class='danger'>The crate's anti-tamper system activates!</span>"
|
||||
for(var/atom/movable/AM in src)
|
||||
qdel(AM)
|
||||
var/turf/T = get_turf(src)
|
||||
explosion(T, -1, -1, 1, 1)
|
||||
explosion(get_turf(src), 0, 1, 5, 5)
|
||||
qdel(src)
|
||||
@@ -193,19 +193,23 @@
|
||||
weaken = 3
|
||||
var/chain
|
||||
|
||||
/obj/item/ammo_casing/magic/hook/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
/obj/item/projectile/hook/fire(setAngle)
|
||||
if(firer)
|
||||
chain = Beam(firer, icon_state = "chain", icon = 'icons/obj/lavaland/artefacts.dmi', time = INFINITY, maxdistance = INFINITY)
|
||||
..()
|
||||
var/obj/item/projectile/hook/P = BB
|
||||
spawn(1)
|
||||
P.chain = P.Beam(user,icon_state="chain",icon = 'icons/obj/lavaland/artefacts.dmi',time=1000, maxdistance = 30)
|
||||
|
||||
/obj/item/projectile/hook/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.visible_message("<span class='danger'>[L] is snagged by [firer]'s hook!</span>")
|
||||
L.forceMove(get_turf(firer))
|
||||
qdel(chain)
|
||||
if(!L.anchored)
|
||||
L.visible_message("<span class='danger'>[L] is snagged by [firer]'s hook!</span>")
|
||||
L.forceMove(get_turf(firer))
|
||||
|
||||
/obj/item/projectile/hook/Destroy()
|
||||
qdel(chain)
|
||||
return ..()
|
||||
|
||||
|
||||
//Immortality Talisman
|
||||
/obj/item/device/immortality_talisman
|
||||
@@ -632,7 +636,9 @@
|
||||
var/transform_string = "lava"
|
||||
var/reset_turf_type = /turf/open/floor/plating/asteroid/basalt
|
||||
var/reset_string = "basalt"
|
||||
var/cooldown = 200
|
||||
var/create_cooldown = 100
|
||||
var/create_delay = 30
|
||||
var/reset_cooldown = 50
|
||||
var/timer = 0
|
||||
var/banned_turfs
|
||||
|
||||
@@ -654,15 +660,31 @@
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!istype(T, turf_type))
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [transform_string]!</span>")
|
||||
message_admins("[key_name_admin(user)] fired the lava staff at (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[get_area(target)] ([T.x], [T.y], [T.z])</a>).")
|
||||
log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).")
|
||||
T.ChangeTurf(turf_type)
|
||||
var/obj/effect/overlay/temp/lavastaff/L = PoolOrNew(/obj/effect/overlay/temp/lavastaff, T)
|
||||
L.alpha = 0
|
||||
animate(L, alpha = 255, time = create_delay)
|
||||
user.visible_message("<span class='danger'>[user] points [src] at [T]!</span>")
|
||||
timer = world.time + create_delay + 1
|
||||
if(do_after(user, create_delay, target = T))
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [transform_string]!</span>")
|
||||
message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)]. [ADMIN_COORDJMP(T)]")
|
||||
log_game("[key_name(user)] fired the lava staff at [get_area(target)] [COORD(T)].")
|
||||
T.ChangeTurf(turf_type)
|
||||
timer = world.time + create_cooldown
|
||||
qdel(L)
|
||||
else
|
||||
timer = world.time
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [reset_string]!</span>")
|
||||
T.ChangeTurf(reset_turf_type)
|
||||
playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1)
|
||||
timer = world.time + cooldown
|
||||
timer = world.time + reset_cooldown
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
|
||||
/obj/effect/overlay/temp/lavastaff
|
||||
icon_state = "lavastaff_warn"
|
||||
duration = 50
|
||||
|
||||
///Bubblegum
|
||||
|
||||
@@ -737,3 +759,189 @@
|
||||
H.equip_to_slot_or_del(new /obj/item/weapon/kitchen/knife/butcher(H), slot_l_hand)
|
||||
|
||||
qdel(src)
|
||||
|
||||
//Hierophant
|
||||
|
||||
/obj/item/weapon/hierophant_staff
|
||||
name = "Hierophant's staff"
|
||||
desc = "A large club with intense magic power infused into it."
|
||||
icon_state = "hierophant_staff"
|
||||
item_state = "hierophant_staff"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = 4
|
||||
force = 20
|
||||
hitsound = "swing_hit"
|
||||
//hitsound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
|
||||
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
|
||||
var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
|
||||
var/chaser_timer = 0 //what our current chaser cooldown is
|
||||
var/timer = 0 //what our current cooldown is
|
||||
var/blast_range = 3 //how long the cardinal blast's walls are
|
||||
var/obj/effect/hierophant/rune //the associated rune we teleport to
|
||||
var/teleporting = FALSE //if we ARE teleporting
|
||||
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
|
||||
|
||||
/obj/item/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T || timer > world.time)
|
||||
return
|
||||
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
|
||||
if(proximity_flag)
|
||||
addtimer(src, "aoe_burst", 0, FALSE, T, user)
|
||||
add_logs(user, target, "fired 3x3 blast at", src)
|
||||
else
|
||||
if(istype(target, /turf/closed/mineral) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
|
||||
addtimer(src, "cardinal_blasts", 0, FALSE, T, user)
|
||||
timer = world.time + cooldown_time
|
||||
else if(target in view(5, get_turf(user))) //if the target is in view, hit it
|
||||
timer = world.time + cooldown_time
|
||||
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
|
||||
chaser_timer = world.time + chaser_cooldown
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(get_turf(user), user, target, 1.5, friendly_fire_check))
|
||||
add_logs(user, target, "fired a chaser at", src)
|
||||
else
|
||||
addtimer(src, "cardinal_blasts", 0, FALSE, T, user) //otherwise, just do cardinal blast
|
||||
add_logs(user, target, "fired cardinal blast at", src)
|
||||
else
|
||||
user << "<span class='warning'>That target is out of range!</span>" //too far away
|
||||
|
||||
/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype)
|
||||
if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
|
||||
friendly_fire_check = !friendly_fire_check
|
||||
user << "<span class='warning'>You toggle friendly fire [friendly_fire_check ? "off":"on"]!</span>"
|
||||
return
|
||||
if(!rune)
|
||||
if(isturf(user.loc))
|
||||
user.visible_message("<span class='hierophant_warning'>[user] holds [src] carefully in front of them, moving it in a strange pattern...</span>", \
|
||||
"<span class='notice'>You start creating a hierophant rune to teleport to...</span>")
|
||||
timer = world.time + 51
|
||||
if(do_after(user, 50, target = user))
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(T,'sound/magic/Blind.ogg', 200, 1, -4)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, user))
|
||||
var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
|
||||
rune = H
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] creates a strange rune beneath them!</span>", \
|
||||
"<span class='hierophant'>You create a hierophant rune, which you can teleport yourself and any allies to at any time!</span>\n\
|
||||
<span class='notice'>You can remove the rune to place a new one by striking it with the staff.</span>")
|
||||
else
|
||||
timer = world.time
|
||||
else
|
||||
user << "<span class='warning'>You need to be on solid ground to produce a rune!</span>"
|
||||
return
|
||||
if(src != user.l_hand && src != user.r_hand) //you need to hold the staff to teleport
|
||||
user << "<span class='warning'>You need to hold the staff in your hands to [rune ? "teleport with it":"create a rune"]!</span>"
|
||||
return
|
||||
if(get_dist(user, rune) <= 2) //rune too close abort
|
||||
user << "<span class='warning'>You are too close to the rune to teleport to it!</span>"
|
||||
return
|
||||
if(is_blocked_turf(get_turf(rune)))
|
||||
user << "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>"
|
||||
return
|
||||
teleporting = TRUE //start channel
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] starts to glow faintly...</span>")
|
||||
timer = world.time + 50
|
||||
if(do_after(user, 40, target = user) && rune)
|
||||
var/turf/T = get_turf(rune)
|
||||
var/turf/source = get_turf(user)
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
user << "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>"
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, user))
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, user))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
|
||||
playsound(source,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
|
||||
if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
user << "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>"
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to")
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, user))
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, user))
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, TRUE)) //blasts produced will not hurt allies
|
||||
B.damage = 30
|
||||
for(var/t in RANGE_TURFS(1, source))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, TRUE)) //but absolutely will hurt enemies
|
||||
B.damage = 30
|
||||
for(var/mob/living/L in range(1, source))
|
||||
addtimer(src, "teleport_mob", 0, FALSE, source, L, T, user) //regardless, take all mobs near us along
|
||||
sleep(6) //at this point the blasts detonate
|
||||
else
|
||||
timer = world.time
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
|
||||
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
|
||||
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to))
|
||||
return
|
||||
animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades out!</span>")
|
||||
sleep(2)
|
||||
if(!M)
|
||||
return
|
||||
M.forceMove(turf_to_teleport_to)
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades in!</span>")
|
||||
if(user != M)
|
||||
add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])")
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
|
||||
if(!T)
|
||||
return
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, user))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, user, friendly_fire_check))
|
||||
for(var/d in cardinal)
|
||||
addtimer(src, "blast_wall", 0, FALSE, T, d, user)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
|
||||
if(!T)
|
||||
return
|
||||
var/range = blast_range
|
||||
var/turf/previousturf = T
|
||||
var/turf/J = get_step(previousturf, dir)
|
||||
for(var/i in 1 to range)
|
||||
if(!J)
|
||||
return
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, user, friendly_fire_check))
|
||||
previousturf = J
|
||||
J = get_step(previousturf, dir)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
|
||||
if(!T)
|
||||
return
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, user))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, friendly_fire_check))
|
||||
|
||||
@@ -88,11 +88,12 @@
|
||||
else
|
||||
process_sheet(O)
|
||||
i++
|
||||
if(i > 0)
|
||||
var/msg = "Now available in the cargo Bay: \n"
|
||||
if(i > 0 && z == ZLEVEL_STATION)
|
||||
var/area/orm_area = get_area(src)
|
||||
var/msg = "Now available in [orm_area.map_name]:"
|
||||
for(var/s in stack_list) // Making an announcement for cargo
|
||||
var/obj/item/stack/sheet/mats = stack_list[s]
|
||||
msg += "[capitalize(mats.name)]: [mats.amount] sheets \n"
|
||||
msg += "\n[capitalize(mats.name)]: [mats.amount] sheets"
|
||||
for(var/obj/machinery/requests_console/D in allConsoles)
|
||||
if(D.department == "Science" || D.department == "Robotics" || D.department == "Research Director's Desk" || D.department == "Chemistry" || D.department == "Bar")
|
||||
D.createmessage("Ore Redemption Machine", "New minerals available!", msg, 1, 0)
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
|
||||
//this item is intended to give the effect of entering the mine, so that light gradually fades
|
||||
/obj/effect/light_emitter
|
||||
name = "Light-emtter"
|
||||
name = "Light emitter"
|
||||
anchored = 1
|
||||
unacidable = 1
|
||||
luminosity = 8
|
||||
invisibility = 101
|
||||
var/set_luminosity = 8
|
||||
var/set_cap = 0
|
||||
|
||||
/obj/effect/light_emitter/New()
|
||||
..()
|
||||
SetLuminosity(set_luminosity, set_cap)
|
||||
|
||||
/**********************Miner Lockers**************************/
|
||||
|
||||
@@ -535,9 +541,15 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
|
||||
say("<span class='danger'>Launch sequence activated! Prepare for drop!</span>")
|
||||
playsound(loc, 'sound/machines/warning-buzzer.ogg', 70, 0)
|
||||
launch_warning = FALSE
|
||||
feedback_add_details("colonies_dropped") //Number of times a base has been dropped!
|
||||
..()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle/auxillary_base/onShuttleMove(turf/T1, rotation)
|
||||
..()
|
||||
if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery
|
||||
feedback_add_details("colonies_dropped", "[x]|[y]|[z]") //Number of times a base has been dropped!
|
||||
|
||||
/obj/machinery/computer/shuttle/auxillary_base/proc/set_mining_mode()
|
||||
if(z == ZLEVEL_MINING) //The console switches to controlling the mining shuttle once landed.
|
||||
req_access = list()
|
||||
@@ -713,4 +725,4 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
|
||||
anti_spam_cd = 0
|
||||
|
||||
/obj/structure/mining_shuttle_beacon/attack_robot(mob/user)
|
||||
return (attack_hand(user)) //So borgies can help
|
||||
return (attack_hand(user)) //So borgies can help
|
||||
|
||||
@@ -619,15 +619,18 @@
|
||||
|
||||
/turf/open/chasm/Entered(atom/movable/AM)
|
||||
START_PROCESSING(SSobj, src)
|
||||
drop_stuff()
|
||||
drop_stuff(AM)
|
||||
|
||||
/turf/open/chasm/process()
|
||||
if(!drop_stuff())
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/turf/open/chasm/proc/drop_stuff()
|
||||
/turf/open/chasm/proc/drop_stuff(AM)
|
||||
. = 0
|
||||
for(var/thing in contents)
|
||||
var/thing_to_check = src
|
||||
if(AM)
|
||||
thing_to_check = list(AM)
|
||||
for(var/thing in thing_to_check)
|
||||
if(droppable(thing))
|
||||
. = 1
|
||||
addtimer(src, "drop", 0, FALSE, thing)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
if(leaping || stat || buckled || lying)
|
||||
return
|
||||
|
||||
if(!has_gravity(src) || !has_gravity(A))
|
||||
if(!has_gravity() || !A.has_gravity())
|
||||
src << "<span class='alertalien'>It is unsafe to leap without gravity!</span>"
|
||||
//It's also extremely buggy visually, so it's balance+bugfix
|
||||
return
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/mob_has_gravity()
|
||||
/mob/living/carbon/human/has_gravity()
|
||||
. = ..()
|
||||
if(!.)
|
||||
if(mob_negates_gravity())
|
||||
|
||||
@@ -849,7 +849,7 @@
|
||||
. -= 2
|
||||
|
||||
if(!(H.status_flags & IGNORESLOWDOWN))
|
||||
if(!has_gravity(H))
|
||||
if(!H.has_gravity())
|
||||
if(FLYING in specflags)
|
||||
. += speedmod
|
||||
return
|
||||
@@ -1416,7 +1416,6 @@
|
||||
if(-INFINITY to 120)
|
||||
H.throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod, BURN)
|
||||
H.apply_status_effect(/datum/status_effect/freon)
|
||||
else
|
||||
H.clear_alert("temp")
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
update_gravity(mob_has_gravity())
|
||||
update_gravity(has_gravity())
|
||||
|
||||
if(machine)
|
||||
machine.check_eye(src)
|
||||
|
||||
@@ -602,7 +602,7 @@
|
||||
. += config.walk_speed
|
||||
|
||||
/mob/living/proc/makeTrail(turf/T)
|
||||
if(!has_gravity(src))
|
||||
if(!has_gravity())
|
||||
return
|
||||
var/blood_exists = 0
|
||||
|
||||
@@ -666,8 +666,8 @@
|
||||
if (AM.density && AM.anchored)
|
||||
pressure_resistance_prob_delta -= 20
|
||||
break
|
||||
|
||||
..(pressure_difference, direction, pressure_resistance_prob_delta)
|
||||
if(!slipping)
|
||||
..(pressure_difference, direction, pressure_resistance_prob_delta)
|
||||
|
||||
/mob/living/verb/resist()
|
||||
set name = "Resist"
|
||||
|
||||
@@ -71,3 +71,5 @@
|
||||
|
||||
var/blood_volume = 0 //how much blood the mob has
|
||||
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
|
||||
|
||||
var/slipping = FALSE
|
||||
@@ -144,7 +144,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans)
|
||||
var/list/listening = get_hearers_in_view(message_range, source)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7 && M.z == z)) && client) // client is so that ghosts don't have to listen to mice
|
||||
listening |= M
|
||||
|
||||
var/rendered = compose_message(src, languages_spoken, message, , spans)
|
||||
|
||||
@@ -19,4 +19,6 @@
|
||||
msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n"
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
user << msg
|
||||
|
||||
..()
|
||||
@@ -9,7 +9,7 @@
|
||||
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
|
||||
//Being dead doesn't mean your temperature never changes
|
||||
|
||||
update_gravity(mob_has_gravity())
|
||||
update_gravity(has_gravity())
|
||||
|
||||
if(malfhack && malfhack.aidisabled)
|
||||
deltimer(malfhacking)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts
|
||||
if(laws && isobserver(user))
|
||||
user << "<b>[src] has the following laws:</b>"
|
||||
laws.show_laws(user)
|
||||
@@ -236,7 +236,7 @@
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
|
||||
if (message && src.stat == CONSCIOUS)
|
||||
if (message && stat == CONSCIOUS)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
@@ -248,9 +248,10 @@
|
||||
set category = "Robot Commands"
|
||||
set name = "Power Warning"
|
||||
|
||||
if(!cell || !cell.charge)
|
||||
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
|
||||
"You announce you are operating in low power mode.")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
else
|
||||
src << "<span class='warning'>You can only use this emote when you're out of charge.</span>"
|
||||
if(stat == CONSCIOUS)
|
||||
if(!cell || !cell.charge)
|
||||
visible_message("The power warning light on <span class='name'>[src]</span> flashes urgently.",\
|
||||
"You announce you are operating in low power mode.")
|
||||
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
|
||||
else
|
||||
src << "<span class='warning'>You can only use this emote when you're out of charge.</span>"
|
||||
@@ -47,3 +47,5 @@
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
|
||||
..()
|
||||
@@ -11,7 +11,7 @@
|
||||
/mob/living/silicon/robot/mob_negates_gravity()
|
||||
return magpulse
|
||||
|
||||
/mob/living/silicon/robot/mob_has_gravity()
|
||||
/mob/living/silicon/robot/has_gravity()
|
||||
return ..() || mob_negates_gravity()
|
||||
|
||||
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
|
||||
|
||||
@@ -859,7 +859,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
src << "<span class='notice'>You sense your form change as you are uploaded into [src].</span>"
|
||||
bot_name = name
|
||||
name = paicard.pai.name
|
||||
faction = user.faction
|
||||
faction = user.faction.Copy()
|
||||
add_logs(user, paicard.pai, "uploaded to [bot_name],")
|
||||
return 1
|
||||
else
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
/mob/living/simple_animal/drone/mob_negates_gravity()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/drone/mob_has_gravity()
|
||||
/mob/living/simple_animal/drone/has_gravity()
|
||||
return ..() || mob_negates_gravity()
|
||||
|
||||
/mob/living/simple_animal/drone/experience_pressure_difference(pressure_difference, direction)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/charger/Move()
|
||||
if(charging)
|
||||
PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
|
||||
PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/charger/snapback()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
response_harm = "hits"
|
||||
maxHealth = 60
|
||||
health = 60
|
||||
var/armored = FALSE
|
||||
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 30
|
||||
@@ -46,11 +47,56 @@
|
||||
icon_state = "snowbear"
|
||||
icon_living = "snowbear"
|
||||
icon_dead = "snowbear_dead"
|
||||
desc = "It's a polar bear, in space, but not actually in space. "
|
||||
desc = "It's a polar bear, in space, but not actually in space."
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/russian
|
||||
name = "combat bear"
|
||||
desc = "A ferocious brown bear decked out in armor plating, a red star with yellow outlining details the shoulder plating."
|
||||
icon_state = "combatbear"
|
||||
icon_living = "combatbear"
|
||||
icon_dead = "combatbear_dead"
|
||||
faction = list("russian")
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1)
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 35
|
||||
armour_penetration = 20
|
||||
health = 120
|
||||
maxHealth = 120
|
||||
armored = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Process_Spacemove(movement_dir = 0)
|
||||
return 1 //No drifting in space for space bears!
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/update_icons()
|
||||
..()
|
||||
if(armored)
|
||||
var/image/B = image(icon = 'icons/mob/animal.dmi', icon_state = "armor_bear")
|
||||
if(B)
|
||||
add_overlay(B)
|
||||
|
||||
/obj/item/bear_armor
|
||||
name = "pile of bear armor"
|
||||
desc = "A scattered pile of various shaped armor pieces fitted for a bear, some duct tape, and a nail filer. Crude instructions \
|
||||
are written on the back of one of the plates in russian. This seems like an awful idea."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "bear_armor_upgrade"
|
||||
|
||||
/obj/item/bear_armor/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(istype(target, /mob/living/simple_animal/hostile/bear) && proximity_flag)
|
||||
var/mob/living/simple_animal/hostile/bear/A = target
|
||||
if(A.armored)
|
||||
user << "<span class='warning'>[A] has already been armored up!</span>"
|
||||
return
|
||||
A.armored = TRUE
|
||||
A.maxHealth += 60
|
||||
A.health += 60
|
||||
A.armour_penetration += 20
|
||||
A.melee_damage_lower += 5
|
||||
A.melee_damage_upper += 5
|
||||
A.update_icons()
|
||||
user << "<span class='info'>You strap the armor plating to [A] and sharpen their claws with the nail filer. This was a great idea.</span>"
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@
|
||||
AIStatus = AI_IDLE // otherwise we go idle
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user)
|
||||
if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user)
|
||||
FindTarget(list(user), 1)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/bullet_act(obj/item/projectile/P)
|
||||
if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client)
|
||||
if(P.firer && get_dist(src, P.firer) <= aggro_vision_range)
|
||||
|
||||
@@ -110,9 +110,9 @@ Difficulty: Hard
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
|
||||
if(!stat)
|
||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1)
|
||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
|
||||
if(charging)
|
||||
PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
|
||||
PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
|
||||
DestroySurroundings()
|
||||
. = ..()
|
||||
if(charging)
|
||||
@@ -126,15 +126,21 @@ Difficulty: Hard
|
||||
charge()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
|
||||
var/turf/T = get_step_away(target, src)
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T || T == loc)
|
||||
return
|
||||
PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, T)
|
||||
charging = 1
|
||||
DestroySurroundings()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, T)
|
||||
walk(src, 0)
|
||||
setDir(get_dir(src, T))
|
||||
var/obj/effect/overlay/temp/decoy/D = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
|
||||
D.color = "#FF0000"
|
||||
animate(D, alpha = 0, color = initial(D.color), transform = matrix()*2, time = 5)
|
||||
sleep(5)
|
||||
walk(src,0)
|
||||
throw_at(T, 7, 1, src, 0)
|
||||
throw_at(T, get_dist(src, T), 1, src, 0)
|
||||
charging = 0
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
Goto(target, move_to_delay, minimum_distance)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A)
|
||||
@@ -148,16 +154,15 @@ Difficulty: Hard
|
||||
if(!charging)
|
||||
return ..()
|
||||
|
||||
else if(A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
|
||||
L.apply_damage(40, BRUTE)
|
||||
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
|
||||
shake_camera(L, 4, 3)
|
||||
shake_camera(src, 2, 3)
|
||||
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
|
||||
L.throw_at_fast(throwtarget)
|
||||
else if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
L.visible_message("<span class='danger'>[src] slams into [L]!</span>", "<span class='userdanger'>[src] slams into you!</span>")
|
||||
L.apply_damage(40, BRUTE)
|
||||
playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
|
||||
shake_camera(L, 4, 3)
|
||||
shake_camera(src, 2, 3)
|
||||
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
|
||||
L.throw_at_fast(throwtarget, 3)
|
||||
|
||||
charging = 0
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ Difficulty: Medium
|
||||
if(stat || swooping)
|
||||
return
|
||||
swoop_cooldown = world.time + 200
|
||||
var/swoop_target
|
||||
var/atom/swoop_target
|
||||
if(manual_target)
|
||||
swoop_target = manual_target
|
||||
else
|
||||
@@ -212,7 +212,7 @@ Difficulty: Medium
|
||||
fire_rain()
|
||||
|
||||
icon_state = "dragon"
|
||||
if(swoop_target && !qdeleted(swoop_target))
|
||||
if(swoop_target && !qdeleted(swoop_target) && swoop_target.z == src.z)
|
||||
tturf = get_turf(swoop_target)
|
||||
else
|
||||
tturf = get_turf(src)
|
||||
|
||||
@@ -0,0 +1,584 @@
|
||||
#define MEDAL_PREFIX "Hierophant"
|
||||
/*
|
||||
|
||||
The Hierophant
|
||||
|
||||
The Hierophant spawns in its arena, an area designed to make it harder to fight than it would otherwise be.
|
||||
|
||||
The text this boss speaks is ROT4, use ROT22 to decode
|
||||
|
||||
The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health;
|
||||
- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time.
|
||||
INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target.
|
||||
INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health.
|
||||
- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts.
|
||||
INTENSITY EFFECT: Creates a second, slower chaser.
|
||||
- Creates an expanding AoE burst.
|
||||
- INTENSE ATTACKS:
|
||||
If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points.
|
||||
As above, but does so multiple times if below half health.
|
||||
Rapidly creates Cross Blasts under a target.
|
||||
If chasers are off cooldown, creates four high-speed chasers.
|
||||
- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target.
|
||||
|
||||
Cross Blasts and the AoE burst gain additional range as the Hierophant loses health, while Chasers gain additional speed.
|
||||
|
||||
When The Hierophant dies, it leaves behind its staff, which, while much weaker than when wielded by The Hierophant itself, is still quite effective.
|
||||
- The staff can place a teleport rune, allowing the user to teleport themself and their allies to the rune.
|
||||
|
||||
Difficulty: Hard
|
||||
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant
|
||||
name = "Hierophant"
|
||||
desc = "Stolen from Hyper Light Drifter."
|
||||
health = 2500
|
||||
maxHealth = 2500
|
||||
attacktext = "clubs"
|
||||
//attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
attack_sound = "swing_hit"
|
||||
icon_state = "hierophant"
|
||||
icon_living = "hierophant"
|
||||
friendly = "stares down"
|
||||
icon = 'icons/mob/lavaland/hierophant.dmi'
|
||||
faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house
|
||||
speak_emote = list("preaches")
|
||||
armour_penetration = 50
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
speed = 1
|
||||
move_to_delay = 10
|
||||
ranged = 1
|
||||
pixel_x = -16
|
||||
ranged_cooldown_time = 40
|
||||
aggro_vision_range = 23
|
||||
loot = list(/obj/item/weapon/hierophant_staff)
|
||||
wander = FALSE
|
||||
var/burst_range = 3 //range on burst aoe
|
||||
var/beam_range = 5 //range on cross blast beams
|
||||
var/chaser_speed = 3 //how fast chasers are currently
|
||||
var/chaser_cooldown = 101 //base cooldown/cooldown var between spawning chasers
|
||||
var/major_attack_cooldown = 60 //base cooldown for major attacks
|
||||
var/blinking = FALSE //if we're doing something that requires us to stand still and not attack
|
||||
var/obj/effect/hierophant/spawned_rune //the rune we teleport back to
|
||||
var/timeout_time = 15 //after this many Life() ticks with no target, we return to our rune
|
||||
var/did_reset = TRUE //if we timed out, returned to our rune, and healed some
|
||||
//var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...")
|
||||
//var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.")
|
||||
medal_type = MEDAL_PREFIX
|
||||
score_type = BIRD_SCORE
|
||||
del_on_death = TRUE
|
||||
death_sound = 'sound/magic/Repulse.ogg'
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/New()
|
||||
..()
|
||||
internal = new/obj/item/device/gps/internal/hierophant(src)
|
||||
spawned_rune = new(loc)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/Life()
|
||||
. = ..()
|
||||
if(. && spawned_rune && !client)
|
||||
if(target || loc == spawned_rune.loc)
|
||||
timeout_time = initial(timeout_time)
|
||||
else
|
||||
timeout_time--
|
||||
if(timeout_time <= 0 && !did_reset)
|
||||
did_reset = TRUE
|
||||
//visible_message("<span class='hierophant'>\"Vixyvrmrk xs fewi...\"</span>")
|
||||
blink(spawned_rune)
|
||||
adjustHealth(max((health - maxHealth) * 0.5, 25)) //heal for 50% of our missing health
|
||||
wander = FALSE
|
||||
/*if(health > maxHealth * 0.9)
|
||||
visible_message("<span class='hierophant'>\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"</span>")
|
||||
else
|
||||
visible_message("<span class='hierophant'>\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"</span>")*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/death()
|
||||
if(health > 0 || stat == DEAD)
|
||||
return
|
||||
else
|
||||
stat = DEAD
|
||||
blinking = TRUE //we do a fancy animation, release a huge burst(), and leave our staff.
|
||||
animate(src, alpha = 0, color = "660099", time = 20, easing = EASE_OUT)
|
||||
burst_range = 10
|
||||
//visible_message("<span class='hierophant'>\"Mrmxmexmrk wipj-hiwxvygx wiuyirgi...\"</span>")
|
||||
visible_message("<span class='hierophant_warning'>[src] disappears in a massive burst of magic, leaving only its staff.</span>")
|
||||
burst(get_turf(src))
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
|
||||
qdel(spawned_rune)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
|
||||
for(var/obj/item/W in L)
|
||||
if(!L.unEquip(W))
|
||||
qdel(W)
|
||||
/*visible_message(
|
||||
"<span class='hierophant'>\"[pick(kill_phrases)]\"</span>\n<span class='hierophant_warning'>[src] annihilates [L]!</span>",
|
||||
"<span class='userdanger'>You annihilate [L], restoring your health!</span>")*/
|
||||
visible_message(
|
||||
"<span class='hierophant'>\"Caw.\"</span>\n<span class='hierophant_warning'>[src] annihilates [L]!</span>",
|
||||
"<span class='userdanger'>You annihilate [L], restoring your health!</span>")
|
||||
adjustHealth(-L.maxHealth*0.5)
|
||||
L.dust()
|
||||
|
||||
/*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target)
|
||||
var/targets_the_same = (new_target == target)
|
||||
. = ..()
|
||||
if(. && target && !targets_the_same)
|
||||
visible_message("<span class='hierophant'>\"[pick(target_phrases)]\"</span>")*/
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount)
|
||||
. = ..()
|
||||
if(src && amount > 0 && !blinking)
|
||||
wander = TRUE
|
||||
did_reset = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/AttackingTarget()
|
||||
if(!blinking)
|
||||
if(target && isliving(target))
|
||||
addtimer(src, "melee_blast", 0, FALSE, get_turf(target)) //melee attacks on living mobs produce a 3x3 blast
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings()
|
||||
if(!blinking)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/Move()
|
||||
if(!blinking)
|
||||
/*if(!stat)
|
||||
playsound(loc, 'sound/mecha/mechmove04.ogg', 150, 1, -4)*/
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/Goto(target, delay, minimum_distance)
|
||||
wander = TRUE
|
||||
if(!blinking)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall
|
||||
did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall
|
||||
anger_modifier = Clamp(((maxHealth - health) / 42),0,50)
|
||||
burst_range = initial(burst_range) + round(anger_modifier * 0.08)
|
||||
beam_range = initial(beam_range) + round(anger_modifier * 0.12)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire()
|
||||
calculate_rage()
|
||||
var/target_is_slow = FALSE
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!blinking && L.stat == DEAD && get_dist(src, L) > 2)
|
||||
blink(L)
|
||||
return
|
||||
if(L.movement_delay() > 1.5)
|
||||
target_is_slow = TRUE
|
||||
chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5)
|
||||
if(blinking)
|
||||
return
|
||||
ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger.
|
||||
|
||||
if(prob(anger_modifier * 0.75)) //major ranged attack
|
||||
var/list/possibilities = list()
|
||||
var/cross_counter = 1 + round(anger_modifier * 0.12)
|
||||
if(cross_counter > 1)
|
||||
possibilities += "cross_blast_spam"
|
||||
if(get_dist(src, target) > 2)
|
||||
possibilities += "blink_spam"
|
||||
if(chaser_cooldown < world.time)
|
||||
if(prob(anger_modifier * 2))
|
||||
possibilities = list("chaser_swarm")
|
||||
else
|
||||
possibilities += "chaser_swarm"
|
||||
if(possibilities.len)
|
||||
ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) //we didn't cancel out of an attack, use the higher cooldown
|
||||
var/blink_counter = 1 + round(anger_modifier * 0.08)
|
||||
switch(pick(possibilities))
|
||||
if("blink_spam") //blink either once or multiple times.
|
||||
if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1)
|
||||
//visible_message("<span class='hierophant'>\"Mx ampp rsx iwgeti.\"</span>")
|
||||
animate(src, color = "#660099", time = 6)
|
||||
while(health && target && blink_counter)
|
||||
if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now
|
||||
break
|
||||
blink_counter--
|
||||
blinking = FALSE
|
||||
blink(target)
|
||||
blinking = TRUE
|
||||
sleep(5)
|
||||
animate(src, color = initial(color), time = 8)
|
||||
sleep(8)
|
||||
blinking = FALSE
|
||||
else
|
||||
blink(target)
|
||||
if("cross_blast_spam") //fire a lot of cross blasts at a target.
|
||||
//visible_message("<span class='hierophant'>\"Piezi mx rsalivi xs vyr.\"</span>")
|
||||
blinking = TRUE
|
||||
animate(src, color = "#660099", time = 6)
|
||||
while(health && target && cross_counter)
|
||||
cross_counter--
|
||||
var/delay = 6
|
||||
if(prob(60))
|
||||
addtimer(src, "cardinal_blasts", 0, FALSE, target)
|
||||
else
|
||||
addtimer(src, "diagonal_blasts", 0, FALSE, target)
|
||||
delay = 5 //this one isn't so mean, so do the next one faster(if there is one)
|
||||
sleep(delay)
|
||||
animate(src, color = initial(color), time = 8)
|
||||
sleep(8)
|
||||
blinking = FALSE
|
||||
if("chaser_swarm") //fire four fucking chasers at a target and their friends.
|
||||
//visible_message("<span class='hierophant'>\"Mx gerrsx lmhi.\"</span>")
|
||||
blinking = TRUE
|
||||
animate(src, color = "#660099", time = 10)
|
||||
var/list/targets = ListTargets()
|
||||
var/list/cardinal_copy = cardinal.Copy()
|
||||
while(health && targets.len && cardinal_copy.len)
|
||||
var/mob/living/pickedtarget = pick(targets)
|
||||
if(targets.len > 4)
|
||||
pickedtarget = pick_n_take(targets)
|
||||
if(pickedtarget.stat == DEAD)
|
||||
pickedtarget = target
|
||||
var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, pickedtarget, chaser_speed, FALSE))
|
||||
C.moving = 3
|
||||
C.moving_dir = pick_n_take(cardinal_copy)
|
||||
sleep(10)
|
||||
chaser_cooldown = world.time + initial(chaser_cooldown)
|
||||
animate(src, color = initial(color), time = 8)
|
||||
sleep(8)
|
||||
blinking = FALSE
|
||||
return
|
||||
|
||||
if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2)
|
||||
blink(target)
|
||||
|
||||
else if(prob(70 - anger_modifier)) //a cross blast of some type
|
||||
if(prob(anger_modifier)) //at us?
|
||||
if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs
|
||||
addtimer(src, "alldir_blasts", 0, FALSE, src)
|
||||
else if(prob(60))
|
||||
addtimer(src, "cardinal_blasts", 0, FALSE, src)
|
||||
else
|
||||
addtimer(src, "diagonal_blasts", 0, FALSE, src)
|
||||
else //at them?
|
||||
if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs
|
||||
addtimer(src, "alldir_blasts", 0, FALSE, target)
|
||||
else if(prob(60))
|
||||
addtimer(src, "cardinal_blasts", 0, FALSE, target)
|
||||
else
|
||||
addtimer(src, "diagonal_blasts", 0, FALSE, target)
|
||||
else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some!
|
||||
var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, chaser_speed, FALSE))
|
||||
chaser_cooldown = world.time + initial(chaser_cooldown)
|
||||
if((prob(anger_modifier) || target.Adjacent(src)) && target != src)
|
||||
var/obj/effect/overlay/temp/hierophant/chaser/OC = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE))
|
||||
OC.moving = 4
|
||||
OC.moving_dir = pick(cardinal - C.moving_dir)
|
||||
else //just release a burst of power
|
||||
addtimer(src, "burst", 0, FALSE, get_turf(src))
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/diagonal_blasts(mob/victim) //fire diagonal cross blasts with a delay
|
||||
var/turf/T = get_turf(victim)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/diagonal, list(T, src))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
|
||||
for(var/d in diagonals)
|
||||
addtimer(src, "blast_wall", 0, FALSE, T, d)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cardinal_blasts(mob/victim) //fire cardinal cross blasts with a delay
|
||||
var/turf/T = get_turf(victim)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, src))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
|
||||
for(var/d in cardinal)
|
||||
addtimer(src, "blast_wall", 0, FALSE, T, d)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/alldir_blasts(mob/victim) //fire alldir cross blasts with a delay
|
||||
var/turf/T = get_turf(victim)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
|
||||
for(var/d in alldirs)
|
||||
addtimer(src, "blast_wall", 0, FALSE, T, d)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blast_wall(turf/T, dir) //make a wall of blasts beam_range tiles long
|
||||
var/range = beam_range
|
||||
var/turf/previousturf = T
|
||||
var/turf/J = get_step(previousturf, dir)
|
||||
for(var/i in 1 to range)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, src, FALSE))
|
||||
previousturf = J
|
||||
J = get_step(previousturf, dir)
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blink(mob/victim) //blink to a target
|
||||
if(blinking || !victim)
|
||||
return
|
||||
var/turf/T = get_turf(victim)
|
||||
var/turf/source = get_turf(src)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, src))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
|
||||
playsound(source,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
|
||||
blinking = TRUE
|
||||
sleep(2) //short delay before we start...
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, src))
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, src))
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
|
||||
B.damage = 30
|
||||
for(var/t in RANGE_TURFS(1, source))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
|
||||
B.damage = 30
|
||||
animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out
|
||||
sleep(1)
|
||||
visible_message("<span class='hierophant_warning'>[src] fades out!</span>")
|
||||
density = FALSE
|
||||
sleep(2)
|
||||
forceMove(T)
|
||||
sleep(1)
|
||||
animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN
|
||||
sleep(1)
|
||||
density = TRUE
|
||||
visible_message("<span class='hierophant_warning'>[src] fades in!</span>")
|
||||
sleep(1) //at this point the blasts we made detonate
|
||||
blinking = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/melee_blast(mob/victim) //make a 3x3 blast around a target
|
||||
if(!victim)
|
||||
return
|
||||
var/turf/T = get_turf(victim)
|
||||
if(!T)
|
||||
return
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original) //release a wave of blasts
|
||||
playsound(original,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(original,'sound/machines/AirlockOpen.ogg', 200, 1)
|
||||
var/last_dist = 0
|
||||
for(var/t in spiral_range_turfs(burst_range, original))
|
||||
var/turf/T = t
|
||||
if(!T)
|
||||
continue
|
||||
var/dist = get_dist(original, T)
|
||||
if(dist > last_dist)
|
||||
last_dist = dist
|
||||
sleep(1 + (burst_range - last_dist) * 0.5) //gets faster as it gets further out
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck)
|
||||
if(!istype(A) || get_dist(A, src) <= 2)
|
||||
return
|
||||
blink(A)
|
||||
|
||||
//Hierophant overlays
|
||||
/obj/effect/overlay/temp/hierophant
|
||||
layer = BELOW_MOB_LAYER
|
||||
var/mob/living/caster //who made this, anyway
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/New(loc, new_caster)
|
||||
..()
|
||||
if(new_caster)
|
||||
caster = new_caster
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds.
|
||||
duration = 98
|
||||
var/mob/living/target //what it's following
|
||||
var/moving_dir //what dir it's moving in
|
||||
var/previous_moving_dir //what dir it was moving in before that
|
||||
var/more_previouser_moving_dir //what dir it was moving in before THAT
|
||||
var/moving = 0 //how many steps to move before recalculating
|
||||
var/standard_moving_before_recalc = 4 //how many times we step before recalculating normally
|
||||
var/tiles_per_step = 1 //how many tiles we move each step
|
||||
var/speed = 3 //how many deciseconds between each step
|
||||
var/currently_seeking = FALSE
|
||||
var/friendly_fire_check = FALSE //if blasts produced apply friendly fire
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/chaser/New(loc, new_caster, new_target, new_speed, is_friendly_fire)
|
||||
..()
|
||||
target = new_target
|
||||
friendly_fire_check = is_friendly_fire
|
||||
if(new_speed)
|
||||
speed = new_speed
|
||||
addtimer(src, "seek_target", 1)
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/chaser/proc/get_target_dir()
|
||||
. = get_cardinal_dir(src, target)
|
||||
if((. != previous_moving_dir && . == more_previouser_moving_dir) || . == 0) //we're alternating, recalculate
|
||||
var/list/cardinal_copy = cardinal.Copy()
|
||||
cardinal_copy -= more_previouser_moving_dir
|
||||
. = pick(cardinal_copy)
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/chaser/proc/seek_target()
|
||||
if(!currently_seeking)
|
||||
currently_seeking = TRUE
|
||||
while(target && src && !qdeleted(src) && currently_seeking && x && y && target.x && target.y) //can this target actually be sook out
|
||||
if(!moving) //we're out of tiles to move, find more and where the target is!
|
||||
more_previouser_moving_dir = previous_moving_dir
|
||||
previous_moving_dir = moving_dir
|
||||
moving_dir = get_target_dir()
|
||||
var/standard_target_dir = get_cardinal_dir(src, target)
|
||||
if((standard_target_dir != previous_moving_dir && standard_target_dir == more_previouser_moving_dir) || standard_target_dir == 0)
|
||||
moving = 1 //we would be repeating, only move a tile before checking
|
||||
else
|
||||
moving = standard_moving_before_recalc
|
||||
if(moving) //move in the dir we're moving in right now
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/i in 1 to tiles_per_step)
|
||||
var/maybe_new_turf = get_step(T, moving_dir)
|
||||
if(maybe_new_turf)
|
||||
T = maybe_new_turf
|
||||
else
|
||||
break
|
||||
forceMove(T)
|
||||
make_blast() //make a blast, too
|
||||
moving--
|
||||
sleep(speed)
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/chaser/proc/make_blast()
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(loc, caster, friendly_fire_check))
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/telegraph
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "hierophant_telegraph"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 3
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/telegraph/diagonal
|
||||
icon_state = "hierophant_telegraph_diagonal"
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/telegraph/cardinal
|
||||
icon_state = "hierophant_telegraph_cardinal"
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/telegraph/teleport
|
||||
icon_state = "hierophant_telegraph_teleport"
|
||||
duration = 9
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/blast
|
||||
icon_state = "hierophant_blast"
|
||||
name = "vortex blast"
|
||||
luminosity = 1
|
||||
desc = "Get out of the way!"
|
||||
duration = 9
|
||||
var/damage = 10 //how much damage do we do?
|
||||
var/list/hit_things = list() //we hit these already, ignore them
|
||||
var/friendly_fire_check = FALSE
|
||||
var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/blast/New(loc, new_caster, friendly_fire)
|
||||
..()
|
||||
friendly_fire_check = friendly_fire
|
||||
if(new_caster)
|
||||
hit_things += new_caster
|
||||
if(istype(loc, /turf/closed/mineral)) //drill mineral turfs
|
||||
var/turf/closed/mineral/M = loc
|
||||
M.gets_drilled(caster)
|
||||
addtimer(src, "blast", 0)
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/blast/proc/blast()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return
|
||||
playsound(T,'sound/magic/Blind.ogg', 125, 1, -5) //make a sound
|
||||
sleep(6) //wait a little
|
||||
bursting = TRUE
|
||||
do_damage(T) //do damage and mark us as bursting
|
||||
sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds
|
||||
bursting = FALSE //we no longer damage crossers
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/blast/Crossed(atom/movable/AM)
|
||||
..()
|
||||
if(bursting)
|
||||
do_damage(get_turf(src))
|
||||
|
||||
/obj/effect/overlay/temp/hierophant/blast/proc/do_damage(turf/T)
|
||||
for(var/mob/living/L in T.contents - hit_things) //find and damage mobs...
|
||||
hit_things += L
|
||||
if((friendly_fire_check && caster && caster.faction_check(L)) || L.stat == DEAD)
|
||||
continue
|
||||
if(L.client)
|
||||
flash_color(L.client, "#660099", 1)
|
||||
playsound(L,'sound/weapons/sear.ogg', 50, 1, -4)
|
||||
L << "<span class='userdanger'>You're struck by a [name]!</span>"
|
||||
var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
|
||||
var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
|
||||
L.apply_damage(damage, BURN, limb_to_hit, armor)
|
||||
if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))
|
||||
L.adjustBruteLoss(damage)
|
||||
add_logs(caster, L, "struck with a [name]")
|
||||
for(var/obj/mecha/M in T.contents - hit_things) //and mechs.
|
||||
hit_things += M
|
||||
if(M.occupant)
|
||||
if(friendly_fire_check && caster && caster.faction_check(M.occupant))
|
||||
continue
|
||||
M.occupant << "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>"
|
||||
playsound(M,'sound/weapons/sear.ogg', 50, 1, -4)
|
||||
M.take_damage(damage, "fire", 0)
|
||||
|
||||
/obj/effect/hierophant
|
||||
name = "hierophant rune"
|
||||
desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will."
|
||||
icon = 'icons/obj/rune.dmi'
|
||||
icon_state = "hierophant"
|
||||
layer = LOW_OBJ_LAYER
|
||||
anchored = TRUE
|
||||
color = "#CC00FF"
|
||||
|
||||
/obj/effect/hierophant/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/hierophant_staff))
|
||||
var/obj/item/weapon/hierophant_staff/H = I
|
||||
if(H.rune == src)
|
||||
user << "<span class='notice'>You start removing your hierophant rune...</span>"
|
||||
H.timer = world.time + 51
|
||||
if(do_after(user, 50, target = src))
|
||||
playsound(src,'sound/magic/Blind.ogg', 200, 1, -4)
|
||||
PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(get_turf(src), user))
|
||||
user << "<span class='hierophant_warning'>You touch the rune with the staff, dispelling it!</span>"
|
||||
H.rune = null
|
||||
user.update_action_buttons_icon()
|
||||
qdel(src)
|
||||
else
|
||||
H.timer = world.time
|
||||
else
|
||||
user << "<span class='hierophant_warning'>You touch the rune with the staff, but nothing happens.</span>"
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/gps/internal/hierophant
|
||||
icon_state = null
|
||||
gpstag = "Zealous Signal"
|
||||
desc = "Heed its words."
|
||||
invisibility = 100
|
||||
|
||||
/turf/open/indestructible/hierophant
|
||||
icon_state = "hierophant1"
|
||||
initial_gas_mix = "o2=14;n2=23;TEMP=300"
|
||||
desc = "A floor with a square pattern. It's faintly cool to the touch."
|
||||
|
||||
/turf/open/indestructible/hierophant/New()
|
||||
..()
|
||||
if(prob(50))
|
||||
icon_state = "hierophant2"
|
||||
|
||||
/turf/closed/indestructible/riveted/hierophant
|
||||
name = "wall"
|
||||
desc = "A wall made out of smooth, cold stone."
|
||||
icon = 'icons/turf/walls/hierophant_wall.dmi'
|
||||
icon_state = "hierophant"
|
||||
smooth = SMOOTH_TRUE
|
||||
|
||||
#undef MEDAL_PREFIX
|
||||
@@ -110,6 +110,8 @@ Difficulty: Medium
|
||||
L.update_transform()
|
||||
update_transform()
|
||||
|
||||
L.faction = faction.Copy()
|
||||
|
||||
L.GiveTarget(target)
|
||||
|
||||
visible_message("<span class='boldannounce'>[src] splits in twain!</span>")
|
||||
|
||||
@@ -223,9 +223,8 @@
|
||||
A.admin_spawned = admin_spawned
|
||||
A.GiveTarget(target)
|
||||
A.friends = friends
|
||||
A.faction = faction
|
||||
A.faction = faction.Copy()
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget()
|
||||
OpenFire()
|
||||
@@ -733,6 +732,7 @@
|
||||
speak_emote = list("telepathically cries")
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
stat_attack = 1
|
||||
flying = TRUE
|
||||
robust_searching = 1
|
||||
loot = list()
|
||||
butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
|
||||
|
||||
@@ -303,9 +303,6 @@
|
||||
break
|
||||
. = dense_object_backup
|
||||
|
||||
/mob/proc/mob_has_gravity(turf/T)
|
||||
return has_gravity(src, T)
|
||||
|
||||
/mob/proc/mob_negates_gravity()
|
||||
return 0
|
||||
|
||||
|
||||
@@ -372,7 +372,7 @@ var/const/GRAV_NEEDS_WRENCH = 3
|
||||
for(var/mob/M in mob_list)
|
||||
if(M.z != z)
|
||||
continue
|
||||
M.update_gravity(M.mob_has_gravity())
|
||||
M.update_gravity(M.has_gravity())
|
||||
if(M.client)
|
||||
shake_camera(M, 15, 1)
|
||||
M.playsound_local(T, 'sound/effects/alert.ogg', 100, 1, 0.5)
|
||||
|
||||
@@ -177,14 +177,15 @@
|
||||
icon_state = "purple_laser"
|
||||
var/chain
|
||||
|
||||
/obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
/obj/item/projectile/energy/shock_revolver/fire(setAngle)
|
||||
if(firer)
|
||||
chain = Beam(firer, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = INFINITY, maxdistance = INFINITY)
|
||||
..()
|
||||
var/obj/item/projectile/hook/P = BB
|
||||
spawn(1)
|
||||
P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30)
|
||||
|
||||
/obj/item/projectile/energy/shock_revolver/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
tesla_zap(src, 3, 10000)
|
||||
|
||||
/obj/item/projectile/energy/shock_revolver/Destroy()
|
||||
qdel(chain)
|
||||
|
||||
@@ -12,7 +12,7 @@ var/const/INJECT = 5 //injection
|
||||
var/list/datum/reagent/reagent_list = new/list()
|
||||
var/total_volume = 0
|
||||
var/maximum_volume = 100
|
||||
var/atom/my_atom = null
|
||||
var/datum/my_atom = null
|
||||
var/chem_temp = 150
|
||||
var/last_tick = 1
|
||||
var/addiction_tick = 1
|
||||
@@ -61,30 +61,32 @@ var/const/INJECT = 5 //injection
|
||||
/datum/reagents/Destroy()
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
qdel(R)
|
||||
reagent_list.Cut()
|
||||
reagent_list = null
|
||||
cached_reagents.Cut()
|
||||
cached_reagents = null
|
||||
if(my_atom && my_atom.reagents == src)
|
||||
my_atom.reagents = null
|
||||
|
||||
/datum/reagents/proc/remove_any(amount = 1)
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/total_transfered = 0
|
||||
var/current_list_element = 1
|
||||
|
||||
current_list_element = rand(1, reagent_list.len)
|
||||
current_list_element = rand(1, cached_reagents.len)
|
||||
|
||||
while(total_transfered != amount)
|
||||
if(total_transfered >= amount)
|
||||
break
|
||||
if(total_volume <= 0 || !reagent_list.len)
|
||||
if(total_volume <= 0 || !cached_reagents.len)
|
||||
break
|
||||
|
||||
if(current_list_element > reagent_list.len)
|
||||
if(current_list_element > cached_reagents.len)
|
||||
current_list_element = 1
|
||||
|
||||
var/datum/reagent/R = reagent_list[current_list_element]
|
||||
var/datum/reagent/R = cached_reagents[current_list_element]
|
||||
remove_reagent(R.id, 1)
|
||||
|
||||
current_list_element++
|
||||
@@ -95,9 +97,10 @@ var/const/INJECT = 5 //injection
|
||||
return total_transfered
|
||||
|
||||
/datum/reagents/proc/remove_all(amount = 1)
|
||||
var/list/cached_reagents = reagent_list
|
||||
if(total_volume > 0)
|
||||
var/part = amount / total_volume
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
remove_reagent(R.id, R.volume * part)
|
||||
|
||||
@@ -106,9 +109,10 @@ var/const/INJECT = 5 //injection
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/get_master_reagent_name()
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/name
|
||||
var/max_volume = 0
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
if(R.volume > max_volume)
|
||||
max_volume = R.volume
|
||||
@@ -117,9 +121,10 @@ var/const/INJECT = 5 //injection
|
||||
return name
|
||||
|
||||
/datum/reagents/proc/get_master_reagent_id()
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/id
|
||||
var/max_volume = 0
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
if(R.volume > max_volume)
|
||||
max_volume = R.volume
|
||||
@@ -128,6 +133,8 @@ var/const/INJECT = 5 //injection
|
||||
return id
|
||||
|
||||
/datum/reagents/proc/trans_to(obj/target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
|
||||
var/list/cached_reagents = reagent_list
|
||||
|
||||
if(!target || !total_volume)
|
||||
return
|
||||
var/datum/reagents/R
|
||||
@@ -140,7 +147,7 @@ var/const/INJECT = 5 //injection
|
||||
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
|
||||
var/part = amount / src.total_volume
|
||||
var/trans_data = null
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/T = reagent
|
||||
var/transfer_amount = T.volume * part
|
||||
if(preserve_data)
|
||||
@@ -156,6 +163,7 @@ var/const/INJECT = 5 //injection
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1)
|
||||
var/list/cached_reagents = reagent_list
|
||||
if(!target)
|
||||
return
|
||||
if(!target.reagents || src.total_volume<=0)
|
||||
@@ -164,7 +172,7 @@ var/const/INJECT = 5 //injection
|
||||
amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume)
|
||||
var/part = amount / total_volume
|
||||
var/trans_data = null
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/T = reagent
|
||||
var/copy_amount = T.volume * part
|
||||
if(preserve_data)
|
||||
@@ -178,6 +186,7 @@ var/const/INJECT = 5 //injection
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
|
||||
var/list/cached_reagents = reagent_list
|
||||
if (!target)
|
||||
return
|
||||
if (!target.reagents || src.total_volume<=0 || !src.get_reagent_amount(reagent))
|
||||
@@ -188,58 +197,28 @@ var/const/INJECT = 5 //injection
|
||||
amount = src.get_reagent_amount(reagent)
|
||||
amount = min(amount, R.maximum_volume-R.total_volume)
|
||||
var/trans_data = null
|
||||
for (var/datum/reagent/current_reagent in src.reagent_list)
|
||||
for (var/CR in cached_reagents)
|
||||
var/datum/reagent/current_reagent = CR
|
||||
if(current_reagent.id == reagent)
|
||||
if(preserve_data)
|
||||
trans_data = current_reagent.data
|
||||
R.add_reagent(current_reagent.id, amount, trans_data, src.chem_temp)
|
||||
src.remove_reagent(current_reagent.id, amount, 1)
|
||||
remove_reagent(current_reagent.id, amount, 1)
|
||||
break
|
||||
|
||||
src.update_total()
|
||||
R.update_total()
|
||||
R.handle_reactions()
|
||||
//src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating and) transferring a specific reagent.
|
||||
return amount
|
||||
|
||||
/*
|
||||
if (!target) return
|
||||
var/total_transfered = 0
|
||||
var/current_list_element = 1
|
||||
var/datum/reagents/R = target.reagents
|
||||
var/trans_data = null
|
||||
//if(R.total_volume + amount > R.maximum_volume) return 0
|
||||
|
||||
current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix.
|
||||
|
||||
while(total_transfered != amount)
|
||||
if(total_transfered >= amount) break //Better safe than sorry.
|
||||
if(total_volume <= 0 || !reagent_list.len) break
|
||||
if(R.total_volume >= R.maximum_volume) break
|
||||
|
||||
if(current_list_element > reagent_list.len) current_list_element = 1
|
||||
var/datum/reagent/current_reagent = reagent_list[current_list_element]
|
||||
if(preserve_data)
|
||||
trans_data = current_reagent.data
|
||||
R.add_reagent(current_reagent.id, (1 * multiplier), trans_data)
|
||||
src.remove_reagent(current_reagent.id, 1)
|
||||
|
||||
current_list_element++
|
||||
total_transfered++
|
||||
src.update_total()
|
||||
R.update_total()
|
||||
R.handle_reactions()
|
||||
handle_reactions()
|
||||
|
||||
return total_transfered
|
||||
*/
|
||||
|
||||
/datum/reagents/proc/metabolize(mob/living/carbon/C, can_overdose = 0)
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/list/cached_addictions = addiction_list
|
||||
if(C)
|
||||
chem_temp = C.bodytemperature
|
||||
handle_reactions()
|
||||
var/need_mob_update = 0
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
if(!R.holder)
|
||||
continue
|
||||
@@ -253,13 +232,13 @@ var/const/INJECT = 5 //injection
|
||||
R.overdosed = 1
|
||||
need_mob_update += R.overdose_start(C)
|
||||
if(R.addiction_threshold)
|
||||
if(R.volume >= R.addiction_threshold && !is_type_in_list(R, addiction_list))
|
||||
if(R.volume >= R.addiction_threshold && !is_type_in_list(R, cached_addictions))
|
||||
var/datum/reagent/new_reagent = new R.type()
|
||||
addiction_list.Add(new_reagent)
|
||||
cached_addictions.Add(new_reagent)
|
||||
if(R.overdosed)
|
||||
need_mob_update += R.overdose_process(C)
|
||||
if(is_type_in_list(R,addiction_list))
|
||||
for(var/addiction in addiction_list)
|
||||
if(is_type_in_list(R,cached_addictions))
|
||||
for(var/addiction in cached_addictions)
|
||||
var/datum/reagent/A = addiction
|
||||
if(istype(R, A))
|
||||
A.addiction_stage = -15 // you're satisfied for a good while.
|
||||
@@ -268,7 +247,7 @@ var/const/INJECT = 5 //injection
|
||||
if(can_overdose)
|
||||
if(addiction_tick == 6)
|
||||
addiction_tick = 1
|
||||
for(var/addiction in addiction_list)
|
||||
for(var/addiction in cached_addictions)
|
||||
var/datum/reagent/R = addiction
|
||||
if(C && R)
|
||||
R.addiction_stage++
|
||||
@@ -283,7 +262,7 @@ var/const/INJECT = 5 //injection
|
||||
need_mob_update += R.addiction_act_stage4(C)
|
||||
if(40 to INFINITY)
|
||||
C << "<span class='notice'>You feel like you've gotten over your need for [R.name].</span>"
|
||||
addiction_list.Remove(R)
|
||||
cached_addictions.Remove(R)
|
||||
addiction_tick++
|
||||
if(C && need_mob_update) //some of the metabolized reagents had effects on the mob that requires some updates.
|
||||
C.updatehealth()
|
||||
@@ -292,11 +271,12 @@ var/const/INJECT = 5 //injection
|
||||
update_total()
|
||||
|
||||
/datum/reagents/process()
|
||||
var/list/cached_reagents = reagent_list
|
||||
if(flags & REAGENT_NOREACT)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
R.on_tick()
|
||||
|
||||
@@ -311,34 +291,41 @@ var/const/INJECT = 5 //injection
|
||||
flags |= REAGENT_NOREACT
|
||||
|
||||
/datum/reagents/proc/conditional_update_move(atom/A, Running = 0)
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
R.on_move (A, Running)
|
||||
update_total()
|
||||
|
||||
/datum/reagents/proc/conditional_update(atom/A)
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
R.on_update (A)
|
||||
update_total()
|
||||
|
||||
/datum/reagents/proc/handle_reactions()
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/list/cached_reactions = chemical_reactions_list
|
||||
var/datum/cached_my_atom = my_atom
|
||||
if(flags & REAGENT_NOREACT)
|
||||
return //Yup, no reactions here. No siree.
|
||||
|
||||
var/reaction_occured = 0
|
||||
do
|
||||
reaction_occured = 0
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
for(var/reaction in chemical_reactions_list[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
|
||||
for(var/reaction in cached_reactions[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
|
||||
if(!reaction)
|
||||
continue
|
||||
|
||||
var/datum/chemical_reaction/C = reaction
|
||||
var/total_required_reagents = C.required_reagents.len
|
||||
var/list/cached_required_reagents = C.required_reagents
|
||||
var/total_required_reagents = cached_required_reagents.len
|
||||
var/total_matching_reagents = 0
|
||||
var/total_required_catalysts = C.required_catalysts.len
|
||||
var/list/cached_required_catalysts = C.required_catalysts
|
||||
var/total_required_catalysts = cached_required_catalysts.len
|
||||
var/total_matching_catalysts= 0
|
||||
var/matching_container = 0
|
||||
var/matching_other = 0
|
||||
@@ -347,32 +334,39 @@ var/const/INJECT = 5 //injection
|
||||
var/is_cold_recipe = C.is_cold_recipe
|
||||
var/meets_temp_requirement = 0
|
||||
|
||||
for(var/B in C.required_reagents)
|
||||
if(!has_reagent(B, C.required_reagents[B]))
|
||||
var/list/cached_results = C.results
|
||||
|
||||
for(var/B in cached_required_reagents)
|
||||
if(!has_reagent(B, cached_required_reagents[B]))
|
||||
break
|
||||
total_matching_reagents++
|
||||
multipliers += round(get_reagent_amount(B) / C.required_reagents[B])
|
||||
for(var/B in C.required_catalysts)
|
||||
if(!has_reagent(B, C.required_catalysts[B]))
|
||||
multipliers += round(get_reagent_amount(B) / cached_required_reagents[B])
|
||||
for(var/B in cached_required_catalysts)
|
||||
if(!has_reagent(B, cached_required_catalysts[B]))
|
||||
break
|
||||
total_matching_catalysts++
|
||||
|
||||
if(!C.required_container)
|
||||
matching_container = 1
|
||||
|
||||
else
|
||||
if(my_atom.type == C.required_container)
|
||||
if(cached_my_atom)
|
||||
if(!C.required_container)
|
||||
matching_container = 1
|
||||
if (isliving(my_atom)) //Makes it so certain chemical reactions don't occur in mobs
|
||||
if (C.mob_react)
|
||||
return
|
||||
if(!C.required_other)
|
||||
matching_other = 1
|
||||
|
||||
else if(istype(my_atom, /obj/item/slime_extract))
|
||||
var/obj/item/slime_extract/M = my_atom
|
||||
else
|
||||
if(cached_my_atom.type == C.required_container)
|
||||
matching_container = 1
|
||||
if (isliving(cached_my_atom)) //Makes it so certain chemical reactions don't occur in mobs
|
||||
if (C.mob_react)
|
||||
return
|
||||
if(!C.required_other)
|
||||
matching_other = 1
|
||||
|
||||
if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
|
||||
else if(istype(cached_my_atom, /obj/item/slime_extract))
|
||||
var/obj/item/slime_extract/M = cached_my_atom
|
||||
|
||||
if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
|
||||
matching_other = 1
|
||||
else
|
||||
if(!C.required_container)
|
||||
matching_container = 1
|
||||
if(!C.required_other)
|
||||
matching_other = 1
|
||||
|
||||
if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp))
|
||||
@@ -380,30 +374,30 @@ var/const/INJECT = 5 //injection
|
||||
|
||||
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && meets_temp_requirement)
|
||||
var/multiplier = min(multipliers)
|
||||
for(var/B in C.required_reagents)
|
||||
remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1)
|
||||
for(var/B in cached_required_reagents)
|
||||
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1)
|
||||
|
||||
for(var/P in C.results)
|
||||
feedback_add_details("chemical_reaction", "[P]|[C.results[P]*multiplier]")
|
||||
feedback_add_details("chemical_reaction", "[P]|[cached_results[P]*multiplier]")
|
||||
multiplier = max(multiplier, 1) //this shouldnt happen ...
|
||||
add_reagent(P, C.results[P]*multiplier, null, chem_temp)
|
||||
add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
|
||||
|
||||
var/list/seen = viewers(4, get_turf(my_atom))
|
||||
|
||||
if(!istype(my_atom, /mob)) // No bubbling mobs
|
||||
if(C.mix_sound)
|
||||
playsound(get_turf(my_atom), C.mix_sound, 80, 1)
|
||||
for(var/mob/M in seen)
|
||||
M << "<span class='notice'>\icon[my_atom] [C.mix_message]</span>"
|
||||
|
||||
if(istype(my_atom, /obj/item/slime_extract))
|
||||
var/obj/item/slime_extract/ME2 = my_atom
|
||||
ME2.Uses--
|
||||
if(ME2.Uses <= 0) // give the notification that the slime core is dead
|
||||
if(cached_my_atom)
|
||||
if(!ismob(cached_my_atom)) // No bubbling mobs
|
||||
if(C.mix_sound)
|
||||
playsound(get_turf(cached_my_atom), C.mix_sound, 80, 1)
|
||||
for(var/mob/M in seen)
|
||||
M << "<span class='notice'>\icon[my_atom] \The [my_atom]'s power is consumed in the reaction.</span>"
|
||||
ME2.name = "used slime extract"
|
||||
ME2.desc = "This extract has been used up."
|
||||
M << "<span class='notice'>\icon[my_atom] [C.mix_message]</span>"
|
||||
|
||||
if(istype(cached_my_atom, /obj/item/slime_extract))
|
||||
var/obj/item/slime_extract/ME2 = my_atom
|
||||
ME2.Uses--
|
||||
if(ME2.Uses <= 0) // give the notification that the slime core is dead
|
||||
for(var/mob/M in seen)
|
||||
M << "<span class='notice'>\icon[my_atom] \The [my_atom]'s power is consumed in the reaction.</span>"
|
||||
ME2.name = "used slime extract"
|
||||
ME2.desc = "This extract has been used up."
|
||||
|
||||
C.on_reaction(src, multiplier)
|
||||
reaction_occured = 1
|
||||
@@ -414,26 +408,29 @@ var/const/INJECT = 5 //injection
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/isolate_reagent(reagent)
|
||||
for(var/_reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
var/datum/reagent/R = _reagent
|
||||
if(R.id != reagent)
|
||||
del_reagent(R.id)
|
||||
update_total()
|
||||
|
||||
/datum/reagents/proc/del_reagent(reagent)
|
||||
for(var/_reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
var/datum/reagent/R = _reagent
|
||||
if(R.id == reagent)
|
||||
if(istype(my_atom, /mob/living))
|
||||
if(my_atom && istype(my_atom, /mob/living))
|
||||
var/mob/living/M = my_atom
|
||||
R.on_mob_delete(M)
|
||||
qdel(R)
|
||||
reagent_list -= R
|
||||
update_total()
|
||||
my_atom.on_reagent_change()
|
||||
check_ignoreslow(my_atom)
|
||||
check_gofast(my_atom)
|
||||
check_goreallyfast(my_atom)
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
check_ignoreslow(my_atom)
|
||||
check_gofast(my_atom)
|
||||
check_goreallyfast(my_atom)
|
||||
return 1
|
||||
|
||||
/datum/reagents/proc/check_ignoreslow(mob/M)
|
||||
@@ -458,8 +455,9 @@ var/const/INJECT = 5 //injection
|
||||
M.status_flags &= ~GOTTAGOREALLYFAST
|
||||
|
||||
/datum/reagents/proc/update_total()
|
||||
var/list/cached_reagents = reagent_list
|
||||
total_volume = 0
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
if(R.volume < 0.1)
|
||||
del_reagent(R.id)
|
||||
@@ -469,44 +467,54 @@ var/const/INJECT = 5 //injection
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/clear_reagents()
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
del_reagent(R.id)
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
|
||||
var/react_type
|
||||
if(isliving(A))
|
||||
var/touch_protection = 0
|
||||
if(method == VAPOR)
|
||||
var/mob/living/L = A
|
||||
touch_protection = L.get_permeability_protection()
|
||||
for(var/reagent in reagent_list)
|
||||
var/datum/reagent/R = reagent
|
||||
R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
|
||||
react_type = "LIVING"
|
||||
else if(isturf(A))
|
||||
for(var/reagent in reagent_list)
|
||||
var/datum/reagent/R = reagent
|
||||
R.reaction_turf(A, R.volume * volume_modifier, show_message)
|
||||
react_type = "TURF"
|
||||
else if(isobj(A))
|
||||
for(var/reagent in reagent_list)
|
||||
var/datum/reagent/R = reagent
|
||||
R.reaction_obj(A, R.volume * volume_modifier, show_message)
|
||||
react_type = "OBJ"
|
||||
else
|
||||
return
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
switch(react_type)
|
||||
if("LIVING")
|
||||
var/touch_protection = 0
|
||||
if(method == VAPOR)
|
||||
var/mob/living/L = A
|
||||
touch_protection = L.get_permeability_protection()
|
||||
R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
|
||||
if("TURF")
|
||||
R.reaction_turf(A, R.volume * volume_modifier, show_message)
|
||||
if("OBJ")
|
||||
R.reaction_obj(A, R.volume * volume_modifier, show_message)
|
||||
|
||||
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0)
|
||||
if(!isnum(amount) || !amount)
|
||||
return 1
|
||||
var/list/cached_reagents = reagent_list
|
||||
update_total()
|
||||
if(total_volume + amount > maximum_volume)
|
||||
amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen.
|
||||
chem_temp = round(((amount * reagtemp) + (total_volume * chem_temp)) / (total_volume + amount)) //equalize with new chems
|
||||
|
||||
for(var/A in reagent_list)
|
||||
for(var/A in cached_reagents)
|
||||
|
||||
var/datum/reagent/R = A
|
||||
if (R.id == reagent)
|
||||
R.volume += amount
|
||||
update_total()
|
||||
my_atom.on_reagent_change()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
R.on_merge(data)
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
@@ -516,7 +524,7 @@ var/const/INJECT = 5 //injection
|
||||
if(D)
|
||||
|
||||
var/datum/reagent/R = new D.type(data)
|
||||
reagent_list += R
|
||||
cached_reagents += R
|
||||
R.holder = src
|
||||
R.volume = amount
|
||||
if(data)
|
||||
@@ -524,7 +532,8 @@ var/const/INJECT = 5 //injection
|
||||
R.on_new(data)
|
||||
|
||||
update_total()
|
||||
my_atom.on_reagent_change()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
return 0
|
||||
@@ -549,20 +558,24 @@ var/const/INJECT = 5 //injection
|
||||
if(!isnum(amount))
|
||||
return 1
|
||||
|
||||
for(var/A in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
|
||||
for(var/A in cached_reagents)
|
||||
var/datum/reagent/R = A
|
||||
if (R.id == reagent)
|
||||
R.volume -= amount
|
||||
update_total()
|
||||
if(!safety)//So it does not handle reactions when it need not to
|
||||
handle_reactions()
|
||||
my_atom.on_reagent_change()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/datum/reagents/proc/has_reagent(reagent, amount = -1)
|
||||
for(var/_reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
var/datum/reagent/R = _reagent
|
||||
if (R.id == reagent)
|
||||
if(!amount)
|
||||
@@ -576,7 +589,8 @@ var/const/INJECT = 5 //injection
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/get_reagent_amount(reagent)
|
||||
for(var/_reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/_reagent in cached_reagents)
|
||||
var/datum/reagent/R = _reagent
|
||||
if (R.id == reagent)
|
||||
return R.volume
|
||||
@@ -585,7 +599,8 @@ var/const/INJECT = 5 //injection
|
||||
|
||||
/datum/reagents/proc/get_reagents()
|
||||
var/list/names = list()
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
names += R.name
|
||||
|
||||
@@ -593,10 +608,10 @@ var/const/INJECT = 5 //injection
|
||||
|
||||
/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
|
||||
if(!isnum(amount)) return 1
|
||||
|
||||
var/list/cached_reagents = reagent_list
|
||||
var/has_removed_reagent = 0
|
||||
|
||||
for(var/reagent in reagent_list)
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
var/matches = 0
|
||||
// Switch between how we check the reagent type
|
||||
@@ -615,14 +630,16 @@ var/const/INJECT = 5 //injection
|
||||
|
||||
//two helper functions to preserve data across reactions (needed for xenoarch)
|
||||
/datum/reagents/proc/get_data(reagent_id)
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
if(R.id == reagent_id)
|
||||
//world << "proffering a data-carrying reagent ([reagent_id])"
|
||||
return R.data
|
||||
|
||||
/datum/reagents/proc/set_data(reagent_id, new_data)
|
||||
for(var/reagent in reagent_list)
|
||||
var/list/cached_reagents = reagent_list
|
||||
for(var/reagent in cached_reagents)
|
||||
var/datum/reagent/R = reagent
|
||||
if(R.id == reagent_id)
|
||||
//world << "reagent data set ([reagent_id])"
|
||||
@@ -650,7 +667,8 @@ var/const/INJECT = 5 //injection
|
||||
return trans_data
|
||||
|
||||
/datum/reagents/proc/get_reagent(type)
|
||||
. = locate(type) in reagent_list
|
||||
var/list/cached_reagents = reagent_list
|
||||
. = locate(type) in cached_reagents
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -658,7 +676,7 @@ var/const/INJECT = 5 //injection
|
||||
|
||||
// Convenience proc to create a reagents holder for an atom
|
||||
// Max vol is maximum volume of holder
|
||||
/atom/proc/create_reagents(max_vol)
|
||||
/datum/proc/create_reagents(max_vol)
|
||||
if(reagents)
|
||||
qdel(reagents)
|
||||
reagents = new/datum/reagents(max_vol)
|
||||
|
||||
@@ -443,7 +443,7 @@
|
||||
/datum/reagent/oxygen
|
||||
name = "Oxygen"
|
||||
id = "oxygen"
|
||||
description = "A colorless, odorless gas."
|
||||
description = "A colorless, odorless gas. Grows on trees but is still pretty valuable."
|
||||
reagent_state = GAS
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
|
||||
@@ -460,14 +460,14 @@
|
||||
/datum/reagent/copper
|
||||
name = "Copper"
|
||||
id = "copper"
|
||||
description = "A highly ductile metal."
|
||||
description = "A highly ductile metal. Things made out of copper aren't very durable, but it makes a decent material for electrical wiring."
|
||||
reagent_state = SOLID
|
||||
color = "#6E3B08" // rgb: 110, 59, 8
|
||||
|
||||
/datum/reagent/nitrogen
|
||||
name = "Nitrogen"
|
||||
id = "nitrogen"
|
||||
description = "A colorless, odorless, tasteless gas."
|
||||
description = "A colorless, odorless, tasteless gas. A simple asphyxiant that can silently displace vital oxygen."
|
||||
reagent_state = GAS
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
|
||||
@@ -498,7 +498,7 @@
|
||||
/datum/reagent/mercury
|
||||
name = "Mercury"
|
||||
id = "mercury"
|
||||
description = "A chemical element."
|
||||
description = "A curious metal that's a liquid at room temperature. Neurodegenerative and very bad for the mind."
|
||||
color = "#484848" // rgb: 72, 72, 72
|
||||
|
||||
/datum/reagent/mercury/on_mob_life(mob/living/M)
|
||||
@@ -512,14 +512,14 @@
|
||||
/datum/reagent/sulfur
|
||||
name = "Sulfur"
|
||||
id = "sulfur"
|
||||
description = "A chemical element."
|
||||
description = "A sickly yellow solid mostly known for its nasty smell. It's actually much more helpful than it looks in biochemisty."
|
||||
reagent_state = SOLID
|
||||
color = "#BF8C00" // rgb: 191, 140, 0
|
||||
|
||||
/datum/reagent/carbon
|
||||
name = "Carbon"
|
||||
id = "carbon"
|
||||
description = "A chemical element."
|
||||
description = "A crumbly black solid that, while unexciting on an physical level, forms the base of all known life. Kind of a big deal."
|
||||
reagent_state = SOLID
|
||||
color = "#1C1300" // rgb: 30, 20, 0
|
||||
|
||||
@@ -532,7 +532,7 @@
|
||||
/datum/reagent/chlorine
|
||||
name = "Chlorine"
|
||||
id = "chlorine"
|
||||
description = "A chemical element."
|
||||
description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless."
|
||||
reagent_state = GAS
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
|
||||
@@ -544,7 +544,7 @@
|
||||
/datum/reagent/fluorine
|
||||
name = "Fluorine"
|
||||
id = "fluorine"
|
||||
description = "A highly-reactive chemical element."
|
||||
description = "A comically-reactive chemical element. The universe does not want this stuff to exist in this form in the slightest."
|
||||
reagent_state = GAS
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
|
||||
@@ -556,21 +556,21 @@
|
||||
/datum/reagent/sodium
|
||||
name = "Sodium"
|
||||
id = "sodium"
|
||||
description = "A chemical element."
|
||||
description = "A soft silver metal that can easily be cut with a knife. It's not salt just yet, so refrain from putting in on your chips."
|
||||
reagent_state = SOLID
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
|
||||
/datum/reagent/phosphorus
|
||||
name = "Phosphorus"
|
||||
id = "phosphorus"
|
||||
description = "A chemical element."
|
||||
description = "A ruddy red powder that burns readily. Though it comes in many colors, the general theme is always the same."
|
||||
reagent_state = SOLID
|
||||
color = "#832828" // rgb: 131, 40, 40
|
||||
|
||||
/datum/reagent/lithium
|
||||
name = "Lithium"
|
||||
id = "lithium"
|
||||
description = "A chemical element."
|
||||
description = "A silver metal, it's claim to fame is its remarkably low density. Using it is a bit too effective in calming oneself down."
|
||||
reagent_state = SOLID
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
|
||||
@@ -865,7 +865,7 @@
|
||||
name = "Carbon Dioxide"
|
||||
id = "co2"
|
||||
reagent_state = GAS
|
||||
description = "A gas commonly produced by burning carbon fuels."
|
||||
description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs."
|
||||
color = "#B0B0B0" // rgb : 192, 192, 192
|
||||
|
||||
/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume)
|
||||
@@ -1010,21 +1010,14 @@
|
||||
/datum/reagent/iodine
|
||||
name = "Iodine"
|
||||
id = "iodine"
|
||||
description = "A slippery solution."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
/datum/reagent/fluorine
|
||||
name = "Fluorine"
|
||||
id = "fluorine"
|
||||
description = "A slippery solution."
|
||||
description = "Commonly added to table salt as a nutrient. On its own it tastes far less pleasing."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
/datum/reagent/carpet
|
||||
name = "Carpet"
|
||||
id = "carpet"
|
||||
description = "A slippery solution."
|
||||
description = "For those that need a more creative way to roll out a red carpet."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
@@ -1038,35 +1031,35 @@
|
||||
/datum/reagent/bromine
|
||||
name = "Bromine"
|
||||
id = "bromine"
|
||||
description = "A slippery solution."
|
||||
description = "A brownish liquid that's highly reactive. Useful for stopping free radicals, but not intended for human consumption."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
/datum/reagent/phenol
|
||||
name = "Phenol"
|
||||
id = "phenol"
|
||||
description = "Used for certain medical recipes."
|
||||
description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
/datum/reagent/ash
|
||||
name = "Ash"
|
||||
id = "ash"
|
||||
description = "Basic ingredient in a couple of recipes."
|
||||
description = "Supposedly pheonixes rise from these, but you've never seen it."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
/datum/reagent/acetone
|
||||
name = "Acetone"
|
||||
id = "acetone"
|
||||
description = "Common ingredient in other recipes."
|
||||
description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
|
||||
/datum/reagent/colorful_reagent
|
||||
name = "Colorful Reagent"
|
||||
id = "colorful_reagent"
|
||||
description = "A solution."
|
||||
description = "Thoroughly sample the rainbow."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700")
|
||||
@@ -1096,7 +1089,7 @@
|
||||
/datum/reagent/hair_dye
|
||||
name = "Quantum Hair Dye"
|
||||
id = "hair_dye"
|
||||
description = "A solution."
|
||||
description = "Has a high chance of making you look like a mad scientist."
|
||||
reagent_state = LIQUID
|
||||
color = "#C8A5DC"
|
||||
var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code
|
||||
@@ -1144,21 +1137,21 @@
|
||||
/datum/reagent/saltpetre
|
||||
name = "Saltpetre"
|
||||
id = "saltpetre"
|
||||
description = "Volatile."
|
||||
description = "Volatile. Controversial. Third Thing."
|
||||
reagent_state = LIQUID
|
||||
color = "#60A584" // rgb: 96, 165, 132
|
||||
|
||||
/datum/reagent/lye
|
||||
name = "Lye"
|
||||
id = "lye"
|
||||
description = "Also known as sodium hydroxide."
|
||||
description = "Also known as sodium hydroxide. As a profession making this is somewhat underwhelming."
|
||||
reagent_state = LIQUID
|
||||
color = "#FFFFD6" // very very light yellow
|
||||
|
||||
/datum/reagent/drying_agent
|
||||
name = "Drying agent"
|
||||
id = "drying_agent"
|
||||
description = "Can be used to dry things."
|
||||
description = "A desiccant. Can be used to dry things."
|
||||
reagent_state = LIQUID
|
||||
color = "#A70FFF"
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/proc/boom()
|
||||
visible_message("<span class='danger'>\The [src] ruptures!</span>")
|
||||
chem_splash(loc, 5, list(reagents))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank
|
||||
@@ -56,20 +58,11 @@
|
||||
desc = "A water tank."
|
||||
icon_state = "water"
|
||||
|
||||
/obj/structure/reagent_dispensers/waterank/bullet_act(obj/item/projectile/Proj)
|
||||
/obj/structure/reagent_dispensers/bullet_act(obj/item/projectile/Proj)
|
||||
..()
|
||||
if(tank_volume && istype(Proj) && !Proj.nodamage && ((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)))
|
||||
boom()
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/boom()
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
|
||||
PoolOrNew(/obj/effect/particle_effect/water, loc)
|
||||
for(var/turf/open/T in view(5,loc))
|
||||
T.MakeSlippery(min_wet_time = 20, wet_time_to_add = 15)
|
||||
for(var/mob/living/L in T)
|
||||
L.adjust_fire_stacks(-20)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/blob_act(obj/effect/blob/B)
|
||||
if(prob(50))
|
||||
PoolOrNew(/obj/effect/particle_effect/water, loc)
|
||||
|
||||
@@ -37,7 +37,7 @@ other types of metals and chemistry for reagents).
|
||||
var/build_path = null //The file path of the object that gets created
|
||||
var/list/make_reagents = list() //Reagents produced. Format: "id" = amount. Currently only supported by the biogenerator.
|
||||
var/list/category = null //Primarily used for Mech Fabricators, but can be used for anything
|
||||
var/list/reagents = list() //List of reagents. Format: "id" = amount.
|
||||
var/list/reagents_list = list() //List of reagents. Format: "id" = amount.
|
||||
var/maxstack = 1
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
req_tech = list("programming" = 1)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/circuitboard/computer/arcade/battle
|
||||
category = list("Computer Boards")
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
req_tech = list("programming" = 2, "engineering" = 1)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_METAL = 250, MAT_GLASS = 100)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/network_card
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
req_tech = list("programming" = 4, "engineering" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 200)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/network_card/advanced
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
req_tech = list("programming" = 5, "engineering" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_METAL = 2500, MAT_GLASS = 400)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/network_card/wired
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
req_tech = list("programming" = 1)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 800)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/hard_drive/portable
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
req_tech = list("programming" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1600)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/hard_drive/portable/advanced
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
req_tech = list("programming" = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 3200)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/hard_drive/portable/super
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -216,7 +216,7 @@
|
||||
req_tech = list("programming" = 3, "engineering" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1600)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/processor_unit
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
req_tech = list("programming" = 2, "engineering" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 800)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/processor_unit/small
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
req_tech = list("programming" = 5, "engineering" = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS= 6400, MAT_GOLD = 2000)
|
||||
reagents = list("sacid" = 40)
|
||||
reagents_list = list("sacid" = 40)
|
||||
build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic
|
||||
category = list("Computer Parts")
|
||||
|
||||
@@ -246,6 +246,6 @@
|
||||
req_tech = list("programming" = 4, "engineering" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 3200, MAT_GOLD = 1000)
|
||||
reagents = list("sacid" = 20)
|
||||
reagents_list = list("sacid" = 20)
|
||||
build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic/small
|
||||
category = list("Computer Parts")
|
||||
@@ -69,7 +69,7 @@
|
||||
req_tech = list("combat" = 5, "materials" = 5, "biotech" = 6, "plasmatech" = 7)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_GOLD = 5000,MAT_URANIUM = 10000)
|
||||
reagents = list("mutagen" = 40)
|
||||
reagents_list = list("mutagen" = 40)
|
||||
build_path = /obj/item/weapon/gun/energy/decloner
|
||||
category = list("Weapons")
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
req_tech = list("materials" = 2, "biotech" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 2000, MAT_GLASS = 500)
|
||||
reagents = list("radium" = 20)
|
||||
reagents_list = list("radium" = 20)
|
||||
build_path = /obj/item/weapon/gun/energy/floragun
|
||||
category = list("Weapons")
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
var/datum/design/D = files.known_designs[href_list["copy_design_ID"]]
|
||||
if(D)
|
||||
var/autolathe_friendly = 1
|
||||
if(D.reagents.len)
|
||||
if(D.reagents_list.len)
|
||||
autolathe_friendly = 0
|
||||
D.category -= "Imported"
|
||||
else
|
||||
@@ -426,16 +426,16 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
enough_materials = 0
|
||||
g2g = 0
|
||||
else
|
||||
for(var/R in being_built.reagents)
|
||||
if(!linked_lathe.reagents.has_reagent(R, being_built.reagents[R]*coeff))
|
||||
for(var/R in being_built.reagents_list)
|
||||
if(!linked_lathe.reagents.has_reagent(R, being_built.reagents_list[R]*coeff))
|
||||
linked_lathe.say("Not enough reagents to complete prototype.")
|
||||
enough_materials = 0
|
||||
g2g = 0
|
||||
|
||||
if(enough_materials)
|
||||
linked_lathe.materials.use_amount(efficient_mats, amount)
|
||||
for(var/R in being_built.reagents)
|
||||
linked_lathe.reagents.remove_reagent(R, being_built.reagents[R]*coeff)
|
||||
for(var/R in being_built.reagents_list)
|
||||
linked_lathe.reagents.remove_reagent(R, being_built.reagents_list[R]*coeff)
|
||||
|
||||
var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes.
|
||||
spawn(32*coeff*amount**0.8)
|
||||
@@ -499,16 +499,16 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
enough_materials = 0
|
||||
g2g = 0
|
||||
else
|
||||
for(var/R in being_built.reagents)
|
||||
if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents[R]/coeff))
|
||||
for(var/R in being_built.reagents_list)
|
||||
if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents_list[R]/coeff))
|
||||
linked_imprinter.say("Not enough reagents to complete prototype.")
|
||||
enough_materials = 0
|
||||
g2g = 0
|
||||
|
||||
if(enough_materials)
|
||||
linked_imprinter.materials.use_amount(efficient_mats)
|
||||
for(var/R in being_built.reagents)
|
||||
linked_imprinter.reagents.remove_reagent(R, being_built.reagents[R]/coeff)
|
||||
for(var/R in being_built.reagents_list)
|
||||
linked_imprinter.reagents.remove_reagent(R, being_built.reagents_list[R]/coeff)
|
||||
|
||||
var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes.
|
||||
spawn(16)
|
||||
@@ -727,7 +727,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
if(D.build_type & MECHFAB) dat += "Exosuit Fabricator<BR>"
|
||||
if(D.build_type & BIOGENERATOR) dat += "Biogenerator<BR>"
|
||||
dat += "Required Materials:<BR>"
|
||||
var/all_mats = D.materials + D.reagents
|
||||
var/all_mats = D.materials + D.reagents_list
|
||||
for(var/M in all_mats)
|
||||
dat += "* [CallMaterialName(M)] x [all_mats[M]]<BR>"
|
||||
dat += "Operations: <A href='?src=\ref[src];updt_design=[i]'>Upload to Database</A> <A href='?src=\ref[src];clear_design=[i]'>Clear Slot</A>"
|
||||
@@ -848,7 +848,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
var/c = 50
|
||||
var/t
|
||||
|
||||
var/all_materials = D.materials + D.reagents
|
||||
var/all_materials = D.materials + D.reagents_list
|
||||
for(var/M in all_materials)
|
||||
t = linked_lathe.check_mat(D, M)
|
||||
temp_material += " | "
|
||||
@@ -882,7 +882,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
var/temp_material
|
||||
var/c = 50
|
||||
var/t
|
||||
var/all_materials = D.materials + D.reagents
|
||||
var/all_materials = D.materials + D.reagents_list
|
||||
for(var/M in all_materials)
|
||||
t = linked_lathe.check_mat(D, M)
|
||||
temp_material += " | "
|
||||
@@ -967,7 +967,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
var/temp_materials
|
||||
var/check_materials = 1
|
||||
|
||||
var/all_materials = D.materials + D.reagents
|
||||
var/all_materials = D.materials + D.reagents_list
|
||||
|
||||
for(var/M in all_materials)
|
||||
temp_materials += " | "
|
||||
@@ -993,7 +993,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
for(var/datum/design/D in matching_designs)
|
||||
var/temp_materials
|
||||
var/check_materials = 1
|
||||
var/all_materials = D.materials + D.reagents
|
||||
var/all_materials = D.materials + D.reagents_list
|
||||
for(var/M in all_materials)
|
||||
temp_materials += " | "
|
||||
if (!linked_imprinter.check_mat(D, M))
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
user.mind.transfer_to(SM)
|
||||
SM.languages_spoken = user.languages_spoken
|
||||
SM.languages_understood = user.languages_understood
|
||||
SM.faction = user.faction
|
||||
SM.faction = user.faction.Copy()
|
||||
SM.sentience_act() //Same deal here as with sentience
|
||||
user.death()
|
||||
SM << "<span class='notice'>In a quick flash, you feel your consciousness flow into [SM]!</span>"
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
|
||||
//Areas
|
||||
/area/ruin/unpowered/hierophant
|
||||
name = "Hierophant's Arena"
|
||||
|
||||
/area/ruin/unpowered/no_grav/way_home
|
||||
name = "\improper Salvation"
|
||||
|
||||
@@ -182,8 +182,15 @@
|
||||
processing_uis.Remove(ui) // Remove it from the list of processing UIs.
|
||||
if(ui.user) // If the user exists, remove it from them too.
|
||||
ui.user.open_uis.Remove(ui)
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key] // Remove it from the list of open UIs.
|
||||
var/Ukey = ui.ui_key
|
||||
var/list/uis = open_uis[src_object_key][Ukey] // Remove it from the list of open UIs.
|
||||
uis.Remove(ui)
|
||||
if(!uis.len)
|
||||
var/list/uiobj = open_uis[src_object_key]
|
||||
uiobj.Remove(Ukey)
|
||||
if(!uiobj.len)
|
||||
open_uis.Remove(src_object_key)
|
||||
|
||||
return 1 // Let the caller know we did it.
|
||||
|
||||
/**
|
||||
|
||||
@@ -799,7 +799,7 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
|
||||
name = "Military Belt"
|
||||
desc = "A robust seven-slot red belt that is capable of holding all manner of tatical equipment."
|
||||
item = /obj/item/weapon/storage/belt/military
|
||||
cost = 3
|
||||
cost = 1
|
||||
exclude_modes = list(/datum/game_mode/nuclear)
|
||||
|
||||
/datum/uplink_item/device_tools/medkit
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
|
||||
|
||||
/obj/vehicle/Process_Spacemove(direction)
|
||||
if(has_gravity(src))
|
||||
if(has_gravity())
|
||||
return 1
|
||||
|
||||
if(pulledby)
|
||||
|
||||
+2
-2
@@ -8,7 +8,6 @@
|
||||
# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. #
|
||||
###############################################################################################
|
||||
Optimumtact = Host
|
||||
kevinz000 = Host
|
||||
kingofkosmos = Game Master
|
||||
MrStonedOne = Game Master
|
||||
microscopics = Game Master
|
||||
@@ -118,4 +117,5 @@ TechnoAlchemist = Game Master
|
||||
Aloraydrel = Game Master
|
||||
Quiltyquilty = Game Master
|
||||
SnipeDragon = Game Master
|
||||
Fjeld = Game Master
|
||||
Fjeld = Game Master
|
||||
kevinz000 = Game Master
|
||||
|
||||
+47
-93
@@ -55,6 +55,53 @@
|
||||
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
<h2 class="date">04 September 2016</h2>
|
||||
<h3 class="author">A-t48 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Radiation storms no longer spam "Your armor softened the blow."</li>
|
||||
<li class="bugfix">Radiation always gives a message that you are being irradiated, regardless of armor level (only an issue if you stripped off all clothing)</li>
|
||||
<li class="bugfix">Radiation now displays a message appropriate for all mob types (no longer references clothes).</li>
|
||||
</ul>
|
||||
<h3 class="author">Gun Hog updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Ghosts may now read an AI or Cyborg's laws by examining them.</li>
|
||||
</ul>
|
||||
<h3 class="author">Joan updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">The talisman of construction now has 25 uses, each of which can convert a sheet of plasteel to a sheet of runed metal. It can still convert metal into construct shells, and requires no specific amount of uses to do so.</li>
|
||||
<li class="rscadd">Added the 'Drain Life' rune to the runes cultists can make. It will drain life from all creatures on the rune, healing the invoker.</li>
|
||||
<li class="imageadd">The 'Astral Communion' rune has a new sprite, made by WJohnston.</li>
|
||||
<li class="rscdel">You can no longer use telekinesis to hit people with items they're holding, items inside items they're holding, items embedded in them, items actually implanted in them, or items they're wearing.</li>
|
||||
</ul>
|
||||
<h3 class="author">MMMiracles updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">A set of combat gear for bears has been added, see your local russian for more information.</li>
|
||||
</ul>
|
||||
<h3 class="author">XDTM updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Nanotrasen has now stocked the DNA Manipulators with potassium iodide instead of epinephrine as rejuvenators.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">02 September 2016</h2>
|
||||
<h3 class="author">A-t48 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Fixed cyborgs being able to use Power Warning emote when broken.</li>
|
||||
</ul>
|
||||
<h3 class="author">Iamgoofball updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="experiment">Freon has been reworked completely.</li>
|
||||
<li class="rscadd">Water Vapor has been added to the Janitor's Closet.</li>
|
||||
</ul>
|
||||
<h3 class="author">RemieRichards updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Cutting bedsheets with a sharp object/wirecutters no longer puts the resulting cloth INSIDE OF YOU if you're holding it, what a bug.</li>
|
||||
</ul>
|
||||
<h3 class="author">bgobandit updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">You can hide small items in urinals now. Use a screwdriver to screw open the drain enclosure.</li>
|
||||
<li class="rscadd">Every space urinal comes complete with space urinal cake. Do not eat.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">01 September 2016</h2>
|
||||
<h3 class="author">Cruix updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
@@ -1122,99 +1169,6 @@
|
||||
<li class="rscadd">Immovable rods now notify ghosts when created, allowing them to orbit it and follow their path of destruction through the station.</li>
|
||||
<li class="bugfix">Fixed bugs where no meteors would come or go from the south. Seriously, that was a real bug. Meteor showers are now about 33% stronger as a result.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">03 July 2016</h2>
|
||||
<h3 class="author">Cruix updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Hand labelers can now label storage containers.</li>
|
||||
<li class="bugfix">You can now properly resist out of wrapped lockers.</li>
|
||||
<li class="bugfix">You can now resist out of morgues if you are in a bodybag.</li>
|
||||
<li class="bugfix">Mechs can no longer spam doors they do not have access to.</li>
|
||||
</ul>
|
||||
<h3 class="author">Joan updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Clock Cult can now happen at 24 players, same as cult.</li>
|
||||
<li class="tweak">Clock Cult player scaling is lower; 3 people, plus one for every 15 players above 30, from 1 for every 10 players with a player minimum of 30.</li>
|
||||
<li class="experiment">Guvax now invokes 1 second faster(5 seconds), but is 0.75 seconds slower for each scripture-valid servant above 5, up to a maximum of 15 seconds.</li>
|
||||
<li class="experiment">Clockwork Slabs generate components 20 seconds slower for each scripture-valid servant above 5, up to a maximum of 1 component every 5 minutes.</li>
|
||||
<li class="tweak">Tinkerer's Daemons that would be useless cannot be made.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">02 July 2016</h2>
|
||||
<h3 class="author">Joan updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Clockwork Proselytizers can now reform stored alloy into usable component alloy when used in-hand.</li>
|
||||
<li class="rscdel">Mending motors start with 2500W of power in alloy, from 5000. Sigils of Transmission start with 2500W of power, from 4000. Clockwork Proselytizers start with 90 alloy, from 100.</li>
|
||||
<li class="rscdel">Umbras have been removed.</li>
|
||||
<li class="rscadd">Revenants have been readded, though they are now vulnerable to salt piles.</li>
|
||||
</ul>
|
||||
<h3 class="author">MMMiracles updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Added the power fist, a gauntlet with a piston-powered ram attached to the top for traitors to punch people across the station. Punch people into walls for added fun.</li>
|
||||
</ul>
|
||||
<h3 class="author">incoming5643 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Nuke ops can now harness the power of METAL BOXES: special versions of cardboard boxes that can take a lot of abuse and can fit the whole team if need be. They're not nearly as light as their cardboard brothers though...</li>
|
||||
</ul>
|
||||
<h3 class="author">kevinz000 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Some new emojis have been added to OOC for your enjoyment. Try them out.</li>
|
||||
<li class="rscadd">New emojis are : coffee, trophy, tea, gear, supermatter, forceweapon, gift, kudzu, dosh, chrono, nya, and tophat. Type :nameofemoji: in OOC to use.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">01 July 2016</h2>
|
||||
<h3 class="author">Flavo updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">fixed a bug where lights would not update.</li>
|
||||
</ul>
|
||||
<h3 class="author">Joan updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Clockwork Slabs now use an action button to communicate instead of the "Report" option in the menu after using a slab.</li>
|
||||
<li class="tweak">Clockwork Slabs now fit in pockets, the belt slot, or in the suit storage slot(if wearing clockwork armor), where they can be used as hands-free communication.</li>
|
||||
<li class="imageadd">Clockwork items with action buttons have a new, clockwork-y background.</li>
|
||||
<li class="rscadd">Judicial Visors now tell the user how many targets the Judicial Blast struck.</li>
|
||||
<li class="soundadd">Judicial Markers now have sounds when appearing and exploding.</li>
|
||||
<li class="tweak">Wet turfs should remain that way for slightly longer than 5 seconds now.</li>
|
||||
<li class="rscadd">Drones and Swarmers should now sound more robotic.</li>
|
||||
<li class="tweak">Ratvarian Spears will stun cyborgs and cultists for twice as long when thrown; on cyborgs, this should be long enough to use Guvax on them.</li>
|
||||
<li class="rscdel">Removed the Justicar's Gavel application scripture.</li>
|
||||
<li class="tweak">Vitality Matrices will drain and heal 50% faster, and the base cost to revive is 20% lower; 20, from 25.</li>
|
||||
<li class="rscadd">Vitality Matrices will not revive or heal corpses unless they can grab the ghost of the corpse, and will immediately grab the ghost when reviving.</li>
|
||||
<li class="rscadd">Swarmers consuming swarmer shells now refunds the swarmer the entire cost of the shell instead of 2% of the shell's cost.</li>
|
||||
<li class="experiment">Application scriptures require at least 75 CV, from 50.</li>
|
||||
<li class="experiment">Revenant scriptures require at least 4 Caches, from 3, and at least 150 CV, from 100.</li>
|
||||
<li class="experiment">Judgement scripture requires at least 12 servants, from 10, 5 Caches, from 3, and at least 250 CV, from 100.</li>
|
||||
<li class="experiment">Script and Application scripture have had their component costs and requirements tweaked to reduce overuse of certain components.</li>
|
||||
<li class="wip">Invoke times for a few scriptures that were instant are now very short instead.</li>
|
||||
</ul>
|
||||
<h3 class="author">Kor updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscdel">Holoparasites are no longer in the uplink</li>
|
||||
</ul>
|
||||
<h3 class="author">NikNak updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Showcases are now movable and deconstructable. Wrench them to unanchor and then screwdriver and crowbar to deconstruct.</li>
|
||||
</ul>
|
||||
<h3 class="author">Papa Bones updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Security now has energy bolas available to them in their vending machines, check them out!</li>
|
||||
</ul>
|
||||
<h3 class="author">bobdobbington updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Added skub to the AutoDrobe as a premium item.</li>
|
||||
</ul>
|
||||
<h3 class="author">coiax updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">The CTF arena regenerates every round, and the blue team now shoot blue lasers.</li>
|
||||
<li class="rscadd">Adds some descriptions to alien surgery tools</li>
|
||||
<li class="rscadd">The agent vest can be locked and unlocked (toggling the NODROP flag)</li>
|
||||
<li class="rscadd">An abductor team can spend data points to purchase an agent vest (note that only abductor agents are trained in their use)</li>
|
||||
<li class="rscadd">The nuke disk reappears on the station in far more random locations, but tends to re-materialise in safe pressurised areas that aren't on fire.</li>
|
||||
</ul>
|
||||
<h3 class="author">name: Lzimann updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Mulebots with pAI cards no longer stun people</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<b>GoonStation 13 Development Team</b>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user