Large diffs are not rendered by default.

@@ -140,7 +140,7 @@ Pipelines + Other Objects -> Pipe network
user << "<span class='warning'>As you begin unwrenching \the [src] a gush of air blows in your face... maybe you should reconsider?</span>"
unsafe_wrenching = TRUE //Oh dear oh dear

if (do_after(user, 20, target = src) && !gc_destroyed)
if (do_after(user, 20/W.toolspeed, target = src) && !gc_destroyed)
user.visible_message( \
"[user] unfastens \the [src].", \
"<span class='notice'>You unfasten \the [src].</span>", \
@@ -93,17 +93,21 @@ Passive gate is similar to the regular pump except:

return 1

/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
/obj/machinery/atmospherics/components/binary/passive_gate/interact(mob/user)
if(stat & (BROKEN|NOPOWER)) return
ui_interact(user)

ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_gas_pump.tmpl", name, 400, 120, 0)
/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
if (!ui)
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100)
ui.open()

/obj/machinery/atmospherics/components/binary/passive_gate/get_ui_data()
var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
data["set_pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
return data

/obj/machinery/atmospherics/components/binary/passive_gate/atmosinit()
@@ -142,17 +146,11 @@ Passive gate is similar to the regular pump except:


/obj/machinery/atmospherics/components/binary/passive_gate/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
user << "<span class='danger'>Access denied.</span>"
return
usr.set_machine(src)
ui_interact(user)
return
if(..() || !user) return
add_fingerprint(usr)
interact(user)

/obj/machinery/atmospherics/components/binary/passive_gate/Topic(href,href_list)
/obj/machinery/atmospherics/components/binary/passive_gate/Topic(href, href_list)
if(..()) return
if(href_list["power"])
on = !on
@@ -164,17 +162,13 @@ Passive gate is similar to the regular pump except:
if ("set")
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

update_icon()

/obj/machinery/atmospherics/components/binary/passive_gate/power_change()
..()
update_icon()



/obj/machinery/atmospherics/components/binary/passive_gate/attackby(obj/item/weapon/W, mob/user, params)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
@@ -98,17 +98,24 @@ Thus, the two variables affect pump operation are set in New():

return 1

/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
/obj/machinery/atmospherics/components/binary/pump/interact(mob/user)
if(stat & (BROKEN|NOPOWER)) return
if(!src.allowed(usr))
usr << "<span class='danger'>Access denied.</span>"
return
ui_interact(user)

ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_gas_pump.tmpl", name, 400, 120, 0)
/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
if (!ui)
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100)
ui.open()

/obj/machinery/atmospherics/components/binary/pump/get_ui_data()
var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
data["set_pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
return data

/obj/machinery/atmospherics/components/binary/pump/atmosinit()
@@ -146,15 +153,8 @@ Thus, the two variables affect pump operation are set in New():


/obj/machinery/atmospherics/components/binary/pump/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
user << "<span class='danger'>Access denied.</span>"
return
usr.set_machine(src)
ui_interact(user)
return
if(..() | !user) return
interact(user)

/obj/machinery/atmospherics/components/binary/pump/Topic(href,href_list)
if(..()) return
@@ -168,10 +168,9 @@ Thus, the two variables affect pump operation are set in New():
if ("set")
target_pressure = max(0, min(MAX_OUTPUT_PRESSURE, safe_input("Pressure control", "Enter new output pressure (0-[MAX_OUTPUT_PRESSURE] kPa)", target_pressure)))
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

add_fingerprint(usr)
update_icon()

/obj/machinery/atmospherics/components/binary/pump/power_change()
..()
@@ -94,17 +94,24 @@ Thus, the two variables affect pump operation are set in New():

return 1

/obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
/obj/machinery/atmospherics/components/binary/volume_pump/interact(mob/user)
if(stat & (BROKEN|NOPOWER)) return
if(!src.allowed(usr))
usr << "<span class='danger'>Access denied.</span>"
return
ui_interact(user)

ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_gas_pump.tmpl", name, 400, 120, 0)
/obj/machinery/atmospherics/components/binary/volume_pump/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
if (!ui)
ui = new(user, src, ui_key, "atmos_pump.tmpl", name, 400, 100)
ui.open()

/obj/machinery/atmospherics/components/binary/volume_pump/get_ui_data()
var/data = list()
data["on"] = on
data["transfer_rate"] = round(transfer_rate*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_rate"] = MAX_TRANSFER_RATE
data["transfer_rate"] = round(transfer_rate)
data["max_rate"] = round(MAX_TRANSFER_RATE)
return data

/obj/machinery/atmospherics/components/binary/volume_pump/atmosinit()
@@ -142,15 +149,8 @@ Thus, the two variables affect pump operation are set in New():


/obj/machinery/atmospherics/components/binary/volume_pump/attack_hand(mob/user)
if(..())
return
src.add_fingerprint(usr)
if(!src.allowed(user))
user << "<span class='danger'>Access denied.</span>"
return
usr.set_machine(src)
ui_interact(user)
return
if(..() | !user) return
interact(user)

/obj/machinery/atmospherics/components/binary/volume_pump/Topic(href,href_list)
if(..()) return
@@ -164,17 +164,14 @@ Thus, the two variables affect pump operation are set in New():
if ("set")
transfer_rate = max(0, min(MAX_TRANSFER_RATE, safe_input("Pressure control", "Enter new transfer rate (0-[MAX_TRANSFER_RATE] L/s)", transfer_rate)))
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
usr.set_machine(src)
src.update_icon()
src.updateUsrDialog()
return

add_fingerprint(usr)
update_icon()

/obj/machinery/atmospherics/components/binary/volume_pump/power_change()
..()
update_icon()



/obj/machinery/atmospherics/components/binary/volume_pump/attackby(obj/item/weapon/W, mob/user, params)
if (!istype(W, /obj/item/weapon/wrench))
return ..()
@@ -157,34 +157,32 @@ Filter types:
return ..()

/obj/machinery/atmospherics/components/trinary/filter/attack_hand(mob/user)
if(..())
return
if(..() | !user) return
interact(user)

if(!src.allowed(user))
user << "<span class='danger'>Access denied.</span>"
/obj/machinery/atmospherics/components/trinary/filter/interact(mob/user)
if(stat & (BROKEN|NOPOWER)) return
if(!src.allowed(usr))
usr << "<span class='danger'>Access denied.</span>"
return

ui_interact(user)

/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return

ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_filter.tmpl", name, 400, 320, 0)
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
if (!ui)
ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 400, 120)
ui.open()

/obj/machinery/atmospherics/components/trinary/filter/get_ui_data()
var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
data["set_pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
data["filter_type"] = filter_type
return data

/obj/machinery/atmospherics/components/trinary/filter/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
src.add_fingerprint(usr)
if(..()) return
if(href_list["filterset"])
src.filter_type = text2num(href_list["filterset"])
var/filtering_name = "nothing"
@@ -212,11 +210,6 @@ Filter types:
if(href_list["power"])
on=!on
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
src.update_icon()
src.updateUsrDialog()
/*
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
src.attack_hand(M)
*/
return

add_fingerprint(usr)
update_icon()
@@ -120,26 +120,27 @@
return 1

/obj/machinery/atmospherics/components/trinary/mixer/attack_hand(mob/user)
if(..())
return
if(..() | !user) return
interact(user)

if(!src.allowed(user))
user << "<span class='danger'>Access denied.</span>"
/obj/machinery/atmospherics/components/trinary/mixer/interact(mob/user)
if(stat & (BROKEN|NOPOWER)) return
if(!src.allowed(usr))
usr << "<span class='danger'>Access denied.</span>"
return

ui_interact(user)

/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return

ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_mixer.tmpl", name, 400, 320, 0)
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
if (!ui)
ui = new(user, src, ui_key, "atmos_mixer.tmpl", name, 400, 145)
ui.open()

/obj/machinery/atmospherics/components/trinary/mixer/get_ui_data()
var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
data["set_pressure"] = round(target_pressure)
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
data["node1_concentration"] = round(node1_concentration*100)
data["node2_concentration"] = round(node2_concentration*100)
return data
@@ -166,6 +167,6 @@
src.node2_concentration = max(0, min(1, src.node2_concentration + value))
src.node1_concentration = max(0, min(1, src.node1_concentration - value))
investigate_log("was set to [node2_concentration] % on node 2 by [key_name(usr)]", "atmos")
src.update_icon()
src.updateUsrDialog()
return

add_fingerprint(usr)
update_icon()
@@ -42,7 +42,7 @@
T.contents += contents

if(beaker)
beaker.loc = get_step(loc, SOUTH) //Beaker is carefully ejected from the wreckage of the cryotube
beaker.loc = get_step(loc, SOUTH) //Beaker is carefully fed from the wreckage of the cryotube
beaker = null
return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos()
@@ -65,16 +65,11 @@
if(!NODE1 || !is_operational())
return

if(!on)
updateDialog()
return

if(AIR1)
if (occupant)
process_occupant()
expel_gas()

updateDialog()
return 1

/obj/machinery/atmospherics/components/unary/cryo_cell/MouseDrop_T(mob/target, mob/user)
@@ -120,28 +115,20 @@
user << "Seems empty."

/obj/machinery/atmospherics/components/unary/cryo_cell/attack_hand(mob/user)
if(..())
if(..() | !user)
return
interact(user)

ui_interact(user)


/**
* The ui_interact proc is used to open and update Nano UIs
* If ui_interact is not used then the UI will not update correctly
* ui_interact is currently defined for /atom/movable
*
* @param user /mob The mob who is interacting with this ui
* @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main")
*
* @return nothing
*/
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null)
if(user == occupant || user.stat || panel_open)
/obj/machinery/atmospherics/components/unary/cryo_cell/interact(mob/user)
if(panel_open)
return
ui_interact(user)

ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "cryo.tmpl", "Cryo Cell Control System", 520, 410, 1)
//user.set_machine(src)
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 0)
SSnano.try_update_ui(user, src, ui_key, ui, force_open = force_open)
if (!ui)
ui = new(user, src, ui_key, "cryo.tmpl", name, 520, 410, state = notcontained_state)
ui.open()

