Merge branch 'master' of https://github.com/tgstation/-tg-station into bring_colossus_back_2016

This commit is contained in:
Ergovisavi
2016-09-07 01:08:58 -07:00
138 changed files with 1794 additions and 584 deletions
@@ -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
+1 -1
View File
@@ -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"]"
+2 -1
View File
@@ -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
+4 -4
View File
@@ -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)
+9 -4
View File
@@ -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
+34
View File
@@ -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"
+6
View File
@@ -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
View File
@@ -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()
+4 -1
View File
@@ -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
View File
@@ -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.")
+2 -2
View File
@@ -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)
+3 -3
View File
@@ -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
+8
View File
@@ -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"
+3 -3
View File
@@ -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
-6
View File
@@ -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++
+3 -1
View File
@@ -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
+2 -2
View File
@@ -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)
+3 -1
View File
@@ -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>"
+48 -12
View File
@@ -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"
+21 -12
View File
@@ -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>"
-12
View File
@@ -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."
+5 -4
View File
@@ -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()
+4 -4
View File
@@ -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)
-5
View File
@@ -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)
+1 -1
View File
@@ -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()
+3
View File
@@ -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
+1
View File
@@ -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()
..()
+3 -2
View File
@@ -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
..()
+5 -3
View File
@@ -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
*/
+1 -1
View File
@@ -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
+5 -2
View File
@@ -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)
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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
+7 -4
View File
@@ -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)
. = ..()
+21 -14
View File
@@ -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)
-2
View File
@@ -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)
+1 -1
View File
@@ -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()
+2 -2
View File
@@ -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]
+7 -3
View File
@@ -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)
+222 -14
View File
@@ -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))
+4 -3
View File
@@ -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)
+16 -4
View File
@@ -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
+6 -3
View File
@@ -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")
+1 -1
View File
@@ -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)
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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
..()
+1 -1
View File
@@ -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)
-3
View File
@@ -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
+1 -1
View File
@@ -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)
+154 -136
View File
@@ -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"
+3 -10
View File
@@ -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)
+1 -1
View File
@@ -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")
+14 -14
View File
@@ -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>"
+2
View File
@@ -19,6 +19,8 @@
//Areas
/area/ruin/unpowered/hierophant
name = "Hierophant's Arena"
/area/ruin/unpowered/no_grav/way_home
name = "\improper Salvation"
+8 -1
View File
@@ -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.
/**
+1 -1
View File
@@ -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
+1 -1
View File
@@ -129,7 +129,7 @@
/obj/vehicle/Process_Spacemove(direction)
if(has_gravity(src))
if(has_gravity())
return 1
if(pulledby)
+2 -2
View File
@@ -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
View File
@@ -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