Files
S.P.L.U.R.T-Station-13/code/game/gamemodes/clock_cult/clock_cult.dm
Poojawa 6674f9fc15 Tg 2 11 sync (#215)
* first series of updates

* datums

* games folder

* admin and atmosia stuffs

* moar

* mob updates borg riding

* sprites and stuff

* fixes for various things

* oops. some missed fixes
2017-02-12 03:56:14 -06:00

247 lines
11 KiB
Plaintext

/*
CLOCKWORK CULT: Based off of the failed pull requests from /vg/
While Nar-Sie is the oldest and most prominent of the elder gods, there are other forces at work in the universe.
Ratvar, the Clockwork Justiciar, a homage to Nar-Sie granted sentience by its own power, is one such other force.
Imprisoned within a massive construct known as the Celestial Derelict - or Reebe - an intense hatred of the Blood God festers.
Ratvar, unable to act in the mortal plane, seeks to return and forms covenants with mortals in order to bolster his influence.
Due to his mechanical nature, Ratvar is also capable of influencing silicon-based lifeforms, unlike Nar-Sie, who can only influence natural life.
This is a team-based gamemode, and the team's objective is shared by all cultists. It can include summoning Ratvar, escaping on the shuttle, or converting the AI and its cyborgs.
The clockwork version of an arcane tome is the clockwork slab.
While it can perform certain actions, it consumes a resource called components.
Components, which are fallen fragments of Ratvar's body as he rusts in Reebe, are powerful and have various effects.
Game-wise, clockwork slabs will generate components over time, with more powerful components being slower.
This file's folder contains:
clock_cult.dm: Core gamemode files.
clock_effect.dm: The base clockwork effect code.
- Effect files are in game/gamemodes/clock_cult/clock_effects/
clock_item.dm: The base clockwork item code.
- Item files are in game/gamemodes/clock_cult/clock_items/
clock_mobs.dm: Hostile clockwork creatures.
clock_scripture.dm: The base Scripture code.
- Scripture files are in game/gamemodes/clock_cult/clock_scripture/
clock_structure.dm: The base clockwork structure code, including clockwork machines.
- Structure files, and Ratvar, are in game/gamemodes/clock_cult/clock_structures/
game/gamemodes/clock_cult/clock_helpers/ contains several helper procs, including the Ratvarian language.
clockcult defines are in __DEFINES/clockcult.dm
Credit where due:
1. VelardAmakar from /vg/ for the entire design document, idea, and plan. Thank you very much.
2. SkowronX from /vg/ for MANY of the assets
3. FuryMcFlurry from /vg/ for many of the assets
4. PJB3005 from /vg/ for the failed continuation PR
5. Xhuis from /tg/ for coding the basic gamemode as it is today
6. ChangelingRain from /tg/ for maintaining the gamemode for months after its release
*/
///////////
// PROCS //
///////////
/proc/is_servant_of_ratvar(mob/living/M)
return istype(M) && M.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
/proc/is_eligible_servant(mob/living/M)
if(!istype(M))
return FALSE
if(M.mind)
if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
return FALSE
if(M.mind.enslaved_to && !is_servant_of_ratvar(M.mind.enslaved_to))
return FALSE
else
return FALSE
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
return FALSE
if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab))
return TRUE
return FALSE
/proc/add_servant_of_ratvar(mob/living/L, silent = FALSE)
var/update_type = /datum/antagonist/clockcultist
if(silent)
update_type = /datum/antagonist/clockcultist/silent
. = L.gain_antag_datum(update_type)
/proc/remove_servant_of_ratvar(mob/living/L, silent = FALSE)
var/datum/antagonist/clockcultist/clock_datum = L.has_antag_datum(/datum/antagonist/clockcultist, TRUE)
if(!clock_datum)
return FALSE
clock_datum.silent_update = silent
clock_datum.on_remove()
return TRUE
///////////////
// GAME MODE //
///////////////
/datum/game_mode
var/list/servants_of_ratvar = list() //The Enlightened servants of Ratvar
var/clockwork_objective = CLOCKCULT_GATEWAY //The objective that the servants must fulfill
var/clockwork_explanation = "Construct a Gateway to the Celestial Derelict and free Ratvar." //The description of the current objective
/datum/game_mode/clockwork_cult
name = "clockwork cult"
config_tag = "clockwork_cult"
antag_flag = ROLE_SERVANT_OF_RATVAR
required_players = 10
required_enemies = 3
recommended_enemies = 3
enemy_minimum_age = 14
protected_jobs = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain") //Silicons can eventually be converted
restricted_jobs = list("Chaplain", "Captain")
announce_span = "brass"
announce_text = "Servants of Ratvar are trying to summon the Justiciar!\n\
<span class='brass'>Servants</span>: Take over the station and summon Ratvar.\n\
<span class='notice'>Crew</span>: Stop the servants before they can summon the Clockwork Justiciar."
var/servants_to_serve = list()
var/roundstart_player_count
/datum/game_mode/clockwork_cult/pre_setup()
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
restricted_jobs += "Assistant"
var/starter_servants = 3 //Guaranteed three servants
var/number_players = num_players()
roundstart_player_count = number_players
if(number_players > 30) //plus one servant for every additional 15 players
number_players -= 30
starter_servants += round(number_players/15)
while(starter_servants)
var/datum/mind/servant = pick(antag_candidates)
servants_to_serve += servant
antag_candidates -= servant
modePlayer += servant
servant.special_role = "Servant of Ratvar"
servant.restricted_roles = restricted_jobs
starter_servants--
return 1
/datum/game_mode/clockwork_cult/post_setup()
forge_clock_objectives()
for(var/S in servants_to_serve)
var/datum/mind/servant = S
log_game("[servant.key] was made an initial servant of Ratvar")
var/mob/living/L = servant.current
greet_servant(L)
equip_servant(L)
add_servant_of_ratvar(L, TRUE)
..()
return 1
/datum/game_mode/clockwork_cult/proc/forge_clock_objectives() //Determine what objective that Ratvar's servants will fulfill
var/list/possible_objectives = list(CLOCKCULT_ESCAPE, CLOCKCULT_GATEWAY)
clockwork_objective = pick(possible_objectives)
switch(clockwork_objective)
if(CLOCKCULT_ESCAPE)
clockwork_explanation = "Construct a Gateway to the Celestial Derelict and proselytize the entire station."
if(CLOCKCULT_GATEWAY)
clockwork_explanation = "Construct a Gateway to the Celestial Derelict and free Ratvar."
return 1
/datum/game_mode/clockwork_cult/proc/greet_servant(mob/M) //Description of their role
if(!M)
return 0
var/greeting_text = "<br><b><span class='large_brass'>You are a servant of Ratvar, the Clockwork Justiciar.</span>\n\
Rusting eternally in the Celestial Derelict, Ratvar has formed a covenant of mortals, with you as one of its members. As one of the Justiciar's servants, you are to work to the best of your \
ability to assist in completion of His agenda. You may not know the specifics of how to do so, but luckily you have a vessel to help you learn.</b>"
M << greeting_text
return 1
/datum/game_mode/proc/equip_servant(mob/living/L) //Grants a clockwork slab to the mob, with one of each component
if(!L || !istype(L))
return FALSE
var/obj/item/clockwork/slab/starter/S = new/obj/item/clockwork/slab/starter(null) //start it off in null
var/slot = "At your feet"
var/list/slots = list("In your left pocket" = slot_l_store, "In your right pocket" = slot_r_store, "In your backpack" = slot_in_backpack, "On your belt" = slot_belt)
if(ishuman(L))
var/mob/living/carbon/human/H = L
slot = H.equip_in_one_of_slots(S, slots)
if(slot == "In your backpack")
slot = "In your [H.back.name]"
if(slot == "At your feet")
if(!S.forceMove(get_turf(L)))
qdel(S)
if(S && !QDELETED(S))
L << "<b>[slot] is a link to the halls of Reebe and your master. You may use it to perform many tasks, but also become oriented with the workings of Ratvar and how to best complete your \
tasks. This clockwork slab will be instrumental in your triumph. Remember: you can speak discreetly with your fellow servants by using the <span class='brass'>Hierophant Network</span> action button, \
and you can find a concise tutorial by using the slab in-hand and selecting Recollection.</b>"
L << "<i>Alternatively, check out the wiki page at </i><b>https://tgstation13.org/wiki/Clockwork_Cult</b><i>, which contains additional information.</i>"
return TRUE
return FALSE
/datum/game_mode/clockwork_cult/proc/present_tasks(mob/living/L) //Memorizes and displays the clockwork cult's objective
if(!L || !istype(L) || !L.mind)
return 0
var/datum/mind/M = L.mind
M.current << "<b>This is Ratvar's will:</b> [clockwork_explanation]"
M.memory += "<b>Ratvar's will:</b> [clockwork_explanation]<br>"
return 1
/datum/game_mode/clockwork_cult/proc/check_clockwork_victory()
switch(clockwork_objective)
if(CLOCKCULT_ESCAPE)
if(clockwork_gateway_activated)
ticker.news_report = CLOCK_PROSELYTIZATION
return TRUE
if(CLOCKCULT_GATEWAY)
if(ratvar_awakens)
ticker.news_report = CLOCK_SUMMON
return TRUE
ticker.news_report = CULT_FAILURE
return FALSE
/datum/game_mode/clockwork_cult/declare_completion()
..()
return 0 //Doesn't end until the round does
/datum/game_mode/proc/auto_declare_completion_clockwork_cult()
var/text = ""
if(istype(ticker.mode, /datum/game_mode/clockwork_cult)) //Possibly hacky?
var/datum/game_mode/clockwork_cult/C = ticker.mode
if(C.check_clockwork_victory())
text += "<span class='large_brass'><b>Ratvar's servants have succeeded in fulfilling His goals!</b></span>"
feedback_set_details("round_end_result", "win - servants completed their objective ([clockwork_objective])")
else
var/half_victory = FALSE
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in all_clockwork_objects
if(G)
half_victory = TRUE
if(half_victory)
text += "<span class='large_brass'><b>The crew escaped before [clockwork_objective == CLOCKCULT_GATEWAY ? "Ratvar could rise":"the station could be proselytized"], but the gateway \
was successfully constructed!</b></span>"
feedback_set_details("round_end_result", "halfwin - round ended before the gateway finished")
else
text += "<span class='userdanger'>Ratvar's servants have failed!</span>"
feedback_set_details("round_end_result", "loss - servants failed their objective ([clockwork_objective])")
text += "<br><b>The servants' objective was:</b> <br>[clockwork_explanation]"
text += "<br>Ratvar's servants had <b>[clockwork_caches]</b> Tinkerer's Caches."
text += "<br><b>Construction Value(CV)</b> was: <b>[clockwork_construction_value]</b>"
var/list/scripture_states = scripture_unlock_check()
for(var/i in scripture_states)
if(i != SCRIPTURE_DRIVER)
text += "<br><b>[i] scripture</b> was: <b>[scripture_states[i] ? "UN":""]LOCKED</b>"
if(servants_of_ratvar.len)
text += "<br><b>Ratvar's servants were:</b>"
for(var/datum/mind/M in servants_of_ratvar)
text += printplayer(M)
world << text
/datum/game_mode/proc/update_servant_icons_added(datum/mind/M)
var/datum/atom_hud/antag/A = huds[ANTAG_HUD_CLOCKWORK]
A.join_hud(M.current)
set_antag_hud(M.current, "clockwork")
/datum/game_mode/proc/update_servant_icons_removed(datum/mind/M)
var/datum/atom_hud/antag/A = huds[ANTAG_HUD_CLOCKWORK]
A.leave_hud(M.current)
set_antag_hud(M.current, null)