/obj/machinery/atmospherics/components/unary/cryo_cell/get_ui_data()
// this is the data which will be sent to the ui
@@ -193,35 +180,30 @@
return data

/obj/machinery/atmospherics/components/unary/cryo_cell/Topic(href, href_list)
if(usr == occupant || panel_open)
return 0 // don't update UIs attached to this object

if(..())
return 0 // don't update UIs attached to this object
return

if(href_list["switchOn"])
if(!state_open)
on = 1

if(href_list["open"])
open_machine()

if(href_list["close"])
if(close_machine() == usr)
var/datum/nanoui/ui = SSnano.get_open_ui(usr, src, "main")
ui.close()
on = 1
if(href_list["switchOff"])
on = 0

if(href_list["openCell"])
open_machine()

if(href_list["closeCell"])
close_machine()

if(href_list["ejectBeaker"])
if(beaker)
var/obj/item/weapon/reagent_containers/glass/B = beaker
B.loc = get_step(loc, SOUTH)
beaker = null
update_icon()

add_fingerprint(usr)
return 1 // update UIs attached to this object
update_icon()

/obj/machinery/atmospherics/components/unary/cryo_cell/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/reagent_containers/glass))
@@ -266,7 +266,7 @@
if (WT.remove_fuel(0,user))
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
user << "<span class='notice'>You begin welding the vent...</span>"
if(do_after(user, 20, target = src))
if(do_after(user, 20/W.toolspeed, target = src))
if(!src || !WT.isOn()) return
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
if(!welded)
@@ -297,7 +297,7 @@
if(WT.remove_fuel(0,user))
playsound(loc, 'sound/items/Welder.ogg', 40, 1)
user << "<span class='notice'>Now welding the scrubber.</span>"
if(do_after(user, 20, target = src))
if(do_after(user, 20/W.toolspeed, target = src))
if(!src || !WT.isOn())
return
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
@@ -271,6 +271,7 @@ var/list/bloody_footprints_cache = list()
#define TURF_DRY 0
#define TURF_WET_WATER 1
#define TURF_WET_LUBE 2
#define TURF_WET_ICE 3

//Object/Item sharpness
#define IS_BLUNT 0
@@ -0,0 +1,15 @@
/**
* NanoUI Defines
*
* Contains all NanoUI state definitions.
*
* /tg/station user interface library
* thanks to baystation12
*
* modified by neersighted
**/

#define NANO_INTERACTIVE 2 // Green/Interactive
#define NANO_UPDATE 1 // Orange/Updates Only
#define NANO_DISABLED 0 // Red/Disabled
#define NANO_CLOSE -1 // Closed
@@ -374,7 +374,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/list/names = list()
var/list/pois = list()
var/list/namecounts = list()

for(var/mob/M in mobs)
var/name = M.name
if (name in names)
@@ -915,6 +915,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/rough_y = 0
var/final_x = 0
var/final_y = 0
var/final_z = 0

//Assume standards
var/i_width = world.icon_size
@@ -938,11 +939,18 @@ Turf and target are seperate in case you want to teleport some distance from a t
rough_y = round(AM.pixel_y/n_height)

//Find coordinates
final_x = AM.x + rough_x
final_y = AM.y + rough_y
if(!isturf(AM.loc))
var/turf/T = get_turf(AM)
final_x = T.x + rough_x
final_y = T.y + rough_y
final_z = T.z
else
final_x = AM.x + rough_x
final_y = AM.y + rough_y
final_z = AM.z

if(final_x || final_y)
return locate(final_x, final_y, AM.z)
return locate(final_x, final_y, final_z)

//Finds the distance between two atoms, in pixels
//centered = 0 counts from turf edge to edge
@@ -1342,4 +1350,12 @@ B --><-- A
L += T.contents
c_dist++

return L
return L

/atom/proc/contains(var/atom/location)
if(!location)
return 0
for(location, location && location != src, location=location.loc); //semicolon is for the empty statement
if(location == src)
return 1
return 0
@@ -8,8 +8,8 @@ var/datum/subsystem/events/SSevent
var/list/running = list() //list of all existing /datum/round_event

var/scheduled = 0 //The next world.time that a naturally occuring random event can be selected.
var/frequency_lower = 3000 //5 minutes lower bound.
var/frequency_upper = 9000 //15 minutes upper bound. Basically an event will happen every 5 to 15 minutes.
var/frequency_lower = 1800 //3 minutes lower bound.
var/frequency_upper = 6000 //10 minutes upper bound. Basically an event will happen every 3 to 10 minutes.

var/list/holidays //List of all holidays occuring today or null if no holidays
var/wizardmode = 0
@@ -0,0 +1,28 @@
var/datum/subsystem/nano/SSnano

/datum/subsystem/nano
name = "NanoUI"
can_fire = 1
wait = 10
priority = 16

var/list/open_uis = list() // A list of open NanoUIs, grouped by src_object and ui_key.
var/list/processing_uis = list() // A list of processing NanoUIs, not grouped.


/datum/subsystem/nano/New()
NEW_SS_GLOBAL(SSnano) // Register the subsystem.


/datum/subsystem/nano/stat_entry()
..("P:[processing_uis.len]") // Show how many interfaces we are processing.


/datum/subsystem/nano/fire() // Process UIs.
for(var/thing in SSnano.processing_uis)
if(thing)
var/datum/nanoui/ui = thing
if(ui.src_object && ui.user)
ui.process()
continue
processing_uis.Remove(thing)

This file was deleted.

@@ -41,6 +41,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/spell_level = 0 //if a spell can be taken multiple times, this raises
var/level_max = 4 //The max possible level_max is 4
var/cooldown_min = 0 //This defines what spell quickened four times has as a cooldown. Make sure to set this for every spell
var/player_lock = 1 //If it can be used by simple mobs

var/overlay = 0
var/overlay_icon = 'icons/obj/wizard.dmi'
@@ -62,9 +63,13 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin

/obj/effect/proc_holder/spell/proc/cast_check(skipcharge = 0,mob/user = usr) //checks if the spell can be cast based on its settings; skipcharge is used when an additional cast_check is called inside the spell

if(((!user.mind) || !(src in user.mind.spell_list)) && !(src in user.mob_spell_list))
user << "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>"
return 0
if(player_lock)
if(!user.mind || !(src in user.mind.spell_list) && !(src in user.mob_spell_list))
user << "<span class='warning'>You shouldn't have this spell! Something's wrong.</span>"
return 0
else
if(!(src in user.mob_spell_list))
return 0

if(user.z == ZLEVEL_CENTCOM && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
return 0
@@ -170,8 +175,9 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin

/obj/effect/proc_holder/spell/proc/perform(list/targets, recharge = 1, mob/user = usr) //if recharge is started is important for the trigger spells
before_cast(targets)
invocation()
user.attack_log += text("\[[time_stamp()]\] <span class='danger'>[user.real_name] ([user.ckey]) cast the spell [name].</span>")
invocation(user)
if(user.ckey)
user.attack_log += text("\[[time_stamp()]\] <span class='danger'>[user.real_name] ([user.ckey]) cast the spell [name].</span>")
spawn(0)
if(charge_type == "recharge" && recharge)
start_recharge()
@@ -180,7 +186,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
if(prob(critfailchance))
critfail(targets)
else
cast(targets)
cast(targets,user=user)
after_cast(targets)

/obj/effect/proc_holder/spell/proc/before_cast(list/targets)
@@ -227,7 +233,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
smoke.start()


/obj/effect/proc_holder/spell/proc/cast(list/targets)
/obj/effect/proc_holder/spell/proc/cast(list/targets,mob/user = usr)
return

/obj/effect/proc_holder/spell/proc/critfail(list/targets)
@@ -334,7 +340,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
revert_cast(user)
return

perform(targets)
perform(targets,user=user)

return

@@ -349,7 +355,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
revert_cast()
return

perform(targets)
perform(targets,user=user)

return

@@ -418,7 +424,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
if(!user)
revert_cast()
return
perform(user)
perform(null,user=user)

/obj/effect/proc_holder/spell/self/basic_heal //This spell exists mainly for debugging purposes, and also to show how casting works
name = "Lesser Heal"
@@ -32,8 +32,8 @@

return thearea

/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea)
playsound(get_turf(usr), sound1, 50,1)
/obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea,mob/user = usr)
playsound(get_turf(user), sound1, 50,1)
for(var/mob/living/target in targets)
var/list/L = list()
for(var/turf/T in get_area_turfs(thearea.type))
@@ -67,22 +67,22 @@

if(!success)
target.loc = pick(L)
playsound(get_turf(usr), sound2, 50,1)
playsound(get_turf(user), sound2, 50,1)

return

