Revert "pls"

This reverts commit 8c97511871.
This commit is contained in:
Fermi
2019-11-24 03:04:04 +00:00
parent 4c1c257035
commit c8b206a4cf
3003 changed files with 63963 additions and 157107 deletions
@@ -96,7 +96,6 @@ GLOBAL_LIST_EMPTY(antagonists)
LAZYREMOVE(owner.antag_datums, src)
if(!silent && owner.current)
farewell()
owner.objectives -= objectives
var/datum/team/team = get_team()
if(team)
team.remove_member(owner)
@@ -132,14 +131,14 @@ GLOBAL_LIST_EMPTY(antagonists)
report += printplayer(owner)
var/objectives_complete = TRUE
if(owner.objectives.len)
report += printobjectives(owner)
for(var/datum/objective/objective in owner.objectives)
if(objectives.len)
report += printobjectives(objectives)
for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
if(owner.objectives.len == 0 || objectives_complete)
if(objectives.len == 0 || objectives_complete)
report += "<span class='greentext big'>The [name] was successful!</span>"
else
report += "<span class='redtext big'>The [name] has failed!</span>"
@@ -216,25 +215,6 @@ GLOBAL_LIST_EMPTY(antagonists)
return
antag_memory = new_memo
//This datum will autofill the name with special_role
//Used as placeholder for minor antagonists, please create proper datums for these
/datum/antagonist/auto_custom
show_in_antagpanel = FALSE
antagpanel_category = "Other"
show_name_in_check_antagonists = TRUE
/datum/antagonist/auto_custom/on_gain()
..()
name = owner.special_role
//Add all objectives not already owned by other datums to this one.
var/list/already_registered_objectives = list()
for(var/datum/antagonist/A in owner.antag_datums)
if(A == src)
continue
else
already_registered_objectives |= A.objectives
objectives = owner.objectives - already_registered_objectives
//This one is created by admin tools for custom objectives
/datum/antagonist/custom
antagpanel_category = "Custom"
@@ -182,6 +182,10 @@
name = "syndicate medical teleporter"
borg_to_spawn = "Medical"
/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur
name = "syndicate saboteur teleporter"
borg_to_spawn = "Saboteur"
/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user)
var/mob/living/silicon/robot/R
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE)
@@ -191,6 +195,8 @@
switch(borg_to_spawn)
if("Medical")
R = new /mob/living/silicon/robot/modules/syndicate/medical(T)
if("Saboteur")
R = new /mob/living/silicon/robot/modules/syndicate/saboteur(T)
else
R = new /mob/living/silicon/robot/modules/syndicate(T) //Assault borg by default
+20 -15
View File
@@ -26,7 +26,7 @@
sub_role = "Scientist"
outfit = /datum/outfit/abductor/scientist
landmark_type = /obj/effect/landmark/abductor/scientist
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
greet_text = "Use your experimental console and surgical equipment to monitor your agent and experiment upon abducted humans."
show_in_antagpanel = TRUE
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
@@ -40,17 +40,18 @@
return team
/datum/antagonist/abductor/on_gain()
owner.special_role = "[name] [sub_role]"
owner.assigned_role = "[name] [sub_role]"
owner.objectives += team.objectives
owner.special_role = "[name]"
owner.assigned_role = "[name]"
objectives += team.objectives
finalize_abductor()
ADD_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/on_removal()
owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"<span class='userdanger'>You are no longer the [owner.special_role]!</span>")
owner.special_role = null
REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/greet()
@@ -64,6 +65,7 @@
//Equip
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/abductor)
H.real_name = "[team.name] [sub_role]"
H.equipOutfit(outfit)
@@ -75,11 +77,15 @@
update_abductor_icons_added(owner,"abductor")
/datum/antagonist/abductor/scientist/finalize_abductor()
..()
var/mob/living/carbon/human/H = owner.current
var/datum/species/abductor/A = H.dna.species
A.scientist = TRUE
/datum/antagonist/abductor/scientist/on_gain()
ADD_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
ADD_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
. = ..()
/datum/antagonist/abductor/scientist/on_removal()
REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
REMOVE_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
. = ..()
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
var/list/current_teams = list()
@@ -93,8 +99,8 @@
else
return
new_owner.add_antag_datum(src)
log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!")
message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !")
log_admin("[key_name(usr)] made [key_name(new_owner)] [name] on [choice]!")
message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner)] [name] on [choice] !")
/datum/antagonist/abductor/get_admin_commands()
. = ..()
@@ -147,7 +153,7 @@
result += "<span class='header'>The abductors of [name] were:</span>"
for(var/datum/mind/abductor_mind in members)
result += printplayer(abductor_mind)
result += printobjectives(abductor_mind)
result += printobjectives(objectives)
return "<div class='panel redborder'>[result.Join("<br>")]</div>"
@@ -172,7 +178,6 @@
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
var/datum/objective/abductee/O = new objtype()
objectives += O
owner.objectives += objectives
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
@@ -214,4 +219,4 @@
/datum/antagonist/proc/update_abductor_icons_removed(datum/mind/alien_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
hud.leave_hud(alien_mind.current)
set_antag_hud(alien_mind.current, null)
set_antag_hud(alien_mind.current, null)
@@ -55,7 +55,7 @@
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to activate the vest if he's actually wearing it.
return 1
@@ -132,22 +132,26 @@
/obj/item/abductor
icon = 'icons/obj/abductor.dmi'
/obj/item/abductor/proc/AbductorCheck(user)
if(isabductor(user))
/obj/item/abductor/proc/AbductorCheck(mob/user)
if(HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
return TRUE
if (istype(user) && user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
return TRUE
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
return FALSE
/obj/item/abductor/proc/ScientistCheck(user)
if(!AbductorCheck(user))
return FALSE
/obj/item/abductor/proc/ScientistCheck(mob/user)
var/training = HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
var/sci_training = HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING))
var/mob/living/carbon/human/H = user
var/datum/species/abductor/S = H.dna.species
if(S.scientist)
return TRUE
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
return FALSE
if(training && !sci_training)
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
. = FALSE
else if(!training && !sci_training)
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
. = FALSE
else
. = TRUE
/obj/item/abductor/gizmo
name = "science tool"
@@ -341,8 +345,8 @@
if(QDELETED(G))
return
if(istype(C.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
to_chat(user, "<span class='warning'>Your target seems to have some sort of protective headgear on, blocking the message from being sent!</span>")
if(C.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='warning'>Your target seems to have some sort of tinfoil protection on, blocking the message from being sent!</span>")
return
G.mind_control(command, user)
@@ -389,23 +393,22 @@
name = "Dissection Guide"
icon_state = "alienpaper_words"
info = {"<b>Dissection for Dummies</b><br>
<br>
1.Acquire fresh specimen.<br>
2.Put the specimen on operating table.<br>
3.Apply surgical drapes, preparing for experimental dissection.<br>
4.Apply scalpel to specimen's torso.<br>
5.Clamp bleeders on specimen's torso with a hemostat.<br>
6.Retract skin of specimen's torso with a retractor.<br>
7.Apply scalpel again to specimen's torso.<br>
8.Search through the specimen's torso with your hands to remove any superfluous organs.<br>
9.Insert replacement gland (Retrieve one from gland storage).<br>
10.Consider dressing the specimen back to not disturb the habitat. <br>
11.Put the specimen in the experiment machinery.<br>
12.Choose one of the machine options. The target will be analyzed and teleported to the selected drop-off point.<br>
13.You will receive one supply credit, and the subject will be counted towards your quota.<br>
<br>
Congratulations! You are now trained for invasive xenobiology research!"}
<br>
1.Acquire fresh specimen.<br>
2.Put the specimen on operating table.<br>
3.Apply surgical drapes, preparing for experimental dissection.<br>
4.Apply scalpel to specimen's torso.<br>
5.Clamp bleeders on specimen's torso with a hemostat.<br>
6.Retract skin of specimen's torso with a retractor.<br>
7.Apply scalpel again to specimen's torso.<br>
8.Search through the specimen's torso with your hands to remove any superfluous organs.<br>
9.Insert replacement gland (Retrieve one from gland storage).<br>
10.Consider dressing the specimen back to not disturb the habitat. <br>
11.Put the specimen in the experiment machinery.<br>
12.Choose one of the machine options. The target will be analyzed and teleported to the selected drop-off point.<br>
13.You will receive one supply credit, and the subject will be counted towards your quota.<br>
<br>
Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/paper/guides/antag/abductor/update_icon()
return
@@ -520,10 +523,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
if(L.incapacitated(TRUE, TRUE))
if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
to_chat(user, "<span class='warning'>The specimen's protective headgear is interfering with the sleep inducement!</span>")
L.visible_message("<span class='danger'>[user] tried to induced sleep in [L] with [src], but [L.p_their()] headgear protected [L.p_them()]!</span>", \
"<span class='userdanger'>You feel a strange wave of heavy drowsiness wash over you, but your headgear deflects most of it!</span>")
if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='warning'>The specimen's tinfoil protection is interfering with the sleep inducement!</span>")
L.visible_message("<span class='danger'>[user] tried to induced sleep in [L] with [src], but [L.p_their()] tinfoil protected [L.p_them()]!</span>", \
"<span class='userdanger'>You feel a strange wave of heavy drowsiness wash over you, but your tinfoil protection deflects most of it!</span>")
L.drowsyness += 2
return
L.visible_message("<span class='danger'>[user] has induced sleep in [L] with [src]!</span>", \
@@ -532,10 +535,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
L.Sleeping(1200)
log_combat(user, L, "put to sleep")
else
if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
to_chat(user, "<span class='warning'>The specimen's protective headgear is completely blocking our sleep inducement methods!</span>")
L.visible_message("<span class='danger'>[user] tried to induce sleep in [L] with [src], but [L.p_their()] headgear completely protected [L.p_them()]!</span>", \
"<span class='userdanger'>Any sense of drowsiness is quickly diminished as your headgear deflects the effects!</span>")
if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='warning'>The specimen's tinfoil protection is completely blocking our sleep inducement methods!</span>")
L.visible_message("<span class='danger'>[user] tried to induce sleep in [L] with [src], but [L.p_their()] tinfoil completely protected [L.p_them()]!</span>", \
"<span class='userdanger'>Any sense of drowsiness is quickly diminished as your tinfoil protection deflects the effects!</span>")
return
L.drowsyness += 1
to_chat(user, "<span class='warning'>Sleep inducement works fully only on stunned specimens! </span>")
@@ -683,7 +686,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
desc = "Abduct with style - spiky style. Prevents digital tracking."
icon_state = "alienhelmet"
item_state = "alienhelmet"
blockTracking = 1
blockTracking = TRUE
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
// Operating Table / Beds / Lockers
@@ -5,6 +5,7 @@
icon_state = "gland"
status = ORGAN_ROBOTIC
beating = TRUE
var/true_name = "baseline placebo referencer"
var/cooldown_low = 300
var/cooldown_high = 300
var/next_activation = 0
@@ -16,6 +17,11 @@
var/mind_control_duration = 1800
var/active_mind_control = FALSE
/obj/item/organ/heart/gland/examine(mob/user)
. = ..()
if((user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)) || isobserver(user))
to_chat(user, "<span class='notice'>It is \a [true_name].</span>")
/obj/item/organ/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return TRUE
@@ -42,19 +48,19 @@
/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user)
if(!ownerCheck() || !mind_control_uses || active_mind_control)
return
return FALSE
mind_control_uses--
to_chat(owner, "<span class='userdanger'>You suddenly feel an irresistible compulsion to follow an order...</span>")
to_chat(owner, "<span class='mind_control'>[command]</span>")
active_mind_control = TRUE
log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
message_admins("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
update_gland_hud()
addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
/obj/item/organ/heart/gland/proc/clear_mind_control()
if(!ownerCheck() || !active_mind_control)
return
return FALSE
to_chat(owner, "<span class='userdanger'>You feel the compulsion fade, and you completely forget about your previous orders.</span>")
active_mind_control = FALSE
@@ -67,7 +73,7 @@
clear_mind_control()
..()
/obj/item/organ/heart/gland/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
if(special != 2 && uses) // Special 2 means abductor surgery
Start()
@@ -95,6 +101,7 @@
return
/obj/item/organ/heart/gland/heals
true_name = "coherency harmonizer"
cooldown_low = 200
cooldown_high = 400
uses = -1
@@ -109,6 +116,7 @@
owner.adjustOxyLoss(-20)
/obj/item/organ/heart/gland/slime
true_name = "gastric animation galvanizer"
cooldown_low = 600
cooldown_high = 1200
uses = -1
@@ -116,7 +124,7 @@
mind_control_uses = 1
mind_control_duration = 2400
/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
owner.faction |= "slime"
owner.grant_language(/datum/language/slime)
@@ -130,6 +138,7 @@
Slime.Leader = owner
/obj/item/organ/heart/gland/mindshock
true_name = "neural crosstalk uninhibitor"
cooldown_low = 400
cooldown_high = 700
uses = -1
@@ -156,6 +165,7 @@
H.hallucination += 60
/obj/item/organ/heart/gland/pop
true_name = "anthropmorphic translocator"
cooldown_low = 900
cooldown_high = 1800
uses = -1
@@ -171,6 +181,7 @@
owner.set_species(species)
/obj/item/organ/heart/gland/ventcrawling
true_name = "pliant cartilage enabler"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
@@ -183,6 +194,7 @@
owner.ventcrawler = VENTCRAWLER_ALWAYS
/obj/item/organ/heart/gland/viral
true_name = "contamination incubator"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
@@ -217,6 +229,7 @@
return A
/obj/item/organ/heart/gland/trauma
true_name = "white matter randomiser"
cooldown_low = 800
cooldown_high = 1200
uses = 5
@@ -235,6 +248,7 @@
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
/obj/item/organ/heart/gland/spiderman
true_name = "araneae cloister accelerator"
cooldown_low = 450
cooldown_high = 900
uses = -1
@@ -249,6 +263,7 @@
S.directive = "Protect your nest inside [owner.real_name]."
/obj/item/organ/heart/gland/egg
true_name = "roe/enzymatic synthesizer"
cooldown_low = 300
cooldown_high = 400
uses = -1
@@ -264,13 +279,14 @@
new /obj/item/reagent_containers/food/snacks/egg/gland(T)
/obj/item/organ/heart/gland/electric
true_name = "electron accumulator/discharger"
cooldown_low = 800
cooldown_high = 1200
uses = -1
mind_control_uses = 2
mind_control_duration = 900
/obj/item/organ/heart/gland/electric/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/electric/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, ORGAN_TRAIT)
@@ -289,6 +305,7 @@
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1)
/obj/item/organ/heart/gland/chem
true_name = "intrinsic pharma-provider"
cooldown_low = 50
cooldown_high = 50
uses = -1
@@ -315,6 +332,7 @@
..()
/obj/item/organ/heart/gland/plasma
true_name = "effluvium sanguine-synonym emitter"
cooldown_low = 1200
cooldown_high = 1800
uses = -1
@@ -17,9 +17,9 @@
/obj/machinery/computer/camera_advanced/abductor/CreateEye()
..()
eyeobj.visible_icon = 1
eyeobj.icon = 'icons/obj/abductor.dmi'
eyeobj.icon_state = "camera_target"
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/mob/cameramob.dmi'
eyeobj.icon_state = "generic_camera"
/obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user)
..()
@@ -55,8 +55,7 @@
actions += set_droppoint_action
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
var/datum/species/abductor/S = H.dna.species
return S.scientist
return HAS_TRAIT(H, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)
/datum/action/innate/teleport_in
name = "Send To"
@@ -28,7 +28,7 @@
. = ..()
if(.)
return
if(!isabductor(user))
if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
to_chat(user, "<span class='warning'>You start mashing alien buttons at random!</span>")
if(do_after(user,100, target = src))
TeleporterSend()
@@ -178,8 +178,8 @@
c.console = src
/obj/machinery/abductor/console/proc/AddSnapshot(mob/living/carbon/human/target)
if(istype(target.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
say("Subject wearing specialized protective headgear, unable to get a proper scan!")
if(target.anti_magic_check(FALSE, FALSE, TRUE, 0))
say("Subject wearing specialized protective tinfoil gear, unable to get a proper scan!")
return
var/datum/icon_snapshot/entry = new
entry.name = target.name
@@ -53,4 +53,4 @@
. = ..()
var/datum/effect_system/spark_spread/S = new
S.set_up(10,0,loc)
S.start()
S.start()
-1
View File
@@ -30,7 +30,6 @@
var/datum/objective/blob_takeover/main = new
main.owner = owner
objectives += main
owner.objectives |= objectives
/datum/antagonist/blob/apply_innate_effects(mob/living/mob_override)
if(!isovermind(owner.current))
@@ -27,7 +27,7 @@
. = ..()
/obj/structure/blob/core/proc/generate_announcement()
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5")
/obj/structure/blob/core/scannerreport()
return "Directs the blob's expansion, gradually expands, and sustains nearby blob spores and blobbernauts."
@@ -9,7 +9,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
name = "Blob Overmind"
real_name = "Blob Overmind"
desc = "The overmind. It controls the blob."
icon = 'icons/mob/blob.dmi'
icon = 'icons/mob/cameramob.dmi'
icon_state = "marker"
mouse_opacity = MOUSE_OPACITY_ICON
move_on_shuttle = 1
@@ -0,0 +1,33 @@
/datum/antagonist/blood_contract
name = "Blood Contract Target"
show_in_roundend = FALSE
show_in_antagpanel = FALSE
/datum/antagonist/blood_contract/on_gain()
. = ..()
give_objective()
start_the_hunt()
/datum/antagonist/blood_contract/proc/give_objective()
var/datum/objective/survive/survive = new
survive.owner = owner
objectives += survive
/datum/antagonist/blood_contract/greet()
. = ..()
to_chat(owner, "<span class='userdanger'>You've been marked for death! Don't let the demons get you! KILL THEM ALL!</span>")
/datum/antagonist/blood_contract/proc/start_the_hunt()
var/mob/living/carbon/human/H = owner.current
if(!istype(H))
return
H.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY)
var/obj/effect/mine/pickup/bloodbath/B = new(H)
INVOKE_ASYNC(B, /obj/effect/mine/pickup/bloodbath/.proc/mineEffect, H) //could use moving out from the mine
for(var/mob/living/carbon/human/P in GLOB.player_list)
if(P == H)
continue
to_chat(P, "<span class='userdanger'>You have an overwhelming desire to kill [H]. [H.p_theyve(TRUE)] been marked red! Whoever [H.p_they()] [H.p_were()], friend or foe, go kill [H.p_them()]!</span>")
P.put_in_hands(new /obj/item/kitchen/knife/butcher(P), TRUE)
@@ -9,7 +9,6 @@
for(var/O in directives)
var/datum/objective/brainwashing/objective = new(O)
B.objectives += objective
M.objectives += objective
B.greet()
else
B = new()
@@ -32,10 +31,6 @@
antagpanel_category = "Other"
show_name_in_check_antagonists = TRUE
/datum/antagonist/brainwashed/on_gain()
owner.objectives |= objectives
. = ..()
/datum/antagonist/brainwashed/greet()
to_chat(owner, "<span class='warning'>Your mind reels as it begins focusing on a single purpose...</span>")
to_chat(owner, "<big><span class='warning'><b>Follow the Directives, at any cost!</b></span></big>")
@@ -20,7 +20,6 @@
/datum/antagonist/brother/on_gain()
SSticker.mode.brothers += owner
objectives += team.objectives
owner.objectives += objectives
owner.special_role = special_role
finalize_brother()
return ..()
@@ -459,8 +459,6 @@
objectives += identity_theft
escape_objective_possible = FALSE
owner.objectives |= objectives
/datum/antagonist/changeling/proc/update_changeling_icons_added()
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
hud.join_hud(owner.current)
@@ -334,7 +334,7 @@
/obj/item/projectile/tentacle/proc/tentacle_stab(mob/living/carbon/human/H, mob/living/carbon/C)
if(H.Adjacent(C))
for(var/obj/item/I in H.held_items)
if(I.is_sharp())
if(I.get_sharpness())
C.visible_message("<span class='danger'>[H] impales [C] with [H.p_their()] [I.name]!</span>", "<span class='userdanger'>[H] impales you with [H.p_their()] [I.name]!</span>")
C.apply_damage(I.force, BRUTE, BODY_ZONE_CHEST)
H.do_item_attack_animation(C, used_item = I)
@@ -21,7 +21,7 @@
to_chat(user, "<span class='notice'>Our muscles tense and strengthen.</span>")
changeling.chem_recharge_slowdown += 0.5
else
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
to_chat(user, "<span class='notice'>Our muscles relax.</span>")
changeling.chem_recharge_slowdown -= 0.5
if(stacks >= 20)
@@ -36,12 +36,12 @@
/obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
while(active)
ADD_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
user.add_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
active = !active
to_chat(user, "<span class='notice'>Our muscles relax without the energy to strengthen them.</span>")
user.Knockdown(40)
REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
changeling.chem_recharge_slowdown -= 0.5
break
@@ -147,6 +147,11 @@
if(iscarbon(L))
var/mob/living/carbon/M = L
M.uncuff()
var/brutedamage = L.getBruteLoss()
var/burndamage = L.getFireLoss()
if(brutedamage || burndamage)
L.adjustBruteLoss(-(brutedamage * 0.25))
L.adjustFireLoss(-(burndamage * 0.25))
L.Knockdown(50) //Completely defenseless for five seconds - mainly to give them time to read over the information they've just been presented with
if(iscarbon(L))
var/mob/living/carbon/C = L
@@ -262,7 +267,7 @@
clockwork_desc = "A sigil that will drain non-Servants that remain on it. Servants that remain on it will be healed if it has any vitality drained."
icon_state = "sigilvitality"
layer = SIGIL_LAYER
alpha = 75
alpha = 125
color = "#123456"
affects_servants = TRUE
stat_affected = DEAD
@@ -366,6 +371,8 @@
break
if(!GLOB.ratvar_awakens)
if(GLOB.clockwork_vitality <= 0)
break
GLOB.clockwork_vitality -= vitality_used
sleep(2)
@@ -35,7 +35,7 @@
/obj/item/clockwork/weapon/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check() && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check(chargecost = 0) && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
var/bonus_damage = bonus_burn //normally a total of 20 damage, 30 with ratvar
if(issilicon(target))
target.visible_message("<span class='warning'>[target] shudders violently at [src]'s touch!</span>", "<span class='userdanger'>ERROR: Temperature rising!</span>")
@@ -64,7 +64,7 @@
/obj/item/clockwork/slab/cyborg/janitor //six scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \
/datum/clockwork_scripture/create_object/stargazer, /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor)
/datum/clockwork_scripture/create_object/stargazer, /datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor)
/obj/item/clockwork/slab/cyborg/service //six scriptures, plus xray vision
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant,/datum/clockwork_scripture/create_object/stargazer, \
@@ -15,7 +15,7 @@
. = ..()
var/area/A = get_area(src)
if(A && construct_type)
notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_CONSTRUCT)
notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_CONSTRUCT, ignore_dnr_observers = TRUE)
GLOB.poi_list += src
LAZYADD(GLOB.mob_spawners[name], src)
@@ -39,7 +39,9 @@
. = ..()
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/item/clockwork/construct_chassis/attack_ghost(mob/user)
/obj/item/clockwork/construct_chassis/attack_ghost(mob/dead/observer/user)
if(!user.can_reenter_round())
return FALSE
if(!SSticker.mode)
to_chat(user, "<span class='danger'>You cannot use that before the game has started.</span>")
return
@@ -27,7 +27,7 @@
qdel(blaster)
return ..()
/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user)
/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot != SLOT_GLASSES)
return 0
return ..()
@@ -190,8 +190,8 @@
for(var/mob/living/L in range(1, src))
if(is_servant_of_ratvar(L))
continue
if(L.anti_magic_check())
var/atom/I = L.anti_magic_check()
var/atom/I = L.anti_magic_check()
if(I)
if(isitem(I))
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")
@@ -119,3 +119,33 @@
var/datum/clockwork_scripture/create_object/construct/clockwork_marauder/CM = new()
CM.recent_marauders--
qdel(CM)
//Summon Neovgre: Summon a very powerful combat mech that explodes when destroyed for massive damage.
/datum/clockwork_scripture/create_object/summon_arbiter
descname = "Powerful Assault Mech"
name = "Summon Neovgre, the Anima Bulwark"
desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\
mech with superior defensive and offensive capabilities. It will \
steadily regenerate HP and triple its regeneration speed while standing \
on a clockwork tile. It will automatically draw power from nearby sigils of \
transmission should the need arise. Its Arbiter laser cannon can decimate foes \
from a range and is capable of smashing through any barrier presented to it. \
Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \
in you cannot leave and when it is destroyed it will explode catastrophically with you inside."
invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
power_cost = 75000 //75 KW
usage_tip = "Neovgre is a powerful mech that will crush your enemies!"
invokers_required = 5
multiple_invokers_used = TRUE
object_path = /obj/mecha/combat/neovgre
tier = SCRIPTURE_APPLICATION
primary_component = BELLIGERENT_EYE
sort_priority = 2
creator_message = "<span class='brass'>Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come.</span>"
/datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements()
if(GLOB.neovgre_exists)
to_chat(invoker, "<span class='brass'>\"You've already got one...\"</span>")
return FALSE
return ..()
@@ -80,7 +80,7 @@
power_cost = 125
whispered = TRUE
object_path = /obj/effect/clockwork/sigil/submission
creator_message = "<span class='brass'>A luminous sigil appears below you. Any non-Servants to cross it will be converted after 8 seconds if they do not move.</span>"
creator_message = "<span class='brass'>A luminous sigil appears below you. Any non-Servants to cross it will be converted and healed of some of their wounds after 8 seconds if they do not move.</span>"
usage_tip = "This is the primary conversion method, though it will not penetrate mindshield implants."
tier = SCRIPTURE_DRIVER
one_per_tile = TRUE
@@ -71,6 +71,7 @@
return TRUE
/obj/structure/destructible/clockwork/trap/proc/activate()
return
//These objects send signals to normal traps to activate
/obj/structure/destructible/clockwork/trap/trigger
@@ -79,6 +80,14 @@
break_message = "<span class='warning'>The trigger breaks apart!</span>"
density = FALSE
/obj/structure/destructible/clockwork/trap/trigger/Initialize()
. = ..()
for(var/obj/structure/destructible/clockwork/trap/T in get_turf(src))
if(!istype(T, /obj/structure/destructible/clockwork/trap/trigger))
wired_to += T
T.wired_to += src
to_chat(usr, "<span class='alloy'>[src] automatically links with [T] beneath it.</span>")
/obj/structure/destructible/clockwork/trap/trigger/activate()
for(var/obj/structure/destructible/clockwork/trap/T in wired_to)
if(istype(T, /obj/structure/destructible/clockwork/trap/trigger)) //Triggers don't go off multiple times
@@ -78,7 +78,7 @@
return
voters += user.key
else
if(!user.key in voters)
if(!(user.key in voters))
return
voters -= user.key
var/votes_left = votes_needed - voters.len
@@ -60,7 +60,7 @@
else
if(isliving(target))
var/mob/living/L = target
if(!L.anti_magic_check())
if(!L.anti_magic_check(chargecost = 0))
if(isrevenant(L))
var/mob/living/simple_animal/revenant/R = L
if(R.revealed)
@@ -110,9 +110,7 @@
if(!(BI.resistance_flags & ON_FIRE))
BI.fire_act()
continue
if(is_servant_of_ratvar(L) || (HAS_TRAIT(L, TRAIT_BLIND)) || L.anti_magic_check(TRUE, TRUE))
continue
if(L.stat || L.lying)
if(is_servant_of_ratvar(L) || (HAS_TRAIT(L, TRAIT_BLIND)) || L.anti_magic_check(TRUE, TRUE) || L.incapacitated(TRUE))
continue
if (iscarbon(L))
var/mob/living/carbon/c = L
@@ -53,7 +53,7 @@
/obj/structure/destructible/clockwork/taunting_trail/proc/affect_mob(mob/living/L)
if(istype(L) && !is_servant_of_ratvar(L))
if(!L.anti_magic_check())
if(!L.anti_magic_check(chargecost = 0))
L.confused = min(L.confused + 15, 50)
L.dizziness = min(L.dizziness + 15, 50)
if(L.confused >= 25)
@@ -7,18 +7,10 @@
icon_state = "pressure_sensor"
alpha = 50
/obj/structure/destructible/clockwork/trap/trigger/Initialize()
. = ..()
for(var/obj/structure/destructible/clockwork/trap/T in get_turf(src))
if(!istype(T, /obj/structure/destructible/clockwork/trap/trigger))
wired_to += T
T.wired_to += src
to_chat(usr, "<span class='alloy'>[src] automatically links with [T] beneath it.</span>")
/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/Crossed(atom/movable/AM)
if(isliving(AM) && !is_servant_of_ratvar(AM))
var/mob/living/L = AM
if(L.stat || L.m_intent == MOVE_INTENT_WALK || L.lying)
if(L.stat || L.m_intent == MOVE_INTENT_WALK || L.movement_type & (FLYING|FLOATING))
return
audible_message("<i>*click*</i>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE)
@@ -7,7 +7,6 @@
break_message = "<span class='warning'>The vent snaps and collapses!</span>"
max_integrity = 100
density = FALSE
layer = BELOW_OBJ_LAYER
/obj/structure/destructible/clockwork/trap/steam_vent/activate()
opacity = !opacity
@@ -5,7 +5,6 @@
unanchored_icon = "wall_gear"
climbable = TRUE
max_integrity = 100
layer = BELOW_OBJ_LAYER
construction_value = 3
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
break_message = "<span class='warning'>The gear breaks apart into shards of alloy!</span>"
-1
View File
@@ -35,7 +35,6 @@
/datum/antagonist/cult/proc/add_objectives()
objectives |= cult_team.objectives
owner.objectives |= objectives
/datum/antagonist/cult/Destroy()
QDEL_NULL(communion)
+4 -4
View File
@@ -275,7 +275,7 @@
desc = "A torn, dust-caked hood. Strange letters line the inside."
flags_inv = HIDEFACE|HIDEHAIR|HIDEEARS
flags_cover = HEADCOVERSEYES
armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
cold_protection = HEAD
min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT
heat_protection = HEAD
@@ -288,7 +288,7 @@
item_state = "cultrobes"
body_parts_covered = CHEST|GROIN|LEGS|ARMS
allowed = list(/obj/item/tome, /obj/item/melee/cultblade)
armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
flags_inv = HIDEJUMPSUIT
cold_protection = CHEST|GROIN|LEGS|ARMS
min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT
@@ -493,7 +493,7 @@
desc = "You peer within this smokey orb and glimpse terrible fates befalling the escape shuttle."
icon = 'icons/obj/cult.dmi'
icon_state ="shuttlecurse"
var/global/curselimit = 0
var/static/curselimit = 0
/obj/item/shuttle_curse/attack_self(mob/living/user)
if(!iscultist(user))
@@ -530,7 +530,7 @@
playsound(user.loc, 'sound/effects/glassbr1.ogg', 50, 1)
qdel(src)
sleep(20)
var/global/list/curses
var/static/list/curses
if(!curses)
curses = list("A fuel technician just slit his own throat and begged for death.",
"The shuttle's navigation programming was replaced by a file containing just two words: IT COMES.",
+1 -1
View File
@@ -107,7 +107,7 @@ This file contains the cult dagger and rune list code
if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move
to_chat(user, "<span class='cultlarge'>The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!</span>")
return
priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg')
priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", "spanomalies")
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/sanguine/N = new(B)
shields += N
+6 -6
View File
@@ -237,7 +237,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(M, "<span class='warning'>You need at least two invokers to convert [convertee]!</span>")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed
if(convertee.anti_magic_check(TRUE, TRUE, chargecost = 0)) //Not major because it can be spammed
for(var/M in invokers)
to_chat(M, "<span class='warning'>Something is shielding [convertee]'s mind!</span>")
log_game("Offer rune failed - convertee had anti-magic")
@@ -249,7 +249,7 @@ structure_check() searches for nearby cultist structures required for the invoca
convertee.adjustFireLoss(-(burndamage * 0.75))
convertee.visible_message("<span class='warning'>[convertee] writhes in pain \
[brutedamage || burndamage ? "even as [convertee.p_their()] wounds heal and close" : "as the markings below [convertee.p_them()] glow a bloody red"]!</span>", \
"<span class='cultlarge'><i>AAAAAAAAAAAAAA-</i></span>")
"<span class='cultlarge'><i>AAAAAAAAAAAAAA-</i></span>")
SSticker.mode.add_cultist(convertee.mind, 1)
new /obj/item/melee/cultblade/dagger(get_turf(src))
convertee.mind.special_role = ROLE_CULTIST
@@ -767,7 +767,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
var/atom/I = L.anti_magic_check()
var/atom/I = L.anti_magic_check(chargecost = 0)
if(I)
if(isitem(I))
to_chat(L, "<span class='userdanger'>[I] suddenly burns hotly before returning to normal!</span>")
@@ -797,7 +797,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
if(L.anti_magic_check())
if(L.anti_magic_check(chargecost = 0))
continue
L.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier)
if(is_servant_of_ratvar(L))
@@ -848,10 +848,10 @@ structure_check() searches for nearby cultist structures required for the invoca
fail_invoke()
log_game("Manifest rune failed - too many summoned ghosts")
return list()
notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src)
notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src, ignore_dnr_observers = TRUE)
var/list/ghosts_on_rune = list()
for(var/mob/dead/observer/O in T)
if(O.client && !jobban_isbanned(O, ROLE_CULTIST) && !QDELETED(src) && !QDELETED(O))
if(!QDELETED(O) && O.client && !jobban_isbanned(O, ROLE_CULTIST) && !QDELETED(src) && O.can_reenter_round())
ghosts_on_rune += O
if(!ghosts_on_rune.len)
to_chat(user, "<span class='cultitalic'>There are no spirits near [src]!</span>")
+1 -1
View File
@@ -549,7 +549,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/list/parts = list()
parts += printplayer(owner)
parts += printdevilinfo()
parts += printobjectives(owner)
parts += printobjectives(objectives)
return parts.Join("<br>")
//A simple super light weight datum for the codex gigas.
+15
View File
@@ -57,3 +57,18 @@
visible_message("<span class='danger'>[src] screams in agony as it sublimates into a sulfurous smoke.</span>")
ghostize()
qdel(src)
/datum/antagonist/imp
name = "Imp"
antagpanel_category = "Devil"
show_in_roundend = FALSE
/datum/antagonist/imp/on_gain()
. = ..()
give_objectives()
/datum/antagonist/imp/proc/give_objectives()
var/datum/objective/newobjective = new
newobjective.explanation_text = "Try to get a promotion to a higher devilic rank."
newobjective.owner = owner
objectives += newobjective
@@ -106,7 +106,7 @@
/mob/living/carbon/true_devil/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null)
return 666
/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
/mob/living/carbon/true_devil/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
if(mind && has_bane(BANE_LIGHT))
mind.disrupt_spells(-500)
return ..() //flashes don't stop devils UNLESS it's their bane.
@@ -147,13 +147,8 @@
if(ascended || user.mind.soulOwner == src.mind)
var/mob/living/simple_animal/imp/S = new(get_turf(loc))
user.transfer_ckey(S, FALSE)
S.mind.assigned_role = "Imp"
S.mind.special_role = "Imp"
var/datum/objective/newobjective = new
newobjective.explanation_text = "Try to get a promotion to a higher devilic rank."
S.mind.objectives += newobjective
to_chat(S, S.playstyle_string)
to_chat(S, "<B>Objective #[1]</B>: [newobjective.explanation_text]")
var/datum/antagonist/imp/A = new()
S.mind.add_antag_datum(A)
else
return ..()
@@ -10,12 +10,10 @@
var/datum/objective/O = new /datum/objective/disease_infect()
O.owner = owner
objectives += O
owner.objectives += O
O = new /datum/objective/disease_infect_centcom()
O.owner = owner
objectives += O
owner.objectives += O
. = ..()
@@ -3,6 +3,7 @@
name = "Spawn Sentient Disease"
typepath = /datum/round_event/ghost_role/sentient_disease
weight = 7
gamemode_blacklist = list("dynamic")
max_occurrences = 1
min_players = 5
@@ -9,7 +9,7 @@ the new instance inside the host to be updated to the template's stats.
name = "Sentient Disease"
real_name = "Sentient Disease"
desc = ""
icon = 'icons/mob/blob.dmi'
icon = 'icons/mob/cameramob.dmi'
icon_state = "marker"
mouse_opacity = MOUSE_OPACITY_ICON
move_on_shuttle = FALSE
@@ -31,7 +31,6 @@ the new instance inside the host to be updated to the template's stats.
var/browser_open = FALSE
var/mob/living/following_host
var/datum/component/redirect/move_listener
var/list/disease_instances
var/list/hosts //this list is associative, affected_mob -> disease_instance
var/datum/disease/advance/sentient_disease/disease_template
@@ -261,16 +260,10 @@ the new instance inside the host to be updated to the template's stats.
refresh_adaptation_menu()
/mob/camera/disease/proc/set_following(mob/living/L)
if(following_host)
UnregisterSignal(following_host, COMSIG_MOVABLE_MOVED)
RegisterSignal(L, COMSIG_MOVABLE_MOVED, .proc/follow_mob)
following_host = L
if(!move_listener)
move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob)))
else
if(L)
L.TakeComponent(move_listener)
if(QDELING(move_listener))
move_listener = null
else
QDEL_NULL(move_listener)
follow_mob()
/mob/camera/disease/proc/follow_next(reverse = FALSE)
-1
View File
@@ -113,7 +113,6 @@
/datum/antagonist/ert/proc/forge_objectives()
if(ert_team)
objectives |= ert_team.objectives
owner.objectives |= objectives
/datum/antagonist/ert/proc/equipERT()
var/mob/living/carbon/human/H = owner.current
@@ -8,7 +8,6 @@
O.completed = TRUE //YES!
O.owner = owner
objectives += O
owner.objectives += objectives
/datum/antagonist/greentext/on_gain()
forge_objectives()
@@ -24,8 +24,6 @@
hijack_objective.owner = owner
objectives += hijack_objective
owner.objectives |= objectives
/datum/antagonist/highlander/on_gain()
forge_objectives()
owner.special_role = "highlander"
@@ -0,0 +1,9 @@
/datum/antagonist/magic_servant
name = "Magic Servant"
show_in_roundend = FALSE
show_in_antagpanel = FALSE
/datum/antagonist/magic_servant/proc/setup_master(mob/M)
var/datum/objective/O = new("Serve [M.real_name].")
O.owner = owner
objectives |= O
@@ -63,7 +63,6 @@
/datum/antagonist/monkey/proc/forge_objectives()
objectives |= monkey_team.objectives
owner.objectives |= objectives
/datum/antagonist/monkey/admin_remove(mob/admin)
var/mob/living/carbon/monkey/M = owner.current
-1
View File
@@ -96,7 +96,6 @@
var/datum/objective/O = new /datum/objective/survive()
O.owner = owner
objectives += O
owner.objectives |= objectives
/proc/remove_ninja(mob/living/L)
if(!L || !L.mind)
@@ -0,0 +1,181 @@
/obj/item/borg_chameleon
name = "cyborg chameleon projector"
icon = 'icons/obj/device.dmi'
icon_state = "shield0"
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
var/friendlyName
var/savedName
var/active = FALSE
var/activationCost = 300
var/activationUpkeep = 50
var/disguise = null
var/disguise_icon_override = null
var/disguise_pixel_offset = null
var/mob/listeningTo
var/static/list/signalCache = list( // list here all signals that should break the camouflage
COMSIG_PARENT_ATTACKBY,
COMSIG_ATOM_ATTACK_HAND,
COMSIG_MOVABLE_IMPACT_ZONE,
COMSIG_ATOM_BULLET_ACT,
COMSIG_ATOM_EX_ACT,
COMSIG_ATOM_FIRE_ACT,
COMSIG_ATOM_EMP_ACT,
)
var/mob/living/silicon/robot/user // needed for process()
var/animation_playing = FALSE
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
/obj/item/borg_chameleon/Initialize()
. = ..()
friendlyName = pick(GLOB.ai_names)
/obj/item/borg_chameleon/Destroy()
listeningTo = null
return ..()
/obj/item/borg_chameleon/dropped(mob/user)
. = ..()
disrupt(user)
/obj/item/borg_chameleon/equipped(mob/user)
. = ..()
disrupt(user)
/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/user)
if (user && user.cell && user.cell.charge > activationCost)
if (isturf(user.loc))
toggle(user)
else
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
else
to_chat(user, "<span class='warning'>You need at least [activationCost] charge in your cell to use [src]!</span>")
/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/user)
if(active)
playsound(src, 'sound/effects/pop.ogg', 100, TRUE, -6)
to_chat(user, "<span class='notice'>You deactivate \the [src].</span>")
deactivate(user)
else
if(animation_playing)
to_chat(user, "<span class='notice'>\the [src] is recharging.</span>")
return
var/borg_icon = input(user, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
disguise = "engineer"
disguise_icon_override = 'icons/mob/robots.dmi'
if("Default - Treads")
disguise = "engi-tread"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Loader")
disguise = "loaderborg"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Handy")
disguise = "handyeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
disguise = "sleekeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
disguise = "caneng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
disguise = "marinaeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
disguise = "spidereng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
disguise = "heavyeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Pup Dozer")
disguise = "pupdozer"
disguise_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
disguise_pixel_offset = -16
if("Vale")
disguise = "valeeng"
disguise_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
disguise_pixel_offset = -16
animation_playing = TRUE
to_chat(user, "<span class='notice'>You activate \the [src].</span>")
playsound(src, 'sound/effects/seedling_chargeup.ogg', 100, TRUE, -6)
var/start = user.filters.len
var/X,Y,rsq,i,f
for(i=1, i<=7, ++i)
do
X = 60*rand() - 30
Y = 60*rand() - 30
rsq = X*X + Y*Y
while(rsq<100 || rsq>900)
user.filters += filter(type="wave", x=X, y=Y, size=rand()*2.5+0.5, offset=rand())
for(i=1, i<=7, ++i)
f = user.filters[start+i]
animate(f, offset=f:offset, time=0, loop=3, flags=ANIMATION_PARALLEL)
animate(offset=f:offset-1, time=rand()*20+10)
if (do_after(user, 50, target=user) && user.cell.use(activationCost))
playsound(src, 'sound/effects/bamf.ogg', 100, TRUE, -6)
to_chat(user, "<span class='notice'>You are now disguised as the Nanotrasen engineering borg \"[friendlyName]\".</span>")
activate(user)
else
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
do_sparks(3, FALSE, user)
for(i=1, i<=min(7, user.filters.len), ++i) // removing filters that are animating does nothing, we gotta stop the animations first
f = user.filters[start+i]
animate(f)
user.filters = null
animation_playing = FALSE
/obj/item/borg_chameleon/process()
if (user)
if (!user.cell || !user.cell.use(activationUpkeep))
disrupt(user)
else
return PROCESS_KILL
/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/user)
START_PROCESSING(SSobj, src)
src.user = user
savedName = user.name
user.name = friendlyName
user.module.cyborg_base_icon = disguise
user.module.cyborg_icon_override = disguise_icon_override
user.module.cyborg_pixel_offset = disguise_pixel_offset
user.bubble_icon = "robot"
active = TRUE
user.update_icons()
if(listeningTo == user)
return
if(listeningTo)
UnregisterSignal(listeningTo, signalCache)
RegisterSignal(user, signalCache, .proc/disrupt)
listeningTo = user
/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/user)
STOP_PROCESSING(SSobj, src)
if(listeningTo)
UnregisterSignal(listeningTo, signalCache)
listeningTo = null
do_sparks(5, FALSE, user)
user.name = savedName
user.module.cyborg_base_icon = initial(user.module.cyborg_base_icon)
user.module.cyborg_icon_override = 'icons/mob/robots.dmi'
user.bubble_icon = "syndibot"
active = FALSE
user.update_icons()
user.pixel_x = 0 //this solely exists because of dogborgs. I want anyone who ever reads this code later on to know this. Don't ask me why it's here, doesn't work above update_icons()
src.user = user
/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/user)
if(active)
to_chat(user, "<span class='danger'>Your chameleon field deactivates.</span>")
deactivate(user)
@@ -64,7 +64,7 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec)
D.jammed = TRUE
GLOB.war_declared = TRUE
GLOB.war_declared = TRUE
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/actual_players = GLOB.joined_player_list.len - nukeops.len
var/tc_malus = 0
@@ -74,6 +74,11 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
qdel(src)
@@ -94,6 +99,14 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
if(board.moved)
to_chat(user, "The shuttle has already been moved! You have forfeit the right to declare war.")
return FALSE
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement))
to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.")
return FALSE
else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost))
to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.")
return FALSE
return TRUE
/obj/item/nuclear_challenge/clownops
@@ -343,10 +343,10 @@
/obj/machinery/nuclearbomb/proc/set_anchor()
if(!isinspace())
anchored = !anchored
else
if(isinspace() && !anchored)
to_chat(usr, "<span class='warning'>There is nothing to anchor to!</span>")
else
anchored = !anchored
/obj/machinery/nuclearbomb/proc/set_safety()
safety = !safety
+1 -1
View File
@@ -87,7 +87,7 @@
/datum/antagonist/nukeop/proc/forge_objectives()
if(nuke_team)
owner.objectives |= nuke_team.objectives
objectives |= nuke_team.objectives
/datum/antagonist/nukeop/proc/move_to_spawnpoint()
var/team_number = 1
@@ -36,8 +36,6 @@
missionobj.completed = 1
mission = missionobj
objectives |= mission
owner.objectives |= objectives
/datum/antagonist/official/on_gain()
forge_objectives()
@@ -26,7 +26,6 @@
// Sets objectives, equips all antags with the storage implant.
/datum/antagonist/overthrow/on_gain()
objectives += team.objectives
owner.objectives += objectives
..()
owner.announce_objectives()
equip_overthrow()
@@ -34,7 +33,6 @@
/datum/antagonist/overthrow/on_removal()
owner.special_role = null
owner.objectives -= objectives
..()
// Creates the overthrow team, or sets it. The objectives are static for all the team members.
@@ -35,7 +35,9 @@
objectives += heads_obj
for(var/i in members)
var/datum/mind/M = i
M.objectives += heads_obj
var/datum/antagonist/overthrow/O = M.has_antag_datum(/datum/antagonist/overthrow)
if(O)
O.objectives += heads_obj
heads_obj.find_targets()
addtimer(CALLBACK(src,.proc/update_objectives),OBJECTIVE_UPDATING_TIME,TIMER_UNIQUE)
+4 -7
View File
@@ -31,12 +31,7 @@
/datum/antagonist/pirate/on_gain()
if(crew)
owner.objectives |= crew.objectives
. = ..()
/datum/antagonist/pirate/on_removal()
if(crew)
owner.objectives -= crew.objectives
objectives |= crew.objectives
. = ..()
/datum/team/pirate
@@ -53,7 +48,9 @@
getbooty.update_explanation_text()
objectives += getbooty
for(var/datum/mind/M in members)
M.objectives |= objectives
var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate)
if(P)
P.objectives |= objectives
/datum/objective/loot
@@ -69,7 +69,7 @@
/mob/living/simple_animal/revenant/Initialize(mapload)
. = ..()
AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null))
AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
AddSpell(new /obj/effect/proc_holder/spell/targeted/telepathy/revenant(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/blight(null))
@@ -27,6 +27,7 @@
if(prob(10))
to_chat(target, "You feel as if you are being watched.")
return
face_atom(target)
draining = TRUE
essence_drained += rand(15, 20)
to_chat(src, "<span class='revennotice'>You search for the soul of [target].</span>")
@@ -65,7 +66,7 @@
if(target.anti_magic_check(FALSE, TRUE))
to_chat(src, "<span class='revenminor'>Something's wrong! [target] seems to be resisting the siphoning, leaving you vulnerable!</span>")
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
"<span class='revenwarning'>Violet lights, dancing in your vision, receding--</span>")
draining = FALSE
return
var/datum/beam/B = Beam(target,icon_state="drain_life",time=INFINITY)
@@ -104,36 +105,16 @@
action_background_icon_state = "bg_revenant"
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
name = "Transmit"
desc = "Telepathically transmits a message to the target."
/obj/effect/proc_holder/spell/targeted/telepathy/revenant
name = "Revenant Transmit"
panel = "Revenant Abilities"
charge_max = 0
clothes_req = 0
range = 7
include_user = 0
action_icon = 'icons/mob/actions/actions_revenant.dmi'
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
charge_counter = charge_max
return
log_directed_talk(user, M, msg, LOG_SAY, "revenant whisper")
to_chat(user, "<span class='revenboldnotice'>You transmit to [M]:</span> <span class='revennotice'>[msg]</span>")
if(!M.anti_magic_check(FALSE, TRUE)) //hear no evil
to_chat(M, "<span class='revenboldnotice'>You hear something behind you talking...</span> <span class='revennotice'>[msg]</span>")
for(var/ded in GLOB.dead_mob_list)
if(!isobserver(ded))
continue
var/follow_rev = FOLLOW_LINK(ded, user)
var/follow_whispee = FOLLOW_LINK(ded, M)
to_chat(ded, "[follow_rev] <span class='revenboldnotice'>[user] Revenant Transmit:</span> <span class='revennotice'>\"[msg]\" to</span> [follow_whispee] <span class='name'>[M]</span>")
notice = "revennotice"
boldnotice = "revenboldnotice"
holy_check = TRUE
tinfoil_check = FALSE
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
@@ -14,8 +14,6 @@
objective2.owner = owner
objectives += objective2
owner.objectives |= objectives
/datum/antagonist/revenant/on_gain()
forge_objectives()
. = ..()
@@ -12,8 +12,8 @@
disease_flags = CURABLE
permeability_mod = 1
severity = DISEASE_SEVERITY_DANGEROUS
var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
var/datum/mood_event/revenant_blight/depression
var/finalstage = FALSE //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
var/depression = FALSE
/datum/disease/revblight/cure()
if(affected_mob)
@@ -44,12 +44,13 @@
affected_mob.emote("pale")
if(3)
if(!depression)
depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY)
SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
depression = TRUE
SEND_SIGNAL(affected_mob, COMSIG_MODIFY_SANITY, -0.12, SANITY_CRAZY)
if(prob(10))
affected_mob.emote(pick("pale","shiver"))
if(4)
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.18, SANITY_CRAZY)
SEND_SIGNAL(affected_mob, COMSIG_MODIFY_SANITY, -0.18, SANITY_CRAZY)
if(prob(15))
affected_mob.emote(pick("pale","shiver","cries"))
if(5)
@@ -4,6 +4,7 @@
name = "Spawn Revenant" // Did you mean 'griefghost'?
typepath = /datum/round_event/ghost_role/revenant
weight = 7
gamemode_blacklist = list("dynamic")
max_occurrences = 1
min_players = 5
@@ -66,10 +66,10 @@
return rev_team
/datum/antagonist/rev/proc/create_objectives()
owner.objectives |= rev_team.objectives
objectives |= rev_team.objectives
/datum/antagonist/rev/proc/remove_objectives()
owner.objectives -= rev_team.objectives
objectives -= rev_team.objectives
//Bump up to head_rev
/datum/antagonist/rev/proc/promote()
@@ -207,9 +207,20 @@
owner.current.visible_message("<span class='deconversion_message'>The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.</span>", null, null, null, owner.current)
to_chat(owner, "<span class='userdanger'>The frame's firmware detects and deletes your neural reprogramming! You remember nothing of your time spent reprogrammed, you can't even remember the names or identities of anyone involved...</span>")
/datum/antagonist/rev/head/farewell()
if((ishuman(owner.current) || ismonkey(owner.current)))
if(owner.current.stat != DEAD)
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!</span>", null, null, null, owner.current)
to_chat(owner, "<span class ='deconversion_message bold'>You have given up your cause of overthrowing the command staff. You are no longer a Head Revolutionary.</span>")
else
to_chat(owner, "<span class ='deconversion_message bold'>The sweet release of death. You are no longer a Head Revolutionary.</span>")
else if(issilicon(owner.current))
owner.current.visible_message("<span class='deconversion_message'>The frame beeps contentedly, suppressing the disloyal personality traits from the MMI before initalizing it.</span>", null, null, null, owner.current)
to_chat(owner, "<span class='userdanger'>The frame's firmware detects and suppresses your unwanted personality traits! You feel more content with the leadership around these parts.</span>")
//blunt trauma deconversions call this through species.dm spec_attacked_by()
/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter)
log_attack("[key_name(owner.current)] has been deconverted from the revolution by [key_name(deconverter)]!")
log_attack("[key_name(owner.current)] has been deconverted from the revolution by [ismob(deconverter) ? key_name(deconverter) : deconverter]!")
if(borged)
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
owner.special_role = null
@@ -219,9 +230,8 @@
owner.remove_antag_datum(type)
/datum/antagonist/rev/head/remove_revolutionary(borged,deconverter)
if(!borged)
return
. = ..()
if(borged || deconverter == "gamemode")
. = ..()
/datum/antagonist/rev/head/equip_rev()
var/mob/living/carbon/human/H = owner.current
@@ -253,6 +263,8 @@
/datum/team/revolution
name = "Revolution"
var/max_headrevs = 3
var/list/ex_headrevs = list() // Dynamic removes revs on loss, used to keep a list for the roundend report.
var/list/ex_revs = list()
/datum/team/revolution/proc/update_objectives(initial = FALSE)
var/untracked_heads = SSjob.get_all_heads()
@@ -265,7 +277,8 @@
new_target.update_explanation_text()
objectives += new_target
for(var/datum/mind/M in members)
M.objectives |= objectives
var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
R.objectives |= objectives
addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
@@ -295,9 +308,12 @@
addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
/datum/team/revolution/proc/save_members()
ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE)
ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE)
/datum/team/revolution/roundend_report()
if(!members.len)
if(!members.len && !ex_headrevs.len)
return
var/list/result = list()
@@ -317,8 +333,17 @@
var/list/targets = list()
var/list/datum/mind/headrevs = get_antag_minds(/datum/antagonist/rev/head)
var/list/datum/mind/revs = get_antag_minds(/datum/antagonist/rev,TRUE)
var/list/datum/mind/headrevs
var/list/datum/mind/revs
if(ex_headrevs.len)
headrevs = ex_headrevs
else
headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE)
if(ex_revs.len)
revs = ex_revs
else
revs = get_antag_minds(/datum/antagonist/rev, TRUE)
if(headrevs.len)
var/list/headrev_part = list()
headrev_part += "<span class='header'>The head revolutionaries were:</span>"
+29
View File
@@ -0,0 +1,29 @@
/datum/antagonist/santa
name = "Santa"
show_in_antagpanel = FALSE
/datum/antagonist/santa/on_gain()
. = ..()
give_equipment()
give_objective()
/datum/antagonist/santa/greet()
. = ..()
to_chat(owner, "<span class='boldannounce'>You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag.</span>")
/datum/antagonist/santa/proc/give_equipment()
var/mob/living/carbon/human/H = owner.current
if(istype(H))
H.equipOutfit(/datum/outfit/santa)
owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents)
var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new
telespell.clothes_req = 0 //santa robes aren't actually magical.
owner.AddSpell(telespell) //does the station have chimneys? WHO KNOWS!
/datum/antagonist/santa/proc/give_objective()
var/datum/objective/santa_objective = new()
santa_objective.explanation_text = "Bring joy and presents to the station!"
santa_objective.completed = 1 //lets cut our santas some slack.
santa_objective.owner = owner
objectives |= santa_objective
@@ -34,7 +34,6 @@
melee_damage_upper = 30
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
var/boost = 0
bloodcrawl = BLOODCRAWL_EAT
var/playstyle_string = "<span class='big bold'>You are a slaughter demon,</span><B> a terrible creature from another realm. You have a single desire: To kill. \
You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and disappearing from the station at will. \
@@ -54,24 +53,18 @@
if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
bloodspell.phased = TRUE
/mob/living/simple_animal/slaughter/Life()
..()
if(boost<world.time)
speed = 1
else
speed = 0
/obj/effect/decal/cleanable/blood/innards
icon = 'icons/obj/surgery.dmi'
name = "pile of viscera"
desc = "A repulsive pile of guts and gore."
gender = NEUTER
icon_state = "innards"
random_icon_states = null
/mob/living/simple_animal/slaughter/phasein()
. = ..()
speed = 0
boost = world.time + 60
add_movespeed_modifier(MOVESPEED_ID_SLAUGHTER, update=TRUE, priority=100, multiplicative_slowdown=-1)
addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, MOVESPEED_ID_SLAUGHTER, TRUE), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
//The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl
@@ -101,7 +94,7 @@
user.temporarilyRemoveItemFromInventory(src, TRUE)
src.Insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E
/obj/item/organ/heart/demon/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/heart/demon/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
if(M.mind)
M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null))
@@ -26,8 +26,6 @@
new_objective2.explanation_text = "[objective_verb] everyone[summoner ? " else while you're at it":""]."
objectives += new_objective2
owner.objectives |= objectives
/datum/antagonist/slaughter/laughter
name = "Laughter demon"
objective_verb = "Hug and Tickle"
@@ -3,6 +3,7 @@
typepath = /datum/round_event/ghost_role/slaughter
weight = 1 //Very rare
max_occurrences = 1
gamemode_blacklist = list("dynamic")
earliest_start = 1 HOURS
min_players = 20
@@ -8,7 +8,6 @@
var/datum/objective/survive/survive = new
survive.owner = owner
objectives += survive
owner.objectives |= objectives
/datum/antagonist/survivalist/on_gain()
owner.special_role = "survivalist"
+1 -1
View File
@@ -33,7 +33,7 @@
. = ..()
var/area/A = get_area(src)
if(A)
notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE)
notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
/obj/effect/mob_spawn/swarmer/attack_hand(mob/living/user)
. = ..()
@@ -78,15 +78,14 @@
scan_target = null
if(owner)
if(owner.mind)
if(owner.mind.objectives)
for(var/datum/objective/objective_ in owner.mind.objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
var/mob/current = objective.target.current
if(current&&current.stat!=DEAD)
scan_target = current
break
for(var/datum/objective/objective_ in owner.mind.get_all_objectives())
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
var/mob/current = objective.target.current
if(current&&current.stat!=DEAD)
scan_target = current
break
/datum/status_effect/agent_pinpointer/tick()
if(!owner)
@@ -100,9 +99,9 @@
return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal))
/datum/antagonist/traitor/proc/replace_escape_objective()
if(!owner||!owner.objectives)
if(!owner || !objectives.len)
return
for (var/objective_ in owner.objectives)
for (var/objective_ in objectives)
if(!(istype(objective_, /datum/objective/escape)||istype(objective_, /datum/objective/survive)))
continue
remove_objective(objective_)
@@ -112,9 +111,9 @@
add_objective(martyr_objective)
/datum/antagonist/traitor/proc/reinstate_escape_objective()
if(!owner||!owner.objectives)
if(!owner||!objectives.len)
return
for (var/objective_ in owner.objectives)
for (var/objective_ in objectives)
if(!istype(objective_, /datum/objective/martyr))
continue
remove_objective(objective_)
@@ -131,7 +130,7 @@
return
to_chat(owner.current, "<span class='userdanger'> Target eliminated: [victim.name]</span>")
LAZYINITLIST(targets_stolen)
for(var/objective_ in victim.objectives)
for(var/objective_ in victim.get_all_objectives())
if(istype(objective_, /datum/objective/assassinate/internal))
var/datum/objective/assassinate/internal/objective = objective_
if(objective.target==owner)
@@ -159,7 +158,7 @@
var/status_text = objective.check_completion() ? "neutralised" : "active"
to_chat(owner.current, "<span class='userdanger'> New target added to database: [objective.target.name] ([status_text]) </span>")
last_man_standing = TRUE
for(var/objective_ in owner.objectives)
for(var/objective_ in objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
@@ -175,7 +174,7 @@
/datum/antagonist/traitor/internal_affairs/proc/iaa_process()
if(owner&&owner.current&&owner.current.stat!=DEAD)
for(var/objective_ in owner.objectives)
for(var/objective_ in objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
@@ -224,8 +223,6 @@
special_role = TRAITOR_AGENT_ROLE
syndicate = TRUE
forge_single_objective()
else
..() // Give them standard objectives.
return
/datum/antagonist/traitor/internal_affairs/forge_traitor_objectives()
@@ -55,12 +55,10 @@
owner.special_role = null
..()
/datum/antagonist/traitor/proc/add_objective(var/datum/objective/O)
owner.objectives += O
/datum/antagonist/traitor/proc/add_objective(datum/objective/O)
objectives += O
/datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O)
owner.objectives -= O
/datum/antagonist/traitor/proc/remove_objective(datum/objective/O)
objectives -= O
/datum/antagonist/traitor/proc/forge_traitor_objectives()
@@ -72,7 +70,17 @@
/datum/antagonist/traitor/proc/forge_human_objectives()
var/is_hijacker = FALSE
if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks
var/datum/game_mode/dynamic/mode
var/is_dynamic = FALSE
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
if(GLOB.joined_player_list.len>=GLOB.dynamic_high_pop_limit)
is_hijacker = (prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement))
else
var/indice_pop = min(10,round(GLOB.joined_player_list.len/mode.pop_per_requirement)+1)
is_hijacker = (prob(10) && (mode.threat_level >= CONFIG_GET(number_list/dynamic_hijack_requirements)[indice_pop]))
else if (GLOB.joined_player_list.len >= 30) // Less murderboning on lowpop thanks
is_hijacker = prob(10)
var/martyr_chance = prob(20)
var/objective_count = is_hijacker //Hijacking counts towards number of objectives
@@ -89,15 +97,19 @@
forge_single_objective()
if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
if (!(locate(/datum/objective/hijack) in owner.objectives))
if (!(locate(/datum/objective/hijack) in objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = owner
add_objective(hijack_objective)
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[owner.name] spent [threat_spent] on hijack.")
return
var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
for(var/datum/objective/O in owner.objectives)
for(var/datum/objective/O in objectives)
if(!O.martyr_compatible)
martyr_compatibility = 0
break
@@ -106,10 +118,14 @@
var/datum/objective/martyr/martyr_objective = new
martyr_objective.owner = owner
add_objective(martyr_objective)
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_hijack_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[owner.name] spent [threat_spent] on glorious death.")
return
else
if(!(locate(/datum/objective/escape) in owner.objectives))
if(!(locate(/datum/objective/escape) in objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
add_objective(escape_objective)
@@ -141,7 +157,18 @@
/datum/antagonist/traitor/proc/forge_single_human_objective() //Returns how many objectives are added
.=1
if(prob(50))
var/assassin_prob = 50
var/is_dynamic = FALSE
var/datum/game_mode/dynamic/mode
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
assassin_prob = mode.threat_level*(2/3)
if(prob(assassin_prob))
if(is_dynamic)
var/threat_spent = CONFIG_GET(number/dynamic_assassinate_cost)
mode.spend_threat(threat_spent)
mode.log_threat("[owner.name] spent [threat_spent] on an assassination target.")
var/list/active_ais = active_ais()
if(active_ais.len && prob(100/GLOB.joined_player_list.len))
var/datum/objective/destroy/destroy_objective = new
@@ -159,7 +186,7 @@
kill_objective.find_target()
add_objective(kill_objective)
else
if(prob(15) && !(locate(/datum/objective/download) in owner.objectives) && !(owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
if(prob(15) && !(locate(/datum/objective/download) in objectives) && !(owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
var/datum/objective/download/download_objective = new
download_objective.owner = owner
download_objective.gen_amount_goal()
@@ -208,7 +208,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
var/unlock_text = "<span class='notice'>Hello World!</span>" //Text shown when an ability is unlocked
var/unlock_sound //Sound played when an ability is unlocked
/datum/AI_Module/proc/upgrade(mob/living/silicon/AI/AI) //Apply upgrades!
/datum/AI_Module/proc/upgrade(mob/living/silicon/ai/AI) //Apply upgrades!
return
/datum/AI_Module/large //Big, powerful stuff that can only be used once.
@@ -304,7 +304,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
sleep(30)
if(!owner || QDELETED(owner))
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", "aimalf")
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE
@@ -397,7 +397,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
unlock_text = "<span class='notice'>You establish a power diversion to your turrets, upgrading their health and damage.</span>"
unlock_sound = 'sound/items/rped.ogg'
/datum/AI_Module/large/upgrade_turrets/upgrade(mob/living/silicon/AI/AI)
/datum/AI_Module/large/upgrade_turrets/upgrade(mob/living/silicon/ai/AI)
for(var/obj/machinery/porta_turret/ai/turret in GLOB.machines)
turret.obj_integrity += 30
turret.lethal_projectile = /obj/item/projectile/beam/laser/heavylaser //Once you see it, you will know what it means to FEAR.
@@ -9,7 +9,6 @@
var/datum/objective/martyr/normiesgetout = new
normiesgetout.owner = owner
objectives += normiesgetout
owner.objectives += objectives
/datum/antagonist/heartbreaker/on_gain()
forge_objectives()
@@ -12,7 +12,6 @@
protect_objective.human_check = FALSE
protect_objective.explanation_text = "Protect [date.name], your date."
objectives += protect_objective
owner.objectives += objectives
/datum/antagonist/valentine/on_gain()
forge_objectives()
@@ -34,8 +33,8 @@
//Squashed up a bit
/datum/antagonist/valentine/roundend_report()
var/objectives_complete = TRUE
if(owner.objectives.len)
for(var/datum/objective/objective in owner.objectives)
if(objectives.len)
for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
@@ -51,8 +50,8 @@
/datum/antagonist/valentine/chem/roundend_report()
var/objectives_complete = TRUE
if(owner.objectives.len)
for(var/datum/objective/objective in owner.objectives)
if(objectives.len)
for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
@@ -8,7 +8,6 @@
var/datum/objective/hijack/hijack = new
hijack.owner = owner
objectives += hijack
owner.objectives |= objectives
/datum/antagonist/wishgranter/on_gain()
owner.special_role = "Avatar of the Wish Granter"
@@ -113,7 +113,7 @@
/obj/singularity/wizard/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
GET_COMPONENT_FROM(insaneinthemembrane, /datum/component/mood, C)
var/datum/component/mood/insaneinthemembrane = C.GetComponent(/datum/component/mood)
if(insaneinthemembrane.sanity < 15)
return //they've already seen it and are about to die, or are just too insane to care
to_chat(C, "<span class='userdanger'>OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!</span>")
@@ -255,7 +255,7 @@
/obj/item/voodoo/attackby(obj/item/I, mob/user, params)
if(target && cooldown < world.time)
if(I.is_hot())
if(I.get_temperature())
to_chat(target, "<span class='userdanger'>You suddenly feel very hot</span>")
target.adjust_bodytemperature(50)
GiveHint(target)
@@ -324,14 +324,11 @@
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
possible = list()
LAZYINITLIST(possible)
if(!voodoo_link)
return
var/list/prints = voodoo_link.return_fingerprints()
if(!length(prints))
return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(prints[md5(H.dna.uni_identity)])
if(md5(H.dna.uni_identity) in voodoo_link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
@@ -343,9 +340,9 @@
to_chat(victim, "<span class='notice'>You feel a dark presence from [A.name]</span>")
/obj/item/voodoo/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] links the voodoo doll to [user.p_them()]self and sits on it, infinitely crushing [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!</span>")
user.gib()
return(BRUTELOSS)
user.visible_message("<span class='suicide'>[user] links the voodoo doll to [user.p_them()]self and sits on it, infinitely crushing [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!</span>")
user.gib()
return(BRUTELOSS)
/obj/item/voodoo/fire_act(exposed_temperature, exposed_volume)
if(target)
@@ -386,7 +383,9 @@
if(!istype(user) || on_cooldown)
return
var/turf/T = get_turf(user)
if(!T)
var/area/A = get_area(user)
if(!T || !A || A.noteleport)
to_chat(user, "<span class='warning'>You play \the [src], yet no sound comes out of it... Looks like it won't work here.</span>")
return
on_cooldown = TRUE
last_user = user
@@ -238,6 +238,7 @@
T.stop_sound_channel(CHANNEL_HEARTBEAT)
T.invisibility = INVISIBILITY_ABSTRACT
T.dust_animation()
QDEL_IN(T, 5)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src)
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = FALSE//Can't move out of the soul stone
@@ -11,12 +11,18 @@
var/buy_word = "Learn"
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
var/list/no_coexistance_typecache //Used so you can't have specific spells together
var/dynamic_cost = 0 // How much threat the spell costs to purchase for dynamic.
var/dynamic_requirement = 0 // How high the threat level needs to be for purchasing in dynamic.
/datum/spellbook_entry/New()
..()
no_coexistance_typecache = typecacheof(no_coexistance_typecache)
/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(dynamic_requirement > 0 && mode.threat_level < dynamic_requirement)
return 0
return 1
/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user,obj/item/spellbook/book) // Specific circumstances
@@ -25,6 +31,10 @@
for(var/spell in user.mind.spell_list)
if(is_type_in_typecache(spell, no_coexistance_typecache))
return 0
if(dynamic_cost>0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < dynamic_cost)
return 0
return 1
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
@@ -60,6 +70,10 @@
SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[aspell.spell_level]"))
return 1
//No same spell found - just learn it
if(dynamic_cost > 0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.spend_threat(dynamic_cost)
mode.log_threat("Wizard spent [dynamic_cost] on [name].")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
user.mind.AddSpell(S)
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
@@ -83,6 +97,10 @@
if(!S)
S = new spell_type()
var/spell_levels = 0
if(dynamic_cost > 0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.refund_threat(dynamic_cost)
mode.log_threat("Wizard refunded [dynamic_cost] on [name].")
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
@@ -285,6 +303,8 @@
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
dynamic_requirement = 60
dynamic_cost = 20
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
@@ -369,6 +389,8 @@
desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side."
item_path = /obj/item/antag_spawner/contract
category = "Assistance"
dynamic_requirement = 50
dynamic_cost = 10
/datum/spellbook_entry/item/guardian
name = "Guardian Deck"
@@ -388,6 +410,11 @@
item_path = /obj/item/antag_spawner/slaughter_demon
limit = 3
category = "Assistance"
dynamic_requirement = 60
/datum/spellbook_entry/item/bloodbottle/New()
..()
dynamic_cost = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]
/datum/spellbook_entry/item/hugbottle
name = "Bottle of Tickles"
@@ -402,6 +429,11 @@
cost = 1 //non-destructive; it's just a jape, sibling!
limit = 3
category = "Assistance"
dynamic_requirement = 40
/datum/spellbook_entry/item/hugbottle/New()
..()
dynamic_cost = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
@@ -465,7 +497,7 @@
if(!SSticker.mode)
return FALSE
else
return TRUE
return ..()
/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
@@ -478,11 +510,13 @@
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!"
dynamic_cost = 10
dynamic_requirement = 60
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return !CONFIG_GET(flag/no_summon_guns)
return (!CONFIG_GET(flag/no_summon_guns) && ..())
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
@@ -490,16 +524,23 @@
active = 1
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon guns!</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon guns.")
return 1
/datum/spellbook_entry/summon/magic
name = "Summon Magic"
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
dynamic_cost = 10
dynamic_requirement = 60
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return !CONFIG_GET(flag/no_summon_magic)
return (!CONFIG_GET(flag/no_summon_guns) && ..())
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
@@ -507,21 +548,33 @@
active = 1
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon magic!</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon magic.")
return 1
/datum/spellbook_entry/summon/events
name = "Summon Events"
desc = "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events."
dynamic_cost = 20
dynamic_requirement = 60
var/times = 0
/datum/spellbook_entry/summon/events/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return !CONFIG_GET(flag/no_summon_events)
return (!CONFIG_GET(flag/no_summon_events) && ..())
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
summonevents()
if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0)
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon events.")
times++
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon events.</span>")
@@ -626,16 +679,16 @@
dat += {"
<head>
<style type="text/css">
body { font-size: 80%; font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif; }
ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; }
ul#tabs li { display: inline; }
ul#tabs li a { color: #42454a; background-color: #dedbde; border: 1px solid #c9c3ba; border-bottom: none; padding: 0.3em; text-decoration: none; }
ul#tabs li a:hover { background-color: #f1f0ee; }
ul#tabs li a.selected { color: #000; background-color: #f1f0ee; font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
div.tabContent { border: 1px solid #c9c3ba; padding: 0.5em; background-color: #f1f0ee; }
div.tabContent.hide { display: none; }
</style>
</head>
body { font-size: 80%; font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif; }
ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; }
ul#tabs li { display: inline; }
ul#tabs li a { color: #42454a; background-color: #dedbde; border: 1px solid #c9c3ba; border-bottom: none; padding: 0.3em; text-decoration: none; }
ul#tabs li a:hover { background-color: #f1f0ee; }
ul#tabs li a.selected { color: #000; background-color: #f1f0ee; font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
div.tabContent { border: 1px solid #c9c3ba; padding: 0.5em; background-color: #f1f0ee; }
div.tabContent.hide { display: none; }
</style>
</head>
"}
dat += {"[content]</body></html>"}
return dat
+7 -9
View File
@@ -57,19 +57,19 @@
if(!GLOB.wizardstart.len)
SSjob.SendToLateJoin(owner.current)
to_chat(owner, "HOT INSERTION, GO GO GO")
owner.current.forceMove(pick(GLOB.wizardstart))
else
owner.current.forceMove(pick(GLOB.wizardstart))
/datum/antagonist/wizard/proc/create_objectives()
var/datum/objective/new_objective = new("Cause as much creative mayhem as you can aboard the station! The more outlandish your methods of achieving this, the better! Make sure there's a decent amount of crew alive to tell of your tale.")
new_objective.completed = TRUE //So they can greentext without admin intervention.
new_objective.owner = owner
objectives += new_objective
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
objectives += escape_objective
for(var/datum/objective/O in objectives)
owner.objectives += O
if (!(locate(/datum/objective/escape) in objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
objectives += escape_objective
/datum/antagonist/wizard/on_removal()
unregister()
@@ -183,7 +183,6 @@
new_objective.owner = owner
new_objective.target = master
new_objective.explanation_text = "Protect [master.current.real_name], the wizard."
owner.objectives += new_objective
objectives += new_objective
//Random event wizard
@@ -251,7 +250,6 @@
/datum/antagonist/wizard/academy/create_objectives()
var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders")
new_objective.owner = owner
owner.objectives += new_objective
objectives += new_objective
//Solo wizard report