"
+ for(var/obj/item in hand_items)
+ if(ABSTRACT in item.flags || NODROP in item.flags)
+ continue
+ marked_item = item
+ user << "You begin to focus your very being into the [item.name]..."
+ break
+
+ if(!marked_item)
+ user << "You must hold an item you wish to make your phylactery..."
+
+ spawn(50)
+ if(marked_item.loc != user) //I changed my mind I don't want to put my soul in a cheeseburger!
+ user << "Your soul snaps back to your body as you drop the [marked_item.name]!"
+ marked_item = null
+ return
+ name = "RISE!"
+ desc = "Rise from the dead! You will reform at the location of your phylactery and your old body will crumble away."
+ charge_max = 1800 //3 minute cooldown, if you rise in sight of someone and killed again, you're probably screwed.
+ charge_counter = 1800
+ stat_allowed = 1
+ marked_item.name = "Ensouled [marked_item.name]"
+ marked_item.desc = "A terrible aura surrounds this item, its very existence is offensive to life itself..."
+ marked_item.color = "#003300"
+ user << "With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!"
+ hardset_dna(user, null, null, null, null, /datum/species/skeleton)
+ current_body = user.mind.current
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ H.unEquip(H.wear_suit)
+ H.unEquip(H.head)
+ H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/black(H), slot_wear_suit)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/black(H), slot_head)
\ No newline at end of file
diff --git a/code/datums/spells/summonitem.dm b/code/datums/spells/summonitem.dm
index e74ce4a92c6..7b29e448844 100644
--- a/code/datums/spells/summonitem.dm
+++ b/code/datums/spells/summonitem.dm
@@ -7,7 +7,7 @@
invocation = "GAR YOK"
invocation_type = "whisper"
range = -1
- level_max = 1 //cannot be improved
+ level_max = 0 //cannot be improved
cooldown_min = 100
include_user = 1
diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm
deleted file mode 100644
index 33f8c1421a5..00000000000
--- a/code/datums/wires/camera.dm
+++ /dev/null
@@ -1,76 +0,0 @@
-// Wires for cameras.
-
-/datum/wires/camera
- random = 0
- holder_type = /obj/machinery/camera
- wire_count = 6
-
-/datum/wires/camera/GetInteractWindow()
-
- . = ..()
- var/obj/machinery/camera/C = holder
- . += "
\n[(C.view_range == initial(C.view_range) ? "The focus light is on." : "The focus light is off.")]"
- . += "
\n[(C.can_use() ? "The power link light is on." : "The power link light is off.")]"
- . += "
\n[(C.light_disabled ? "The camera light is off." : "The camera light is on.")]"
- . += "
\n[(C.alarm_on ? "The alarm light is on." : "The alarm light is off.")]"
- return .
-
-/datum/wires/camera/CanUse(var/mob/living/L)
- var/obj/machinery/camera/C = holder
- if(!C.panel_open)
- return 0
- return 1
-
-var/const/CAMERA_WIRE_FOCUS = 1
-var/const/CAMERA_WIRE_POWER = 2
-var/const/CAMERA_WIRE_LIGHT = 4
-var/const/CAMERA_WIRE_ALARM = 8
-var/const/CAMERA_WIRE_NOTHING1 = 16
-var/const/CAMERA_WIRE_NOTHING2 = 32
-
-/datum/wires/camera/UpdateCut(var/index, var/mended)
- var/obj/machinery/camera/C = holder
-
- switch(index)
- if(CAMERA_WIRE_FOCUS)
- var/range = (mended ? initial(C.view_range) : C.short_range)
- C.setViewRange(range)
-
- if(CAMERA_WIRE_POWER)
- if(C.status && !mended || !C.status && mended)
- C.deactivate(usr, 1)
-
- if(CAMERA_WIRE_LIGHT)
- C.light_disabled = !mended
-
- if(CAMERA_WIRE_ALARM)
- if(!mended)
- C.triggerCameraAlarm()
- else
- C.cancelCameraAlarm()
- return
-
-/datum/wires/camera/UpdatePulsed(var/index)
- var/obj/machinery/camera/C = holder
- if(IsIndexCut(index))
- return
- switch(index)
- if(CAMERA_WIRE_FOCUS)
- var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range))
- C.setViewRange(new_range)
-
- if(CAMERA_WIRE_POWER)
- C.deactivate(null) // Deactivate the camera
-
- if(CAMERA_WIRE_LIGHT)
- C.light_disabled = !C.light_disabled
-
- if(CAMERA_WIRE_ALARM)
- C.visible_message("\icon[C] *beep*", "\icon[C] *beep*")
- return
-
-/datum/wires/camera/proc/CanDeconstruct()
- if(IsIndexCut(CAMERA_WIRE_POWER) && IsIndexCut(CAMERA_WIRE_FOCUS) && IsIndexCut(CAMERA_WIRE_LIGHT) && IsIndexCut(CAMERA_WIRE_NOTHING1) && IsIndexCut(CAMERA_WIRE_NOTHING2))
- return 1
- else
- return 0
\ No newline at end of file
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index ba6f252724a..e483513c40a 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -102,8 +102,7 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown",
/datum/wires/Topic(href, href_list)
..()
- if(in_range(holder, usr) && isliving(usr))
-
+ if(usr.Adjacent(holder) && isliving(usr))
var/mob/living/L = usr
if(CanUse(L) && href_list["action"])
var/obj/item/I = L.get_active_hand()
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 8afadbc4ce8..cb638aa6f31 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -21,6 +21,10 @@
// replaced by OPENCONTAINER flags and atom/proc/is_open_container()
///Chemistry.
var/allow_spin = 1
+
+ //Value used to increment ex_act() if reactionary_explosions is on
+ var/explosion_block = 0
+
/atom/proc/onCentcom()
var/turf/T = get_turf(src)
if(!T)
diff --git a/code/game/communications.dm b/code/game/communications.dm
index 75155dff914..9f7d515a300 100644
--- a/code/game/communications.dm
+++ b/code/game/communications.dm
@@ -299,4 +299,4 @@ var/list/pointers = list()
for(var/d in data)
var/val = data[d]
if(istext(val))
- data[d] = strip_html_properly(val)
+ data[d] = html_encode(val)
diff --git a/code/game/dna.dm b/code/game/dna.dm
index 128b7aa1fc6..60fa4a6ca9d 100644
--- a/code/game/dna.dm
+++ b/code/game/dna.dm
@@ -21,7 +21,7 @@
var/uni_identity
var/blood_type
var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man)
- var/mutant_color = "FFF" // What color you are if you have certain speciess
+ var/list/features = list("FFF") //first value is mutant color
var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
var/list/mutations = list() //All mutations are from now on here
var/mob/living/carbon/holder
@@ -36,7 +36,7 @@
destination.dna.uni_identity = uni_identity
destination.dna.blood_type = blood_type
hardset_dna(destination, null, null, null, null, species)
- destination.dna.mutant_color = mutant_color
+ destination.dna.features = features
destination.dna.real_name = real_name
destination.dna.mutations = mutations
@@ -46,7 +46,7 @@
new_dna.uni_identity = uni_identity
new_dna.blood_type = blood_type
new_dna.species = new species.type
- new_dna.mutant_color = mutant_color
+ new_dna.features = features
new_dna.real_name = real_name
new_dna.mutations = mutations
@@ -131,7 +131,7 @@
spans |= M.get_spans()
return spans
-/proc/hardset_dna(mob/living/carbon/owner, ui, se, real_name, blood_type, datum/species/mrace, mcolor)
+/proc/hardset_dna(mob/living/carbon/owner, ui, se, real_name, blood_type, datum/species/mrace, features)
if(!ismonkey(owner) && !ishuman(owner))
return
if(!owner.dna)
@@ -143,8 +143,8 @@
owner.reagents.del_reagent(exotic_blood.id)
owner.dna.species = new mrace()
- if(mcolor)
- owner.dna.mutant_color = mcolor
+ if(features)
+ owner.dna.features = features
if(real_name)
owner.real_name = real_name
@@ -193,6 +193,7 @@
character.dna.uni_identity = character.dna.generate_uni_identity(character)
character.dna.struc_enzymes = character.dna.generate_struc_enzymes(character)
character.dna.unique_enzymes = character.dna.generate_unique_enzymes(character)
+ character.dna.features = character.features
return character.dna
/proc/create_dna(mob/living/carbon/C, datum/species/S) //don't use this unless you're about to use hardset_dna or ready_dna
@@ -497,8 +498,8 @@
/obj/machinery/computer/scan_consolenew
name = "\improper DNA scanner access console"
desc = "Scan DNA."
- icon = 'icons/obj/computer.dmi'
- icon_state = "scanner"
+ icon_screen = "dna"
+ icon_keyboard = "med_key"
density = 1
circuit = /obj/item/weapon/circuitboard/scan_consolenew
var/radduration = 2
@@ -972,7 +973,7 @@
/datum/dna/proc/is_same_as(var/datum/dna/D)
if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name)
- if(species == D.species && mutant_color == D.mutant_color && blood_type == D.blood_type)
+ if(species == D.species && features == D.features && blood_type == D.blood_type)
return 1
return 0
diff --git a/code/game/gamemodes/abduction/gland.dm b/code/game/gamemodes/abduction/gland.dm
index ccb60820159..959f98b5b2a 100644
--- a/code/game/gamemodes/abduction/gland.dm
+++ b/code/game/gamemodes/abduction/gland.dm
@@ -92,7 +92,7 @@
for(var/mob/living/carbon/human/H in orange(4,T))
if(H == host)
continue
- H << " You hear a buzz in your head "
+ H << "You hear a buzz in your head "
H.confused += 20
/obj/item/gland/pop
@@ -213,7 +213,7 @@
/obj/effect/cocoon/abductor/proc/Copy(var/mob/living/carbon/human/H)
var/mob/living/carbon/human/interactive/greytide/clone = new(src)
- hardset_dna(clone,H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.mutant_color)
+ hardset_dna(clone,H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features)
//There's no define for this / get all items ?
var/list/slots = list(slot_back,slot_w_uniform,slot_wear_suit,\
diff --git a/code/game/gamemodes/abduction/machinery/experiment.dm b/code/game/gamemodes/abduction/machinery/experiment.dm
index 3d79a64b56b..e9ac19599cd 100644
--- a/code/game/gamemodes/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/abduction/machinery/experiment.dm
@@ -43,7 +43,7 @@
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]_s")
else
photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]_s")
- photo.Blend("#[H.dna.mutant_color]", ICON_MULTIPLY)
+ photo.Blend("#[H.dna.features["mcolor"]]", ICON_MULTIPLY)
var/icon/eyes_s
if(EYECOLOR in H.dna.species.specflags)
@@ -86,7 +86,7 @@
dat += "Analyze
"
dat += ""
else
- dat += " Experiment "
+ dat += "Experiment "
if(!occupant)
dat += "Machine Unoccupied
"
diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm
index 549243bf86c..a621168182a 100644
--- a/code/game/gamemodes/antag_spawner.dm
+++ b/code/game/gamemodes/antag_spawner.dm
@@ -146,4 +146,52 @@
ticker.mode.syndicates += R.mind
ticker.mode.update_synd_icons_added(R.mind)
R.mind.special_role = "syndicate"
- R.faction = list("syndicate")
\ No newline at end of file
+ R.faction = list("syndicate")
+
+
+/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"
+
+
+/obj/item/weapon/antag_spawner/slaughter_demon/attack_self(mob/user as mob)
+ var/list/demon_candidates = get_candidates(BE_ALIEN)
+ if(user.z != 1)
+ user << "You should probably wait until you reach the station."
+ return
+ if(demon_candidates.len > 0)
+ used = 1
+ var/client/C = pick(demon_candidates)
+ spawn_antag(C, get_turf(src.loc), "Slaughter Demon")
+ user << "You shatter the bottle, no turning back now!"
+ user << "You sense a dark presence lurking just beyond the veil..."
+ playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
+ qdel(src)
+ else
+ user << "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later."
+
+
+/obj/item/weapon/antag_spawner/slaughter_demon/spawn_antag(var/client/C, var/turf/T, var/type = "")
+
+ var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T)
+ var/mob/living/simple_animal/slaughter/S = new /mob/living/simple_animal/slaughter/(holder)
+ S.phased = TRUE
+ S.key = C.key
+ S.mind.assigned_role = "Slaughter Demon"
+ S.mind.special_role = "Slaughter Demon"
+ ticker.mode.traitors += S.mind
+ var/datum/objective/assassinate/new_objective = new /datum/objective/assassinate
+ new_objective.owner = S:mind
+ new_objective:target = usr:mind
+ new_objective.explanation_text = "Kill [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 = "Kill everyone else while you're at it."
+ S.mind.objectives += new_objective2
+ S << S.playstyle_string
+ S << "You are currently not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest."
+ S << "Objective #[1]: [new_objective.explanation_text]"
+ S << "Objective #[2]: [new_objective2.explanation_text]"
\ No newline at end of file
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index 7dcd49f1821..70f29cab8ef 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -86,7 +86,7 @@
if(overmind && overmind.blob_reagent_datum)
adjustcolors(overmind.blob_reagent_datum.color)
H.loc = src
- loc.visible_message(" The corpse of [H.name] suddenly rises!")
+ loc.visible_message("The corpse of [H.name] suddenly rises!")
/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed)
..(1)
diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm
index 840e16b90f5..40ccd99868f 100644
--- a/code/game/gamemodes/blob/overmind.dm
+++ b/code/game/gamemodes/blob/overmind.dm
@@ -65,12 +65,12 @@
/mob/camera/blob/proc/update_health()
if(blob_core)
- hud_used.blobhealthdisplay.maptext = " [round(blob_core.health)]
"
+ hud_used.blobhealthdisplay.maptext = "[round(blob_core.health)]
"
/mob/camera/blob/proc/add_points(var/points)
if(points != 0)
blob_points = Clamp(blob_points + points, 0, max_blob_points)
- hud_used.blobpwrdisplay.maptext = " [round(src.blob_points)]
"
+ hud_used.blobpwrdisplay.maptext = "[round(src.blob_points)]
"
/mob/camera/blob/say(var/message)
if (!message)
diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm
index 913b6dd295d..516a407cbef 100644
--- a/code/game/gamemodes/changeling/powers/absorb.dm
+++ b/code/game/gamemodes/changeling/powers/absorb.dm
@@ -92,7 +92,7 @@
new_dna.struc_enzymes = T.dna.struc_enzymes
new_dna.real_name = T.dna.real_name
new_dna.species = T.dna.species
- new_dna.mutant_color = T.dna.mutant_color
+ new_dna.features = T.dna.features
new_dna.blood_type = T.dna.blood_type
absorbedcount++
store_dna(new_dna, user)
diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm
index fc897feff6b..40884bda963 100644
--- a/code/game/gamemodes/changeling/powers/mutations.dm
+++ b/code/game/gamemodes/changeling/powers/mutations.dm
@@ -303,8 +303,7 @@
icon_state = "lingarmor"
flags = NODROP
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
- slowdown = 2
- armor = list(melee = 65, bullet = 20, laser = 10, energy = 13, bomb = 0, bio = 0, rad = 0)
+ armor = list(melee = 40, bullet = 20, laser = 30, energy = 13, bomb = 0, bio = 0, rad = 0)
flags_inv = HIDEJUMPSUIT
cold_protection = 0
heat_protection = 0
@@ -322,7 +321,7 @@
desc = "A tough, hard covering of black chitin with transparent chitin in front."
icon_state = "lingarmorhelmet"
flags = HEADCOVERSEYES | BLOCKHAIR | NODROP
- armor = list(melee = 70, bullet = 15, laser = 7,energy = 10, bomb = 5, bio = 2, rad = 0)
+ armor = list(melee = 40, bullet = 15, laser = 30,energy = 10, bomb = 5, bio = 2, rad = 0)
flags_inv = HIDEEARS
/obj/item/clothing/head/helmet/changeling/dropped()
diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm
index 936f3f47662..bbadbcd6cac 100644
--- a/code/game/gamemodes/changeling/powers/tiny_prick.dm
+++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm
@@ -91,7 +91,7 @@
var/datum/dna/NewDNA = selected_dna
if(ismonkey(target))
user << "We stealthily sting [target.name]."
- hardset_dna(target, NewDNA.uni_identity, NewDNA.struc_enzymes, NewDNA.real_name, NewDNA.blood_type, NewDNA.species.type, NewDNA.mutant_color)
+ hardset_dna(target, NewDNA.uni_identity, NewDNA.struc_enzymes, NewDNA.real_name, NewDNA.blood_type, NewDNA.species.type, NewDNA.features)
updateappearance(target)
feedback_add_details("changeling_powers","TS")
return 1
diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm
index 7b13ecf03da..2f57a81ebb7 100644
--- a/code/game/gamemodes/changeling/powers/transform.dm
+++ b/code/game/gamemodes/changeling/powers/transform.dm
@@ -17,8 +17,7 @@
user.dna = chosen_dna
user.real_name = chosen_dna.real_name
- hardset_dna(user, null, null, null, null, chosen_dna.species.type)
- user.dna.mutant_color = chosen_dna.mutant_color
+ hardset_dna(user, null, null, null, null, chosen_dna.species.type, chosen_dna.features)
updateappearance(user)
domutcheck(user)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 4bfeecb2247..eddb0216d76 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -188,7 +188,7 @@
return 0
- if(living_antag_player && living_antag_player.mind && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player))
+ if(living_antag_player && living_antag_player.mind && isliving(living_antag_player) && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player))
return 0 //A resource saver: once we find someone who has to die for all antags to be dead, we can just keep checking them, cycling over everyone only when we lose our mark.
for(var/mob/Player in living_mob_list)
diff --git a/code/game/gamemodes/gang/dominator.dm b/code/game/gamemodes/gang/dominator.dm
new file mode 100644
index 00000000000..0bb8c7b21de
--- /dev/null
+++ b/code/game/gamemodes/gang/dominator.dm
@@ -0,0 +1,212 @@
+/obj/machinery/dominator
+ name = "dominator"
+ desc = "A visibly sinister device. Looks like you can break it if you hit it enough."
+ icon = 'icons/obj/machines/dominator.dmi'
+ icon_state = "dominator"
+ density = 1
+ anchored = 1.0
+ layer = 3.6
+ var/health = 200
+ var/gang
+ var/operating = 0
+ var/broken = 0
+
+/obj/machinery/dominator/New()
+ if(!istype(ticker.mode, /datum/game_mode/gang))
+ qdel(src)
+ return
+ SetLuminosity(2)
+
+/obj/machinery/dominator/examine(mob/user)
+ ..()
+ if(broken)
+ user << "It looks completely busted."
+ return
+
+ var/datum/game_mode/gang/mode = ticker.mode
+ var/time = null
+ if(gang == "A")
+ if(isnum(mode.A_timer))
+ time = max(mode.A_timer, 0)
+ if(gang == "B")
+ if(isnum(mode.B_timer))
+ time = max(mode.B_timer, 0)
+ if(isnum(time))
+ if(time > 0)
+ user << "Hostile Takeover in progress. Estimated [time] seconds remain."
+ else
+ user << "Hostile Takeover of [station_name()] successful. Have a great day."
+ else
+ user << "System on standby."
+ user << "System Integrity: [health/2]%"
+
+
+/obj/machinery/dominator/proc/healthcheck(var/damage)
+ var/iconname = "dominator"
+ if(gang)
+ iconname += "-[gang]"
+ SetLuminosity(3)
+
+ var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread
+
+ health -= damage
+
+ switch(health)
+ if(101 to INFINITY)
+ if(prob(damage*2))
+ sparks.set_up(5, 1, src)
+ sparks.start()
+ if(1 to 100)
+ sparks.set_up(5, 1, src)
+ sparks.start()
+ iconname += "-damaged"
+
+ if(!broken)
+ if(health <= 0)
+ set_broken()
+ else
+ icon_state = iconname
+
+ if(health <= -50)
+ new /obj/item/stack/sheet/plasteel(src.loc)
+ qdel(src)
+
+/obj/machinery/dominator/proc/set_broken()
+ var/datum/game_mode/gang/mode = ticker.mode
+ if(gang == "A")
+ mode.A_timer = "OFFLINE"
+ if(gang == "B")
+ mode.B_timer = "OFFLINE"
+ if(!isnum(mode.A_timer) && !isnum(mode.B_timer))
+ SSshuttle.emergencyNoEscape = 0
+ if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
+ SSshuttle.emergency.mode = SHUTTLE_DOCKED
+ SSshuttle.emergency.timer = world.time
+ priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
+ else
+ priority_announce("All hostile activity within station systems have ceased.","Network Alert")
+ if(gang)
+ ticker.mode.message_gangtools(((gang=="A") ? ticker.mode.A_tools : ticker.mode.B_tools),"Hostile takeover cancelled: Dominator is no longer operational.",1,1)
+ SetLuminosity(0)
+ icon_state = "dominator-broken"
+ broken = 1
+
+/obj/machinery/dominator/Destroy()
+ if(!broken)
+ set_broken()
+ ..()
+
+/obj/machinery/dominator/emp_act(severity)
+ healthcheck(100)
+ ..()
+
+/obj/machinery/dominator/ex_act(severity, target)
+ if(target == src)
+ qdel(src)
+ return
+ switch(severity)
+ if(1.0)
+ qdel(src)
+ if(2.0)
+ healthcheck(120)
+ if(3.0)
+ healthcheck(30)
+ return
+
+/obj/machinery/dominator/bullet_act(var/obj/item/projectile/Proj)
+ if(Proj.damage)
+ if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ visible_message("[src] was hit by [Proj].")
+ healthcheck(Proj.damage)
+ ..()
+
+/obj/machinery/dominator/blob_act()
+ healthcheck(110)
+
+/obj/machinery/dominator/attackby(I as obj, user as mob, params)
+
+ return
+
+/obj/machinery/dominator/attack_hand(mob/user)
+ if(operating||broken)
+ examine(user)
+ return
+
+ var/datum/game_mode/gang/mode = ticker.mode
+ var/gang_territory
+ var/timer
+
+ var/tempgang
+ if(user.mind in (ticker.mode.A_gang|ticker.mode.A_bosses))
+ tempgang = "A"
+ gang_territory = ticker.mode.A_territory.len
+ timer = mode.A_timer
+ else if(user.mind in (ticker.mode.B_gang|ticker.mode.B_bosses))
+ tempgang = "B"
+ gang_territory = ticker.mode.B_territory.len
+ timer = mode.B_timer
+
+ if(!tempgang)
+ examine(user)
+ return
+
+ if(isnum(timer)) //In theory, this shouldn't happen. But if it does, they get this meme
+ user << "Error: Hostile Takeover is already in progress."
+ return
+
+ var/time = max(180,900 - ((round((gang_territory/start_state.num_territories)*200, 1) - 60) * 15))
+ if(alert(user,"With [round((gang_territory/start_state.num_territories)*100, 1)]% station control, a takeover will require [time] seconds.\nYour gang will be unable to gain influence while it is active.\nThe entire station will likely be alerted to it once it starts.\nAre you ready?","Confirm","Ready","Later") == "Ready")
+ if ((!in_range(src, user) || !istype(src.loc, /turf)))
+ return 0
+ var/area/srcloc = get_area(src.loc)
+ gang = tempgang
+ mode.domination(gang,1,srcloc.name)
+ src.name = "[gang_name(gang)] Gang [src.name]"
+ healthcheck(0)
+ operating = 1
+ ticker.mode.message_gangtools(((gang=="A") ? ticker.mode.A_tools : ticker.mode.B_tools),"Hostile takeover in progress: Estimated [time] seconds until victory.")
+
+/obj/machinery/dominator/attack_alien(mob/living/user)
+ user.do_attack_animation(src)
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ user.visible_message("[user] smashes against [src] with its claws.",\
+ "You smash against [src] with your claws.",\
+ "You hear metal scraping.")
+ healthcheck(15)
+
+/obj/machinery/dominator/attack_animal(mob/living/user as mob)
+ if(!isanimal(user))
+ return
+ var/mob/living/simple_animal/M = user
+ M.do_attack_animation(src)
+ if(M.melee_damage_upper <= 0)
+ return
+ healthcheck(M.melee_damage_upper)
+
+/obj/machinery/dominator/mech_melee_attack(obj/mecha/M)
+ if(M.damtype == "brute")
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ visible_message("[M.name] has hit [src].")
+ healthcheck(M.force)
+ return
+
+/obj/machinery/dominator/attack_hulk(mob/user)
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ user.visible_message("[user] smashes [src].",\
+ "You punch [src].",\
+ "You hear metal being slammed.")
+ healthcheck(5)
+
+/obj/machinery/dominator/attackby(obj/item/weapon/I as obj, mob/living/user as mob, params)
+ if(istype(I, /obj/item/weapon))
+ add_fingerprint(user)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.do_attack_animation(src)
+ if( (I.flags&NOBLUDGEON) || !I.force )
+ return
+ playsound(src, 'sound/weapons/smash.ogg', 50, 1)
+ visible_message("[user] has hit \the [src] with [I].")
+ if(I.damtype == BURN || I.damtype == BRUTE)
+ healthcheck(I.force)
+ return
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index 6967dc894c7..2b448e0b833 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -15,6 +15,10 @@
var/list/A_territory_lost = list()
var/list/B_territory_new = list()
var/list/B_territory_lost = list()
+ var/gang_A_style
+ var/gang_A_headgear
+ var/gang_B_style
+ var/gang_B_headgear
/datum/game_mode/gang
name = "gang war"
@@ -26,14 +30,15 @@
recommended_enemies = 2
enemy_minimum_age = 14
var/finished = 0
- var/goal_scalar = 0.5 //Goal = Total territories x goal_scalar
-
+ // Victory timers
+ var/A_timer = "OFFLINE"
+ var/B_timer = "OFFLINE"
///////////////////////////
//Announces the game type//
///////////////////////////
/datum/game_mode/gang/announce()
world << "The current game mode is - Gang War!"
- world << "A violent turf war has erupted on the station!
Gangsters - Take over the station by claiming more than [round(100*goal_scalar,1)]% of the station!
Crew - The gangs will try to keep you on the station. Successfully evacuate the station to win!"
+ world << "A violent turf war has erupted on the station!
Gangsters - Take over the station by activating and defending a Dominator!
Crew - The gangs will try to keep you on the station. Successfully evacuate the station to win!"
///////////////////////////////////////////////////////////////////////////////
@@ -73,6 +78,15 @@
modePlayer += B_bosses
..()
+/datum/game_mode/gang/process(seconds)
+ if(!finished)
+ if(isnum(A_timer))
+ A_timer -= seconds
+ if(isnum(B_timer))
+ B_timer -= seconds
+
+ ticker.mode.check_win()
+
/datum/game_mode/gang/proc/assign_bosses()
var/datum/mind/boss = pick(antag_candidates)
A_bosses += boss
@@ -91,7 +105,7 @@
/datum/game_mode/proc/forge_gang_objectives(var/datum/mind/boss_mind)
var/datum/objective/rival_obj = new
rival_obj.owner = boss_mind
- rival_obj.explanation_text = "Claim more than 50% the station before the [(boss_mind in A_bosses) ? gang_name("B") : gang_name("A")] Gang does."
+ rival_obj.explanation_text = "Preform a hostile takeover of the station with a Dominator."
boss_mind.objectives += rival_obj
@@ -103,6 +117,17 @@
boss_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
obj_count++
+/datum/game_mode/gang/proc/domination(var/gang,var/modifier=1,var/dominatorloc)
+ if(gang=="A")
+ A_timer = max(180,900 - ((round((ticker.mode.A_territory.len/start_state.num_territories)*200, 1) - 60) * 15)) * modifier
+ if(gang=="B")
+ B_timer = max(180,900 - ((round((ticker.mode.B_territory.len/start_state.num_territories)*200, 1) - 60) * 15)) * modifier
+ if(gang && dominatorloc)
+ priority_announce("Hostile runtimes detected in all station systems. A network breach by the [gang_name(gang)] Gang has been located in [dominatorloc].","Network Alert")
+ if(get_security_level() != "delta")
+ set_security_level("red")
+ SSshuttle.emergencyNoEscape = 1
+
///////////////////////////////////////////////////////////////////////////
//This equips the bosses with their gear, and makes the clown not clumsy//
///////////////////////////////////////////////////////////////////////////
@@ -132,37 +157,91 @@
var/where = mob.equip_in_one_of_slots(gangtool, slots)
if (!where)
mob << "Your Syndicate benefactors were unfortunately unable to get you a Gangtool."
+ . += 1
else
gangtool.register_device(mob)
- mob << "The Gangtool in your [where] will allow you to use your influence to purchase items and prevent the station from evacuating before you can take over. Use it to recall the emergency shuttle from anywhere on the station."
+ mob << "The Gangtool in your [where] will allow you to purchase items, send messages to your gangsters and recall the emergency shuttle from anywhere on the station."
mob << "You can also promote your gang members to lieutenant by giving them an unregistered gangtool. Lieutenants cannot be deconverted and are able to use recruitment pens and gangtools."
- . += 1
var/where2 = mob.equip_in_one_of_slots(T, slots)
if (!where2)
mob << "Your Syndicate benefactors were unfortunately unable to get you a recruitment pen to start."
- else
- mob << "The recruitment pen in your [where2] will help you get your gang started. Use it on unsuspecting crew members to recruit them."
. += 1
+ else
+ mob << "The recruitment pen in your [where2] will help you get your gang started. Stab unsuspecting crew members with it to recruit them."
var/where3 = mob.equip_in_one_of_slots(SC, slots)
if (!where3)
mob << "Your Syndicate benefactors were unfortunately unable to get you a territory spraycan to start."
- else
- mob << "The territory spraycan in your [where3] can be used to claim areas of the station for your gang. The more territory your gang controls, the more influence you get. Distribute these to your gangsters to grow your influence faster."
. += 1
+ else
+ mob << "The territory spraycan in your [where3] can be used to claim areas of the station for your gang. The more territory your gang controls, the more influence you get. All gangsters can use these, so distribute them to grow your influence faster."
mob.update_icons()
return .
+//Used by recallers when purchasing a gang outfit. First time a gang outfit is purchased the buyer decides a gang style which is stored so gang outfits are uniform
+/datum/game_mode/proc/gang_outfit(mob/user,var/obj/item/device/gangtool/gangtool,var/gang)
+ if(!user || !gangtool || !gang)
+ return 0
+ if(!gangtool.can_use(user))
+ return 0
+
+ var/gang_style_list = list("Gang Colors","Leather Jackets","Black Suits","White Suits")
+ var/style
+ if(gang == "A")
+ if(!gang_A_style)
+ gang_A_style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
+ style = gang_A_style
+
+ if(gang == "B")
+ if(!gang_B_style)
+ gang_B_style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
+ style = gang_B_style
+
+ if(!style)
+ return 0
+
+ if(gangtool.can_use(user) && (((gang == "A") ? gang_points.A : gang_points.B) >= 1))
+ switch(style)
+ if("Gang Colors")
+ if(gang == "A")
+ new /obj/item/clothing/under/color/blue(user.loc)
+ if(gang == "B")
+ new /obj/item/clothing/under/color/red(user.loc)
+ if("Leather Jackets")
+ new /obj/item/clothing/suit/jacket/leather(user.loc)
+ if("Black Suits")
+ new /obj/item/clothing/under/suit_jacket/charcoal(user.loc)
+ if("White Suits")
+ new /obj/item/clothing/under/suit_jacket/white(user.loc)
+
+ return 1
+
+ return 0
+
/////////////////////////////////////////////
//Checks if the either gang have won or not//
/////////////////////////////////////////////
/datum/game_mode/gang/check_win()
- if(A_territory.len > (start_state.num_territories * goal_scalar))
- finished = "A" //Gang A wins
- else if(B_territory.len > (start_state.num_territories * goal_scalar))
- finished = "B" //Gang B wins
+ var/winner = 0
+
+ if(isnum(A_timer))
+ if(A_timer < 0)
+ winner += 1
+ if(isnum(B_timer))
+ if(B_timer < 0)
+ winner += 2
+
+ if(winner)
+ if(winner == 3) //Edge Case: If both dominators activate at the same time
+ domination("A",0.5)
+ domination("B",0.5)
+ priority_announce("Multiple station takeover attempts have made simultaneously. Conflicting hostile runtimes appears to have delayed both attempts.","Network Alert")
+ else if(winner == 1)
+ finished = "A" //Gang A wins
+ else if(winner == 2)
+ finished = "B" //Gang B wins
///////////////////////////////
//Checks if the round is over//
@@ -282,7 +361,7 @@
if(!finished)
world << "The station was [station_was_nuked ? "destroyed!" : "evacuated before either gang could claim it!"]"
else
- world << "The [finished=="A" ? gang_name("A") : gang_name("B")] Gang has claimed over [round(100*goal_scalar,1)]% of the station and has assumed control!"
+ world << "The [finished=="A" ? gang_name("A") : gang_name("B")] Gang successfully preformed a hostile takeover of the station!!"
..()
return 1
@@ -338,8 +417,8 @@
//////////////////////////////////////////////////////////
/datum/gang_points
- var/A = 30
- var/B = 30
+ var/A = 25
+ var/B = 25
var/next_point_interval = 1800
var/next_point_time
@@ -371,25 +450,43 @@
B_lost_names += "[ticker.mode.B_territory_lost[area]], "
ticker.mode.B_territory -= area
+ var/datum/game_mode/gang/gangmode
+ if(istype(ticker.mode, /datum/game_mode/gang))
+ gangmode = ticker.mode
+
//Calculate and report influence growth
- ticker.mode.message_gangtools(ticker.mode.A_tools,"[gang_name("A")] Gang Status Report:")
- var/A_new = min(999,A + 15 + ticker.mode.A_territory.len)
+ ticker.mode.message_gangtools(ticker.mode.A_tools,"*---------*
[gang_name("A")] Gang Status Report:")
var/A_message = ""
- if(A_new != A)
- A_message += "Your gang has gained [A_new - A] Influence for holding on to [ticker.mode.A_territory.len] territories."
- if(A_new == 999)
- A_message += " You cannot gain any more influence without spending some with this device."
- A = A_new
+ if(gangmode && isnum(gangmode.A_timer))
+ var/new_time = max(180,gangmode.A_timer - (ticker.mode.A_territory.len * 2))
+ if(new_time < gangmode.A_timer)
+ A_message += "Your takeover has been rushed by [gangmode.A_timer - new_time] seconds for holding on to [ticker.mode.A_territory.len] territories. "
+ gangmode.A_timer = new_time
+ A_message += "[gangmode.A_timer] seconds remain in hostile takeover."
+ else
+ var/A_new = min(999,A + 15 + ticker.mode.A_territory.len)
+ if(A_new != A)
+ A_message += "Your gang has gained [A_new - A] Influence for holding on to [ticker.mode.A_territory.len] territories."
+ if(A_new == 999)
+ A_message += " You cannot gain any more influence without spending some with this device."
+ A = A_new
ticker.mode.message_gangtools(ticker.mode.A_tools,A_message,0)
ticker.mode.message_gangtools(ticker.mode.B_tools,"[gang_name("B")] Gang Status Report:")
- var/B_new = min(999,B + 15 + ticker.mode.B_territory.len)
var/B_message = ""
- if(B_new != B)
- B_message += "Your gang has gained [B_new - B] Influence for holding on to [ticker.mode.B_territory.len] territories."
- if(B_new == 999)
- B_message += " You cannot gain any more influence without spending some with this device."
- B = B_new
+ if(gangmode && isnum(gangmode.B_timer))
+ var/new_time = max(180,gangmode.B_timer - (ticker.mode.B_territory.len * 2))
+ if(new_time < gangmode.B_timer)
+ B_message += "Your takeover has been rushed by [gangmode.B_timer - new_time] seconds for holding on to [ticker.mode.B_territory.len] territories. "
+ gangmode.B_timer = new_time
+ B_message += "[gangmode.B_timer] seconds remain in hostile takeover."
+ else
+ var/B_new = min(999,B + 15 + ticker.mode.B_territory.len)
+ if(B_new != B)
+ B_message += "Your gang has gained [B_new - B] Influence for holding on to [ticker.mode.B_territory.len] territories."
+ if(B_new == 999)
+ B_message += " You cannot gain any more influence without spending some with this device."
+ B = B_new
ticker.mode.message_gangtools(ticker.mode.B_tools,B_message,0)
@@ -428,13 +525,12 @@
var/A_control = round((ticker.mode.A_territory.len/start_state.num_territories)*100, 1)
var/B_control = round((ticker.mode.B_territory.len/start_state.num_territories)*100, 1)
- ticker.mode.message_gangtools((ticker.mode.A_tools),"Your gang now has [A_control]% control of the station.",0)
- ticker.mode.message_gangtools((ticker.mode.A_tools),"The [gang_name("B")] Gang has [B_control]% control of the station.",0,1)
- ticker.mode.message_gangtools((ticker.mode.B_tools),"Your gang now has [B_control]% control of the station.",0)
- ticker.mode.message_gangtools((ticker.mode.B_tools),"The [gang_name("A")] Gang has [A_control]% control of the station.",0,1)
+ ticker.mode.message_gangtools((ticker.mode.A_tools),"Your gang now has [A_control]% control of the station.
*---------*",0)
+ ticker.mode.message_gangtools((ticker.mode.B_tools),"Your gang now has [B_control]% control of the station.
*---------*",0)
- //Victory check
- ticker.mode.check_win()
+ //Increase outfit stock
+ for(var/obj/item/device/gangtool/tool in (ticker.mode.A_tools | ticker.mode.B_tools))
+ tool.outfits = min(tool.outfits+3,10)
//Restart the counter
start()
diff --git a/code/game/objects/items/devices/recaller.dm b/code/game/gamemodes/gang/recaller.dm
similarity index 70%
rename from code/game/objects/items/devices/recaller.dm
rename to code/game/gamemodes/gang/recaller.dm
index de3f046635c..b081a80686e 100644
--- a/code/game/objects/items/devices/recaller.dm
+++ b/code/game/gamemodes/gang/recaller.dm
@@ -2,7 +2,7 @@
/obj/item/device/gangtool
name = "suspicious device"
desc = "A strange device of sorts. Hard to really make out what it actually does just by looking."
- icon_state = "recaller"
+ icon_state = "gangtool"
item_state = "walkietalkie"
throwforce = 0
w_class = 1.0
@@ -13,6 +13,7 @@
var/boss = 1 //If it has the power to promote gang members
var/recalling = 0
var/promotions = 0
+ var/outfits = 5
/obj/item/device/gangtool/New() //Initialize supply point income if it hasn't already been started
if(!ticker.mode.gang_points)
@@ -33,30 +34,35 @@
else
dat += "Register Device
"
else
+ var/datum/game_mode/gang/gangmode
+ if(istype(ticker.mode, /datum/game_mode/gang))
+ gangmode = ticker.mode
+
var/gang_size = ((gang == "A")? (ticker.mode.A_gang.len + ticker.mode.A_bosses.len) : (ticker.mode.B_gang.len + ticker.mode.B_bosses.len))
var/gang_territory = ((gang == "A")? ticker.mode.A_territory.len : ticker.mode.B_territory.len)
var/points = ((gang == "A") ? ticker.mode.gang_points.A : ticker.mode.gang_points.B)
+ var/timer
+ if(gangmode)
+ timer = ((gang == "A") ? gangmode.A_timer : gangmode.B_timer)
+ if(isnum(timer))
+ dat += "Takeover In Progress:
[timer] seconds remain
"
dat += "Registration: [(gang == "A")? gang_name("A") : gang_name("B")] Gang [boss ? "Administrator" : "Lieutenant"]
"
- dat += "Organization Size: [gang_size]
"
- dat += "Station Control: [round((gang_territory/start_state.num_territories)*100, 1)]%
"
- dat += "Recall Emergency Shuttle
"
+ dat += "Organization Size: [gang_size] | Station Control: [round((gang_territory/start_state.num_territories)*100, 1)]%
"
+ if(outfits > 0)
+ dat += "Create Gang Outfit
"
+ else
+ dat += "Create Gang Outfit (Restocking)
"
+ dat += "Send Gang-wide Message
"
+ if(gangmode)
+ dat += "Recall Emergency Shuttle
"
+
dat += "
"
+
dat += "Influence: [points]
"
- dat += "Time until Influence grows: [(points >= 100) ? ("--:--") : (time2text(ticker.mode.gang_points.next_point_time - world.time, "mm:ss"))]
"
- dat += "Purchase Items:
"
-
- dat += "(5 Influence) "
- if(points >= 5)
- dat += "Send Gang-wide Message
"
- else
- dat += "Send Gang-wide Message
"
-
- dat += "(10 Influence) "
- if(points >= 10)
- dat += "Territory Spraycan
"
- else
- dat += "Territory Spraycan
"
+ dat += "Time until Influence grows: [(points >= 999) ? ("--:--") : (time2text(ticker.mode.gang_points.next_point_time - world.time, "mm:ss"))]
"
+ dat += "
"
+ dat += "Purchase Weapons:
"
dat += "(10 Influence) "
if(points >= 10)
@@ -64,8 +70,8 @@
else
dat += "Switchblade
"
- dat += "(25 Influence) "
- if(points >= 25)
+ dat += "(20 Influence) "
+ if(points >= 20)
dat += "10mm Pistol
"
else
dat += "10mm Pistol
"
@@ -76,8 +82,29 @@
else
dat += "10mm Ammo
"
- dat += "(40 Influence) "
- if(points >= 40)
+ dat += "(50 Influence) "
+ if(points >= 50)
+ dat += "Thompson SMG
"
+ else
+ dat += "Thompson SMG
"
+
+ dat += "
"
+ dat += "Purchase Utilities:
"
+
+ dat += "(5 Influence) "
+ if(points >= 5)
+ dat += "Territory Spraycan
"
+ else
+ dat += "Territory Spraycan
"
+
+ dat += "(10 Influence) "
+ if(points >= 10)
+ dat += "Bulletproof Vest
"
+ else
+ dat += "Bulletproof Vest
"
+
+ dat += "(30 Influence) "
+ if(points >= 30)
dat += "Recruitment Pen
"
else
dat += "Recruitment Pen
"
@@ -86,19 +113,28 @@
if(promotions >= 3)
dat += "(Out of stock) Promote a Gangster
"
else
- dat += "([(promotions*20)+10] Influence, [3-promotions] left) "
- if(points >= (promotions*20)+10)
+ dat += "([(promotions*10)+10] Influence, [3-promotions] left) "
+ if(points >= (promotions*10)+10)
dat += "Promote a Gangster
"
else
dat += "Promote a Gangster
"
+ if(gangmode)
+ dat += "(30 Influence) "
+ if(points >= 30)
+ dat += "Station Dominator
"
+ else
+ dat += "Station Dominator
"
+ dat += "(Estimated Takeover Time: [round(max(180,900 - ((round((gang_territory/start_state.num_territories)*200, 10) - 60) * 15))/60,1)] minutes)
"
dat += "
"
dat += "Refresh
"
- var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v0.4")
+ var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v0.4", 340, 600)
popup.set_content(dat)
popup.open()
+
+
/obj/item/device/gangtool/Topic(href, href_list)
if(!can_use(usr))
return
@@ -116,44 +152,77 @@
var/item_type
switch(href_list["purchase"])
if("spraycan")
- if(points >= 10)
+ if(points >= 5)
item_type = /obj/item/toy/crayon/spraycan/gang
- points = 10
+ points = 5
if("switchblade")
if(points >= 10)
item_type = /obj/item/weapon/switchblade
points = 10
if("pistol")
- if(points >= 25)
+ if(points >= 20)
item_type = /obj/item/weapon/gun/projectile/automatic/pistol
- points = 25
+ points = 20
if("ammo")
if(points >= 10)
item_type = /obj/item/ammo_box/magazine/m10mm
points = 10
+ if("SMG")
+ if(points >= 50)
+ item_type = /obj/item/weapon/gun/projectile/automatic/tommygun
+ points = 50
+ if("vest")
+ if(points >= 10)
+ item_type = /obj/item/clothing/suit/armor/bulletproof
+ points = 10
if("pen")
- if(points >= 40)
+ if(points >= 30)
item_type = /obj/item/weapon/pen/gang
- points = 40
+ points = 30
if("gangtool")
- if((promotions < 3) && (points >= (promotions*20)+10))
+ if((promotions < 3) && (points >= (promotions*10)+10))
item_type = /obj/item/device/gangtool/lt
- points = (promotions*20)+10
+ points = (promotions*10)+10
promotions++
+ if("dominator")
+ if(istype(ticker.mode, /datum/game_mode/gang))
+ var/datum/game_mode/gang/mode = ticker.mode
+ if(isnum((gang == "A") ? mode.A_timer : mode.B_timer))
+ return
+
+ var/usrarea = get_area(usr.loc)
+ var/usrturf = get_turf(usr.loc)
+ if(istype(usrarea,/area/space) || istype(usrturf,/turf/space) || usr.z != 1)
+ usr << "You can only use this on the station!"
+ return
+
+ for(var/obj/obj in usrturf)
+ if(obj.density)
+ usr << "There's not enough room here!"
+ return
+
+ if(points >= 30)
+ item_type = /obj/machinery/dominator
+ points = 30
if(item_type)
if(gang == "A")
ticker.mode.gang_points.A -= points
else if(gang == "B")
ticker.mode.gang_points.B -= points
- var/obj/purchased = new item_type(get_turf(usr))
- var/mob/living/carbon/human/H = usr
- H.put_in_any_hand_if_possible(purchased)
+ if(ispath(item_type))
+ var/obj/purchased = new item_type(get_turf(usr))
+ var/mob/living/carbon/human/H = usr
+ H.put_in_any_hand_if_possible(purchased)
ticker.mode.message_gangtools(((gang=="A")? ticker.mode.A_tools : ticker.mode.B_tools), "A [href_list["purchase"]] was purchased by [usr] for [points] Influence.")
log_game("A [href_list["purchase"]] was purchased by [key_name(usr)] for [points] Influence.")
else if(href_list["choice"])
switch(href_list["choice"])
+ if("outfit")
+ if(outfits > 0)
+ ticker.mode.gang_outfit(usr,src,gang)
+ outfits -= 1
if("recall")
recall(usr)
if("ping")
@@ -172,19 +241,17 @@
return
var/list/members = list()
if(gang == "A")
- if(ticker.mode.gang_points.A >= 5)
- members += ticker.mode.A_bosses | ticker.mode.A_gang
- ticker.mode.gang_points.A -= 5
+ members += ticker.mode.A_bosses | ticker.mode.A_gang
else if(gang == "B")
- if(ticker.mode.gang_points.B >= 5)
- members += ticker.mode.B_bosses | ticker.mode.B_gang
- ticker.mode.gang_points.B -= 5
+ members += ticker.mode.B_bosses | ticker.mode.B_gang
if(members.len)
+ var/ping = "[gang_name(gang)] [boss ? "Gang Boss" : "Gang Lieutenant"]: [message]"
for(var/datum/mind/ganger in members)
if(ganger.current.z <= 2)
- ganger.current << "BOSS: [message]"
- message_admins("[key_name_admin(user)] sent a global message to the [gang_name(gang)] Gang ([gang]): [message].")
- log_game("[key_name(user)] sent a global message to the [gang_name(gang)] Gang ([gang]): [message].")
+ ganger.current << ping
+ for(var/mob/M in dead_mob_list)
+ M << ping
+ log_game("[key_name(user)] Messaged [gang_name(gang)] Gang ([gang]): [message].")
/obj/item/device/gangtool/proc/register_device(var/mob/user)
@@ -196,6 +263,7 @@
if(user.mind in (ticker.mode.A_gang | ticker.mode.A_bosses))
ticker.mode.A_tools += src
gang = "A"
+ icon_state = "gangtool-a"
if(!(user.mind in ticker.mode.A_bosses))
ticker.mode.remove_gangster(user.mind, 0, 2)
ticker.mode.A_bosses += user.mind
@@ -206,6 +274,7 @@
else if(user.mind in (ticker.mode.B_gang | ticker.mode.B_bosses))
ticker.mode.B_tools += src
gang = "B"
+ icon_state = "gangtool-b"
if(!(user.mind in ticker.mode.B_bosses))
ticker.mode.remove_gangster(user.mind, 0, 2)
ticker.mode.B_bosses += user.mind
@@ -218,7 +287,7 @@
user << "You have been promoted to Lieutenant!"
ticker.mode.forge_gang_objectives(user.mind)
ticker.mode.greet_gang(user.mind,0)
- user << "The Gangtool you registered will allow you to use your gang's influence to purchase items and prevent the station from evacuating before your gang can take over. Use it to recall the emergency shuttle from anywhere on the station."
+ user << "The Gangtool you registered will allow you to purchase items, send messages to your gangsters and to recall the emergency shuttle from anywhere on the station."
user << "You may also now use recruitment pens to grow your gang membership. Use them on unsuspecting crew members to recruit them."
if(!gang)
usr << "ACCESS DENIED: Unauthorized user."
@@ -227,6 +296,9 @@
if(recalling || !can_use(user))
return
+ if(!istype(ticker.mode, /datum/game_mode/gang))
+ return
+
recalling = 1
loc << "\icon[src]Generating shuttle recall order with codes retrieved from last call signal..."
diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm
index e392f101ae7..6fe17405212 100644
--- a/code/game/gamemodes/intercept_report.dm
+++ b/code/game/gamemodes/intercept_report.dm
@@ -228,9 +228,9 @@
*/
/datum/intercept_text/proc/build_gang(datum/mind/correct_person)
- src.text += "
We have recieved reports of a sudden increase of criminal activity in close proximity to our operations within your sector."
- src.text += "Ensure law and order is maintained on the station and be on the lookout for unusually territorial behavior from the crew."
- src.text += "In the event of a full-scale takeover attempt, sensitive research items are to be secured and the station evacuated ASAP."
+ src.text += "
We have reports of criminal activity in close proximity to our operations within your sector."
+ src.text += "Ensure law and order is maintained on the station and be on the lookout for aggressive factionalism within the crew."
+ src.text += "In the event of a full-scale criminal takeover threat, sensitive research items are to be secured and the station evacuated ASAP."
src.text += "
"
/datum/intercept_text/proc/build_wizard(datum/mind/correct_person)
@@ -289,3 +289,4 @@
*/
src.text += "These lifeforms are associated with the [orgname1] [orgname2] and may be attempting to acquire sensitive materials on their behalf. "
src.text += "Please take care not to alarm the crew, as [cname] may take advantage of a panic situation. Remember, they can be anybody, suspect everybody!"
+ src.text += "
"
\ No newline at end of file
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 5ef07cdcbf5..90bb59dc92f 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -99,7 +99,7 @@
C.post_status("alert", "lockdown")
src.verbs += /mob/living/silicon/ai/proc/disablelockdown
- src << "Lockdown Initiated."
+ src << "Lockdown Initiated."
malf_cooldown = 1
spawn(30)
malf_cooldown = 0
@@ -127,7 +127,7 @@
else if(!D.stat) //Opens only powered doors.
D.open() //Open everything!
- src << "Lockdown Lifted."
+ src << "Lockdown Lifted."
malf_cooldown = 1
spawn(30)
malf_cooldown = 0
diff --git a/code/game/gamemodes/monkey/monkey.dm b/code/game/gamemodes/monkey/monkey.dm
index 18a62827b4f..d27155825c0 100644
--- a/code/game/gamemodes/monkey/monkey.dm
+++ b/code/game/gamemodes/monkey/monkey.dm
@@ -46,7 +46,7 @@
/datum/game_mode/monkey/proc/greet_carrier(var/datum/mind/carrier)
- carrier.current << "You are the Jungle Fever patient zero!!"
+ carrier.current << "You are the Jungle Fever patient zero!!"
carrier.current << "You have been planted onto this station by the Animal Rights Consortium."
carrier.current << "Soon the disease will transform you into an ape. Afterwards, you will be able spread the infection to others with a bite."
carrier.current << "While your infection strain is undetectable by scanners, any other infectees will show up on medical equipment."
diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm
index 351f87f9c37..8a5b0de73ce 100644
--- a/code/game/gamemodes/wizard/soulstone.dm
+++ b/code/game/gamemodes/wizard/soulstone.dm
@@ -49,7 +49,7 @@
dat += "Captured Soul: [A.name]
"
dat += {"Summon Shade"}
dat += "
"
- dat += {" Close"}
+ dat += {"Close"}
user << browse(dat, "window=aicard")
onclose(user, "aicard")
return
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 27c449dbb2f..2c9ea69ef97 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -1,3 +1,394 @@
+/datum/spellbook_entry
+ var/name = "Entry Name"
+
+ var/spell_type = null
+ var/desc = ""
+ var/category = "Offensive Spells"
+ var/log_name = "XX" //What it shows up as in logs
+ var/cost = 1
+ var/refundable = 1
+ var/surplus = -1 // -1 for infinite, not used by anything atm
+ var/obj/effect/proc_holder/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell
+ var/buy_word = "Learn"
+
+/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied
+ return 1
+/datum/spellbook_entry/proc/CanBuy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book) // Specific circumstances
+ if(book.uses= aspell.level_max)
+ user << "This spell cannot be improved further."
+ return 0
+ else
+ aspell.name = initial(aspell.name)
+ aspell.spell_level++
+ aspell.charge_max = round(initial(aspell.charge_max) - aspell.spell_level * (initial(aspell.charge_max) - aspell.cooldown_min)/ aspell.level_max)
+ if(aspell.charge_max < aspell.charge_counter)
+ aspell.charge_counter = aspell.charge_max
+ switch(aspell.spell_level)
+ if(1)
+ user << "You have improved [aspell.name] into Efficient [aspell.name]."
+ aspell.name = "Efficient [aspell.name]"
+ if(2)
+ user << "You have further improved [aspell.name] into Quickened [aspell.name]."
+ aspell.name = "Quickened [aspell.name]"
+ if(3)
+ user << "You have further improved [aspell.name] into Free [aspell.name]."
+ aspell.name = "Free [aspell.name]"
+ if(4)
+ user << "You have further improved [aspell.name] into Instant [aspell.name]."
+ aspell.name = "Instant [aspell.name]"
+ if(aspell.spell_level >= aspell.level_max)
+ user << "This spell cannot be strengthened any further."
+ return 1
+ //No same spell found - just learn it
+ feedback_add_details("wizard_spell_learned",log_name)
+ user.mind.AddSpell(S)
+ user << "You have learned [S.name]."
+ return 1
+
+/datum/spellbook_entry/proc/CanRefund(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ if(!refundable)
+ return 0
+ if(!S)
+ S = new spell_type()
+ for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
+ if(initial(S.name) == initial(aspell.name))
+ return 1
+ return 0
+
+/datum/spellbook_entry/proc/Refund(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book) //return point value or -1 for failure
+ var/area/wizard_station/A = locate()
+ if(!(user in A.contents))
+ user << "You can only refund spells at the wizard lair"
+ return -1
+ if(!S)
+ S = new spell_type()
+ var/spell_levels = 0
+ 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
+ user.mind.spell_list.Remove(aspell)
+ del(S)
+ return cost * (spell_levels+1)
+ return -1
+/datum/spellbook_entry/proc/GetInfo()
+ if(!S)
+ S = new spell_type()
+ var/dat =""
+ dat += "[initial(S.name)]"
+ if(S.charge_type == "recharge")
+ dat += " Cooldown:[S.charge_max/10]"
+ dat += " Cost:[cost]
"
+ dat += "[S.desc][desc]
"
+ dat += "[S.clothes_req?"Needs wizard garb":"Can be cast without wizard garb"]
"
+ return dat
+
+/datum/spellbook_entry/fireball
+ name = "Fireball"
+ spell_type = /obj/effect/proc_holder/spell/dumbfire/fireball
+ log_name = "FB"
+
+/datum/spellbook_entry/magicm
+ name = "Magic Missile"
+ spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
+ log_name = "MM"
+
+/datum/spellbook_entry/disintegrate
+ name = "Disintegrate"
+ spell_type = /obj/effect/proc_holder/spell/targeted/inflict_handler/disintegrate
+ log_name = "DG"
+
+/datum/spellbook_entry/disabletech
+ name = "Disable Tech"
+ spell_type = /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
+ log_name = "DT"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/repulse
+ name = "Repulse"
+ spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse
+ log_name = "RP"
+
+/datum/spellbook_entry/smoke
+ name = "Smoke"
+ spell_type = /obj/effect/proc_holder/spell/targeted/smoke
+ log_name = "SM"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/blind
+ name = "Blind"
+ spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind
+ log_name = "BD"
+
+/datum/spellbook_entry/mindswap
+ name = "Mindswap"
+ spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer
+ log_name = "MT"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/forcewall
+ name = "Force Wall"
+ spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/forcewall
+ log_name = "FW"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/blink
+ name = "Blink"
+ spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink
+ log_name = "BL"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/teleport
+ name = "Teleport"
+ spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport
+ log_name = "TP"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/mutate
+ name = "Mutate"
+ spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate
+ log_name = "MU"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/jaunt
+ name = "Ethereal Jaunt"
+ spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt
+ log_name = "EJ"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/knock
+ name = "Knock"
+ spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock
+ log_name = "KN"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/fleshtostone
+ name = "Flesh to Stone"
+ spell_type = /obj/effect/proc_holder/spell/targeted/inflict_handler/flesh_to_stone
+ log_name = "FS"
+
+/datum/spellbook_entry/summonitem
+ name = "Summon Item"
+ spell_type = /obj/effect/proc_holder/spell/targeted/summonitem
+ log_name = "IS"
+ category = "Utility Spells"
+
+/datum/spellbook_entry/lichdom
+ name = "Bind Soul"
+ spell_type = /obj/effect/proc_holder/spell/targeted/lichdom
+ log_name = "LD"
+
+/datum/spellbook_entry/lightningbolt
+ name = "Lightning Bolt"
+ spell_type = /obj/effect/proc_holder/spell/targeted/lightning
+ log_name = "LB"
+
+/datum/spellbook_entry/barnyard
+ name = "Barnyard Curse"
+ spell_type = /obj/effect/proc_holder/spell/targeted/barnyardcurse
+ log_name = "BC"
+
+/datum/spellbook_entry/item
+ name = "Buy Item"
+ category = "Artifacts"
+ refundable = 0
+ buy_word = "Summon"
+ var/item_path= null
+
+
+/datum/spellbook_entry/item/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ new item_path(get_turf(user))
+ feedback_add_details("wizard_spell_learned",log_name)
+ return 1
+
+/datum/spellbook_entry/item/GetInfo()
+ var/dat =""
+ dat += "[name]"
+ dat += " Cost:[cost]
"
+ dat += "[desc]
"
+ if(surplus>=0)
+ dat += "[surplus] left.
"
+ return dat
+
+/datum/spellbook_entry/item/staffchange
+ 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/weapon/gun/magic/staff/change
+ log_name = "ST"
+
+/datum/spellbook_entry/item/staffanimation
+ name = "Staff of Animation"
+ desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines."
+ item_path = /obj/item/weapon/gun/magic/staff/animate
+ log_name = "SA"
+
+/datum/spellbook_entry/item/staffchaos
+ name = "Staff of Chaos"
+ desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended."
+ item_path = /obj/item/weapon/gun/magic/staff/chaos
+ log_name = "SC"
+
+/datum/spellbook_entry/item/staffdoor
+ name = "Staff of Door Creation"
+ desc = "A particular staff that can mold solid metal into ornate wooden doors. Useful for getting around in the absence of other transportation. Does not work on glass."
+ item_path = /obj/item/weapon/gun/magic/staff/door
+ log_name = "SD"
+
+/datum/spellbook_entry/item/scryingorb
+ name = "Scrying Orb"
+ desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision."
+ item_path = /obj/item/weapon/scrying
+ log_name = "SO"
+
+/datum/spellbook_entry/item/scryingorb/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ if(..())
+ if (!(user.dna.check_mutation(XRAY)))
+ user.dna.add_mutation(XRAY)
+ return 1
+
+/datum/spellbook_entry/item/soulstones
+ name = "Six Soul Stone Shards and the spell Artificer"
+ desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
+ item_path = /obj/item/weapon/storage/belt/soulstone/full
+ log_name = "SS"
+
+/datum/spellbook_entry/item/soulstones/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ . =..()
+ if(.)
+ user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null))
+ return .
+
+/datum/spellbook_entry/item/necrostone
+ name = "A Necromantic Stone"
+ desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command."
+ item_path = /obj/item/device/necromantic_stone
+ log_name = "NS"
+
+/datum/spellbook_entry/item/wands
+ name = "Wand Assortment"
+ desc = "A collection of wands that allow for a wide variety of utility. Wands do not recharge, so be conservative in use. Comes in a handy belt."
+ item_path = /obj/item/weapon/storage/belt/wands/full
+ log_name = "WA"
+
+/datum/spellbook_entry/item/armor
+ name = "Mastercrafted Armor Set"
+ desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
+ item_path = /obj/item/clothing/suit/space/hardsuit/wizard
+ log_name = "HS"
+
+/datum/spellbook_entry/item/armor/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ . = ..()
+ if(.)
+ new /obj/item/clothing/shoes/sandal(get_turf(user)) //In case they've lost them.
+ new /obj/item/clothing/gloves/color/purple(get_turf(user))//To complete the outfit
+
+/datum/spellbook_entry/item/contract
+ name = "Contract of Apprenticeship"
+ desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side."
+ item_path = /obj/item/weapon/antag_spawner/contract
+ log_name = "CT"
+
+/datum/spellbook_entry/item/bloodbottle
+ name = "Bottle of Blood"
+ desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim."
+ item_path = /obj/item/weapon/antag_spawner/slaughter_demon
+ log_name = "BB"
+
+/datum/spellbook_entry/summon
+ name = "Summon Stuff"
+ category = "Rituals"
+ refundable = 0
+ buy_word = "Cast"
+ var/active = 0
+
+/datum/spellbook_entry/summon/CanBuy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ return ..() && !active
+
+/datum/spellbook_entry/summon/GetInfo()
+ var/dat =""
+ dat += "[name]"
+ if(cost>0)
+ dat += " Cost:[cost]
"
+ else
+ dat += " No Cost
"
+ dat += "[desc]
"
+ if(active)
+ dat += "Already cast!
"
+ return dat
+
+/datum/spellbook_entry/summon/guns
+ name = "Summon Guns"
+ category = "Challenges"
+ 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!"
+ cost = 0
+ log_name = "SG"
+
+/datum/spellbook_entry/summon/guns/IsAvailible()
+ return !config.no_summon_guns
+
+/datum/spellbook_entry/summon/guns/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ feedback_add_details("wizard_spell_learned",log_name)
+ rightandwrong(0, user, 0)
+ book.uses += 1
+ active = 1
+ playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
+ user << "You have cast summon guns and gained an extra charge for your spellbook."
+ return 1
+
+/datum/spellbook_entry/summon/magic
+ name = "Summon Magic"
+ category = "Challenges"
+ 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."
+ cost = 0
+ log_name = "SU"
+
+/datum/spellbook_entry/summon/magic/IsAvailible()
+ return !config.no_summon_magic
+
+/datum/spellbook_entry/summon/magic/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ feedback_add_details("wizard_spell_learned",log_name)
+ rightandwrong(1, user, 0)
+ book.uses += 1
+ active = 1
+ playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
+ user << "You have cast summon magic and gained an extra charge for your spellbook."
+ 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."
+ cost = 1
+ log_name = "SE"
+ var/times = 0
+
+/datum/spellbook_entry/summon/events/IsAvailible()
+ return (ticker.mode.name != "ragin' mages" && !config.no_summon_events)
+
+/datum/spellbook_entry/summon/events/Buy(var/mob/living/carbon/human/user,var/obj/item/weapon/spellbook/book)
+ feedback_add_details("wizard_spell_learned",log_name)
+ summonevents()
+ times++
+ playsound(get_turf(user),"sound/magic/CastSummon.ogg",50,1)
+ user << "You have cast summon events."
+ return 1
+
+/datum/spellbook_entry/summon/events/GetInfo()
+ . = ..()
+ if(times>0)
+ . += "You cast it [times] times.
"
+ return .
+
+
+
/obj/item/weapon/spellbook
name = "spell book"
desc = "The legendary book of spells of the wizard."
@@ -8,11 +399,24 @@
w_class = 1.0
var/uses = 5
var/temp = null
- var/max_uses = 5
var/op = 1
- var/activepage
- var/list/active_challenges = list()
+ var/tab = null
var/mob/living/carbon/human/owner
+ var/list/datum/spellbook_entry/entries = list()
+ var/list/categories = list()
+
+/obj/item/weapon/spellbook/New()
+ ..()
+ var/entry_types = typesof(/datum/spellbook_entry) - /datum/spellbook_entry - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
+ for(var/T in entry_types)
+ var/datum/spellbook_entry/E = new T
+ if(E.IsAvailible())
+ entries |= E
+ categories |= E.category
+ else
+ del(E)
+ tab = categories[1]
+
/obj/item/weapon/spellbook/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/weapon/antag_spawner/contract))
@@ -21,12 +425,53 @@
user << "The contract has been used, you can't get your points back now!"
else
user << "You feed the contract back into the spellbook, refunding your points."
- src.max_uses++
src.uses++
qdel(O)
+ if(istype(O, /obj/item/weapon/antag_spawner/slaughter_demon))
+ user << "On second thought, maybe summoning a demon is a bad idea. You refund your points."
+ src.uses++
+ qdel(O)
+/obj/item/weapon/spellbook/proc/GetCategoryHeader(var/category)
+ var/dat = ""
+ switch(category)
+ if("Offensive Spells")
+ dat += "Spells that can be reused endlessly.
"
+ dat += "The number after the spell name is the cooldown time.
"
+ dat += "You can reduce this number by spending more points on the spell.
"
+ if("Utility Spells")
+ dat += "Spells that can be reused endlessly.
"
+ dat += "The number after the spell name is the cooldown time.
"
+ dat += "You can reduce this number by spending more points on the spell.
"
+ if("Artifacts")
+ dat += "Powerful items imbued with eldritch magics. Summoning one will count towards your maximum number of uses.
"
+ dat += "These items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.
"
+ if("Challenges")
+ dat += "The Wizard Federation typically has hard limits on the potency and number of spells brought to the station based on risk.
"
+ dat += "Arming the station against you will increases the risk, but will grant you one more charge for your spellbook.
"
+ if("Rituals")
+ dat += "These powerful spells change the very fabric of reality. Not always in your favour.
"
+ return dat
-
+/obj/item/weapon/spellbook/proc/wrap(var/content)
+ var/dat = ""
+ dat +="Spellbook"
+ dat += {"
+
+
+
+ "}
+ dat += {"[content]