/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null)
/obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null,mob/user = usr)
if(!invocation_area || !chosenarea)
..()
else
switch(invocation_type)
if("shout")
usr.say("[invocation] [uppertext(chosenarea.name)]")
if(usr.gender==MALE)
playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
user.say("[invocation] [uppertext(chosenarea.name)]")
if(user.gender==MALE)
playsound(user.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
else
playsound(usr.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
playsound(user.loc, pick('sound/misc/null.ogg','sound/misc/null.ogg'), 100, 1)
if("whisper")
usr.whisper("[invocation] [uppertext(chosenarea.name)]")
user.whisper("[invocation] [uppertext(chosenarea.name)]")

return
@@ -12,9 +12,9 @@
include_user = 1


/obj/effect/proc_holder/spell/targeted/charge/cast(list/targets)
for(var/mob/living/user in targets)
var/list/hand_items = list(user.get_active_hand(),user.get_inactive_hand())
/obj/effect/proc_holder/spell/targeted/charge/cast(list/targets,mob/user = usr)
for(var/mob/living/L in targets)
var/list/hand_items = list(L.get_active_hand(),L.get_inactive_hand())
var/charged_item = null
var/burnt_out = 0
for(var/obj/item in hand_items)
@@ -38,15 +38,15 @@
if(istype(item, /obj/item/weapon/spellbook/oneuse))
var/obj/item/weapon/spellbook/oneuse/I = item
if(prob(80))
user.visible_message("<span class='warning'>[I] catches fire!</span>")
L.visible_message("<span class='warning'>[I] catches fire!</span>")
qdel(I)
else
I.used = 0
charged_item = I
break
else
user << "<span class='caution'>Glowing red letters appear on the front cover...</span>"
user << "<span class='warning'>[pick("NICE TRY BUT NO!","CLEVER BUT NOT CLEVER ENOUGH!", "SUCH FLAGRANT CHEESING IS WHY WE ACCEPTED YOUR APPLICATION!", "CUTE!", "YOU DIDN'T THINK IT'D BE THAT EASY, DID YOU?")]</span>"
L << "<span class='caution'>Glowing red letters appear on the front cover...</span>"
L << "<span class='warning'>[pick("NICE TRY BUT NO!","CLEVER BUT NOT CLEVER ENOUGH!", "SUCH FLAGRANT CHEESING IS WHY WE ACCEPTED YOUR APPLICATION!", "CUTE!", "YOU DIDN'T THINK IT'D BE THAT EASY, DID YOU?")]</span>"
burnt_out = 1
else if(istype(item, /obj/item/weapon/gun/magic))
var/obj/item/weapon/gun/magic/I = item
@@ -86,9 +86,9 @@
charged_item = item
break
if(!charged_item)
user << "<span class='notice'>you feel magical power surging to your hands, but the feeling rapidly fades...</span>"
L << "<span class='notice'>you feel magical power surging to your hands, but the feeling rapidly fades...</span>"
else if(burnt_out)
user << "<span class='caution'>[charged_item] doesn't seem to be reacting to the spell...</span>"
L << "<span class='caution'>[charged_item] doesn't seem to be reacting to the spell...</span>"
else
playsound(get_turf(usr), "sound/magic/Charge.ogg", 50, 1)
user << "<span class='notice'>[charged_item] suddenly feels very warm!</span>"
playsound(get_turf(L), "sound/magic/Charge.ogg", 50, 1)
L << "<span class='notice'>[charged_item] suddenly feels very warm!</span>"
@@ -15,8 +15,8 @@

var/cast_sound = 'sound/items/welder.ogg'

/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets)
playsound(get_turf(usr), cast_sound, 50,1)
/obj/effect/proc_holder/spell/aoe_turf/conjure/cast(list/targets,mob/user = usr)
playsound(get_turf(user), cast_sound, 50,1)
for(var/turf/T in targets)
if(T.density && !summon_ignore_density)
targets -= T
@@ -22,13 +22,13 @@

/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr)

var/turf/T = get_turf(usr)
var/turf/T = get_turf(user)
for(var/i = 1; i < range; i++)
var/turf/new_turf = get_step(T, usr.dir)
var/turf/new_turf = get_step(T, user.dir)
if(new_turf.density)
break
T = new_turf
perform(list(T))
perform(list(T),user = user)

/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr)
playMagSound()
@@ -46,7 +46,7 @@
projectile.dir = get_dir(projectile, target)
projectile.name = proj_name

var/current_loc = usr.loc
var/current_loc = user.loc

projectile.loc = current_loc

@@ -60,12 +60,12 @@
step(projectile, projectile.dir)

if(projectile.loc == current_loc || i == proj_lifespan)
projectile.cast(current_loc)
projectile.cast(current_loc,user=user)
break

var/mob/living/L = locate(/mob/living) in range(projectile, proj_trigger_range) - usr
var/mob/living/L = locate(/mob/living) in range(projectile, proj_trigger_range) - user
if(L && L.stat != DEAD)
projectile.cast(L.loc)
projectile.cast(L.loc,user=user)
break

if(proj_trail && projectile)
@@ -8,8 +8,8 @@
action_icon_state = "emp"
sound = "sound/weapons/ZapBang.ogg"

/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets)
playsound(get_turf(usr), sound, 50,1)
/obj/effect/proc_holder/spell/targeted/emplosion/cast(list/targets,mob/user = usr)
playsound(get_turf(user), sound, 50,1)
for(var/mob/living/target in targets)
empulse(target.loc, emp_heavy, emp_light)

@@ -15,8 +15,8 @@
var/jaunt_duration = 50 //in deciseconds
action_icon_state = "jaunt"

/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded
playsound(get_turf(usr), 'sound/magic/Ethereal_Enter.ogg', 50, 1, -1)
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast(list/targets,mob/user = usr) //magnets, so mostly hardcoded
playsound(get_turf(user), 'sound/magic/Ethereal_Enter.ogg', 50, 1, -1)
for(var/mob/living/target in targets)
target.notransform = 1 //protects the mob from being transformed (replaced) midjaunt and getting stuck in bluespace
spawn(0)
@@ -50,7 +50,7 @@
jaunt_steam(mobloc)
target.canmove = 0
holder.reappearing = 1
playsound(get_turf(usr), 'sound/magic/Ethereal_Exit.ogg', 50, 1, -1)
playsound(get_turf(user), 'sound/magic/Ethereal_Exit.ogg', 50, 1, -1)
sleep(20)
jaunt_reappear(animation, target)
sleep(5)
@@ -7,7 +7,7 @@
var/ex_light = 3
var/ex_flash = 4

/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets)
/obj/effect/proc_holder/spell/targeted/explosion/cast(list/targets,mob/user = usr)

for(var/mob/living/target in targets)
explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash)
@@ -15,7 +15,7 @@
6th bit - ?
*/

/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets)
/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr)
playMagSound()
for(var/mob/living/carbon/target in targets)
if(!target.dna)
@@ -19,7 +19,7 @@

var/summon_type = null //this will put an obj at the target's location

/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets)
/obj/effect/proc_holder/spell/targeted/inflict_handler/cast(list/targets,mob/user = usr)

for(var/mob/living/target in targets)
playsound(target,sound, 50,1)
@@ -40,21 +40,11 @@

if(!target)
continue
//damage
if(amt_dam_brute > 0)
if(amt_dam_fire >= 0)
target.take_overall_damage(amt_dam_brute,amt_dam_fire)
else if (amt_dam_fire < 0)
target.take_overall_damage(amt_dam_brute,0)
target.heal_overall_damage(0,amt_dam_fire)
else if(amt_dam_brute < 0)
if(amt_dam_fire > 0)
target.take_overall_damage(0,amt_dam_fire)
target.heal_overall_damage(amt_dam_brute,0)
else if (amt_dam_fire <= 0)
target.heal_overall_damage(amt_dam_brute,amt_dam_fire)
//damage/healing
target.adjustBruteLoss(amt_dam_brute)
target.adjustFireLoss(amt_dam_fire)
target.adjustToxLoss(amt_dam_tox)
target.oxyloss += amt_dam_oxy
target.adjustOxyLoss(amt_dam_oxy)
//disabling
target.Weaken(amt_weakened)
target.Paralyse(amt_paralysis)
@@ -12,8 +12,8 @@

action_icon_state = "knock"

/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets)
usr << sound("sound/magic/Knock.ogg")
/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr)
user << sound("sound/magic/Knock.ogg")
for(var/turf/T in targets)
for(var/obj/machinery/door/door in T.contents)
spawn(1)
@@ -34,35 +34,35 @@
ticker.mode.round_ends_with_antag_death = 1
..()

/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets)
for(var/mob/user in targets)
/obj/effect/proc_holder/spell/targeted/lichdom/cast(list/targets,mob/user = usr)
for(var/mob/M in targets)
var/list/hand_items = list()
if(iscarbon(user))
hand_items = list(user.get_active_hand(),user.get_inactive_hand())
if(iscarbon(M))
hand_items = list(M.get_active_hand(),M.get_inactive_hand())

if(marked_item && !stat_allowed) //sanity, shouldn't happen without badminry
marked_item = null
return

if(stat_allowed) //Death is not my end!
if(user.stat == CONSCIOUS && iscarbon(user))
user << "<span class='notice'>You aren't dead enough to revive!</span>" //Usually a good problem to have
if(M.stat == CONSCIOUS && iscarbon(M))
M << "<span class='notice'>You aren't dead enough to revive!</span>" //Usually a good problem to have
charge_counter = charge_max
return

if(!marked_item || qdeleted(marked_item)) //Wait nevermind
user << "<span class='warning'>Your phylactery is gone!</span>"
M << "<span class='warning'>Your phylactery is gone!</span>"
return

var/turf/user_turf = get_turf(user)
var/turf/user_turf = get_turf(M)
var/turf/item_turf = get_turf(marked_item)

if(user_turf.z != item_turf.z)
user << "<span class='warning'>Your phylactery is out of range!</span>"
M << "<span class='warning'>Your phylactery is out of range!</span>"
return

if(isobserver(user))
var/mob/dead/observer/O = user
if(isobserver(M))
var/mob/dead/observer/O = M
O.reenter_corpse()

var/mob/living/carbon/human/lich = new /mob/living/carbon/human(item_turf)
@@ -72,8 +72,8 @@
lich.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(lich), slot_wear_suit)
lich.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(lich), slot_head)

