[MIRROR] Cerestation Tweaks VI: Shuttle Edition (#876)
* Cerestation Tweaks VI: Shuttle Edition * fix .rej
This commit is contained in:
committed by
Poojawa
parent
ad65636014
commit
eb359f1014
@@ -161,6 +161,12 @@
|
||||
description = "A small, but feature complete shuttle. It boasts a card table to keep crew members occupied on the long flight home."
|
||||
credit_cost = 1000
|
||||
|
||||
/datum/map_template/shuttle/emergency/cere
|
||||
suffix = "cere"
|
||||
name = "Cere Station Emergency Shuttle"
|
||||
description = "The large, beefed-up version of the box-standard shuttle. Includes an expanded brig, fully stocked medbay, enhanced cargo storage with mech chargers, \
|
||||
an engine room stocked with various supplies, and a crew capacity of 80+ to top it all off. Live large, live Cere."
|
||||
|
||||
/datum/map_template/shuttle/emergency/supermatter
|
||||
suffix = "supermatter"
|
||||
name = "Hyperfractal Gigashuttle"
|
||||
@@ -230,6 +236,10 @@
|
||||
suffix = "pubby"
|
||||
name = "NT White UFO"
|
||||
|
||||
/datum/map_template/shuttle/whiteship/cere
|
||||
suffix = "cere"
|
||||
name = "NT Construction Vessel"
|
||||
|
||||
/datum/map_template/shuttle/cargo/box
|
||||
suffix = "box"
|
||||
name = "supply shuttle (Box)"
|
||||
|
||||
@@ -1,295 +1,295 @@
|
||||
/obj/item/weapon/antag_spawner
|
||||
throw_speed = 1
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/used = 0
|
||||
|
||||
/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "")
|
||||
return
|
||||
|
||||
/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
|
||||
return
|
||||
|
||||
|
||||
///////////WIZARD
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract
|
||||
name = "contract"
|
||||
desc = "A magic contract previously signed by an apprentice. In exchange for instruction in the magical arts, they are bound to answer your call for aid."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/attack_self(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat
|
||||
if(used)
|
||||
dat = "<B>You have already summoned your apprentice.</B><BR>"
|
||||
else
|
||||
dat = "<B>Contract of Apprenticeship:</B><BR>"
|
||||
dat += "<I>Using this contract, you may summon an apprentice to aid you on your mission.</I><BR>"
|
||||
dat += "<I>If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.</I><BR>"
|
||||
dat += "<B>Which school of magic is your apprentice studying?:</B><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=destruction'>Destruction</A><BR>"
|
||||
dat += "<I>Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=bluespace'>Bluespace Manipulation</A><BR>"
|
||||
dat += "<I>Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=healing'>Healing</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=robeless'>Robeless</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.</I><BR>"
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/Topic(href, href_list)
|
||||
..()
|
||||
var/mob/living/carbon/human/H = usr
|
||||
|
||||
if(H.stat || H.restrained())
|
||||
return
|
||||
if(!ishuman(H))
|
||||
return 1
|
||||
|
||||
if(loc == H || (in_range(src, H) && isturf(loc)))
|
||||
H.set_machine(src)
|
||||
if(href_list["school"])
|
||||
if(used)
|
||||
to_chat(H, "You already used this contract!")
|
||||
return
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src)
|
||||
if(candidates.len)
|
||||
if(used)
|
||||
to_chat(H, "You already used this contract!")
|
||||
return
|
||||
used = 1
|
||||
var/mob/dead/observer/theghost = pick(candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), href_list["school"])
|
||||
if(H && H.mind)
|
||||
SSticker.mode.update_wiz_icons_added(H.mind)
|
||||
else
|
||||
to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/spawn_antag(client/C, turf/T, type = "")
|
||||
new /obj/effect/particle_effect/smoke(T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
M.key = C.key
|
||||
var/wizard_name = "the wizard"
|
||||
if(usr)
|
||||
wizard_name = usr.real_name
|
||||
to_chat(M, "<B>You are [wizard_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.")
|
||||
switch(type)
|
||||
if("destruction")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.")
|
||||
if("bluespace")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.")
|
||||
if("healing")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
|
||||
M.put_in_hands_or_del(new /obj/item/weapon/gun/magic/staff/healing(M))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.")
|
||||
if("robeless")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
|
||||
|
||||
equip_antag(M)
|
||||
var/wizard_name_first = pick(GLOB.wizard_first)
|
||||
var/wizard_name_second = pick(GLOB.wizard_second)
|
||||
var/randomname = "[wizard_name_first] [wizard_name_second]"
|
||||
if(usr)
|
||||
var/datum/objective/protect/new_objective = new /datum/objective/protect
|
||||
new_objective.owner = M.mind
|
||||
new_objective.target = usr.mind
|
||||
new_objective.explanation_text = "Protect [usr.real_name], the wizard."
|
||||
M.mind.objectives += new_objective
|
||||
SSticker.mode.apprentices += M.mind
|
||||
M.mind.special_role = "apprentice"
|
||||
SSticker.mode.update_wiz_icons_added(M.mind)
|
||||
M << sound('sound/effects/magic.ogg')
|
||||
var/newname = copytext(sanitize(input(M, "You are [wizard_name]'s apprentice. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
|
||||
if (!newname)
|
||||
newname = randomname
|
||||
M.mind.name = newname
|
||||
M.real_name = newname
|
||||
M.name = newname
|
||||
M.dna.update_dna_identity()
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/equip_antag(mob/target)
|
||||
target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_ears)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(target), slot_w_uniform)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(target), slot_shoes)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(target), slot_wear_suit)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(target), slot_head)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(target), slot_back)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/storage/box(target), slot_in_backpack)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll/apprentice(target), slot_r_store)
|
||||
///////////BORGS AND OPERATIVES
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops
|
||||
name = "syndicate operative teleporter"
|
||||
desc = "A single-use teleporter designed to quickly reinforce operatives in the field."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "locator"
|
||||
var/borg_to_spawn
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/proc/check_usability(mob/user)
|
||||
if(used)
|
||||
to_chat(user, "<span class='warning'>[src] is out of power!</span>")
|
||||
return 0
|
||||
if(!(user.mind in SSticker.mode.syndicates))
|
||||
to_chat(user, "<span class='danger'>AUTHENTICATION FAILURE. ACCESS DENIED.</span>")
|
||||
return 0
|
||||
if(user.z != ZLEVEL_CENTCOM)
|
||||
to_chat(user, "<span class='warning'>[src] is out of range! It can only be used at your base!</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/attack_self(mob/user)
|
||||
if(!(check_usability(user)))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You activate [src] and wait for confirmation.</span>")
|
||||
var/list/nuke_candidates = pollCandidatesForMob("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE, src)
|
||||
if(nuke_candidates.len)
|
||||
if(!(check_usability(user)))
|
||||
return
|
||||
used = 1
|
||||
var/mob/dead/observer/theghost = pick(nuke_candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), "syndieborg")
|
||||
do_sparks(4, TRUE, src)
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.</span>")
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
M.key = C.key
|
||||
var/code = "BOMB-NOT-FOUND"
|
||||
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
|
||||
if(nuke)
|
||||
code = nuke.r_code
|
||||
M.mind.make_Nuke(null, code, 0, FALSE)
|
||||
var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname)
|
||||
M.mind.name = newname
|
||||
M.real_name = newname
|
||||
M.name = newname
|
||||
|
||||
//////SYNDICATE BORG
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele
|
||||
name = "syndicate cyborg teleporter"
|
||||
desc = "A single-use teleporter designed to quickly reinforce operatives in the field.."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "locator"
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele/assault
|
||||
name = "syndicate assault cyborg teleporter"
|
||||
borg_to_spawn = "Assault"
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele/medical
|
||||
name = "syndicate medical teleporter"
|
||||
borg_to_spawn = "Medical"
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T)
|
||||
var/mob/living/silicon/robot/R
|
||||
switch(borg_to_spawn)
|
||||
if("Medical")
|
||||
R = new /mob/living/silicon/robot/syndicate/medical(T)
|
||||
else
|
||||
R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default
|
||||
|
||||
var/brainfirstname = pick(GLOB.first_names_male)
|
||||
if(prob(50))
|
||||
brainfirstname = pick(GLOB.first_names_female)
|
||||
var/brainopslastname = pick(GLOB.last_names)
|
||||
if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops.
|
||||
brainopslastname = SSticker.mode.nukeops_lastname
|
||||
var/brainopsname = "[brainfirstname] [brainopslastname]"
|
||||
|
||||
R.mmi.name = "Man-Machine Interface: [brainopsname]"
|
||||
R.mmi.brain.name = "[brainopsname]'s brain"
|
||||
R.mmi.brainmob.real_name = brainopsname
|
||||
R.mmi.brainmob.name = brainopsname
|
||||
|
||||
R.key = C.key
|
||||
R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE)
|
||||
|
||||
///////////SLAUGHTER DEMON
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon //Warning edgiest item in the game
|
||||
name = "vial of blood"
|
||||
desc = "A magically infused bottle of blood, distilled from countless murder victims. Used in unholy rituals to attract horrifying creatures."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
var/shatter_msg = "<span class='notice'>You shatter the bottle, no turning back now!</span>"
|
||||
var/veil_msg = "<span class='warning'>You sense a dark presence lurking just beyond the veil...</span>"
|
||||
var/objective_verb = "Kill"
|
||||
var/mob/living/demon_type = /mob/living/simple_animal/slaughter
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/attack_self(mob/user)
|
||||
if(user.z != 1)
|
||||
to_chat(user, "<span class='notice'>You should probably wait until you reach the station.</span>")
|
||||
return
|
||||
if(used)
|
||||
return
|
||||
var/list/demon_candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", null, null, ROLE_ALIEN, 50, src)
|
||||
if(demon_candidates.len)
|
||||
if(used)
|
||||
return
|
||||
used = 1
|
||||
var/mob/dead/observer/theghost = pick(demon_candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), initial(demon_type.name))
|
||||
to_chat(user, shatter_msg)
|
||||
to_chat(user, veil_msg)
|
||||
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.</span>")
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "")
|
||||
|
||||
var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
|
||||
var/mob/living/simple_animal/slaughter/S = new demon_type(holder)
|
||||
S.holder = holder
|
||||
S.key = C.key
|
||||
S.mind.assigned_role = S.name
|
||||
S.mind.special_role = S.name
|
||||
SSticker.mode.traitors += S.mind
|
||||
var/datum/objective/assassinate/new_objective
|
||||
if(usr)
|
||||
new_objective = new /datum/objective/assassinate
|
||||
new_objective.owner = S.mind
|
||||
new_objective.target = usr.mind
|
||||
new_objective.explanation_text = "[objective_verb] [usr.real_name], the one who summoned you."
|
||||
S.mind.objectives += new_objective
|
||||
var/datum/objective/new_objective2 = new /datum/objective
|
||||
new_objective2.owner = S.mind
|
||||
new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]."
|
||||
S.mind.objectives += new_objective2
|
||||
to_chat(S, S.playstyle_string)
|
||||
to_chat(S, "<B>You are currently not currently in the same plane of existence as the station. \
|
||||
Ctrl+Click a blood pool to manifest.</B>")
|
||||
if(new_objective)
|
||||
to_chat(S, "<B>Objective #[1]</B>: [new_objective.explanation_text]")
|
||||
to_chat(S, "<B>Objective #[new_objective ? "[2]":"[1]"]</B>: [new_objective2.explanation_text]")
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/laughter
|
||||
name = "vial of tickles"
|
||||
desc = "A magically infused bottle of clown love, distilled from countless hugging attacks. Used in funny rituals to attract adorable creatures."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
color = "#FF69B4" // HOT PINK
|
||||
|
||||
veil_msg = "<span class='warning'>You sense an adorable presence lurking just beyond the veil...</span>"
|
||||
objective_verb = "Hug and Tickle"
|
||||
demon_type = /mob/living/simple_animal/slaughter/laughter
|
||||
/obj/item/weapon/antag_spawner
|
||||
throw_speed = 1
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/used = 0
|
||||
|
||||
/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "")
|
||||
return
|
||||
|
||||
/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
|
||||
return
|
||||
|
||||
|
||||
///////////WIZARD
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract
|
||||
name = "contract"
|
||||
desc = "A magic contract previously signed by an apprentice. In exchange for instruction in the magical arts, they are bound to answer your call for aid."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/attack_self(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat
|
||||
if(used)
|
||||
dat = "<B>You have already summoned your apprentice.</B><BR>"
|
||||
else
|
||||
dat = "<B>Contract of Apprenticeship:</B><BR>"
|
||||
dat += "<I>Using this contract, you may summon an apprentice to aid you on your mission.</I><BR>"
|
||||
dat += "<I>If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.</I><BR>"
|
||||
dat += "<B>Which school of magic is your apprentice studying?:</B><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=destruction'>Destruction</A><BR>"
|
||||
dat += "<I>Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=bluespace'>Bluespace Manipulation</A><BR>"
|
||||
dat += "<I>Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=healing'>Healing</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.</I><BR>"
|
||||
dat += "<A href='byond://?src=\ref[src];school=robeless'>Robeless</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.</I><BR>"
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/Topic(href, href_list)
|
||||
..()
|
||||
var/mob/living/carbon/human/H = usr
|
||||
|
||||
if(H.stat || H.restrained())
|
||||
return
|
||||
if(!ishuman(H))
|
||||
return 1
|
||||
|
||||
if(loc == H || (in_range(src, H) && isturf(loc)))
|
||||
H.set_machine(src)
|
||||
if(href_list["school"])
|
||||
if(used)
|
||||
to_chat(H, "You already used this contract!")
|
||||
return
|
||||
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src)
|
||||
if(candidates.len)
|
||||
if(used)
|
||||
to_chat(H, "You already used this contract!")
|
||||
return
|
||||
used = 1
|
||||
var/mob/dead/observer/theghost = pick(candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), href_list["school"])
|
||||
if(H && H.mind)
|
||||
SSticker.mode.update_wiz_icons_added(H.mind)
|
||||
else
|
||||
to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/spawn_antag(client/C, turf/T, type = "")
|
||||
new /obj/effect/particle_effect/smoke(T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
M.key = C.key
|
||||
var/wizard_name = "the wizard"
|
||||
if(usr)
|
||||
wizard_name = usr.real_name
|
||||
to_chat(M, "<B>You are [wizard_name]'s apprentice! You are bound by magic contract to follow their orders and help them in accomplishing their goals.")
|
||||
switch(type)
|
||||
if("destruction")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.")
|
||||
if("bluespace")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.")
|
||||
if("healing")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/charge(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall(null))
|
||||
M.put_in_hands_or_del(new /obj/item/weapon/gun/magic/staff/healing(M))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned livesaving survival spells. You are able to cast charge and forcewall.")
|
||||
if("robeless")
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null))
|
||||
M.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/mind_transfer(null))
|
||||
to_chat(M, "<B>Your service has not gone unrewarded, however. Studying under [wizard_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
|
||||
|
||||
equip_antag(M)
|
||||
var/wizard_name_first = pick(GLOB.wizard_first)
|
||||
var/wizard_name_second = pick(GLOB.wizard_second)
|
||||
var/randomname = "[wizard_name_first] [wizard_name_second]"
|
||||
if(usr)
|
||||
var/datum/objective/protect/new_objective = new /datum/objective/protect
|
||||
new_objective.owner = M.mind
|
||||
new_objective.target = usr.mind
|
||||
new_objective.explanation_text = "Protect [usr.real_name], the wizard."
|
||||
M.mind.objectives += new_objective
|
||||
SSticker.mode.apprentices += M.mind
|
||||
M.mind.special_role = "apprentice"
|
||||
SSticker.mode.update_wiz_icons_added(M.mind)
|
||||
M << sound('sound/effects/magic.ogg')
|
||||
var/newname = copytext(sanitize(input(M, "You are [wizard_name]'s apprentice. Would you like to change your name to something else?", "Name change", randomname) as null|text),1,MAX_NAME_LEN)
|
||||
if (!newname)
|
||||
newname = randomname
|
||||
M.mind.name = newname
|
||||
M.real_name = newname
|
||||
M.name = newname
|
||||
M.dna.update_dna_identity()
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/equip_antag(mob/target)
|
||||
target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_ears)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(target), slot_w_uniform)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(target), slot_shoes)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(target), slot_wear_suit)
|
||||
target.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(target), slot_head)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(target), slot_back)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/storage/box(target), slot_in_backpack)
|
||||
target.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll/apprentice(target), slot_r_store)
|
||||
///////////BORGS AND OPERATIVES
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops
|
||||
name = "syndicate operative teleporter"
|
||||
desc = "A single-use teleporter designed to quickly reinforce operatives in the field."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "locator"
|
||||
var/borg_to_spawn
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/proc/check_usability(mob/user)
|
||||
if(used)
|
||||
to_chat(user, "<span class='warning'>[src] is out of power!</span>")
|
||||
return 0
|
||||
if(!(user.mind in SSticker.mode.syndicates))
|
||||
to_chat(user, "<span class='danger'>AUTHENTICATION FAILURE. ACCESS DENIED.</span>")
|
||||
return 0
|
||||
if(user.z != ZLEVEL_CENTCOM)
|
||||
to_chat(user, "<span class='warning'>[src] is out of range! It can only be used at your base!</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/attack_self(mob/user)
|
||||
if(!(check_usability(user)))
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You activate [src] and wait for confirmation.</span>")
|
||||
var/list/nuke_candidates = pollCandidatesForMob("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE, src)
|
||||
if(nuke_candidates.len)
|
||||
if(!(check_usability(user)))
|
||||
return
|
||||
used = 1
|
||||
var/mob/dead/observer/theghost = pick(nuke_candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), "syndieborg")
|
||||
do_sparks(4, TRUE, src)
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.</span>")
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
M.key = C.key
|
||||
var/code = "BOMB-NOT-FOUND"
|
||||
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list
|
||||
if(nuke)
|
||||
code = nuke.r_code
|
||||
M.mind.make_Nuke(null, code, 0, FALSE)
|
||||
var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname)
|
||||
M.mind.name = newname
|
||||
M.real_name = newname
|
||||
M.name = newname
|
||||
|
||||
//////SYNDICATE BORG
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele
|
||||
name = "syndicate cyborg teleporter"
|
||||
desc = "A single-use teleporter designed to quickly reinforce operatives in the field.."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "locator"
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele/assault
|
||||
name = "syndicate assault cyborg teleporter"
|
||||
borg_to_spawn = "Assault"
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele/medical
|
||||
name = "syndicate medical teleporter"
|
||||
borg_to_spawn = "Medical"
|
||||
|
||||
/obj/item/weapon/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T)
|
||||
var/mob/living/silicon/robot/R
|
||||
switch(borg_to_spawn)
|
||||
if("Medical")
|
||||
R = new /mob/living/silicon/robot/syndicate/medical(T)
|
||||
else
|
||||
R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default
|
||||
|
||||
var/brainfirstname = pick(GLOB.first_names_male)
|
||||
if(prob(50))
|
||||
brainfirstname = pick(GLOB.first_names_female)
|
||||
var/brainopslastname = pick(GLOB.last_names)
|
||||
if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops.
|
||||
brainopslastname = SSticker.mode.nukeops_lastname
|
||||
var/brainopsname = "[brainfirstname] [brainopslastname]"
|
||||
|
||||
R.mmi.name = "Man-Machine Interface: [brainopsname]"
|
||||
R.mmi.brain.name = "[brainopsname]'s brain"
|
||||
R.mmi.brainmob.real_name = brainopsname
|
||||
R.mmi.brainmob.name = brainopsname
|
||||
|
||||
R.key = C.key
|
||||
R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE)
|
||||
|
||||
///////////SLAUGHTER DEMON
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon //Warning edgiest item in the game
|
||||
name = "vial of blood"
|
||||
desc = "A magically infused bottle of blood, distilled from countless murder victims. Used in unholy rituals to attract horrifying creatures."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
var/shatter_msg = "<span class='notice'>You shatter the bottle, no turning back now!</span>"
|
||||
var/veil_msg = "<span class='warning'>You sense a dark presence lurking just beyond the veil...</span>"
|
||||
var/objective_verb = "Kill"
|
||||
var/mob/living/demon_type = /mob/living/simple_animal/slaughter
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/attack_self(mob/user)
|
||||
if(user.z != 1)
|
||||
to_chat(user, "<span class='notice'>You should probably wait until you reach the station.</span>")
|
||||
return
|
||||
if(used)
|
||||
return
|
||||
var/list/demon_candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", null, null, ROLE_ALIEN, 50, src)
|
||||
if(demon_candidates.len)
|
||||
if(used)
|
||||
return
|
||||
used = 1
|
||||
var/mob/dead/observer/theghost = pick(demon_candidates)
|
||||
spawn_antag(theghost.client, get_turf(src), initial(demon_type.name))
|
||||
to_chat(user, shatter_msg)
|
||||
to_chat(user, veil_msg)
|
||||
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.</span>")
|
||||
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "")
|
||||
|
||||
var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
|
||||
var/mob/living/simple_animal/slaughter/S = new demon_type(holder)
|
||||
S.holder = holder
|
||||
S.key = C.key
|
||||
S.mind.assigned_role = S.name
|
||||
S.mind.special_role = S.name
|
||||
SSticker.mode.traitors += S.mind
|
||||
var/datum/objective/assassinate/new_objective
|
||||
if(usr)
|
||||
new_objective = new /datum/objective/assassinate
|
||||
new_objective.owner = S.mind
|
||||
new_objective.target = usr.mind
|
||||
new_objective.explanation_text = "[objective_verb] [usr.real_name], the one who summoned you."
|
||||
S.mind.objectives += new_objective
|
||||
var/datum/objective/new_objective2 = new /datum/objective
|
||||
new_objective2.owner = S.mind
|
||||
new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]."
|
||||
S.mind.objectives += new_objective2
|
||||
to_chat(S, S.playstyle_string)
|
||||
to_chat(S, "<B>You are currently not currently in the same plane of existence as the station. \
|
||||
Ctrl+Click a blood pool to manifest.</B>")
|
||||
if(new_objective)
|
||||
to_chat(S, "<B>Objective #[1]</B>: [new_objective.explanation_text]")
|
||||
to_chat(S, "<B>Objective #[new_objective ? "[2]":"[1]"]</B>: [new_objective2.explanation_text]")
|
||||
|
||||
/obj/item/weapon/antag_spawner/slaughter_demon/laughter
|
||||
name = "vial of tickles"
|
||||
desc = "A magically infused bottle of clown love, distilled from countless hugging attacks. Used in funny rituals to attract adorable creatures."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
color = "#FF69B4" // HOT PINK
|
||||
|
||||
veil_msg = "<span class='warning'>You sense an adorable presence lurking just beyond the veil...</span>"
|
||||
objective_verb = "Hug and Tickle"
|
||||
demon_type = /mob/living/simple_animal/slaughter/laughter
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_mai
|
||||
normal_integrity = 250
|
||||
|
||||
/obj/machinery/door/airlock/maintenance/external
|
||||
name = "external airlock access"
|
||||
icon = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi'
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_mai
|
||||
normal_integrity = 250
|
||||
|
||||
/obj/machinery/door/airlock/mining
|
||||
name = "mining airlock"
|
||||
icon = 'icons/obj/doors/airlocks/station/mining.dmi'
|
||||
|
||||
@@ -30,23 +30,23 @@
|
||||
icon_state = "white"
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_LAYER
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
/obj/effect/abstract/marker
|
||||
name = "marker"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
anchored = TRUE
|
||||
icon_state = "wave3"
|
||||
layer = RIPPLE_LAYER
|
||||
|
||||
/obj/effect/abstract/marker/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.all_abstract_markers += src
|
||||
|
||||
/obj/effect/abstract/marker/Destroy()
|
||||
GLOB.all_abstract_markers -= src
|
||||
. = ..()
|
||||
|
||||
/obj/effect/abstract/marker/at
|
||||
name = "active turf marker"
|
||||
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
/obj/effect/abstract/marker
|
||||
name = "marker"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
anchored = TRUE
|
||||
icon_state = "wave3"
|
||||
layer = RIPPLE_LAYER
|
||||
|
||||
/obj/effect/abstract/marker/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.all_abstract_markers += src
|
||||
|
||||
/obj/effect/abstract/marker/Destroy()
|
||||
GLOB.all_abstract_markers -= src
|
||||
. = ..()
|
||||
|
||||
/obj/effect/abstract/marker/at
|
||||
name = "active turf marker"
|
||||
|
||||
|
||||
@@ -1,212 +1,212 @@
|
||||
GLOBAL_LIST_EMPTY(GPS_list)
|
||||
/obj/item/device/gps
|
||||
name = "global positioning system"
|
||||
desc = "Helping lost spacemen find their way through the planets since 2016. Alt+click to toggle power."
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "gps-c"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "materials=2;magnets=1;bluespace=2"
|
||||
unique_rename = TRUE
|
||||
var/gpstag = "COM0"
|
||||
var/emped = FALSE
|
||||
var/turf/locked_location
|
||||
var/tracking = TRUE
|
||||
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
|
||||
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
|
||||
|
||||
|
||||
/obj/item/device/gps/Initialize()
|
||||
..()
|
||||
GLOB.GPS_list += src
|
||||
name = "global positioning system ([gpstag])"
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/device/gps/Destroy()
|
||||
GLOB.GPS_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/device/gps/emp_act(severity)
|
||||
emped = TRUE
|
||||
cut_overlay("working")
|
||||
add_overlay("emp")
|
||||
addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
|
||||
SStgui.close_uis(src) //Close the UI control if it is open.
|
||||
|
||||
/obj/item/device/gps/proc/reboot()
|
||||
emped = FALSE
|
||||
cut_overlay("emp")
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/device/gps/AltClick(mob/user)
|
||||
toggletracking(user)
|
||||
|
||||
/obj/item/device/gps/proc/toggletracking(mob/user)
|
||||
if(!user.canUseTopic(src, be_close=TRUE))
|
||||
return //user not valid to use gps
|
||||
if(emped)
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
if(tracking)
|
||||
cut_overlay("working")
|
||||
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
|
||||
tracking = FALSE
|
||||
else
|
||||
add_overlay("working")
|
||||
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
|
||||
tracking = TRUE
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
|
||||
if(emped)
|
||||
to_chat(user, "[src] fizzles weakly.")
|
||||
return
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
|
||||
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
|
||||
ui.open()
|
||||
|
||||
ui.set_autoupdate(state = updating)
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = tracking
|
||||
data["tag"] = gpstag
|
||||
data["updating"] = updating
|
||||
data["globalmode"] = global_mode
|
||||
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
|
||||
return data
|
||||
|
||||
var/turf/curr = get_turf(src)
|
||||
data["current"] = "[get_area_name(curr)] ([curr.x], [curr.y], [curr.z])"
|
||||
|
||||
var/list/signals = list()
|
||||
data["signals"] = list()
|
||||
|
||||
for(var/gps in GLOB.GPS_list)
|
||||
var/obj/item/device/gps/G = gps
|
||||
if(G.emped || !G.tracking || G == src)
|
||||
continue
|
||||
var/turf/pos = get_turf(G)
|
||||
if(!global_mode && pos.z != curr.z)
|
||||
continue
|
||||
var/area/gps_area = get_area_name(G)
|
||||
var/list/signal = list()
|
||||
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
|
||||
signal["area"] = format_text(gps_area)
|
||||
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
|
||||
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
|
||||
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
|
||||
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
|
||||
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
|
||||
if(!direction)
|
||||
direction = "CENTER"
|
||||
signal["degrees"] = "N/A"
|
||||
signal["direction"] = direction
|
||||
|
||||
signals += list(signal) //Add this signal to the list of signals
|
||||
data["signals"] = signals
|
||||
return data
|
||||
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = uppertext(copytext(sanitize(a), 1, 5))
|
||||
gpstag = a
|
||||
name = "global positioning system ([gpstag])"
|
||||
. = TRUE
|
||||
if("power")
|
||||
toggletracking(usr)
|
||||
. = TRUE
|
||||
if("updating")
|
||||
updating = !updating
|
||||
. = TRUE
|
||||
if("globalmode")
|
||||
global_mode = !global_mode
|
||||
. = TRUE
|
||||
|
||||
/obj/item/device/gps/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["tag"] )
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = copytext(sanitize(a), 1, 20)
|
||||
if(in_range(src, usr))
|
||||
gpstag = a
|
||||
attack_self(usr)
|
||||
|
||||
/obj/item/device/gps/science
|
||||
icon_state = "gps-s"
|
||||
gpstag = "SCI0"
|
||||
|
||||
/obj/item/device/gps/engineering
|
||||
icon_state = "gps-e"
|
||||
gpstag = "ENG0"
|
||||
|
||||
/obj/item/device/gps/mining
|
||||
icon_state = "gps-m"
|
||||
gpstag = "MINE0"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
|
||||
|
||||
/obj/item/device/gps/cyborg
|
||||
icon_state = "gps-b"
|
||||
gpstag = "BORG0"
|
||||
desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams."
|
||||
flags = NODROP
|
||||
|
||||
/obj/item/device/gps/internal
|
||||
icon_state = null
|
||||
flags = ABSTRACT
|
||||
gpstag = "Eerie Signal"
|
||||
desc = "Report to a coder immediately."
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
|
||||
/obj/item/device/gps/mining/internal
|
||||
icon_state = "gps-m"
|
||||
gpstag = "MINER"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
|
||||
|
||||
/obj/item/device/gps/internal/base
|
||||
gpstag = "NT_AUX"
|
||||
desc = "A homing signal from Nanotrasen's mining base."
|
||||
|
||||
/obj/item/device/gps/visible_debug
|
||||
name = "visible GPS"
|
||||
gpstag = "ADMIN"
|
||||
desc = "This admin-spawn GPS unit leaves the coordinates visible \
|
||||
on any turf that it passes over, for debugging. Especially useful \
|
||||
for marking the area around the transition edges."
|
||||
var/list/turf/tagged
|
||||
|
||||
/obj/item/device/gps/visible_debug/Initialize()
|
||||
. = ..()
|
||||
tagged = list()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/item/device/gps/visible_debug/process()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
// I assume it's faster to color,tag and OR the turf in, rather
|
||||
// then checking if its there
|
||||
T.color = RANDOM_COLOUR
|
||||
T.maptext = "[T.x],[T.y],[T.z]"
|
||||
tagged |= T
|
||||
|
||||
/obj/item/device/gps/visible_debug/proc/clear()
|
||||
while(tagged.len)
|
||||
var/turf/T = pop(tagged)
|
||||
T.color = initial(T.color)
|
||||
T.maptext = initial(T.maptext)
|
||||
|
||||
/obj/item/device/gps/visible_debug/Destroy()
|
||||
if(tagged)
|
||||
clear()
|
||||
tagged = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOBAL_LIST_EMPTY(GPS_list)
|
||||
/obj/item/device/gps
|
||||
name = "global positioning system"
|
||||
desc = "Helping lost spacemen find their way through the planets since 2016. Alt+click to toggle power."
|
||||
icon = 'icons/obj/telescience.dmi'
|
||||
icon_state = "gps-c"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "materials=2;magnets=1;bluespace=2"
|
||||
unique_rename = TRUE
|
||||
var/gpstag = "COM0"
|
||||
var/emped = FALSE
|
||||
var/turf/locked_location
|
||||
var/tracking = TRUE
|
||||
var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user.
|
||||
var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown
|
||||
|
||||
|
||||
/obj/item/device/gps/Initialize()
|
||||
..()
|
||||
GLOB.GPS_list += src
|
||||
name = "global positioning system ([gpstag])"
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/device/gps/Destroy()
|
||||
GLOB.GPS_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/device/gps/emp_act(severity)
|
||||
emped = TRUE
|
||||
cut_overlay("working")
|
||||
add_overlay("emp")
|
||||
addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early
|
||||
SStgui.close_uis(src) //Close the UI control if it is open.
|
||||
|
||||
/obj/item/device/gps/proc/reboot()
|
||||
emped = FALSE
|
||||
cut_overlay("emp")
|
||||
add_overlay("working")
|
||||
|
||||
/obj/item/device/gps/AltClick(mob/user)
|
||||
toggletracking(user)
|
||||
|
||||
/obj/item/device/gps/proc/toggletracking(mob/user)
|
||||
if(!user.canUseTopic(src, be_close=TRUE))
|
||||
return //user not valid to use gps
|
||||
if(emped)
|
||||
to_chat(user, "It's busted!")
|
||||
return
|
||||
if(tracking)
|
||||
cut_overlay("working")
|
||||
to_chat(user, "[src] is no longer tracking, or visible to other GPS devices.")
|
||||
tracking = FALSE
|
||||
else
|
||||
add_overlay("working")
|
||||
to_chat(user, "[src] is now tracking, and visible to other GPS devices.")
|
||||
tracking = TRUE
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state.
|
||||
if(emped)
|
||||
to_chat(user, "[src] fizzles weakly.")
|
||||
return
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
|
||||
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
|
||||
ui.open()
|
||||
|
||||
ui.set_autoupdate(state = updating)
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["power"] = tracking
|
||||
data["tag"] = gpstag
|
||||
data["updating"] = updating
|
||||
data["globalmode"] = global_mode
|
||||
if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
|
||||
return data
|
||||
|
||||
var/turf/curr = get_turf(src)
|
||||
data["current"] = "[get_area_name(curr)] ([curr.x], [curr.y], [curr.z])"
|
||||
|
||||
var/list/signals = list()
|
||||
data["signals"] = list()
|
||||
|
||||
for(var/gps in GLOB.GPS_list)
|
||||
var/obj/item/device/gps/G = gps
|
||||
if(G.emped || !G.tracking || G == src)
|
||||
continue
|
||||
var/turf/pos = get_turf(G)
|
||||
if(!global_mode && pos.z != curr.z)
|
||||
continue
|
||||
var/area/gps_area = get_area_name(G)
|
||||
var/list/signal = list()
|
||||
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
|
||||
signal["area"] = format_text(gps_area)
|
||||
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
|
||||
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
|
||||
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
|
||||
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
|
||||
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
|
||||
if(!direction)
|
||||
direction = "CENTER"
|
||||
signal["degrees"] = "N/A"
|
||||
signal["direction"] = direction
|
||||
|
||||
signals += list(signal) //Add this signal to the list of signals
|
||||
data["signals"] = signals
|
||||
return data
|
||||
|
||||
|
||||
|
||||
/obj/item/device/gps/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = uppertext(copytext(sanitize(a), 1, 5))
|
||||
gpstag = a
|
||||
name = "global positioning system ([gpstag])"
|
||||
. = TRUE
|
||||
if("power")
|
||||
toggletracking(usr)
|
||||
. = TRUE
|
||||
if("updating")
|
||||
updating = !updating
|
||||
. = TRUE
|
||||
if("globalmode")
|
||||
global_mode = !global_mode
|
||||
. = TRUE
|
||||
|
||||
/obj/item/device/gps/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["tag"] )
|
||||
var/a = input("Please enter desired tag.", name, gpstag) as text
|
||||
a = copytext(sanitize(a), 1, 20)
|
||||
if(in_range(src, usr))
|
||||
gpstag = a
|
||||
attack_self(usr)
|
||||
|
||||
/obj/item/device/gps/science
|
||||
icon_state = "gps-s"
|
||||
gpstag = "SCI0"
|
||||
|
||||
/obj/item/device/gps/engineering
|
||||
icon_state = "gps-e"
|
||||
gpstag = "ENG0"
|
||||
|
||||
/obj/item/device/gps/mining
|
||||
icon_state = "gps-m"
|
||||
gpstag = "MINE0"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
|
||||
|
||||
/obj/item/device/gps/cyborg
|
||||
icon_state = "gps-b"
|
||||
gpstag = "BORG0"
|
||||
desc = "A mining cyborg internal positioning system. Used as a recovery beacon for damaged cyborg assets, or a collaboration tool for mining teams."
|
||||
flags = NODROP
|
||||
|
||||
/obj/item/device/gps/internal
|
||||
icon_state = null
|
||||
flags = ABSTRACT
|
||||
gpstag = "Eerie Signal"
|
||||
desc = "Report to a coder immediately."
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
|
||||
/obj/item/device/gps/mining/internal
|
||||
icon_state = "gps-m"
|
||||
gpstag = "MINER"
|
||||
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
|
||||
|
||||
/obj/item/device/gps/internal/base
|
||||
gpstag = "NT_AUX"
|
||||
desc = "A homing signal from Nanotrasen's mining base."
|
||||
|
||||
/obj/item/device/gps/visible_debug
|
||||
name = "visible GPS"
|
||||
gpstag = "ADMIN"
|
||||
desc = "This admin-spawn GPS unit leaves the coordinates visible \
|
||||
on any turf that it passes over, for debugging. Especially useful \
|
||||
for marking the area around the transition edges."
|
||||
var/list/turf/tagged
|
||||
|
||||
/obj/item/device/gps/visible_debug/Initialize()
|
||||
. = ..()
|
||||
tagged = list()
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/item/device/gps/visible_debug/process()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
// I assume it's faster to color,tag and OR the turf in, rather
|
||||
// then checking if its there
|
||||
T.color = RANDOM_COLOUR
|
||||
T.maptext = "[T.x],[T.y],[T.z]"
|
||||
tagged |= T
|
||||
|
||||
/obj/item/device/gps/visible_debug/proc/clear()
|
||||
while(tagged.len)
|
||||
var/turf/T = pop(tagged)
|
||||
T.color = initial(T.color)
|
||||
T.maptext = initial(T.maptext)
|
||||
|
||||
/obj/item/device/gps/visible_debug/Destroy()
|
||||
if(tagged)
|
||||
clear()
|
||||
tagged = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
. = ..()
|
||||
@@ -12,10 +12,10 @@
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits))
|
||||
to_chat(user, "<span class='warning'>You are not capable of wearing underwear.</span>")
|
||||
return
|
||||
|
||||
if(H.dna && H.dna.species && (NO_UNDERWEAR in H.dna.species.species_traits))
|
||||
to_chat(user, "<span class='warning'>You are not capable of wearing underwear.</span>")
|
||||
return
|
||||
|
||||
var/choice = input(user, "Underwear, Undershirt, or Socks?", "Changing") as null|anything in list("Underwear","Undershirt","Socks")
|
||||
|
||||
if(!Adjacent(user))
|
||||
@@ -36,4 +36,4 @@
|
||||
H.socks= new_socks
|
||||
|
||||
add_fingerprint(H)
|
||||
H.update_body()
|
||||
H.update_body()
|
||||
|
||||
+821
-821
File diff suppressed because it is too large
Load Diff
+284
-284
@@ -1,284 +1,284 @@
|
||||
//- Are all the floors with or without air, as they should be? (regular or airless)
|
||||
//- Does the area have an APC?
|
||||
//- Does the area have an Air Alarm?
|
||||
//- Does the area have a Request Console?
|
||||
//- Does the area have lights?
|
||||
//- Does the area have a light switch?
|
||||
//- Does the area have enough intercoms?
|
||||
//- Does the area have enough security cameras? (Use the 'Camera Range Display' verb under Debug)
|
||||
//- Is the area connected to the scrubbers air loop?
|
||||
//- Is the area connected to the vent air loop? (vent pumps)
|
||||
//- Is everything wired properly?
|
||||
//- Does the area have a fire alarm and firedoors?
|
||||
//- Do all pod doors work properly?
|
||||
//- Are accesses set properly on doors, pod buttons, etc.
|
||||
//- Are all items placed properly? (not below vents, scrubbers, tables)
|
||||
//- Does the disposal system work properly from all the disposal units in this room and all the units, the pipes of which pass through this room?
|
||||
//- Check for any misplaced or stacked piece of pipe (air and disposal)
|
||||
//- Check for any misplaced or stacked piece of wire
|
||||
//- Identify how hard it is to break into the area and where the weak points are
|
||||
//- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels.
|
||||
|
||||
GLOBAL_PROTECT(admin_verbs_debug_mapping)
|
||||
GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
|
||||
/client/proc/do_not_use_these, //-errorage
|
||||
/client/proc/camera_view, //-errorage
|
||||
/client/proc/sec_camera_report, //-errorage
|
||||
/client/proc/intercom_view, //-errorage
|
||||
/client/proc/air_status, //Air things
|
||||
/client/proc/Cell, //More air things
|
||||
/client/proc/atmosscan, //check plumbing
|
||||
/client/proc/powerdebug, //check power
|
||||
/client/proc/count_objects_on_z_level,
|
||||
/client/proc/count_objects_all,
|
||||
/client/proc/cmd_assume_direct_control, //-errorage
|
||||
/client/proc/startSinglo,
|
||||
/client/proc/set_server_fps, //allows you to set the ticklag.
|
||||
/client/proc/cmd_admin_grantfullaccess,
|
||||
/client/proc/cmd_admin_areatest,
|
||||
/client/proc/cmd_admin_rejuvenate,
|
||||
/datum/admins/proc/show_traitor_panel,
|
||||
/client/proc/disable_communication,
|
||||
/client/proc/print_pointers,
|
||||
/client/proc/cmd_show_at_list,
|
||||
/client/proc/cmd_show_at_markers,
|
||||
/client/proc/manipulate_organs
|
||||
))
|
||||
|
||||
/obj/effect/debugging/mapfix_marker
|
||||
name = "map fix marker"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "mapfixmarker"
|
||||
desc = "I am a mappers mistake."
|
||||
|
||||
/obj/effect/debugging/marker
|
||||
icon = 'icons/turf/areas.dmi'
|
||||
icon_state = "yellow"
|
||||
|
||||
/obj/effect/debugging/marker/Move()
|
||||
return 0
|
||||
|
||||
/client/proc/do_not_use_these()
|
||||
set category = "Mapping"
|
||||
set name = "-None of these are for ingame use!!"
|
||||
|
||||
..()
|
||||
|
||||
/client/proc/camera_view()
|
||||
set category = "Mapping"
|
||||
set name = "Camera Range Display"
|
||||
|
||||
var/on = 0
|
||||
for(var/turf/T in world)
|
||||
if(T.maptext)
|
||||
on = 1
|
||||
T.maptext = null
|
||||
|
||||
if(!on)
|
||||
var/list/seen = list()
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
for(var/turf/T in C.can_see())
|
||||
seen[T]++
|
||||
for(var/turf/T in seen)
|
||||
T.maptext = "[seen[T]]"
|
||||
SSblackbox.add_details("admin_verb","Show Camera Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
|
||||
/client/proc/sec_camera_report()
|
||||
set category = "Mapping"
|
||||
set name = "Camera Report"
|
||||
|
||||
if(!Master)
|
||||
alert(usr,"Master_controller not found.","Sec Camera Report")
|
||||
return 0
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
CL += C
|
||||
|
||||
var/output = {"<B>CAMERA ANNOMALITIES REPORT</B><HR>
|
||||
<B>The following annomalities have been detected. The ones in red need immediate attention: Some of those in black may be intentional.</B><BR><ul>"}
|
||||
|
||||
for(var/obj/machinery/camera/C1 in CL)
|
||||
for(var/obj/machinery/camera/C2 in CL)
|
||||
if(C1 != C2)
|
||||
if(C1.c_tag == C2.c_tag)
|
||||
output += "<li><font color='red'>c_tag match for sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) and \[[C2.x], [C2.y], [C2.z]\] ([C2.loc.loc]) - c_tag is [C1.c_tag]</font></li>"
|
||||
if(C1.loc == C2.loc && C1.dir == C2.dir && C1.pixel_x == C2.pixel_x && C1.pixel_y == C2.pixel_y)
|
||||
output += "<li><font color='red'>FULLY overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
|
||||
if(C1.loc == C2.loc)
|
||||
output += "<li>overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
|
||||
var/turf/T = get_step(C1,turn(C1.dir,180))
|
||||
if(!T || !isturf(T) || !T.density )
|
||||
if(!(locate(/obj/structure/grille,T)))
|
||||
var/window_check = 0
|
||||
for(var/obj/structure/window/W in T)
|
||||
if (W.dir == turn(C1.dir,180) || W.dir in list(5,6,9,10) )
|
||||
window_check = 1
|
||||
break
|
||||
if(!window_check)
|
||||
output += "<li><font color='red'>Camera not connected to wall at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Network: [C1.network]</color></li>"
|
||||
|
||||
output += "</ul>"
|
||||
usr << browse(output,"window=airreport;size=1000x500")
|
||||
SSblackbox.add_details("admin_verb","Show Camera Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/intercom_view()
|
||||
set category = "Mapping"
|
||||
set name = "Intercom Range Display"
|
||||
|
||||
var/static/intercom_range_display_status = 0
|
||||
if(intercom_range_display_status)
|
||||
intercom_range_display_status = 0
|
||||
else
|
||||
intercom_range_display_status = 1
|
||||
|
||||
for(var/obj/effect/debugging/marker/M in world)
|
||||
qdel(M)
|
||||
|
||||
if(intercom_range_display_status)
|
||||
for(var/obj/item/device/radio/intercom/I in world)
|
||||
for(var/turf/T in orange(7,I))
|
||||
var/obj/effect/debugging/marker/F = new/obj/effect/debugging/marker(T)
|
||||
if (!(F in view(7,I.loc)))
|
||||
qdel(F)
|
||||
SSblackbox.add_details("admin_verb","Show Intercom Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_show_at_list()
|
||||
set category = "Mapping"
|
||||
set name = "Show roundstart AT list"
|
||||
set desc = "Displays a list of active turfs coordinates at roundstart"
|
||||
|
||||
var/dat = {"<b>Coordinate list of Active Turfs at Roundstart</b>
|
||||
<br>Real-time Active Turfs list you can see in Air Subsystem at active_turfs var<br>"}
|
||||
|
||||
for(var/t in GLOB.active_turfs_startlist)
|
||||
var/turf/T = t
|
||||
dat += "[ADMIN_COORDJMP(T)]\n"
|
||||
dat += "<br>"
|
||||
|
||||
usr << browse(dat, "window=at_list")
|
||||
|
||||
SSblackbox.add_details("admin_verb","Show Roundstart Active Turfs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_show_at_markers()
|
||||
set category = "Mapping"
|
||||
set name = "Show roundstart AT markers"
|
||||
set desc = "Places a marker on all active-at-roundstart turfs"
|
||||
|
||||
var/count = 0
|
||||
for(var/obj/effect/abstract/marker/at/AT in GLOB.all_abstract_markers)
|
||||
qdel(AT)
|
||||
count++
|
||||
|
||||
if(count)
|
||||
to_chat(usr, "[count] AT markers removed.")
|
||||
else
|
||||
for(var/t in GLOB.active_turfs_startlist)
|
||||
new /obj/effect/abstract/marker/at(t)
|
||||
count++
|
||||
to_chat(usr, "[count] AT markers placed.")
|
||||
|
||||
SSblackbox.add_details("admin_verb","Show Roundstart Active Turf Markers")
|
||||
|
||||
|
||||
/client/proc/enable_debug_verbs()
|
||||
set category = "Debug"
|
||||
set name = "Debug verbs - Enable"
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
verbs -= /client/proc/enable_debug_verbs
|
||||
verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
|
||||
SSblackbox.add_details("admin_verb","Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/disable_debug_verbs()
|
||||
set category = "Debug"
|
||||
set name = "Debug verbs - Disable"
|
||||
verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
|
||||
verbs += /client/proc/enable_debug_verbs
|
||||
SSblackbox.add_details("admin_verb", "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/count_objects_on_z_level()
|
||||
set category = "Mapping"
|
||||
set name = "Count Objects On Level"
|
||||
var/level = input("Which z-level?","Level?") as text
|
||||
if(!level) return
|
||||
var/num_level = text2num(level)
|
||||
if(!num_level) return
|
||||
if(!isnum(num_level)) return
|
||||
|
||||
var/type_text = input("Which type path?","Path?") as text
|
||||
if(!type_text) return
|
||||
var/type_path = text2path(type_text)
|
||||
if(!type_path) return
|
||||
|
||||
var/count = 0
|
||||
|
||||
var/list/atom/atom_list = list()
|
||||
|
||||
for(var/atom/A in world)
|
||||
if(istype(A,type_path))
|
||||
var/atom/B = A
|
||||
while(!(isturf(B.loc)))
|
||||
if(B && B.loc)
|
||||
B = B.loc
|
||||
else
|
||||
break
|
||||
if(B)
|
||||
if(B.z == num_level)
|
||||
count++
|
||||
atom_list += A
|
||||
/*
|
||||
var/atom/temp_atom
|
||||
for(var/i = 0; i <= (atom_list.len/10); i++)
|
||||
var/line = ""
|
||||
for(var/j = 1; j <= 10; j++)
|
||||
if(i*10+j <= atom_list.len)
|
||||
temp_atom = atom_list[i*10+j]
|
||||
line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; "
|
||||
to_chat(world, line)*/
|
||||
|
||||
to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level]")
|
||||
SSblackbox.add_details("admin_verb","Count Objects Zlevel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/count_objects_all()
|
||||
set category = "Mapping"
|
||||
set name = "Count Objects All"
|
||||
|
||||
var/type_text = input("Which type path?","") as text
|
||||
if(!type_text) return
|
||||
var/type_path = text2path(type_text)
|
||||
if(!type_path) return
|
||||
|
||||
var/count = 0
|
||||
|
||||
for(var/atom/A in world)
|
||||
if(istype(A,type_path))
|
||||
count++
|
||||
/*
|
||||
var/atom/temp_atom
|
||||
for(var/i = 0; i <= (atom_list.len/10); i++)
|
||||
var/line = ""
|
||||
for(var/j = 1; j <= 10; j++)
|
||||
if(i*10+j <= atom_list.len)
|
||||
temp_atom = atom_list[i*10+j]
|
||||
line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; "
|
||||
to_chat(world, line)*/
|
||||
|
||||
to_chat(world, "There are [count] objects of type [type_path] in the game world")
|
||||
SSblackbox.add_details("admin_verb","Count Objects All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
//This proc is intended to detect lag problems relating to communication procs
|
||||
GLOBAL_VAR_INIT(say_disabled, FALSE)
|
||||
/client/proc/disable_communication()
|
||||
set category = "Mapping"
|
||||
set name = "Disable all communication verbs"
|
||||
|
||||
GLOB.say_disabled = !GLOB.say_disabled
|
||||
if(GLOB.say_disabled)
|
||||
message_admins("[src.ckey] used 'Disable all communication verbs', killing all communication methods.")
|
||||
else
|
||||
message_admins("[src.ckey] used 'Disable all communication verbs', restoring all communication methods.")
|
||||
//- Are all the floors with or without air, as they should be? (regular or airless)
|
||||
//- Does the area have an APC?
|
||||
//- Does the area have an Air Alarm?
|
||||
//- Does the area have a Request Console?
|
||||
//- Does the area have lights?
|
||||
//- Does the area have a light switch?
|
||||
//- Does the area have enough intercoms?
|
||||
//- Does the area have enough security cameras? (Use the 'Camera Range Display' verb under Debug)
|
||||
//- Is the area connected to the scrubbers air loop?
|
||||
//- Is the area connected to the vent air loop? (vent pumps)
|
||||
//- Is everything wired properly?
|
||||
//- Does the area have a fire alarm and firedoors?
|
||||
//- Do all pod doors work properly?
|
||||
//- Are accesses set properly on doors, pod buttons, etc.
|
||||
//- Are all items placed properly? (not below vents, scrubbers, tables)
|
||||
//- Does the disposal system work properly from all the disposal units in this room and all the units, the pipes of which pass through this room?
|
||||
//- Check for any misplaced or stacked piece of pipe (air and disposal)
|
||||
//- Check for any misplaced or stacked piece of wire
|
||||
//- Identify how hard it is to break into the area and where the weak points are
|
||||
//- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels.
|
||||
|
||||
GLOBAL_PROTECT(admin_verbs_debug_mapping)
|
||||
GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
|
||||
/client/proc/do_not_use_these, //-errorage
|
||||
/client/proc/camera_view, //-errorage
|
||||
/client/proc/sec_camera_report, //-errorage
|
||||
/client/proc/intercom_view, //-errorage
|
||||
/client/proc/air_status, //Air things
|
||||
/client/proc/Cell, //More air things
|
||||
/client/proc/atmosscan, //check plumbing
|
||||
/client/proc/powerdebug, //check power
|
||||
/client/proc/count_objects_on_z_level,
|
||||
/client/proc/count_objects_all,
|
||||
/client/proc/cmd_assume_direct_control, //-errorage
|
||||
/client/proc/startSinglo,
|
||||
/client/proc/set_server_fps, //allows you to set the ticklag.
|
||||
/client/proc/cmd_admin_grantfullaccess,
|
||||
/client/proc/cmd_admin_areatest,
|
||||
/client/proc/cmd_admin_rejuvenate,
|
||||
/datum/admins/proc/show_traitor_panel,
|
||||
/client/proc/disable_communication,
|
||||
/client/proc/print_pointers,
|
||||
/client/proc/cmd_show_at_list,
|
||||
/client/proc/cmd_show_at_markers,
|
||||
/client/proc/manipulate_organs
|
||||
))
|
||||
|
||||
/obj/effect/debugging/mapfix_marker
|
||||
name = "map fix marker"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "mapfixmarker"
|
||||
desc = "I am a mappers mistake."
|
||||
|
||||
/obj/effect/debugging/marker
|
||||
icon = 'icons/turf/areas.dmi'
|
||||
icon_state = "yellow"
|
||||
|
||||
/obj/effect/debugging/marker/Move()
|
||||
return 0
|
||||
|
||||
/client/proc/do_not_use_these()
|
||||
set category = "Mapping"
|
||||
set name = "-None of these are for ingame use!!"
|
||||
|
||||
..()
|
||||
|
||||
/client/proc/camera_view()
|
||||
set category = "Mapping"
|
||||
set name = "Camera Range Display"
|
||||
|
||||
var/on = 0
|
||||
for(var/turf/T in world)
|
||||
if(T.maptext)
|
||||
on = 1
|
||||
T.maptext = null
|
||||
|
||||
if(!on)
|
||||
var/list/seen = list()
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
for(var/turf/T in C.can_see())
|
||||
seen[T]++
|
||||
for(var/turf/T in seen)
|
||||
T.maptext = "[seen[T]]"
|
||||
SSblackbox.add_details("admin_verb","Show Camera Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
|
||||
/client/proc/sec_camera_report()
|
||||
set category = "Mapping"
|
||||
set name = "Camera Report"
|
||||
|
||||
if(!Master)
|
||||
alert(usr,"Master_controller not found.","Sec Camera Report")
|
||||
return 0
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
CL += C
|
||||
|
||||
var/output = {"<B>CAMERA ANNOMALITIES REPORT</B><HR>
|
||||
<B>The following annomalities have been detected. The ones in red need immediate attention: Some of those in black may be intentional.</B><BR><ul>"}
|
||||
|
||||
for(var/obj/machinery/camera/C1 in CL)
|
||||
for(var/obj/machinery/camera/C2 in CL)
|
||||
if(C1 != C2)
|
||||
if(C1.c_tag == C2.c_tag)
|
||||
output += "<li><font color='red'>c_tag match for sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) and \[[C2.x], [C2.y], [C2.z]\] ([C2.loc.loc]) - c_tag is [C1.c_tag]</font></li>"
|
||||
if(C1.loc == C2.loc && C1.dir == C2.dir && C1.pixel_x == C2.pixel_x && C1.pixel_y == C2.pixel_y)
|
||||
output += "<li><font color='red'>FULLY overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
|
||||
if(C1.loc == C2.loc)
|
||||
output += "<li>overlapping sec. cameras at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Networks: [C1.network] and [C2.network]</font></li>"
|
||||
var/turf/T = get_step(C1,turn(C1.dir,180))
|
||||
if(!T || !isturf(T) || !T.density )
|
||||
if(!(locate(/obj/structure/grille,T)))
|
||||
var/window_check = 0
|
||||
for(var/obj/structure/window/W in T)
|
||||
if (W.dir == turn(C1.dir,180) || W.dir in list(5,6,9,10) )
|
||||
window_check = 1
|
||||
break
|
||||
if(!window_check)
|
||||
output += "<li><font color='red'>Camera not connected to wall at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Network: [C1.network]</color></li>"
|
||||
|
||||
output += "</ul>"
|
||||
usr << browse(output,"window=airreport;size=1000x500")
|
||||
SSblackbox.add_details("admin_verb","Show Camera Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/intercom_view()
|
||||
set category = "Mapping"
|
||||
set name = "Intercom Range Display"
|
||||
|
||||
var/static/intercom_range_display_status = 0
|
||||
if(intercom_range_display_status)
|
||||
intercom_range_display_status = 0
|
||||
else
|
||||
intercom_range_display_status = 1
|
||||
|
||||
for(var/obj/effect/debugging/marker/M in world)
|
||||
qdel(M)
|
||||
|
||||
if(intercom_range_display_status)
|
||||
for(var/obj/item/device/radio/intercom/I in world)
|
||||
for(var/turf/T in orange(7,I))
|
||||
var/obj/effect/debugging/marker/F = new/obj/effect/debugging/marker(T)
|
||||
if (!(F in view(7,I.loc)))
|
||||
qdel(F)
|
||||
SSblackbox.add_details("admin_verb","Show Intercom Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_show_at_list()
|
||||
set category = "Mapping"
|
||||
set name = "Show roundstart AT list"
|
||||
set desc = "Displays a list of active turfs coordinates at roundstart"
|
||||
|
||||
var/dat = {"<b>Coordinate list of Active Turfs at Roundstart</b>
|
||||
<br>Real-time Active Turfs list you can see in Air Subsystem at active_turfs var<br>"}
|
||||
|
||||
for(var/t in GLOB.active_turfs_startlist)
|
||||
var/turf/T = t
|
||||
dat += "[ADMIN_COORDJMP(T)]\n"
|
||||
dat += "<br>"
|
||||
|
||||
usr << browse(dat, "window=at_list")
|
||||
|
||||
SSblackbox.add_details("admin_verb","Show Roundstart Active Turfs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_show_at_markers()
|
||||
set category = "Mapping"
|
||||
set name = "Show roundstart AT markers"
|
||||
set desc = "Places a marker on all active-at-roundstart turfs"
|
||||
|
||||
var/count = 0
|
||||
for(var/obj/effect/abstract/marker/at/AT in GLOB.all_abstract_markers)
|
||||
qdel(AT)
|
||||
count++
|
||||
|
||||
if(count)
|
||||
to_chat(usr, "[count] AT markers removed.")
|
||||
else
|
||||
for(var/t in GLOB.active_turfs_startlist)
|
||||
new /obj/effect/abstract/marker/at(t)
|
||||
count++
|
||||
to_chat(usr, "[count] AT markers placed.")
|
||||
|
||||
SSblackbox.add_details("admin_verb","Show Roundstart Active Turf Markers")
|
||||
|
||||
|
||||
/client/proc/enable_debug_verbs()
|
||||
set category = "Debug"
|
||||
set name = "Debug verbs - Enable"
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
verbs -= /client/proc/enable_debug_verbs
|
||||
verbs.Add(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
|
||||
SSblackbox.add_details("admin_verb","Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/disable_debug_verbs()
|
||||
set category = "Debug"
|
||||
set name = "Debug verbs - Disable"
|
||||
verbs.Remove(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping)
|
||||
verbs += /client/proc/enable_debug_verbs
|
||||
SSblackbox.add_details("admin_verb", "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/count_objects_on_z_level()
|
||||
set category = "Mapping"
|
||||
set name = "Count Objects On Level"
|
||||
var/level = input("Which z-level?","Level?") as text
|
||||
if(!level) return
|
||||
var/num_level = text2num(level)
|
||||
if(!num_level) return
|
||||
if(!isnum(num_level)) return
|
||||
|
||||
var/type_text = input("Which type path?","Path?") as text
|
||||
if(!type_text) return
|
||||
var/type_path = text2path(type_text)
|
||||
if(!type_path) return
|
||||
|
||||
var/count = 0
|
||||
|
||||
var/list/atom/atom_list = list()
|
||||
|
||||
for(var/atom/A in world)
|
||||
if(istype(A,type_path))
|
||||
var/atom/B = A
|
||||
while(!(isturf(B.loc)))
|
||||
if(B && B.loc)
|
||||
B = B.loc
|
||||
else
|
||||
break
|
||||
if(B)
|
||||
if(B.z == num_level)
|
||||
count++
|
||||
atom_list += A
|
||||
/*
|
||||
var/atom/temp_atom
|
||||
for(var/i = 0; i <= (atom_list.len/10); i++)
|
||||
var/line = ""
|
||||
for(var/j = 1; j <= 10; j++)
|
||||
if(i*10+j <= atom_list.len)
|
||||
temp_atom = atom_list[i*10+j]
|
||||
line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; "
|
||||
to_chat(world, line)*/
|
||||
|
||||
to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level]")
|
||||
SSblackbox.add_details("admin_verb","Count Objects Zlevel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/count_objects_all()
|
||||
set category = "Mapping"
|
||||
set name = "Count Objects All"
|
||||
|
||||
var/type_text = input("Which type path?","") as text
|
||||
if(!type_text) return
|
||||
var/type_path = text2path(type_text)
|
||||
if(!type_path) return
|
||||
|
||||
var/count = 0
|
||||
|
||||
for(var/atom/A in world)
|
||||
if(istype(A,type_path))
|
||||
count++
|
||||
/*
|
||||
var/atom/temp_atom
|
||||
for(var/i = 0; i <= (atom_list.len/10); i++)
|
||||
var/line = ""
|
||||
for(var/j = 1; j <= 10; j++)
|
||||
if(i*10+j <= atom_list.len)
|
||||
temp_atom = atom_list[i*10+j]
|
||||
line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; "
|
||||
to_chat(world, line)*/
|
||||
|
||||
to_chat(world, "There are [count] objects of type [type_path] in the game world")
|
||||
SSblackbox.add_details("admin_verb","Count Objects All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
//This proc is intended to detect lag problems relating to communication procs
|
||||
GLOBAL_VAR_INIT(say_disabled, FALSE)
|
||||
/client/proc/disable_communication()
|
||||
set category = "Mapping"
|
||||
set name = "Disable all communication verbs"
|
||||
|
||||
GLOB.say_disabled = !GLOB.say_disabled
|
||||
if(GLOB.say_disabled)
|
||||
message_admins("[src.ckey] used 'Disable all communication verbs', killing all communication methods.")
|
||||
else
|
||||
message_admins("[src.ckey] used 'Disable all communication verbs', restoring all communication methods.")
|
||||
|
||||
+806
-806
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,365 +1,365 @@
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 200
|
||||
clothes_req = 1
|
||||
invocation = "FORTI GY AMA"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
cooldown_min = 60 //35 deciseconds reduction per rank
|
||||
|
||||
max_targets = 0
|
||||
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile"
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
|
||||
proj_trail = 1
|
||||
proj_trail_lifespan = 5
|
||||
proj_trail_icon_state = "magicmd"
|
||||
|
||||
action_icon_state = "magicm"
|
||||
sound = 'sound/magic/MAGIC_MISSILE.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
|
||||
amt_weakened = 3
|
||||
sound = 'sound/magic/MM_Hit.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain laser vision for a short while."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
mutations = list(LASEREYES, HULK)
|
||||
duration = 300
|
||||
cooldown_min = 300 //25 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "mutate"
|
||||
sound = 'sound/magic/Mutate.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 20 //25 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 2
|
||||
smoke_amt = 4
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/lesser //Chaplain smoke book
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a small cloud of choking smoke at your location."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 360
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //50 deciseconds reduction per rank
|
||||
|
||||
emp_heavy = 6
|
||||
emp_light = 10
|
||||
sound = 'sound/magic/Disable_Tech.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 20
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 5 //4 deciseconds reduction per rank
|
||||
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 0
|
||||
|
||||
inner_tele_radius = 0
|
||||
outer_tele_radius = 6
|
||||
|
||||
action_icon_state = "blink"
|
||||
sound1 = 'sound/magic/blink.ogg'
|
||||
sound2 = 'sound/magic/blink.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/cult
|
||||
name = "quickstep"
|
||||
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
cult_req = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "SCYAR NILA"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
sound1 = 'sound/magic/Teleport_diss.ogg'
|
||||
sound2 = 'sound/magic/Teleport_app.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
|
||||
name = "Stop Time"
|
||||
desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen."
|
||||
charge_max = 500
|
||||
clothes_req = 1
|
||||
invocation = "TOKI WO TOMARE"
|
||||
invocation_type = "shout"
|
||||
range = 0
|
||||
cooldown_min = 100
|
||||
summon_amt = 1
|
||||
action_icon_state = "time"
|
||||
|
||||
summon_type = list(/obj/effect/timestop/wizard)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/carp
|
||||
name = "Summon Carp"
|
||||
desc = "This spell conjures a simple carp."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 1
|
||||
invocation = "NOUK FHUNMM SACP RISSKA"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/carp)
|
||||
cast_sound = 'sound/magic/Summon_Karp.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
|
||||
name = "Artificer"
|
||||
desc = "This spell conjures a construct which may be controlled by Shades"
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/constructshell)
|
||||
|
||||
action_icon_state = "artificer"
|
||||
cast_sound = 'sound/magic/SummonItems_generic.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
|
||||
name = "Summon Creature Swarm"
|
||||
desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth"
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 0
|
||||
invocation = "IA IA"
|
||||
invocation_type = "shout"
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/creature)
|
||||
cast_sound = 'sound/magic/SummonItems_generic.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
name = "Blind"
|
||||
desc = "This spell temporarily blinds a single person and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation = "STI KALY"
|
||||
invocation_type = "whisper"
|
||||
message = "<span class='notice'>Your eyes cry out in pain!</span>"
|
||||
cooldown_min = 50 //12 deciseconds reduction per rank
|
||||
|
||||
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
|
||||
|
||||
action_icon_state = "blind"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult
|
||||
name = "Summon Creatures (DANGEROUS)"
|
||||
cult_req = 1
|
||||
charge_max = 5000
|
||||
summon_amt = 2
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
|
||||
amt_eye_blind = 10
|
||||
amt_eye_blurry = 20
|
||||
sound = 'sound/magic/Blind.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/blind
|
||||
mutations = list(BLINDMUT)
|
||||
duration = 300
|
||||
sound = 'sound/magic/Blind.ogg'
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse
|
||||
name = "Repulse"
|
||||
desc = "This spell throws everything around the user away."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "GITTAH WEIGH"
|
||||
invocation_type = "shout"
|
||||
range = 5
|
||||
cooldown_min = 150
|
||||
selection_type = "view"
|
||||
sound = 'sound/magic/Repulse.ogg'
|
||||
var/maxthrow = 5
|
||||
var/sparkle_path = /obj/effect/overlay/temp/gravpush
|
||||
|
||||
action_icon_state = "repulse"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, var/stun_amt = 2)
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
playMagSound()
|
||||
for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously.
|
||||
for(var/atom/movable/AM in T)
|
||||
thrownatoms += AM
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == user || AM.anchored)
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
distfromcaster = get_dist(user, AM)
|
||||
if(distfromcaster == 0)
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Weaken(5)
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='userdanger'>You're slammed into the floor by [user]!</span>")
|
||||
else
|
||||
new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Weaken(stun_amt)
|
||||
to_chat(M, "<span class='userdanger'>You're thrown back by [user]!</span>")
|
||||
AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
|
||||
name = "Tail Sweep"
|
||||
desc = "Throw back attackers with a sweep of your tail."
|
||||
sound = 'sound/magic/Tail_swing.ogg'
|
||||
charge_max = 150
|
||||
clothes_req = 0
|
||||
range = 2
|
||||
cooldown_min = 150
|
||||
invocation_type = "none"
|
||||
sparkle_path = /obj/effect/overlay/temp/dir_setting/tailsweep
|
||||
action_icon_state = "tailsweep"
|
||||
action_background_icon_state = "bg_alien"
|
||||
|
||||
/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)
|
||||
..(targets, user, 3)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame
|
||||
name = "Sacred Flame"
|
||||
desc = "Makes everyone around you more flammable, and lights yourself on fire."
|
||||
charge_max = 60
|
||||
clothes_req = 0
|
||||
invocation = "FI'RAN DADISKO"
|
||||
invocation_type = "shout"
|
||||
max_targets = 0
|
||||
range = 6
|
||||
include_user = 1
|
||||
selection_type = "view"
|
||||
action_icon_state = "sacredflame"
|
||||
sound = 'sound/magic/Fireball.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
var/mob/living/U = user
|
||||
U.IgniteMob()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket
|
||||
name = "Thrown Lightning"
|
||||
desc = "Forged from eldrich energies, a packet of pure power, known as a spell packet will appear in your hand, that when thrown will stun the target."
|
||||
clothes_req = 1
|
||||
item_type = /obj/item/spellpacket/lightningbolt
|
||||
charge_max = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/spellpacket/lightningbolt
|
||||
name = "\improper Lightning bolt Spell Packet"
|
||||
desc = "Some birdseed wrapped in cloth that somehow crackles with electricity."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "snappop"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom)
|
||||
if(!..())
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/M = hit_atom
|
||||
M.electrocute_act(80, src, illusion = 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
. = ..()
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.say("LIGHTNINGBOLT!!")
|
||||
/obj/effect/proc_holder/spell/targeted/projectile/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 200
|
||||
clothes_req = 1
|
||||
invocation = "FORTI GY AMA"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
cooldown_min = 60 //35 deciseconds reduction per rank
|
||||
|
||||
max_targets = 0
|
||||
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile"
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
|
||||
proj_trail = 1
|
||||
proj_trail_lifespan = 5
|
||||
proj_trail_icon_state = "magicmd"
|
||||
|
||||
action_icon_state = "magicm"
|
||||
sound = 'sound/magic/MAGIC_MISSILE.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile
|
||||
amt_weakened = 3
|
||||
sound = 'sound/magic/MM_Hit.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain laser vision for a short while."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
mutations = list(LASEREYES, HULK)
|
||||
duration = 300
|
||||
cooldown_min = 300 //25 deciseconds reduction per rank
|
||||
|
||||
action_icon_state = "mutate"
|
||||
sound = 'sound/magic/Mutate.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 20 //25 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 2
|
||||
smoke_amt = 4
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/smoke/lesser //Chaplain smoke book
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a small cloud of choking smoke at your location."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 360
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
|
||||
action_icon_state = "smoke"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //50 deciseconds reduction per rank
|
||||
|
||||
emp_heavy = 6
|
||||
emp_light = 10
|
||||
sound = 'sound/magic/Disable_Tech.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 20
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 5 //4 deciseconds reduction per rank
|
||||
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 0
|
||||
|
||||
inner_tele_radius = 0
|
||||
outer_tele_radius = 6
|
||||
|
||||
action_icon_state = "blink"
|
||||
sound1 = 'sound/magic/blink.ogg'
|
||||
sound2 = 'sound/magic/blink.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/turf_teleport/blink/cult
|
||||
name = "quickstep"
|
||||
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
cult_req = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "SCYAR NILA"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_user = 1
|
||||
cooldown_min = 200 //100 deciseconds reduction per rank
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 2
|
||||
sound1 = 'sound/magic/Teleport_diss.ogg'
|
||||
sound2 = 'sound/magic/Teleport_app.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
|
||||
name = "Stop Time"
|
||||
desc = "This spell stops time for everyone except for you, allowing you to move freely while your enemies and even projectiles are frozen."
|
||||
charge_max = 500
|
||||
clothes_req = 1
|
||||
invocation = "TOKI WO TOMARE"
|
||||
invocation_type = "shout"
|
||||
range = 0
|
||||
cooldown_min = 100
|
||||
summon_amt = 1
|
||||
action_icon_state = "time"
|
||||
|
||||
summon_type = list(/obj/effect/timestop/wizard)
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/carp
|
||||
name = "Summon Carp"
|
||||
desc = "This spell conjures a simple carp."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 1
|
||||
invocation = "NOUK FHUNMM SACP RISSKA"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/carp)
|
||||
cast_sound = 'sound/magic/Summon_Karp.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/construct
|
||||
name = "Artificer"
|
||||
desc = "This spell conjures a construct which may be controlled by Shades"
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/constructshell)
|
||||
|
||||
action_icon_state = "artificer"
|
||||
cast_sound = 'sound/magic/SummonItems_generic.ogg'
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature
|
||||
name = "Summon Creature Swarm"
|
||||
desc = "This spell tears the fabric of reality, allowing horrific daemons to spill forth"
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 0
|
||||
invocation = "IA IA"
|
||||
invocation_type = "shout"
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
|
||||
summon_type = list(/mob/living/simple_animal/hostile/creature)
|
||||
cast_sound = 'sound/magic/SummonItems_generic.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/trigger/blind
|
||||
name = "Blind"
|
||||
desc = "This spell temporarily blinds a single person and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation = "STI KALY"
|
||||
invocation_type = "whisper"
|
||||
message = "<span class='notice'>Your eyes cry out in pain!</span>"
|
||||
cooldown_min = 50 //12 deciseconds reduction per rank
|
||||
|
||||
starting_spells = list("/obj/effect/proc_holder/spell/targeted/inflict_handler/blind","/obj/effect/proc_holder/spell/targeted/genetic/blind")
|
||||
|
||||
action_icon_state = "blind"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult
|
||||
name = "Summon Creatures (DANGEROUS)"
|
||||
cult_req = 1
|
||||
charge_max = 5000
|
||||
summon_amt = 2
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/inflict_handler/blind
|
||||
amt_eye_blind = 10
|
||||
amt_eye_blurry = 20
|
||||
sound = 'sound/magic/Blind.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/blind
|
||||
mutations = list(BLINDMUT)
|
||||
duration = 300
|
||||
sound = 'sound/magic/Blind.ogg'
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse
|
||||
name = "Repulse"
|
||||
desc = "This spell throws everything around the user away."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "GITTAH WEIGH"
|
||||
invocation_type = "shout"
|
||||
range = 5
|
||||
cooldown_min = 150
|
||||
selection_type = "view"
|
||||
sound = 'sound/magic/Repulse.ogg'
|
||||
var/maxthrow = 5
|
||||
var/sparkle_path = /obj/effect/overlay/temp/gravpush
|
||||
|
||||
action_icon_state = "repulse"
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets,mob/user = usr, var/stun_amt = 2)
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
playMagSound()
|
||||
for(var/turf/T in targets) //Done this way so things don't get thrown all around hilariously.
|
||||
for(var/atom/movable/AM in T)
|
||||
thrownatoms += AM
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == user || AM.anchored)
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user)))
|
||||
distfromcaster = get_dist(user, AM)
|
||||
if(distfromcaster == 0)
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Weaken(5)
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='userdanger'>You're slammed into the floor by [user]!</span>")
|
||||
else
|
||||
new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Weaken(stun_amt)
|
||||
to_chat(M, "<span class='userdanger'>You're thrown back by [user]!</span>")
|
||||
AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1,user)//So stuff gets tossed around at the same time.
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/repulse/xeno //i fixed conflicts only to find out that this is in the WIZARD file instead of the xeno file?!
|
||||
name = "Tail Sweep"
|
||||
desc = "Throw back attackers with a sweep of your tail."
|
||||
sound = 'sound/magic/Tail_swing.ogg'
|
||||
charge_max = 150
|
||||
clothes_req = 0
|
||||
range = 2
|
||||
cooldown_min = 150
|
||||
invocation_type = "none"
|
||||
sparkle_path = /obj/effect/overlay/temp/dir_setting/tailsweep
|
||||
action_icon_state = "tailsweep"
|
||||
action_background_icon_state = "bg_alien"
|
||||
|
||||
/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)
|
||||
..(targets, user, 3)
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame
|
||||
name = "Sacred Flame"
|
||||
desc = "Makes everyone around you more flammable, and lights yourself on fire."
|
||||
charge_max = 60
|
||||
clothes_req = 0
|
||||
invocation = "FI'RAN DADISKO"
|
||||
invocation_type = "shout"
|
||||
max_targets = 0
|
||||
range = 6
|
||||
include_user = 1
|
||||
selection_type = "view"
|
||||
action_icon_state = "sacredflame"
|
||||
sound = 'sound/magic/Fireball.ogg'
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/sacred_flame/cast(list/targets, mob/user = usr)
|
||||
for(var/mob/living/L in targets)
|
||||
L.adjust_fire_stacks(20)
|
||||
if(isliving(user))
|
||||
var/mob/living/U = user
|
||||
U.IgniteMob()
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket
|
||||
name = "Thrown Lightning"
|
||||
desc = "Forged from eldrich energies, a packet of pure power, known as a spell packet will appear in your hand, that when thrown will stun the target."
|
||||
clothes_req = 1
|
||||
item_type = /obj/item/spellpacket/lightningbolt
|
||||
charge_max = 10
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket/cast(list/targets, mob/user = usr)
|
||||
..()
|
||||
for(var/mob/living/carbon/C in targets)
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/spellpacket/lightningbolt
|
||||
name = "\improper Lightning bolt Spell Packet"
|
||||
desc = "Some birdseed wrapped in cloth that somehow crackles with electricity."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "snappop"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_impact(atom/hit_atom)
|
||||
if(!..())
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/M = hit_atom
|
||||
M.electrocute_act(80, src, illusion = 1)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/spellpacket/lightningbolt/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
. = ..()
|
||||
if(ishuman(thrower))
|
||||
var/mob/living/carbon/human/H = thrower
|
||||
H.say("LIGHTNINGBOLT!!")
|
||||
|
||||
Reference in New Issue
Block a user