diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm
index 02a09faf559..9875fd0a84c 100644
--- a/code/__DEFINES/combat.dm
+++ b/code/__DEFINES/combat.dm
@@ -26,6 +26,7 @@
#define CANWEAKEN 2
#define CANPARALYSE 4
#define CANPUSH 8
+#define GOTTAGOFAST 16
#define GODMODE 4096
#define FAKEDEATH 8192 //Replaces stuff like changeling.changeling_fakedeath
#define DISFIGURED 16384 //I'll probably move this elsewhere if I ever get wround to writing a bitflag mob-damage system
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 0b78c6622f7..c90a8c19dbb 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -35,6 +35,9 @@
return
var/list/modifiers = params2list(params)
+ if(modifiers["shift"] && modifiers["ctrl"])
+ CtrlShiftClickOn(A)
+ return
if(modifiers["middle"])
MiddleClickOn(A)
return
@@ -83,6 +86,9 @@
than anything else in the game, atoms have separate procs
for AI shift, ctrl, and alt clicking.
*/
+
+/mob/living/silicon/ai/CtrlShiftClickOn(var/atom/A)
+ A.AICtrlShiftClick(src)
/mob/living/silicon/ai/ShiftClickOn(var/atom/A)
A.AIShiftClick(src)
/mob/living/silicon/ai/CtrlClickOn(var/atom/A)
@@ -94,6 +100,17 @@
The following criminally helpful code is just the previous code cleaned up;
I have no idea why it was in atoms.dm instead of respective files.
*/
+/atom/proc/AICtrlShiftClick()
+ return
+
+/obj/machinery/door/airlock/AICtrlShiftClick() // Sets/Unsets Emergency Access Override
+ if(emagged)
+ return
+ if(!emergency)
+ Topic("aiEnable=11", list("aiEnable"="11"), 1) // 1 meaning no window (consistency!)
+ else
+ Topic("aiDisable=11", list("aiDisable"="11"), 1)
+ return
/atom/proc/AIShiftClick()
return
@@ -122,6 +139,10 @@
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
toggle_breaker()
+/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
+ src.enabled = !src.enabled
+ src.updateTurrets()
+
/atom/proc/AIAltClick(var/mob/living/silicon/ai/user)
AltClick(user)
@@ -138,6 +159,10 @@
Topic("aiDisable=5", list("aiDisable"="5"), 1)
return
+/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
+ src.lethal = !src.lethal
+ src.updateTurrets()
+
//
// Override TurfAdjacent for AltClicking
//
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 00102cf922e..163c7c3aa5f 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -43,6 +43,9 @@
return
var/list/modifiers = params2list(params)
+ if(modifiers["shift"] && modifiers["ctrl"])
+ CtrlShiftClickOn(A)
+ return
if(modifiers["middle"])
MiddleClickOn(A)
return
@@ -98,8 +101,8 @@
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1 indicates adjacency
else
- if(ismob(A))
- changeNext_move(8)
+ //if(ismob(A))
+ // changeNext_move(8)
UnarmedAttack(A)
return
@@ -117,8 +120,8 @@
if(!resolved && A && W)
W.afterattack(A,src,1,params) // 1: clicking something Adjacent
else
- if(ismob(A))
- changeNext_move(8)
+ //if(ismob(A))
+ // changeNext_move(8)
UnarmedAttack(A, 1)
return
else // non-adjacent click
@@ -242,6 +245,17 @@
/mob/proc/TurfAdjacent(var/turf/T)
return T.Adjacent(src)
+/*
+ Control+Shift click
+ Unused except for AI
+*/
+/mob/proc/CtrlShiftClickOn(var/atom/A)
+ A.CtrlShiftClick(src)
+ return
+
+/atom/proc/CtrlShiftClick(var/mob/user)
+ return
+
/*
Misc helpers
diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm
index aefd8747cdc..69d5a23bb2b 100644
--- a/code/_onclick/cyborg.dm
+++ b/code/_onclick/cyborg.dm
@@ -19,6 +19,9 @@
return
var/list/modifiers = params2list(params)
+ if(modifiers["shift"] && modifiers["ctrl"])
+ CtrlShiftClickOn(A)
+ return
if(modifiers["middle"])
MiddleClickOn(A)
return
@@ -87,6 +90,53 @@
cycle_modules()
return
+//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks
+// for non-doors/apcs
+/mob/living/silicon/robot/CtrlShiftClickOn(var/atom/A)
+ A.BorgCtrlShiftClick(src)
+/mob/living/silicon/robot/ShiftClickOn(var/atom/A)
+ A.BorgShiftClick(src)
+/mob/living/silicon/robot/CtrlClickOn(var/atom/A)
+ A.BorgCtrlClick(src)
+/mob/living/silicon/robot/AltClickOn(var/atom/A)
+ A.BorgAltClick(src)
+
+/atom/proc/BorgCtrlShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
+ CtrlShiftClick(user)
+
+/obj/machinery/door/airlock/BorgCtrlShiftClick() // Sets/Unsets Emergency Access Override Forwards to AI code.
+ AICtrlShiftClick()
+
+
+/atom/proc/BorgShiftClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
+ ShiftClick(user)
+
+/obj/machinery/door/airlock/BorgShiftClick() // Opens and closes doors! Forwards to AI code.
+ AIShiftClick()
+
+
+/atom/proc/BorgCtrlClick(var/mob/living/silicon/robot/user) //forward to human click if not overriden
+ CtrlClick(user)
+
+/obj/machinery/door/airlock/BorgCtrlClick() // Bolts doors. Forwards to AI code.
+ AICtrlClick()
+
+/obj/machinery/power/apc/BorgCtrlClick() // turns off/on APCs. Forwards to AI code.
+ AICtrlClick()
+
+/obj/machinery/turretid/BorgCtrlClick() //turret control on/off. Forwards to AI code.
+ AICtrlClick()
+
+/atom/proc/BorgAltClick(var/mob/living/silicon/robot/user)
+ AltClick(user)
+ return
+
+/obj/machinery/door/airlock/BorgAltClick() // Eletrifies doors. Forwards to AI code.
+ AIAltClick()
+
+/obj/machinery/turretid/BorgAltClick() //turret lethal on/off. Forwards to AI code.
+ AIAltClick()
+
/*
As with AI, these are not used in click code,
because the code for robots is specific, not generic.
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index effbae56975..6780a9afd3e 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -598,14 +598,7 @@ datum/mind
log_admin("[key_name(usr)] has de-cult'ed [current].")
if("cultist")
if(!(src in ticker.mode.cult))
- ticker.mode.cult += src
- ticker.mode.update_cult_icons_added(src)
- special_role = "Cultist"
- current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie."
- current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back."
- var/datum/game_mode/cult/cult = ticker.mode
- if (istype(cult))
- cult.memorize_cult_objectives(src)
+ ticker.mode.add_cultist(src)
message_admins("[key_name_admin(usr)] has cult'ed [current].")
log_admin("[key_name(usr)] has cult'ed [current].")
if("tome")
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index fc26183f05e..ea1de0376c6 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -123,7 +123,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 10
containertype = /obj/structure/closet/crate
containername = "firefighting crate"
-
+
/datum/supply_packs/emergency/atmostank
name = "Firefighting Watertank"
contains = list(/obj/item/weapon/watertank/atmos)
@@ -748,7 +748,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 15
containertype = /obj/structure/closet/crate/hydroponics
containername = "hydroponics crate"
-
+
/datum/supply_packs/misc/hydroponics/hydrotank
name = "Hydroponics Watertank Backpack Crate"
contains = list(/obj/item/weapon/watertank)
@@ -900,7 +900,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/datum/supply_packs/misc/lasertag
name = "LaserTag Crate"
- contains = list(/obj/item/weapon/gun/energy/laser/redtag,
+ contains = list(/obj/item/weapon/gun/energy/laser/redtag,
/obj/item/weapon/gun/energy/laser/redtag,
/obj/item/weapon/gun/energy/laser/redtag,
/obj/item/weapon/gun/energy/laser/bluetag,
@@ -917,10 +917,24 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 15
containername = "LaserTag Crate"
+/datum/supply_packs/misc/religious_supplies
+ name = "Religious Supplies Crate"
+ contains = list(/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/weapon/storage/bible/booze,
+ /obj/item/weapon/storage/bible/booze,
+ /obj/item/clothing/suit/chaplain_hoodie,
+ /obj/item/clothing/head/chaplain_hood,
+ /obj/item/clothing/suit/chaplain_hoodie,
+ /obj/item/clothing/head/chaplain_hood)
+ cost = 40 // it costs so much because the Space Church is ran by Space Jews
+ containername = "religious supplies crate"
+
+
///////////// Paper Work
/datum/supply_packs/misc/paper
- name = "Bureaucracy crate"
+ name = "Bureaucracy Crate"
contains = list(/obj/structure/filingcabinet/chestdrawer/wheeled,
/obj/item/device/camera_film,
/obj/item/weapon/hand_labeler,
@@ -936,7 +950,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/obj/item/weapon/clipboard,
/obj/item/weapon/clipboard)
cost = 15
- containername = "Bureaucracy crate"
+ containername = "bureaucracy crate"
/datum/supply_packs/misc/toner
name = "Toner Cartridges"
@@ -977,7 +991,7 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
cost = 10
containertype = /obj/structure/largecrate
containername = "janitorial cart crate"
-
+
/datum/supply_packs/misc/janitor/janitank
name = "Janitor Watertank Backpack Crate"
contains = list(/obj/item/weapon/watertank/janitor)
diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm
index c4c8907feaa..c68c9e0b41f 100644
--- a/code/game/gamemodes/cult/cult.dm
+++ b/code/game/gamemodes/cult/cult.dm
@@ -4,6 +4,8 @@
var/list/datum/mind/cult = list()
var/list/allwords = list("travel","self","see","hell","blood","join","tech","destroy", "other", "hide")
var/list/grantwords = list("travel", "see", "hell", "tech", "destroy", "other", "hide")
+ var/list/cult_objectives = list()
+
/proc/iscultist(mob/living/M as mob)
return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.cult)
@@ -13,6 +15,8 @@
if(istype(mind.current, /mob/living/carbon/human) && (mind.assigned_role in list("Captain", "Chaplain"))) return 0
if(isloyal(mind.current))
return 0
+ if (ticker.mode.name == "cult") //redundent?
+ if(mind.current == ticker.mode.sacrifice_target) return 0
return 1
@@ -20,16 +24,15 @@
name = "cult"
config_tag = "cult"
antag_flag = BE_CULTIST
- restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain")
+ restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")
protected_jobs = list()
- required_players = 15
- required_enemies = 3
- recommended_enemies = 4
+ required_players = 20
+ required_enemies = 6
+ recommended_enemies = 6
uplink_welcome = "Nar-Sie Uplink Console:"
uplink_uses = 10
- var/datum/mind/sacrifice_target = null
var/finished = 0
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
@@ -37,11 +40,9 @@
var/list/startwords = list("blood","join","self","hell")
var/list/secondwords = list("travel", "see", "tech", "destroy", "other", "hide")
- var/list/objectives = list()
-
var/eldergod = 1 //for the summon god objective
- var/const/acolytes_needed = 5 //for the survive objective
+ var/acolytes_needed = 10 //for the survive objective
var/acolytes_survived = 0
@@ -52,11 +53,15 @@
/datum/game_mode/cult/pre_setup()
if(prob(50))
- objectives += "survive"
- objectives += "sacrifice"
+ cult_objectives += "survive"
+ cult_objectives += "sacrifice"
else
- objectives += "eldergod"
- objectives += "sacrifice"
+ cult_objectives += "eldergod"
+ cult_objectives += "sacrifice"
+
+ if(num_players() >= 30)
+ recommended_enemies = 9 // 3+3+3 - d' magic number o' magic numbars mon
+ acolytes_needed = 15
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
@@ -79,7 +84,7 @@
/datum/game_mode/cult/post_setup()
modePlayer += cult
- if("sacrifice" in objectives)
+ if("sacrifice" in cult_objectives)
var/list/possible_targets = get_unconvertables()
if(!possible_targets.len)
@@ -110,9 +115,9 @@
/datum/game_mode/cult/proc/memorize_cult_objectives(var/datum/mind/cult_mind)
- for(var/obj_count = 1,obj_count <= objectives.len,obj_count++)
+ for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++)
var/explanation
- switch(objectives[obj_count])
+ switch(cult_objectives[obj_count])
if("survive")
explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station."
if("sacrifice")
@@ -124,11 +129,12 @@
explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it."
cult_mind.current << "Objective #[obj_count]: [explanation]"
cult_mind.memory += "Objective #[obj_count]: [explanation]
"
- cult_mind.current << "The Geometer of Blood grants you the knowledge to convert non-believers. (Join Blood Self)"
- cult_mind.memory += "The Geometer of Blood grants you the knowledge to convert non-believers. (Join Blood Self)
"
- grant_runeword(cult_mind.current,"join")
- grant_runeword(cult_mind.current,"blood")
- grant_runeword(cult_mind.current,"self")
+ cult_mind.current << "The Geometer of Blood grants you the knowledge to sacrifice non-believers. (Hell Blood Join)"
+ cult_mind.memory += "The Geometer of Blood grants you the knowledge to sacrifice non-believers. (Hell Blood Join)
"
+ for(var/startingword in startwords)
+ grant_runeword(cult_mind.current,startingword)
+// grant_runeword(cult_mind.current,"blood")
+// grant_runeword(cult_mind.current,"hell")
/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob)
if(!istype(mob))
@@ -214,6 +220,7 @@
return 0
if(!(cult_mind in cult) && is_convertable_to_cult(cult_mind))
cult += cult_mind
+ cult_mind.current.cult_add_comm()
update_cult_icons_added(cult_mind)
cult_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the cult!"
return 1
@@ -228,6 +235,7 @@
/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, show_message = 1)
if(cult_mind in cult)
cult -= cult_mind
+ cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm
cult_mind.current << "\red An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it."
cult_mind.memory = ""
cult_mind.cult_words = initial(cult_mind.cult_words)
@@ -294,11 +302,11 @@
/datum/game_mode/cult/proc/check_cult_victory()
var/cult_fail = 0
- if(objectives.Find("survive"))
+ if(cult_objectives.Find("survive"))
cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise
- if(objectives.Find("eldergod"))
+ if(cult_objectives.Find("eldergod"))
cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once
- if(objectives.Find("sacrifice"))
+ if(cult_objectives.Find("sacrifice"))
if(sacrifice_target && !sacrificed.Find(sacrifice_target)) //if the target has been sacrificed, ignore this step. otherwise, add 1 to cult_fail
cult_fail++
@@ -331,11 +339,11 @@
var/text = "Cultists escaped: [acolytes_survived]"
- if(objectives.len)
+ if(cult_objectives.len)
text += "
The cultists' objectives were:"
- for(var/obj_count=1, obj_count <= objectives.len, obj_count++)
+ for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++)
var/explanation
- switch(objectives[obj_count])
+ switch(cult_objectives[obj_count])
if("survive")
if(!check_survive())
explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. Success!"
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 0f0b2543fe6..1a3e6e188cd 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -24,6 +24,51 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
runerandom()
usr << "[wordtravel] is travel, [wordblood] is blood, [wordjoin] is join, [wordhell] is Hell, [worddestr] is destroy, [wordtech] is technology, [wordself] is self, [wordsee] is see, [wordother] is other, [wordhide] is hide."
+/mob/proc/cult_add_comm()
+ verbs += /mob/living/proc/cult_innate_comm
+
+/mob/living/proc/cult_innate_comm()
+ set category = "Cultist"
+ set name = "Communicate"
+
+ #define CHECK_STATUS (usr.stat || usr.restrained() || usr.paralysis || usr.stunned || usr.weakened)
+
+ if(!iscultist(usr)) //they shouldn't have this verb, but just to be sure...
+ return
+
+ if(CHECK_STATUS)
+ return //dead men tell no tales
+
+ var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "")
+ if(!input) // TO-DO: Add some kind of filter to corrupt the inputted text
+ return
+
+ if(ishuman(usr) || ismonkey(usr)) //Damage only applies to humans and monkeys, to allow constructs to communicate
+ usr.visible_message("[usr.name] starts clawing at his arms like a mad man!")
+ apply_damage(25,BRUTE, "l_arm")
+ apply_damage(25,BRUTE, "r_arm")
+ sleep(50)
+ if(CHECK_STATUS)
+ return //Hard to drawn intrinsic symbols when you're bleeding out in your cell.
+ var/turf/location = loc
+ if(istype(location, /turf/simulated)) // tearing your arms apart is going to spill a bit of blood, in fact thats the idea
+ location.add_blood(usr) // TO-DO change this to a badly drawn rune
+ apply_damage(15,BRUTE, "l_arm") // does a metric fuck ton of damage because this meant to be an emergency method of communication.
+ apply_damage(15,BRUTE, "r_arm")
+ if(CHECK_STATUS)
+ return //dead men tell no tales
+ usr.visible_message("[usr.name] paints strange symbols with their own blood")
+ sleep(20)
+
+ usr.say("O bidai nabora se[pick("'","`")]sma!")
+ sleep(10)
+ usr.say("[input]")
+ for(var/datum/mind/H in ticker.mode.cult)
+ if (H.current)
+ H.current << "\red \b [input]"
+ return
+ #undef CHECK_STATUS
+
/proc/runerandom() //randomizes word meaning
var/list/runewords=list("ire","ego","nahlizet","certum","veri","jatkaa","mgar","balaq", "karazet", "geeri") ///"orkan" and "allaq" removed.
@@ -134,7 +179,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
return
- attack_hand(mob/living/user as mob)
+ attack_hand(mob/living/user as mob) // OH GOD this is horrible
if(!iscultist(user))
user << "You can't mouth the arcane scratchings without fumbling over them."
return
@@ -193,6 +238,8 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
return itemport(src.word3)
if(word1 == wordjoin && word2 == wordhide && word3 == wordtech)
return runestun()
+ if(word1 == wordtravel && word2 == wordhell && word3 == wordtech)
+ return summon_shell()
else
user.take_overall_damage(30, 0)
user << "\red You feel the life draining from you, as if Lord Nar-Sie is displeased with you."
@@ -311,6 +358,7 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
var/tomedat = ""
var/list/words = list("ire" = "ire", "ego" = "ego", "nahlizet" = "nahlizet", "certum" = "certum", "veri" = "veri", "jatkaa" = "jatkaa", "balaq" = "balaq", "mgar" = "mgar", "karazet" = "karazet", "geeri" = "geeri")
+
tomedat = {"