lich.real_name = user.mind.name
user.mind.transfer_to(lich)
lich.real_name = M.mind.name
M.mind.transfer_to(lich)
lich.hardset_dna(null,null,lich.real_name,null,/datum/species/skeleton)
lich << "<span class='warning'>Your bones clatter and shutter as they're pulled back into this world!</span>"
charge_max += 600
@@ -99,15 +99,15 @@
if(ABSTRACT in item.flags || NODROP in item.flags)
continue
marked_item = item
user << "<span class='warning'>You begin to focus your very being into the [item.name]...</span>"
M << "<span class='warning'>You begin to focus your very being into the [item.name]...</span>"
break

if(!marked_item)
user << "<span class='caution'>You must hold an item you wish to make your phylactery...</span>"
M << "<span class='caution'>You must hold an item you wish to make your phylactery...</span>"

spawn(50)
if(marked_item.loc != user) //I changed my mind I don't want to put my soul in a cheeseburger!
user << "<span class='warning'>Your soul snaps back to your body as you drop the [marked_item.name]!</span>"
if(marked_item.loc != M) //I changed my mind I don't want to put my soul in a cheeseburger!
M << "<span class='warning'>Your soul snaps back to your body as you drop the [marked_item.name]!</span>"
marked_item = null
return
name = "RISE!"
@@ -118,11 +118,11 @@
marked_item.name = "Ensouled [marked_item.name]"
marked_item.desc = "A terrible aura surrounds this item, its very existence is offensive to life itself..."
marked_item.color = "#003300"
user << "<span class='userdanger'>With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!</span>"
user.set_species(/datum/species/skeleton)
current_body = user.mind.current
if(ishuman(user))
var/mob/living/carbon/human/H = user
M << "<span class='userdanger'>With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!</span>"
M.set_species(/datum/species/skeleton)
current_body = M.mind.current
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.unEquip(H.wear_suit)
H.unEquip(H.head)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), slot_wear_suit)
@@ -27,7 +27,7 @@
Snd = new/sound('sound/magic/lightning_chargeup.ogg',channel = 7)
halo = image("icon"='icons/effects/effects.dmi',"icon_state" ="electricity","layer" = EFFECTS_LAYER)
user.overlays.Add(halo)
playsound(get_turf(usr), Snd, 50, 0)
playsound(get_turf(user), Snd, 50, 0)
if(do_mob(user,user,100,uninterruptible=1))
if(ready && cast_check(skipcharge=1))
choose_targets()
@@ -48,13 +48,13 @@
ready = 0
var/mob/living/carbon/target = targets[1]
Snd=sound(null, repeat = 0, wait = 1, channel = Snd.channel) //byond, why you suck?
playsound(get_turf(usr),Snd,50,0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
playsound(get_turf(user),Snd,50,0)// Sorry MrPerson, but the other ways just didn't do it the way i needed to work, this is the only way.
if(get_dist(user,target)>range)
user << "<span class='notice'>They are too far away!</span>"
Reset(user)
return

playsound(get_turf(usr), 'sound/magic/lightningbolt.ogg', 50, 1)
playsound(get_turf(user), 'sound/magic/lightningbolt.ogg', 50, 1)
user.Beam(target,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)

Bolt(user,target,30,5,user)
@@ -53,7 +53,7 @@
still_recharging_msg = "<span class='warning'>You'll have to wait before you can give your vow of silence again!</span>"
..()

/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets)
/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr)
for(var/mob/living/carbon/human/H in targets)
H.mind.miming=!H.mind.miming
if(H.mind.miming)
@@ -38,7 +38,7 @@
projectile.dir = get_dir(target,projectile)
projectile.name = proj_name

var/current_loc = usr.loc
var/current_loc = user.loc

projectile.loc = current_loc

@@ -76,7 +76,7 @@
qdel(trail)

if(projectile.loc in range(target.loc,proj_trigger_range))
projectile.perform(list(target))
projectile.perform(list(target),user=user)
break

current_loc = projectile.loc
@@ -15,7 +15,7 @@
var/list/current_shapes = list()
var/list/current_casters = list()

/obj/effect/proc_holder/spell/targeted/shapeshift/cast(list/targets)
/obj/effect/proc_holder/spell/targeted/shapeshift/cast(list/targets,mob/user = usr)
for(var/mob/living/M in targets)
if(M in current_shapes)
Restore(M)
@@ -15,9 +15,9 @@

action_icon_state = "summons"

/obj/effect/proc_holder/spell/targeted/summonitem/cast(list/targets)
for(var/mob/living/user in targets)
var/list/hand_items = list(user.get_active_hand(),user.get_inactive_hand())
/obj/effect/proc_holder/spell/targeted/summonitem/cast(list/targets,mob/user = usr)
for(var/mob/living/L in targets)
var/list/hand_items = list(L.get_active_hand(),L.get_inactive_hand())
var/butterfingers = 0
var/message

@@ -58,7 +58,7 @@
var/obj/item/organ/internal/organ = item_to_retrive
if(organ.owner)
// If this code ever runs I will be happy
add_logs(user, organ.owner, "magically removed [organ.name] from", addition="INTENT: [uppertext(user.a_intent)]")
add_logs(L, organ.owner, "magically removed [organ.name] from", addition="INTENT: [uppertext(L.a_intent)]")
organ.Remove(organ.owner)
else
while(!isturf(item_to_retrive.loc) && infinite_recursion < 10) //if it's in something you get the whole thing.
@@ -67,7 +67,7 @@

if(issilicon(M)) //Items in silicons warp the whole silicon
M.loc.visible_message("<span class='warning'>[M] suddenly disappears!</span>")
M.loc = user.loc
M.loc = L.loc
M.loc.visible_message("<span class='caution'>[M] suddenly appears!</span>")
item_to_retrive = null
break
@@ -95,22 +95,22 @@
item_to_retrive.loc.visible_message("<span class='warning'>The [item_to_retrive.name] suddenly disappears!</span>")


if(user.hand) //left active hand
if(!user.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1))
if(!user.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1))
if(L.hand) //left active hand
if(!L.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1))
if(!L.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1))
butterfingers = 1
else //right active hand
if(!user.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1))
if(!user.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1))
if(!L.equip_to_slot_if_possible(item_to_retrive, slot_r_hand, 0, 1, 1))
if(!L.equip_to_slot_if_possible(item_to_retrive, slot_l_hand, 0, 1, 1))
butterfingers = 1
if(butterfingers)
item_to_retrive.loc = user.loc
item_to_retrive.loc = L.loc
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears!</span>")
playsound(get_turf(user),"sound/magic/SummonItems_generic.ogg",50,1)
playsound(get_turf(L),"sound/magic/SummonItems_generic.ogg",50,1)
else
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears in [user]'s hand!</span>")
playsound(get_turf(user),"sound/magic/SummonItems_generic.ogg",50,1)
item_to_retrive.loc.visible_message("<span class='caution'>The [item_to_retrive.name] suddenly appears in [L]'s hand!</span>")
playsound(get_turf(L),"sound/magic/SummonItems_generic.ogg",50,1)


if(message)
user << message
L << message
@@ -14,10 +14,10 @@
return 0
..()

/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets)
for(var/mob/living/carbon/user in targets)
/obj/effect/proc_holder/spell/targeted/touch/cast(list/targets,mob/user = usr)
for(var/mob/living/carbon/C in targets)
if(!attached_hand)
if(!ChargeHand(user))
if(!ChargeHand(C))
return 0
while(attached_hand) //hibernate untill the spell is actually used
charge_counter = 0
@@ -19,7 +19,7 @@
starting_spells = null
return ..()

/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets)
/obj/effect/proc_holder/spell/targeted/trigger/cast(list/targets,mob/user = usr)
playMagSound()
for(var/mob/living/target in targets)
for(var/obj/effect/proc_holder/spell/spell in contents)
@@ -11,8 +11,8 @@
var/sound1 = "sound/weapons/ZapBang.ogg"
var/sound2 = "sound/weapons/ZapBang.ogg"

/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets)
playsound(get_turf(usr), sound1, 50,1)
/obj/effect/proc_holder/spell/targeted/turf_teleport/cast(list/targets,mob/user = usr)
playsound(get_turf(user), sound1, 50,1)
for(var/mob/living/target in targets)
var/list/turfs = new/list()
for(var/turf/T in range(target,outer_tele_radius))
@@ -41,4 +41,4 @@
if(target.buckled_mob)
target.unbuckle_mob(force=1)
target.loc = picked
playsound(get_turf(usr), sound2, 50,1)
playsound(get_turf(user), sound2, 50,1)
@@ -273,7 +273,7 @@
action_icon_state = "fireball"
sound = "sound/magic/Fireball.ogg"

/obj/effect/proc_holder/spell/turf/fireball/cast(turf/T)
/obj/effect/proc_holder/spell/turf/fireball/cast(turf/T,mob/user = usr)
explosion(T, -1, 0, 2, 3, 0, flame_range = 2)


@@ -303,8 +303,7 @@

action_icon_state = "repulse"

/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets)
var/mob/user = usr
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr)
var/list/thrownatoms = list()
var/atom/throwtarget
var/distfromcaster
@@ -351,9 +350,9 @@
action_icon_state = "tailsweep"
action_background_icon_state = "bg_alien"

/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno/cast(list/targets)
if(istype(usr, /mob/living/carbon))
var/mob/living/carbon/C = usr
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno/cast(list/targets,mob/user = usr)
if(istype(user, /mob/living/carbon))
var/mob/living/carbon/C = user
playsound(C.loc, 'sound/voice/hiss5.ogg', 80, 1, 1)
C.spin(6,1)
..()
@@ -1184,8 +1184,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/clothing/under/plasmaman,
/obj/item/weapon/tank/internals/plasmaman/belt/full,
/obj/item/weapon/tank/internals/plasmaman/belt/full,
/obj/item/clothing/head/helmet/plasmaman,
/obj/item/clothing/head/helmet/plasmaman)
/obj/item/clothing/head/helmet/space/plasmaman,
/obj/item/clothing/head/helmet/space/plasmaman)
cost = 20
containername = "plasma-man supply kit"

