-
Notifications
You must be signed in to change notification settings - Fork 541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new midround antag: the divergent clone #37334
Changes from all commits
c9c870b
01f7d54
e94ec95
3628fe5
0576371
1d992e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1095,3 +1095,84 @@ | |
requirements = list(10,10,10,10,10,10,10,10,10,10) | ||
logo = "gun-logo" | ||
repeatable = TRUE | ||
|
||
////////////////////////////////////////////// | ||
// // | ||
// DIVERGENT CLONE // | ||
// // | ||
////////////////////////////////////////////// | ||
|
||
/datum/dynamic_ruleset/midround/from_ghosts/divergentclone | ||
name = "Divergent Clone" | ||
role_category = /datum/role/divergentclone | ||
required_candidates = 1 | ||
weight = 3 | ||
weight_category = "Clone" | ||
cost = 5 | ||
requirements = list(40,30,20,10,10,10,10,10,10,10) | ||
high_population_requirement = 10 | ||
logo = "divergentclone-logo" | ||
repeatable = TRUE | ||
makeBody = FALSE | ||
flags = MINOR_RULESET | ||
|
||
/datum/dynamic_ruleset/midround/from_ghosts/divergentclone/trim_candidates() | ||
..() | ||
for(var/mob/M in dead_players) | ||
if(isdivergentclone(M)) | ||
dead_players -= M | ||
for(var/mob/M in list_observers) | ||
if(isdivergentclone(M)) | ||
list_observers -= M | ||
|
||
|
||
/datum/dynamic_ruleset/midround/from_ghosts/divergentclone/ready(var/forced = 0) | ||
if(!config.revival_cloning) | ||
return 0 | ||
|
||
//Check that we have at least one ghost who isn't already a clone waiting to spawn | ||
var/list/candies = dead_players + list_observers | ||
var/list/valids[0] | ||
for(var/mob/dead/observer/G in candies) | ||
if(isdivergentclone(G)) | ||
continue | ||
valids += G | ||
if(valids.len == 0) | ||
if(forced) | ||
message_admins("Tried to force divergent clone, but no valid candidates found.") | ||
return 0 | ||
|
||
var/list/clonepods = list() | ||
for(var/obj/machinery/cloning/clonepod/pod in machines) | ||
//Check that the pod has cloned something before | ||
if(pod.cloned_records.len) | ||
clonepods += pod | ||
if(!forced && clonepods.len == 0) | ||
return 0 | ||
return ..() | ||
|
||
/datum/dynamic_ruleset/midround/from_ghosts/divergentclone/finish_setup(mob/new_character, index) | ||
//Create a new dummy body to create a new mind for the ghost. | ||
var/L = get_turf(new_character) | ||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(pick(latejoin)) | ||
H.ckey = new_character.ckey | ||
H.fully_replace_character_name(null, "\improper spirit of a divergent clone") | ||
|
||
//Give the about-to-be-a-ghost mob the provisional role and objective | ||
var/datum/role/divergentclone/new_role = new /datum/role/divergentclone(H.mind, override=TRUE) | ||
new_role.ForgeObjectives() | ||
new_role.AnnounceObjectives() | ||
|
||
var/mob/dead/observer/G = H.ghostize(FALSE) | ||
//Give it a more spirity looking icon. | ||
G.icon = initial(G.icon) | ||
G.icon_state = initial(G.icon_state) | ||
QDEL_NULL(H) | ||
G.forceMove(L) | ||
G.add_spell(new /spell/targeted/ghost/divergentclone) | ||
|
||
to_chat(G, "<span class='notice'><b>You were selected to be a divergent clone, but will not be spawned in yet!</b></span>") | ||
to_chat(G, "<span class='notice'>You have been granted the \"Spawn as Divergent Clone\" ghost spell. Use this near a cloning pod to spawn in as a divergent clone of someone who was cloned, or is currently being cloned, in that pod.</span>") | ||
to_chat(G, "<span class='notice'>Using this spell on an unoccupied cloning pod will allow you to choose a record of a person previously cloned in that pod. Using it on an occupied pod will cause you to become a twin of the person currently in the pod, and be ejected from the pod at the same time as them.</span>") | ||
to_chat(G, "<span class='notice'>Remember: you can only use this spell once, and re-entering your corpse will remove it permanently. In fact, for your convenience we have removed your ability to re-enter your corpse.</span>") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure about this - I haven't gotten to the code for this yet but if this role is randomly assigned to someone do they immediately lose the ability to re-enter their corpse? That could be a huge bummer for someone who is having a fun round and wants to be revived while keeping the option open for this role. Maybe make it so that they lose the ability to enter their corpse if they accept this role when prompted? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how to best handle this, but I think the way I'm doing it already is the least worst option. Like, you lose the ability to re-enter your corpse if you get auto-accepted as a ninja or catbeast. The intent here is the same. Allowing someone to reincarnate after they get this role would mean that the role is wasted, and there aren't good frameworks in place in dynamic to monitor if this happens so that threat could be refunded or the role could be passed to the next person (the only solution that doesn't involve massive amounts of new code would be an infinite loop that runs until the ghost either spawns as a divergent clone or gets resurrected and checks their status every time, and I don't like that). |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/datum/objective/freeform/divergentclone_neutral | ||
explanation_text = "Convince the world that you are the real <person>, or at least as real as the other copy." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What did he mean by this?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is mostly just a placeholder/sanity thing. The actual text gets set in PostAppend. |
||
|
||
/datum/objective/freeform/divergentclone_neutral/format_explanation() | ||
return "Convince the world that you are the real [owner.name], or at least as real as the other copy." | ||
|
||
/datum/objective/freeform/divergentclone_neutral/PostAppend() | ||
explanation_text = format_explanation() | ||
return TRUE | ||
|
||
/datum/objective/freeform/divergentclone_evil | ||
explanation_text = "Convince the world that you are the real <person> at any cost, be that by talk, violence or subterfuge. Do not let anyone get in your way, including your original copy." | ||
|
||
/datum/objective/freeform/divergentclone_evil/format_explanation() | ||
return "Convince the world that you are the real [owner.name] at any cost, be that by talk, violence or subterfuge. Do not let anyone get in your way, including your original copy." | ||
|
||
/datum/objective/freeform/divergentclone_evil/PostAppend() | ||
explanation_text = format_explanation() | ||
return TRUE | ||
|
||
/datum/objective/divergentclone/spawn_in | ||
explanation_text = "Reincarnate as a divergent clone." | ||
name = "Reincarnate" | ||
|
||
/datum/objective/divergentclone/spawn_in/IsFulfilled() | ||
if(..()) | ||
return TRUE | ||
if(!owner || !owner.current) | ||
return FALSE | ||
|
||
var/datum/role/divergentclone/role = owner.GetRole(DIVERGENTCLONE) | ||
if(role?.has_spawned_in) | ||
return TRUE | ||
|
||
/datum/objective/acquire_personal_id | ||
explanation_text = "Acquire an ID card matching your name or DNA." | ||
name = "Acquire personal ID card" | ||
|
||
/datum/objective/acquire_personal_id/IsFulfilled() | ||
if(..()) | ||
return TRUE | ||
|
||
if(!owner || !owner.current) | ||
return FALSE | ||
|
||
for(var/obj/O in get_contents_in_object(owner.current)) | ||
var/obj/item/weapon/card/id/I | ||
if(istype(O, /obj/item/weapon/card/id)) | ||
I = O | ||
else if(istype(O, /obj/item/device/pda)) | ||
var/obj/item/device/pda/P = O | ||
I = P.id | ||
else | ||
continue | ||
var/datum/dna/D = owner.current.dna | ||
if((I?.dna_hash == D.unique_enzymes) || (I?.registered_name == owner.name)) | ||
return TRUE | ||
|
||
return FALSE | ||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These procs should fire under /datum/role/divergentclone/New() instead of being called here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I agree that might make sense, it also seems that no other role does this, so I chose not to do it here either. I'm assuming it's to allow admins to add the role to people without it instantly creating objectives or announcing the objectives to them.