@@ -373,7 +373,6 @@ var/list/uplink_items = list()
desc = "A box of shurikens from ancient Earth martial arts. They are highly effective throwing weapons, and will embed into limbs when possible."
item = /obj/item/weapon/storage/box/throwing_stars
cost = 6
excludefrom = list(/datum/game_mode/nuclear)

/datum/uplink_item/stealthy_weapons/edagger
name = "Energy Dagger"
@@ -583,6 +582,16 @@ var/list/uplink_items = list()
cost = 8
excludefrom = list(/datum/game_mode/gang)

/datum/uplink_item/device_tools/hardsuit
name = "Elite Syndicate Hardsuit"
desc = "The elite Syndicate hardsuit is worn by only the best nuclear agents. Features much better armoring and complete fireproofing, as well as a built in jetpack. \
When the built in helmet is deployed your identity will be protected, even in death, as the suit cannot be removed by outside forces. Toggling the suit into combat mode \
will allow you all the mobility of a loose fitting uniform without sacrificing armoring. Additionally the suit is collapsible, small enough to fit within a backpack. \
Nanotrasen crewmembers are trained to report red space suit sightings; these suits in particular are known to drive employees into a panic."
item = /obj/item/clothing/suit/space/hardsuit/syndi/elite
cost = 8
gamemodes = list(/datum/game_mode/nuclear)

/datum/uplink_item/device_tools/thermal
name = "Thermal Imaging Glasses"
desc = "These goggles can be turned to resemble common eyewears throughout the station. \
@@ -793,7 +802,6 @@ var/list/uplink_items = list()
You can also play card games with them or leave them on your victims."
item = /obj/item/toy/cards/deck/syndicate
cost = 1
excludefrom = list(/datum/game_mode/nuclear)
surplus = 40

/datum/uplink_item/badass/syndiecash
@@ -874,4 +882,4 @@ var/list/uplink_items = list()
U.purchase_log += "<BIG>\icon[C]</BIG>"
for(var/item in bought_items)
new item(C)
U.purchase_log += "<BIG>\icon[item]</BIG>"
U.purchase_log += "<BIG>\icon[item]</BIG>"
@@ -30,6 +30,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/lightswitch = 1
var/valid_territory = 1 //If it's a valid territory for gangs to claim

var/blob_allowed = 1 //Does it count for blobs score? By default, all areas count.

var/eject = null

var/requires_power = 1
@@ -97,6 +99,7 @@ var/list/teleportlocs = list()
power_environ = 0
valid_territory = 0
ambientsounds = list('sound/ambience/ambispace.ogg','sound/ambience/title2.ogg',)
blob_allowed = 0 //Eating up space doesn't count for victory as a blob.

/area/space/nearstation
icon_state = "space_near"
@@ -164,6 +167,7 @@ var/list/teleportlocs = list()
icon_state = "centcom"
requires_power = 0
has_gravity = 1
blob_allowed = 0 //Should go without saying, no blobs should take over centcom as a win condition.

/area/centcom/control
name = "Centcom Docks"
@@ -190,6 +194,7 @@ var/list/teleportlocs = list()
icon_state = "syndie-ship"
requires_power = 0
has_gravity = 1
blob_allowed = 0 //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.

/area/syndicate_mothership/control
name = "Syndicate Control Room"
@@ -206,6 +211,8 @@ var/list/teleportlocs = list()
icon_state = "asteroid"
requires_power = 0
has_gravity = 1
blob_allowed = 0 //Nope, no winning on the asteroid as a blob. Gotta eat the station.
valid_territory = 0

/area/asteroid/cave
name = "Asteroid - Underground"
@@ -1011,6 +1018,7 @@ var/list/teleportlocs = list()
name = "Ruskie DJ Station"
icon_state = "DJ"
has_gravity = 1
blob_allowed = 0 //Nope, no winning on the DJ station as a blob. Gotta eat the main station.

/area/djstation/solars
name = "DJ Station Solars"
@@ -1022,6 +1030,7 @@ var/list/teleportlocs = list()
/area/derelict
name = "Derelict Station"
icon_state = "storage"
blob_allowed = 0 //Nope, no winning on the derelict as a blob. Gotta eat the station.

/area/derelict/hallway/primary
name = "Derelict Primary Hallway"
@@ -1,9 +1,10 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31

//Few global vars to track the blob
var/list/blobs = list()
var/list/blobs = list() //complete list of all blobs made.
var/list/blob_cores = list()
var/list/blob_nodes = list()
var/list/blobs_legit = list() //used for win-score calculations, contains only blobs counted for win condition


/datum/game_mode/blob
@@ -1,7 +1,7 @@
/datum/game_mode/blob/check_finished()
if(infected_crew.len > burst)//Some blobs have yet to burst
return 0
if(blobwincount <= blobs.len)//Blob took over
if(blobwincount <= blobs_legit.len)//Blob took over
return 1
if(!blob_cores.len) // blob is dead
if(config.continuous["blob"])
@@ -19,7 +19,7 @@
/datum/game_mode/blob/declare_completion()
if(round_converted) //So badmin blobs later don't step on the dead natural blobs metaphorical toes
..()
if(blobwincount <= blobs.len)
if(blobwincount <= blobs_legit.len)
feedback_set_details("round_end_result","win - blob took over")
world << "<FONT size = 3><B>The blob has taken over the station!</B></FONT>"
world << "<B>The entire station was eaten by the Blob</B>"
@@ -17,9 +17,11 @@
var/fire_resist = 1
var/mob/camera/blob/overmind


/obj/effect/blob/New(loc)
blobs += src
var/area/Ablob = get_area(loc)
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
blobs_legit += src
blobs += src //Keep track of the blob in the normal list either way
src.dir = pick(1, 2, 4, 8)
src.update_icon()
..(loc)
@@ -31,15 +33,19 @@
return

/obj/effect/blob/Destroy()
blobs -= src
if(isturf(loc)) //Necessary because Expand() is retarded and spawns a blob and then deletes it
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
var/area/Ablob = get_area(loc)
if(Ablob.blob_allowed) //Only remove for blobs in areas that counted for the win
blobs_legit -= src
blobs -= src //It's still removed from the normal list
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Expand() is no longer broken, no check necessary.
return ..()


/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0) return 1
if(istype(mover) && mover.checkpass(PASSBLOB)) return 1
if(height==0)
return 1
if(istype(mover) && mover.checkpass(PASSBLOB))
return 1
return 0


@@ -93,7 +99,8 @@
var/list/dirs = list(1,2,4,8)
dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us
for(var/i = 1 to 4)
if(!dirs.len) break
if(!dirs.len)
break
var/dirn = pick(dirs)
dirs.Remove(dirn)
var/turf/T = get_step(src, dirn)
@@ -120,28 +127,37 @@
var/dirn = pick(dirs)
dirs.Remove(dirn)
T = get_step(src, dirn)
if(!(locate(/obj/effect/blob) in T)) break
else T = null

if(!T) return 0
var/obj/effect/blob/B = new /obj/effect/blob/normal(src.loc)
if(!(locate(/obj/effect/blob) in T))
break
else
T = null
if(!T)
return 0
var/Blob_spawnable = 1
if(istype(T, /turf/space) && prob(65))
B.health = 0
B.color = a_color
B.density = 1
if(T.Enter(B,src))//Attempt to move into the tile
B.density = initial(B.density)
B.loc = T
B.update_icon()
else
T.blob_act()//If we cant move in hit the turf
B.loc = null //So we don't play the splat sound, see Destroy()
qdel(B)

for(var/atom/A in T)//Hit everything in the turf
A.blob_act()
Blob_spawnable = 0
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) //Let's give some feedback that we DID try to spawn in space, since players are used to it
for(var/atom/A in T)
if(A.density) //Unless density is 0, don't spawn a blob
Blob_spawnable = 0
A.blob_act() //Hit everything
if(T.density) //Check for walls and such dense turfs
Blob_spawnable = 0
T.blob_act() //Hit the turf
if(Blob_spawnable)
var/obj/effect/blob/B = new /obj/effect/blob/normal(src.loc)
B.color = a_color
B.density = 1
if(T.Enter(B,src)) //NOW we can attempt to move into the tile
B.density = initial(B.density)
B.loc = T
B.update_icon()
else
T.blob_act() //If we cant move in hit the turf
qdel(B) //We should never get to this point, since we checked before moving in. Destroy blob anyway for cleanliness though
return 1


/obj/effect/blob/ex_act(severity, target)
..()
var/damage = 150 - 20 * severity
@@ -358,12 +358,8 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
return
return 1

/datum/changeling/proc/add_profile(var/mob/living/carbon/human/H, var/mob/living/carbon/user, protect = 0)
if(stored_profiles.len > dna_max)
if(!push_out_profile())
return

var/datum/changelingprofile/prof = new()
/datum/changeling/proc/create_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
var/datum/changelingprofile/prof = new

H.dna.real_name = H.real_name //Set this again, just to be sure that it's properly set.
var/datum/dna/new_dna = new H.dna.type
@@ -391,12 +387,22 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
else
continue

return prof

/datum/changeling/proc/add_profile(datum/changelingprofile/prof)
if(stored_profiles.len > dna_max)
if(!push_out_profile())
return

stored_profiles += prof
absorbedcount++

/datum/changeling/proc/add_new_profile(mob/living/carbon/human/H, mob/living/carbon/human/user, protect = 0)
var/datum/changelingprofile/prof = create_profile(H, protect)
add_profile(prof)
return prof

/datum/changeling/proc/remove_profile(var/mob/living/carbon/human/H, force = 0)
/datum/changeling/proc/remove_profile(mob/living/carbon/human/H, force = 0)
for(var/datum/changelingprofile/prof in stored_profiles)
if(H.real_name == prof.name)
if(prof.protected && !force)
@@ -416,7 +422,7 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
return 1
return 0

/proc/changeling_transform(var/mob/living/carbon/human/user, var/datum/changelingprofile/chosen_prof)
/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof)
var/datum/dna/chosen_dna = chosen_prof.dna
user.real_name = chosen_prof.name
user.underwear = chosen_prof.underwear
@@ -476,4 +482,19 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas

/datum/changelingprofile/Destroy()
qdel(dna)
return ..()
return ..()

/datum/changelingprofile/proc/copy_profile(datum/changelingprofile/newprofile)
newprofile.name = name
newprofile.protected = protected
newprofile.dna = new dna.type
dna.copy_dna(newprofile.dna)
newprofile.name_list = name_list.Copy()
newprofile.appearance_list = appearance_list.Copy()
newprofile.flags_cover_list = flags_cover_list.Copy()
newprofile.exists_list = exists_list.Copy()
newprofile.item_color_list = item_color_list.Copy()
newprofile.item_state_list = item_state_list.Copy()
newprofile.underwear = underwear
newprofile.undershirt = undershirt
newprofile.socks = socks
@@ -372,7 +372,7 @@ var/list/sting_paths

var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste
if(ishuman(C))
var/datum/changelingprofile/prof = mind.changeling.add_profile(C)
var/datum/changelingprofile/prof = mind.changeling.add_new_profile(C, src)
mind.changeling.first_prof = prof
return 1

@@ -54,7 +54,7 @@
target << "<span class='userdanger'>You are absorbed by the changeling!</span>"

if(!changeling.has_dna(target.dna))
changeling.add_profile(target, user)
changeling.add_new_profile(target, user)

if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
@@ -152,7 +152,7 @@
target << "<span class='userdanger'>[user] tightens their grip as a painful sensation invades your body.</span>"

if(!changeling.has_dna(target.dna))
changeling.add_profile(target, user)
changeling.add_new_profile(target, user)
changeling.remove_profile(user)

var/mob/dead/observer/ghost = target.ghostize(0)
@@ -47,7 +47,9 @@ var/list/datum/dna/hivemind_bank = list()
if(!chosen_dna)
return

hivemind_bank += chosen_dna
var/datum/changelingprofile/uploaded_dna = new chosen_dna.type
chosen_dna.copy_profile(uploaded_dna)
hivemind_bank += uploaded_dna
user << "<span class='notice'>We channel the DNA of [chosen_name] to the air.</span>"
feedback_add_details("changeling_powers","HU")
return 1
@@ -85,7 +87,9 @@ var/list/datum/dna/hivemind_bank = list()
if(!chosen_prof)
return

changeling.add_profile(chosen_prof, user)
var/datum/changelingprofile/downloaded_prof = new chosen_prof.type
chosen_prof.copy_profile(downloaded_prof)
changeling.add_profile(downloaded_prof)
user << "<span class='notice'>We absorb the DNA of [S] from the air.</span>"
feedback_add_details("changeling_powers","HD")
return 1
@@ -175,7 +175,7 @@
/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
add_logs(user, target, "stung", "extraction sting")
if(!(user.mind.changeling.has_dna(target.dna)))
user.mind.changeling.add_profile(target, user)
user.mind.changeling.add_new_profile(target, user)
feedback_add_details("changeling_powers","ED")
return 1

@@ -41,9 +41,9 @@
for(var/mob/M in mob_list)
if(iscultist(M) || (M in dead_mob_list))
if(clear || !ishuman(user))
M << "<span class='boldannounce'><i>[(ishuman(user) ? "Acolyte" : "Construct")] [user]:</i> [message]</span>"
M << "<span class='cultitalic'><b>[(ishuman(user) ? "Acolyte" : "Construct")] [user]:</b> [message]</span>"
else //Emergency comms
M << "<span class='ghostalert'><i>Acolyte ???:</i> [message]</span>"
M << "<span class='purple'><i>Acolyte ???:</i> <b>[message]</b></span>"
log_say("[user.real_name]/[user.key] : [message]")


@@ -76,12 +76,11 @@


/datum/game_mode/cult/pre_setup()
cult_objectives += "sacrifice"
if(prob(50))
cult_objectives += "survive"
cult_objectives += "sacrifice"
else
cult_objectives += "eldergod"
cult_objectives += "sacrifice"

if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
@@ -16,7 +16,7 @@
if(!iscultist(user))
user.Weaken(5)
user.visible_message("<span class='warning'>A powerful force shoves [user] away from [target]!</span>", \
"<span class='cult'>\"You shouldn't play with sharp things. You'll poke someone's eye out.\"</span>")
"<span class='cultlarge'>\"You shouldn't play with sharp things. You'll poke someone's eye out.\"</span>")
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(rand(force/2, force), BRUTE, pick("l_arm", "r_arm"))
@@ -27,7 +27,7 @@

/obj/item/weapon/melee/cultblade/pickup(mob/living/user)
if(!iscultist(user))
user << "<span class='cult'>\"I wouldn't advise that.\"</span>"
user << "<span class='cultlarge'>\"I wouldn't advise that.\"</span>"
user << "<span class='warning'>An overwhelming sense of nausea overpowers you!</span>"
user.Dizzy(120)

@@ -25,7 +25,7 @@ It also contains rune words, which are soon to be removed.
return

if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate
usr.visible_message("<span class='warning'>[usr] starts clawing at \his arms with \his fingernails!</span>", "<span class='warning'>You begin slicing open your arms with your fingernails!</span>")
usr.visible_message("<span class='warning'>[usr] starts clawing at \his arms with \his fingernails!</span>", "<span class='cultitalic'>You begin slicing open your arms with your fingernails!</span>")
apply_damage(10,BRUTE, "l_arm")
apply_damage(10,BRUTE, "r_arm")
sleep(50)
@@ -38,7 +38,7 @@ It also contains rune words, which are soon to be removed.
apply_damage(10,BRUTE, "r_arm")
if(usr.incapacitated())
return
usr.visible_message("<span class='warning'>[usr] paints strange symbols with their own blood.</span>", "<span class='warning'>You paint a messy rune with your own blood.</span>")
usr.visible_message("<span class='warning'>[usr] paints strange symbols with their own blood.</span>", "<span class='cultitalic'>You paint a messy rune with your own blood.</span>")
sleep(20)

cultist_commune(usr, 0, 1, input)
@@ -56,13 +56,13 @@ It also contains rune words, which are soon to be removed.
/obj/item/weapon/tome/examine(mob/user)
..()
if(iscultist(user))
user << "The scriptures of the Geometer. Allows the scribing of runes and access of knowledge archives."
user << "The scriptures of the Geometer. Allows the scribing of runes and access to the knowledge archives of the cult of Nar-Sie."

/obj/item/weapon/tome/attack(mob/living/M, mob/living/user)
if(istype(M,/mob/dead/observer))
M.invisibility = 0
user.visible_message("<span class='warning'>[user] strikes the air with [src], and a spirit appears!</span>", \
"<span class='danger'>You drag the ghost to your plane of reality!</span>")
user.visible_message("<span class='warning'>[user] strikes the air with [src], and a ghost appears!</span>", \
"<span class='cult'>You drag the ghost to your plane of reality!</span>")
add_logs(user, M, "smacked", src)
return
if(!istype(M))
@@ -71,7 +71,7 @@ It also contains rune words, which are soon to be removed.
return ..()
if(iscultist(M))
if(M.reagents && M.reagents.has_reagent("holywater")) //allows cultists to be rescued from the clutches of ordained religion
user << "<span class='notice'>You remove the taint from [M].</span>"
user << "<span class='cult'>You remove the taint from [M].</span>"
var/holy2unholy = M.reagents.get_reagent_amount("holywater")
M.reagents.del_reagent("holywater")
M.reagents.add_reagent("unholywater",holy2unholy)
@@ -92,15 +92,10 @@ It also contains rune words, which are soon to be removed.
open_tome(user)

/obj/item/weapon/tome/proc/open_tome(mob/user)
var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","(More...)")
var/choice = alert(user,"You open the tome...",,"Commune","Scribe Rune","Read Tome")
switch(choice)
if("(More...)")
var/choice2 = alert(user,"You open the tome...",,"(Back...)", "Information")
switch(choice2)
if("(Back...)")
return open_tome(user)
if("Information")
read_tome(user)
if("Read Tome")
read_tome(user)
if("Scribe Rune")
scribe_rune(user)
if("Commune")
@@ -115,8 +110,7 @@ It also contains rune words, which are soon to be removed.
text += "As a member of the cult, your goals are almost or entirely impossible to complete without special aid from the Geometer's plane. The primary method of doing this are <b>runes</b>. These \
scribings, drawn in blood, are concentrated nodes of the magic within Nar-Sie's realm and will allow the performance of many tasks to aid you and the rest of the cult in your objectives. Runes \
have many different names, and almost all of them are known as Rites. The only rune that is not a Rite is the Ritual of Dimensional Rending, which can only be performed with nine cultists and calls \
forth the avatar of the Geometer itself (so long as it consents). A small description of each rune can be found below.<br><br>Do note that sometimes runes can be drawn incorrectly. Runes such as these \
will be colorful and written in gibberish. They are malformed, and invoking them serves only to ignite the Geometer's wrath. Be cautious in your scribings.<br><br>A rune's name and effects can be \
forth the avatar of the Geometer herself (so long as she consents). A small description of each rune can be found below.<br><br>A rune's name and effects can be \
revealed by examining the rune.<br><br><br>"/*In order to write a rune, you must know the combination of words required for the rune. These words are in the tongue of the Geometer and must be written as such. \
A rune will always have a specific combination, and the combination for runes may be revealed by perfomring actions such as conversion or sacrifice. Once a rune has been written, any cultists can \
examine it to find out its \"grammar\", or the words required to scribe it. To scribe the rune, the words must be entered in lowercase and separated by exactly one space. For instance, to draw a \
@@ -152,23 +146,23 @@ It also contains rune words, which are soon to be removed.

text += "<font color='red'><b>Convert</b></font><br>The Rite of Enlightment is paramount to the success of the cult. It will allow you to convert normal crew members into cultists. \
To do this, simply place the crew member upon the rune and invoke it. This rune requires two acolytes to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \
be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like a null rod will not be converted.<br><br>"
be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like the null rod will not be converted.<br><br>"

text += "<font color='red'><b>Sacrifice</b></font><br>The Rite of Tribute is used to offer sacrifice to the Geometer. Simply place any living creature upon the rune and invoke it (this will not \
target cultists!). If this creature has a mind, a soul shard will be created and the creature's soul transported to it. This rune is required if the cult's objectives include the sacrifice of a crew \
member.<br><br>"

text += "<font color='red'><b>Raise Dead</b></font><br>The Rite of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \
the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to ashes, the life force flowing into the revival target. Assuming the target is not moved \
the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to dust, the life force flowing into the revival target. Assuming the target is not moved \
within a few seconds, they will be brought back to life, healed of all ailments.<br><br>"

text += "<font color='red'><b>Veil Runes</b></font><br>The Rite of Obscurity is a rite that will cause all nearby runes to become invisible. The runes will still be considered by other rites \
(such as the Rite of Translocation) but is unusuable directly.<br><br>"
(such as the Rite of Translocation) but will be unusuable directly.<br><br>"

text += "<font color='red'><b>Reveal Runes</b></font><br>The Rite of True Sight is the foil of the Rite of Obscurity. It will turn all invisible runes visible once more, in addition to causing \
all spirits nearby to become partially corporeal.<br><br>"
all spirits nearby to become visible.<br><br>"

text += "<font color='red'><b>Disguise Runes</b></font><br>Many crew men enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \
text += "<font color='red'><b>Disguise Runes</b></font><br>Many crewmen enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \
False Truths takes advantage of this very joke. When invoked, all nearby runes will appear dull, precisely resembling those drawn in crayon. They still cannot be cleaned by conventional means, so \
anyone trying to clean up the rune may become suspicious as it does not respond.<br><br>"

@@ -190,8 +184,8 @@ It also contains rune words, which are soon to be removed.
text += "<font color='red'><b>Blind</b></font><br>Much like the Rite of the Unheard Whisper, the Rite of the Unseen Glance serves a single purpose. Any non-cultists who can see \
the rune will instantly be blinded for a substantial amount of time.<br><br>"

text += "<font color='red'><b>Stun</b></font><br>A somewhat empowered version of the Rite of the Unseen Glance, this rune will cause any non-cultists that can see the rune to become \
disoriented, disabling them for a short time.<br><br>"
text += "<font color='red'><b>Stun</b></font><br>Though the Rite of Blazing Light is weak when invoked normally, using it in conjuction with the Rite of Binding makes it much more useful. \
This rune will cause any non-cultists that can see the rune to become disoriented, disabling them for a short time.<br><br>"

text += "<font color='red'><b>Summon Cultist</b></font><br>The Rite of Joined Souls requires two acolytes to use. When invoked, it will allow the user to summon a single cultist to the rune from \
any location. This will deal a moderate amount of damage to all invokers.<br><br>"
@@ -202,12 +196,12 @@ It also contains rune words, which are soon to be removed.
text += "<font color='red'><b>Fabricate Shell</b></font><br>The Rite of Fabrication is the main way of creating construct shells. To use it, one must place five sheets of plasteel on top of the rune \
and invoke it. The sheets will them be twisted into a construct shell, ready to recieve a soul to occupy it.<br><br>"

text += "<font color='red'><b>Summon Arnaments</b></font><br>The Rite of Arming will equip the user with invoker's robes, a backpack, a Nar-Sian longsword, and a pair of boots. Any items that cannot \
be equipped will instead not be summoned regardless.<br><br>"
text += "<font color='red'><b>Summon Armaments</b></font><br>The Rite of Arming will equip the user with armored robes, a backpack, an eldrich longsword, and a pair of boots. Any items that cannot \
be equipped will not be summoned.<br><br>"

text += "<font color='red'><b>Drain Life</b></font><br>The Rite of Leeching will drain the life of any non-cultist above the rune and heal the invoker for the same amount.<br><br>"

text += "<font color='red'><b>Boil Blood</b></font><br>The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the Nar-Sian cult. When invoked, it will do a \
text += "<font color='red'><b>Blood Boil</b></font><br>The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the cult of Nar-Sie. When invoked, it will do a \
massive amount of damage to all non-cultist viewers, but it will also emit an explosion upon invocation. Use with caution<br><br>"

text += "<font color='red'><b>Manifest Spirit</b></font><br>If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \
@@ -226,12 +220,13 @@ It also contains rune words, which are soon to be removed.
text += "<font color='red'><b>Talisman of Teleportation</b></font><br>The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \
disappear.<br><br>"

text += "<font color='red'><b>Talisman of Tome summoning</b></font><br>This talisman functions identically to the rune. It can be used once, then disappears.<br><br>"
text += "<font color='red'><b>Talisman of Tome Summoning</b></font><br>This talisman functions nearly identically to the rune. The talisman will attempt to place the tome in your hand \
instead of on the ground, though this is the only advantage it has over the rune. It can be used once, then disappears.<br><br>"

text += "<font color='red'><b>Talismans of Veiling, Revealing, and Disguising</b></font><br>These talismans all function identically to their rune counterparts, but with less range. In addition, \
the Talisman of True Sight will not reveal spirits. They will disappear after one use.<br><br>"

text += "<font color='red'><b>Talisman of Electromagnets</b></font><br>This talisman functions like the Rite of Disruption. It disappears after one use.<br><br>"
text += "<font color='red'><b>Talisman of Electromagnetic Pulse</b></font><br>This talisman functions like the Rite of Disruption. It disappears after one use.<br><br>"

text += "<font color='red'><b>Talisman of Stunning</b></font><br>Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \
talisman functions differently from others. Rather than simply reading the words, the target must be attacked directly with the talisman. The talisman will then knock down the target for a long \
@@ -267,14 +262,14 @@ It also contains rune words, which are soon to be removed.
if(!rune_to_scribe)
return
user.visible_message("<span class='warning'>[user] cuts open their arm and begins writing in their own blood!</span>", \
"<span class='danger'>You slice open your arm and begin drawing a sigil of the Geometer.</span>")
"<span class='cult'>You slice open your arm and begin drawing a sigil of the Geometer.</span>")
if(iscarbon(user))
var/mob/living/carbon/C = user
C.apply_damage(0.1, BRUTE, pick("l_arm", "r_arm"))
if(!do_after(user, 50, target = get_turf(user)))
return
user.visible_message("<span class='warning'>[user] creates a strange circle in their own blood.</span>", \
"<span class='danger'>You finish drawing the arcane markings of the Geometer.</span>")
"<span class='cult'>You finish drawing the arcane markings of the Geometer.</span>")
var/obj/effect/rune/R = new rune_to_scribe(get_turf(user))
if(chosen_keyword)
R.keyword = chosen_keyword

Large diffs are not rendered by default.

@@ -22,15 +22,16 @@ Rite of Disorientation
var/health_cost = 0 //The amount of health taken from the user when invoking the talisman

/obj/item/weapon/paper/talisman/examine(mob/user)
..()
if(iscultist(user) || user.stat == DEAD)
user << "<b>Name:</b> [cultist_name]"
user << "<b>Effect:</b> [cultist_desc]"
user << "<b>Uses Remaining:</b> [uses]"
return
..()

/obj/item/weapon/paper/talisman/attack_self(mob/living/user)
if(!iscultist(user))
user << "<span class='warning'>There are strange, illegible symbols drawn on [src]. Maybe some sort of blueprint?</span>"
user << "<span class='danger'>There are indecipherable images scrawled on the paper in what looks to be... <i>blood?</i></span>"
return
if(invocation)
user.whisper(invocation)
@@ -52,7 +53,7 @@ Rite of Disorientation
invocation = "Ra'sha yoka!"

/obj/item/weapon/paper/talisman/malformed/invoke(mob/living/user)
user << "<span class='warning'>You feel a pain in your head. The Geometer is displeased.</span>"
user << "<span class='cultitalic'>You feel a pain in your head. The Geometer is displeased.</span>"
if(iscarbon(user))
var/mob/living/carbon/C = user
C.apply_damage(10, BRUTE, "head")
@@ -77,7 +78,7 @@ Rite of Disorientation
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>"
dat += "<A href='?src=\ref[src];rune=soulstone'>Kal'om neth!</A> - Summons a soul stone, used to capure the spirits of dead or dying humans.<BR>"
dat += "<A href='?src=\ref[src];rune=construct'>Daa'ig osk!</A> - Summons a construct shell for use with captured souls. It is too large to carry on your person.<BR>"
var/datum/browser/popup = new(user, "talisman", "", 800, 600)
var/datum/browser/popup = new(user, "talisman", "", 400, 400)
popup.set_content(dat)
popup.open()
uses++ //To prevent uses being consumed just by opening it
@@ -139,13 +140,13 @@ Rite of Disorientation
if(R.keyword == src.keyword)
possible_runes.Add(R)
if(!possible_runes.len)
user << "<span class='warning'>There are no Teleport runes with the same keyword!</span>"
user << "<span class='cultitalic'>There are no Teleport runes with the same keyword!</span>"
log_game("Teleportation talisman failed - no teleport runes of the same keyword")
uses++ //To prevent deletion
return
var/chosen_rune = pick(possible_runes)
user.visible_message("<span class='warning'>Dust flows from [user]'s hand, and they disappear in a flash of red light!</span>", \
"<span class='warning'>You speak the words of the talisman and find yourself somewhere else!</span>")
"<span class='cultitalic'>You speak the words of the talisman and find yourself somewhere else!</span>")
if(user.buckled)
user.buckled.unbuckle_mob()
user.loc = get_turf(chosen_rune)
@@ -164,20 +165,20 @@ Rite of Disorientation
//Rite of Knowledge: Same as rune, but has two uses
/obj/item/weapon/paper/talisman/summon_tome
cultist_name = "Talisman of Tome Summoning"
cultist_desc = "A two-use talisman that will call untranslated tomes from the archives of the Geometer."
cultist_desc = "A one-use talisman that will call an untranslated tome from the archives of the Geometer."
invocation = "N'ath reth sh'yro eth d'raggathnor!"
health_cost = 1

/obj/item/weapon/paper/talisman/summon_tome/invoke(mob/living/user)
user.visible_message("<span class='warning'>Dust flows from [user]'s hand for a moment.</span>", \
"<span class='warning'>You speak the words of the talisman!</span>")
user.visible_message("<span class='warning'>[user]'s hand glows red for a moment.</span>", \
"<span class='cultitalic'>You speak the words of the talisman!</span>")
var/obj/item/weapon/tome/T = new(get_turf(user))
if(user.put_in_hands(T))
user.visible_message("<span class='warning'>A tome appears in [user]'s hand!</span>", \
"<span class='warning'>An arcane tome materializes in your free hand.</span>")
"<span class='cultitalic'>An arcane tome materializes in your free hand.</span>")
else
user.visible_message("<span class='warning'>A tome appears at [user]'s feet!</span>", \
"<span class='warning'>An arcane tome materialzies at your feet.</span>")
"<span class='cultitalic'>An arcane tome materialzies at your feet.</span>")

//Rite of Obscurity: Same as rune, but less range
/obj/item/weapon/paper/talisman/hide_runes
@@ -188,7 +189,7 @@ Rite of Disorientation

/obj/item/weapon/paper/talisman/hide_runes/invoke(mob/living/user)
user.visible_message("<span class='warning'>Dust flows from [user]'s hand.</span>", \
"<span class='warning'>You speak the words of the talisman, veiling nearby runes.</span>")
"<span class='cultitalic'>You speak the words of the talisman, veiling nearby runes.</span>")
for(var/obj/effect/rune/R in orange(3,user))
R.visible_message("<span class='danger'>[R] fades away.</span>")
R.invisibility = INVISIBILITY_OBSERVER
@@ -203,7 +204,7 @@ Rite of Disorientation

/obj/item/weapon/paper/talisman/true_sight/invoke(mob/living/user)
user.visible_message("<span class='warning'>A flash of light shines from [user]'s hand!</span>", \
"<span class='warning'>You speak the words of the talisman, revealing nearby runes.</span>")
"<span class='cultitalic'>You speak the words of the talisman, revealing nearby runes.</span>")
for(var/obj/effect/rune/R in orange(3,user))
R.invisibility = 0

@@ -217,21 +218,21 @@ Rite of Disorientation

/obj/item/weapon/paper/talisman/make_runes_fake/invoke(mob/living/user)
user.visible_message("<span class='warning'>Dust flows from [user]s hand.</span>", \
"<span class='warning'>You speak the words of the talisman, making nearby runes appear fake.</span>")
"<span class='cultitalic'>You speak the words of the talisman, making nearby runes appear fake.</span>")
for(var/obj/effect/rune/R in orange(3,user))
R.desc = "A rune drawn in crayon."


//Rite of Disruption: Same as rune, halved radius
//Rite of Disruption: Same as rune
/obj/item/weapon/paper/talisman/emp
cultist_name = "Talisman of Electromagnets"
cultist_name = "Talisman of Electromagnetic Pulse"
cultist_desc = "A talisman that will cause a moderately-sized electromagnetic pulse."
invocation = "Ta'gh fara'qha fel d'amar det!"
health_cost = 5

/obj/item/weapon/paper/talisman/emp/invoke(mob/living/user)
user.visible_message("<span class='warning'>[user]'s hand flashes a bright blue!</span>", \
"<span class='warning'>You speak the words of the talisman, emitting an EMP blast.</span>")
"<span class='cultitalic'>You speak the words of the talisman, emitting an EMP blast.</span>")
empulse(src, 4, 8)


@@ -243,17 +244,19 @@ Rite of Disorientation
health_cost = 10 //A lot of health because of how powerful this is

/obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user)
user << "<span class='warning'>To use this talisman, attack the target directly.</span>"
return
if(iscultist(user))
user << "<span class='warning'>To use this talisman, attack the target directly.</span>"
else
user << "<span class='danger'>There are indecipherable images scrawled on the paper in what looks to be... <i>blood?</i></span>"

/obj/item/weapon/paper/talisman/stun/attack(mob/living/target, mob/living/user)
if(iscultist(user))
user.whisper(invocation)
user.visible_message("<span class='warning'>[user] holds up [src], which explodes in a flash of red light!</span>", \
"<span class='warning'>You stun [target] with the talisman!</span>")
"<span class='cultitalic'>You stun [target] with the talisman!</span>")
var/obj/item/weapon/nullrod/N = locate() in target
if(N)
target.visible_message("<span class='warning'>[target]'s null rod absorbs the talisman's power!</span>", \
target.visible_message("<span class='warning'>[target]'s null rod absorbs the talisman's light!</span>", \
"<span class='userdanger'>Your null rod absorbs the blinding light!</span>")
else
target.Weaken(10)
@@ -274,13 +277,13 @@ Rite of Disorientation
//Rite of Arming: Equips cultist armor on the user, where available
/obj/item/weapon/paper/talisman/armor
cultist_name = "Talisman of Arming"
cultist_desc = "A talisman that will equip the invoker with cultist equipment where available."
cultist_desc = "A talisman that will equip the invoker with cultist equipment if there is a slot to equip it to."
invocation = "N'ath reth sh'yro eth draggathnor!"
health_cost = 3

/obj/item/weapon/paper/talisman/armor/invoke(mob/living/user)
user.visible_message("<span class='warning'>Otherworldy objects suddenly appear on [user]!</span>", \
"<span class='warning'>You speak the words of the talisman, arming yourself!</span>")
user.visible_message("<span class='warning'>Otherworldly armor suddenly appears on [user]!</span>", \
"<span class='cultitalic'>You speak the words of the talisman, arming yourself!</span>")
user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head)
user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit)
user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), slot_shoes)
@@ -286,7 +286,8 @@
usr << "<span class='notice'>The <b>dominator</b> will secure your gang's dominance over the station. Turn it on when you are ready to defend it.</span>"
pointcost = 30
else
usr << "<span class='notice'>The <b>dominator</b> can be spawned only on territory controlled by your gang.</span>"
usr << "<span class='warning'>The <b>dominator</b> can be spawned only on territory controlled by your gang!</span>"
return

if(item_type)
gang.points -= pointcost
@@ -10,7 +10,6 @@
recommended_enemies = 5
antag_flag = ROLE_OPERATIVE
enemy_minimum_age = 14

var/const/agents_possible = 5 //If we ever need more syndicate agents.

var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer!
@@ -43,6 +42,11 @@
synd_mind.assigned_role = "Syndicate"
synd_mind.special_role = "Syndicate"//So they actually have a special role/N
log_game("[synd_mind.key] (ckey) has been selected as a nuclear operative")
if(ishuman(synd_mind.current))//don't want operatives burning to death instantly.
var/mob/living/carbon/human/human = synd_mind.current
if(human.dna && human.dna.species.dangerous_existence)
human.set_species(/datum/species/human)

return 1


@@ -75,7 +75,7 @@ var/bomb_set
if(istype(I, /obj/item/weapon/screwdriver/nuke))
playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
user << "<span class='notice'>You start removing [src]'s front panel's screws...</span>"
if(do_after(user, 60,target=src))
if(do_after(user, 60/I.toolspeed,target=src))
deconstruction_state = NUKESTATE_UNSCREWED
user << "<span class='notice'>You remove the screws from [src]'s front panel.</span>"
update_icon()
@@ -84,7 +84,7 @@ var/bomb_set
if(istype(I, /obj/item/weapon/crowbar))
user << "<span class='notice'>You start removing [src]'s front panel...</span>"
playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
if(do_after(user,30,target=src))
if(do_after(user,30/I.toolspeed,target=src))
user << "<span class='notice'>You remove [src]'s front panel.</span>"
deconstruction_state = NUKESTATE_PANEL_REMOVED
update_icon()
@@ -95,7 +95,7 @@ var/bomb_set
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
user << "<span class='notice'>You start cutting [src]'s inner plate...</span>"
if(welder.remove_fuel(1,user))
if(do_after(user,80,target=src))
if(do_after(user,80/I.toolspeed,target=src))
user << "<span class='notice'>You cut [src]'s inner plate.</span>"
deconstruction_state = NUKESTATE_WELDED
update_icon()
@@ -104,7 +104,7 @@ var/bomb_set
if(istype(I, /obj/item/weapon/crowbar))
user << "<span class='notice'>You start prying off [src]'s inner plate...</span>"
playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
if(do_after(user,50,target=src))
if(do_after(user,50/I.toolspeed,target=src))
user << "<span class='notice'>You pry off [src]'s inner plate. You can see the core's green glow!</span>"
deconstruction_state = NUKESTATE_CORE_EXPOSED
update_icon()