diff --git a/code/__DEFINES/~skyrat_defines/ambitions.dm b/code/__DEFINES/~skyrat_defines/ambitions.dm new file mode 100644 index 00000000000..c5066594580 --- /dev/null +++ b/code/__DEFINES/~skyrat_defines/ambitions.dm @@ -0,0 +1,31 @@ +#define AMBITION_INTENSITY_STEALTH 2 +#define AMBITION_INTENSITY_MILD 3 +#define AMBITION_INTENSITY_MEDIUM 5 +#define AMBITION_INTENSITY_SEVERE 12 +#define AMBITION_INTENSITY_EXTREME 20 + +#define ADMIN_TPMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_JMP(user)] [ADMIN_FLW(user)]" +#define ADMIN_TPMONTY(user) "[key_name_admin(user)] [ADMIN_TPMONTY_NONAME(user)]" + +GLOBAL_LIST_EMPTY(ambitions_to_review) +GLOBAL_VAR_INIT(total_intensity, 0) +GLOBAL_LIST_INIT(intensity_counts, setup_intensity_count_list()) +GLOBAL_LIST_INIT(ambitions_templates, setup_ambition_templates()) + +/proc/setup_intensity_count_list() + var/list/LI = list() + LI["[AMBITION_INTENSITY_STEALTH]"] = 0 + LI["[AMBITION_INTENSITY_MILD]"] = 0 + LI["[AMBITION_INTENSITY_MEDIUM]"] = 0 + LI["[AMBITION_INTENSITY_SEVERE]"] = 0 + LI["[AMBITION_INTENSITY_EXTREME]"] = 0 + return LI + +/proc/setup_ambition_templates() + var/list/LI = list() + for(var/path in subtypesof(/datum/ambition_template)) + var/datum/ambition_template/P = path + if(initial(P.name)) + P = new path() + LI[P.name] = P + return LI diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 89c343b2616..bea4f88b46e 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -555,6 +555,27 @@ currrent_category = A.roundend_category previous_category = A result += A.roundend_report() + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + if(A.owner && A.owner.my_ambitions) + var/datum/ambitions/AMB = A.owner.my_ambitions + result += "
Narrative: [AMB.narrative]" + result += "
Objectives:" + for(var/stri in AMB.objectives) + result += "
* [stri]" + var/intensity = "NOT SET" + switch(AMB.intensity) + if(AMBITION_INTENSITY_STEALTH) + intensity = "Stealth" + if(AMBITION_INTENSITY_MILD) + intensity = "Mild" + if(AMBITION_INTENSITY_MEDIUM) + intensity = "Medium" + if(AMBITION_INTENSITY_SEVERE) + intensity = "Severe" + if(AMBITION_INTENSITY_EXTREME) + intensity = "Extreme" + result += "
Intensity: [intensity]" + //SKYRAT EDIT ADDITION END - AMBITIONS result += "

" CHECK_TICK diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 2acf74d9881..0fd493a9dc9 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -117,6 +117,11 @@ var/mob/living/old_current = current if(current) current.transfer_observers_to(new_character) //transfer anyone observing the old character to the new one + //SKYRAT CHANGE ADDITION BEGIN - AMBITIONS + if(my_ambitions) + remove_verb(current, /mob/proc/view_ambitions) + add_verb(new_character, /mob/proc/view_ambitions) + //SKYRAT CHANGE ADDITION END current = new_character //associate ourself with our new body new_character.mind = src //and associate our new body with ourself for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body @@ -258,6 +263,15 @@ antag_team.add_member(src) INVOKE_ASYNC(A, /datum/antagonist.proc/on_gain) log_game("[key_name(src)] has gained antag datum [A.name]([A.type])") + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + if(A.uses_ambitions) + if(!my_ambitions) + my_ambitions = new(src) + add_verb(current, /mob/proc/view_ambitions) + //If we already have ambitions done, call the add proc to give us the proper powers/uplinks + if(my_ambitions.submitted) + A.ambitions_add() + //SKYRAT EDIT ADDITION END return A /datum/mind/proc/remove_antag_datum(datum_type) @@ -266,6 +280,10 @@ var/datum/antagonist/A = has_antag_datum(datum_type) if(A) A.on_removal() + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + if(A.uses_ambitions && my_ambitions.submitted) + A.ambitions_removal() + //SKYRAT EDIT ADDITION END return TRUE @@ -346,6 +364,10 @@ var/mob/living/carbon/human/traitor_mob = current if (!istype(traitor_mob)) return + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS (no doubling uplinks) + if(find_syndicate_uplink()) + return + //SKYRAT EDIT ADDITION END var/list/all_contents = traitor_mob.GetAllContents() var/obj/item/pda/PDA = locate() in all_contents @@ -634,6 +656,13 @@ else if (href_list["obj_announce"]) announce_objectives() + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + if (href_list["ambitions"]) + if(!my_ambitions) + return + //It's admin viewing the user's ambitions. The user can view them through a verb. + my_ambitions.ShowPanel(usr, TRUE) + //SKYRAT EDIT ADDITION END //Something in here might have changed your mob if(self_antagging && (!usr || !usr.client) && current.client) diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index 19e53b09b45..f34130609db 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -101,6 +101,10 @@ GLOBAL_VAR(antag_prototypes) out += "Mind currently owned by key: [key] [active?"(synced)":"(not synced)"]
" out += "Assigned role: [assigned_role]. Edit
" out += "Faction and special role: [special_role]
" + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + if(my_ambitions) + out += "Ambitions: View
" + //SKYRAT EDIT ADDITION END var/special_statuses = get_special_statuses() if(length(special_statuses)) diff --git a/code/modules/admin/check_antagonists.dm b/code/modules/admin/check_antagonists.dm index 5a4b78d9279..5eca7208b12 100644 --- a/code/modules/admin/check_antagonists.dm +++ b/code/modules/admin/check_antagonists.dm @@ -34,6 +34,24 @@ else parts += "" parts += "Show Objective" + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + if(uses_ambitions && owner.current && owner.current.mind && owner.current.mind.my_ambitions) + var/datum/ambitions/ambs = owner.current.mind.my_ambitions + var/string = "NOT SUBMITTED" + if(ambs.submitted) + switch(ambs.intensity) + if(AMBITION_INTENSITY_STEALTH) + string = "Stealth" + if(AMBITION_INTENSITY_MILD) + string = "Mild" + if(AMBITION_INTENSITY_MEDIUM) + string = "Medium" + if(AMBITION_INTENSITY_SEVERE) + string = "Severe" + if(AMBITION_INTENSITY_EXTREME) + string = "Extreme" + parts += "Ambitions-[string]" + //SKYRAT EDIT ADDITION END return parts //Better as one cell or two/three //Builds table row for the antag diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index ba677de477e..668725fe79f 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -107,6 +107,14 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick)) L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick)) L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick)) + + //SKYRAT EDIT ADDITION BEGIN - AMBITIONS + for(var/key in GLOB.ambitions_to_review) + var/datum/ambitions/AMBI = key + var/reviewer = GLOB.ambitions_to_review[key] + L[++L.len] = list("[reviewer ? "H-[reviewer]. " : ""]AMB: [AMBI.owner_name]:", "[AMBI.narrative]", REF(AMBI)) + L[++L.len] = list("Ambitions intensity:", "STL:[GLOB.intensity_counts["[AMBITION_INTENSITY_STEALTH]"]] MLD:[GLOB.intensity_counts["[AMBITION_INTENSITY_MILD]"]] MED:[GLOB.intensity_counts["[AMBITION_INTENSITY_MEDIUM]"]] SEV:[GLOB.intensity_counts["[AMBITION_INTENSITY_SEVERE]"]] EXT:[GLOB.intensity_counts["[AMBITION_INTENSITY_EXTREME]"]] (HAVOC: [GLOB.total_intensity])", null) + //SKYRAT EDIT ADDITION END return L //Reassociate still open ticket if one exists diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 59706871fa3..2207283b226 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -67,9 +67,13 @@ emporium_action.Grant(owner.current) /datum/antagonist/changeling/on_gain() + //SKYRAT EDIT REMOVAL BEGIN - AMBITIONS + /* create_actions() reset_powers() create_initial_profile() + */ + //SKYRAT EDIT REMOVAL END if(give_objectives) forge_objectives() owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all. @@ -83,7 +87,11 @@ if(B && (B.decoy_override != initial(B.decoy_override))) B.organ_flags |= ORGAN_VITAL B.decoy_override = FALSE + //SKYRAT EDIT REMOVAL BEGIN - AMBITIONS + /* remove_changeling_powers() + */ + //SKYRAT EDIT REMOVAL END . = ..() /datum/antagonist/changeling/proc/reset_properties() @@ -371,6 +379,7 @@ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ling_aler.ogg', 100, FALSE, pressure_affected = FALSE) owner.announce_objectives() + ..() //SKYRAT EDIT ADDITION - AMBITIONS /datum/antagonist/changeling/farewell() to_chat(owner.current, "You grow weak and lose your powers! You are no longer a changeling and are stuck in your current form!") @@ -381,6 +390,10 @@ //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone + + objectives += new /datum/objective/ambitions() //SKYRAT EDIT ADDITION - AMBITIONS + //SKYRAT EDIT REMOVAL BEGIN - AMBITIONS + /* var/escape_objective_possible = TRUE switch(competitive_objectives ? rand(1,3) : 1) @@ -447,6 +460,8 @@ identity_theft.find_target() objectives += identity_theft escape_objective_possible = FALSE + */ + //SKYRAT EDIT REMOVAL END /datum/antagonist/changeling/admin_add(datum/mind/new_owner,mob/admin) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index cc5014a114b..abf75d8b22a 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -55,11 +55,16 @@ objectives -= O /datum/antagonist/traitor/proc/forge_traitor_objectives() + add_objective(new /datum/objective/ambitions()) //SKYRAT EDIT ADDITION - AMBITIONS + //SKYRAT EDIT REMOVAL BEGIN - AMBITIONS + /* switch(traitor_kind) if(TRAITOR_AI) forge_ai_objectives() else forge_human_objectives() + */ + //SKYRAT EDIT REMOVAL END /datum/antagonist/traitor/proc/forge_human_objectives() var/is_hijacker = FALSE @@ -187,6 +192,7 @@ owner.announce_objectives() if(should_give_codewords) give_codewords() + ..() //SKYRAT EDIT ADDITION - AMBITIONS /datum/antagonist/traitor/proc/finalize_traitor() switch(traitor_kind) @@ -195,8 +201,12 @@ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE) owner.current.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MALF) if(TRAITOR_HUMAN) + //SKYRAT EDIT REMOVAL BEGIN - AMBITIONS + /* if(should_equip) equip(silent) + */ + //SKYRAT EDIT REMOVAL END owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE) /datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override) diff --git a/modular_skyrat/modules/ambitions/code/ambition.dm b/modular_skyrat/modules/ambitions/code/ambition.dm new file mode 100644 index 00000000000..48760473de7 --- /dev/null +++ b/modular_skyrat/modules/ambitions/code/ambition.dm @@ -0,0 +1,415 @@ +/datum/ambitions + ///Reasons of why would you act in antagonic ways + var/narrative = "" + ///List of your objectives, in string form + var/list/objectives = list() + ///Chosen intensity of your antagonism + var/intensity = 0 + ///Note in which you can optionally write out your vision/reasonings, useful if you want it to get reviewed + var/note_to_admins = "" + ///Whether it was submitted or not + var/submitted = FALSE + ///Whether we requested an admin review + var/admin_review_requested = FALSE + ///Whether an admin approved our ambitions. + var/admin_approval = FALSE + ///If we changed our ambitions after approval + var/changed_after_approval = FALSE + ///Log of changes made to the ambitions + var/list/log = list("Ambition Logs:") + ///The mind the ambitions belong to + var/datum/mind/my_mind + ///The original name of our character + var/owner_name + ///The last change requested by an admin, if a review was asked for + var/last_requested_change + +/datum/ambitions/New(datum/mind/M) + my_mind = M + if(my_mind.current.client) + owner_name = key_name(my_mind.current.client, FALSE, TRUE) + else + owner_name = my_mind.current.real_name + //Greet our antag player and give him a link to open ambitions! + to_chat(my_mind.current, "You're a story driven antagonist, this means you'll have to fill ambitions before you start antagonising!") + to_chat(my_mind.current, "After filling them out you'll get access to your uplink or powers.") + to_chat(my_mind.current, "Click here to set your ambitions, or access them at any time from your IC tab.") + +/datum/ambitions/proc/ShowPanel(mob/user, admin_view = FALSE) + if(!user || !user.client) + return + var/list/dat = list("
") + if(admin_view) + dat += "

Admin View Options:

" + dat += "Down below you have [owner_name]'s ambitions." + if(admin_review_requested) + dat += "
They have requested an admin review." + if(admin_approval) + dat += "
...and it was granted!" + if(changed_after_approval) + dat += "
...however they changed their ambitions after that, see logs for more info." + else + dat += "
They have NOT requested an admin review." + dat += "
" + if(admin_review_requested && (!admin_approval || changed_after_approval)) + dat += "Approve Handle Request Changes Discard -" + dat += " Logs" + dat += "
" + + dat += "Antagonists are supposed to provide excitement and intrigue, drive a story with the crew, and provide fun and interesting experience for people involved.
Remember, it's not about winning or losing, but about the story and interactions, this is a roleplay server.


" + dat += "Here you write your ambitions for your antagonist round! Ambitions are your motive and what you plan to accomplish throught the round." + dat += "
After filling all things out and submitting your ambition, your uplink/powers will unlock." + dat += "
If you can't come up with anything, use a template, and if you don't know if your ambition are proper, or too extreme, request admin review." + dat += "
You can still edit them post submission." + dat += "
If your ambitions are nonsensical, you may be subjected to an antagonist ban." + var/review_link = (is_proper_ambitions() && !admin_review_requested) ? "href='?src=[REF(src)];pref=request_review'" : "class='linkOff'" + var/submit_link = "class='linkOff'" + if(!is_proper_ambitions()) + dat += "
Before you'll be able to submit your ambitions, you need to fill narratives, objectives and intensity.
" + else if(admin_review_requested && !admin_approval) + dat += "
You've requested admin approval, ambitions will automatically be submitted after approval.
" + else if(!submitted) + submit_link = "href='?src=[REF(src)];pref=submit'" + else + dat += "
You've already submitted your ambitions, but feel free to edit them.
" + dat += "
Submit Choose template Request admin review (optional)
" + dat += "
" + if(changed_after_approval) + dat += "
Some fields were changed after an admin approval." + if(last_requested_change) + dat += "
Requested changes:" + dat += "
[last_requested_change]" + dat += "
Notify admin that you've done them!" + dat += "

Narrative:

" + dat += "Here you set your narrative. It's the reason on why you're doing antagonistic things. Perhaps you need money for personal reasons, or you were contracted to do someone's dirty work, or want to take down the BigPharma." + dat += "
" + if(narrative == "") + dat += "Please set your narrative!" + else + dat += narrative + dat += "
Set your narrative
" + dat += "
" + dat += "
" + dat += "

Objectives:

" + dat += "Here you add your objectives. Think about them as milestones to your narratives." + dat += "
" + if(length(objectives)) + var/even = TRUE + var/index = 0 + for(var/objectiv in objectives) + index++ + even = !even + var/bg_color = "#23273C" + if(even) + bg_color = "#19222C" + dat += "" + else + dat += "" + dat += "" + dat += "
* [objectiv] Edit Remove
Please add atleast one objective!
Add new objective
" + dat += "
" + dat += "

Intensity:

" + dat += "Set the estimated intensity of your ambitions, this helps the admins gauge on how chaotic a round may be. Please set it accordingly." + if(intensity == 0) + dat += "
Please set your intensity!
" + dat += "" + dat += "" + for(var/i in 1 to 5) + var/current_spice + switch(i) + if(1) + current_spice = AMBITION_INTENSITY_STEALTH + if(2) + current_spice = AMBITION_INTENSITY_MILD + if(3) + current_spice = AMBITION_INTENSITY_MEDIUM + if(4) + current_spice = AMBITION_INTENSITY_SEVERE + if(5) + current_spice = AMBITION_INTENSITY_EXTREME + var/active = (current_spice == intensity) + var/spice_link = active ? "class='linkOn'" : "href='?src=[REF(src)];pref=spice;amount=[current_spice]'" + var/spice_name + var/spice_desc + var/spice_color + switch(current_spice) + if(AMBITION_INTENSITY_STEALTH) + spice_name = "Stealth" + spice_desc = "Unseen by the majority of players, actions affecting only a small area/group of players." + spice_color = "#a6a6a6" + if(AMBITION_INTENSITY_MILD) + spice_name = "Mild" + spice_desc = "Mugging, stealing or vandalism." + spice_color = "#fcdf03" + if(AMBITION_INTENSITY_MEDIUM) + spice_name = "Medium" + spice_desc = "Assault, manslaughter, severe vandalism, rioting." + spice_color = "#fcb103" + if(AMBITION_INTENSITY_SEVERE) + spice_name = "Severe" + spice_desc = "Murder, grand theft, grand tresspass." + spice_color = "#fc8c03" + if(AMBITION_INTENSITY_EXTREME) + spice_name = "Extreme" + spice_desc = "Bombings, open combat and terrorism." + spice_color = "#fc5603" + dat += "" + dat += "
[spice_name]
[spice_desc]
" + dat += "
" + dat += "

Note to Admin (optional):

" + dat += "If you want to request a review, you can set this to explain your reasoning or what experience you hope to bring to the station." + dat += "
" + dat += note_to_admins + dat += "

Edit your note to admin
" + dat += "
" + + winshow(usr, "ambition_window", TRUE) + var/datum/browser/popup = new(usr, "ambition_window", "
Ambitions
", 950, 750) + popup.set_content(dat.Join()) + popup.open(FALSE) + onclose(usr, "ambition_window", src) + +/datum/ambitions/proc/ShowTemplatePanel(mob/user) + if(!user || !user.client) + return + var/list/dat = list("
") + dat += "Templates shown here are mostly ideas for your antagonism, you are encouraged to edit them to fit your character the most." + dat += "
Not all of them have all fields, mostly intensity, as it's up to you how you execute a lot of narratives." + dat += "
Hopefully those can give you fun ideas on how to do antagonism in the future too!" + var/list/available_templates = list() + for(var/name in GLOB.ambitions_templates) + var/datum/ambition_template/AT = GLOB.ambitions_templates[name] + if(AT.antag_whitelist) + var/has_required = FALSE + for(var/datum/antagonist/A in my_mind.antag_datums) + if(A.name in AT.antag_whitelist) + has_required = TRUE + break + if(!has_required) + continue + if(AT.job_whitelist) + if(!(my_mind.assigned_role in AT.job_whitelist)) + continue + available_templates += AT + for(var/temp in available_templates) + var/datum/ambition_template/AT = temp + dat += "" + dat += "" + if(AT.narrative != "") + dat += "" + dat += "" + if(length(AT.objectives)) + dat += "" + var/even = FALSE + for(var/objec in AT.objectives) + even = !even + var/bgc = even ? "#13171C" : "#18211C" + dat += "" + if(AT.intensity) + var/string = "ERROR" + switch(AT.intensity) + if(AMBITION_INTENSITY_STEALTH) + string = "Stealth" + if(AMBITION_INTENSITY_MILD) + string = "Mild" + if(AMBITION_INTENSITY_MEDIUM) + string = "Medium" + if(AMBITION_INTENSITY_SEVERE) + string = "Severe" + if(AMBITION_INTENSITY_EXTREME) + string = "Extreme" + dat += "" + if(length(AT.tips)) + dat += "" + var/even = FALSE + for(var/tip in AT.tips) + even = !even + var/bgc = even ? "#13171C" : "#23272C" + dat += "" + dat += "
[AT.name] Choose
Narrative:
[AT.narrative]
Objectives:
* [objec]
Intensity: [string]
Tips:
[tip]
" + dat += "
" + + winshow(usr, "ambition_template_window", TRUE) + var/datum/browser/popup = new(usr, "ambition_template_window", "
Ambition Templates
", 950, 750) + popup.set_content(dat.Join()) + popup.open(FALSE) + onclose(usr, "ambition_template_window", src) + +/datum/ambitions/Topic(href, href_list) + if(href_list["temp_pref"]) + var/temp_name = href_list["name"] + var/datum/ambition_template/AT = GLOB.ambitions_templates[temp_name] + if(AT) + narrative = AT.narrative + objectives = AT.objectives.Copy() + if(submitted) + GLOB.total_intensity -= intensity + if(intensity) + GLOB.intensity_counts["[intensity]"] -= 1 + GLOB.total_intensity += AT.intensity + if(AT.intensity) + GLOB.intensity_counts["[AT.intensity]"] += 1 + intensity = AT.intensity + log_action("TEMPLATE: Chosen the [AT.name] template") + usr << browse(null, "window=ambition_template_window") + ShowPanel(usr) + if(href_list["admin_pref"]) + switch(href_list["admin_pref"]) + if("handle") + var/last_ckey = GLOB.ambitions_to_review[src] + if(last_ckey && last_ckey != usr.ckey) + var/action = alert(usr, "[last_ckey] is already handling this review! Do you want to handle nonetheless?", "", "Yes", "No") + if(action && !(action == "Yes")) + return + GLOB.ambitions_to_review[src] = usr.ckey + message_admins("[usr.ckey] is handling [owner_name]'s ambitions. (VIEW)") + to_chat(my_mind.current, "[usr.ckey] is handling your ambitions.") + if("request_changes") + var/changes_wanted = input(usr, "Requested changes:", "Ambitions") as message|null + if(changes_wanted) + last_requested_change = changes_wanted + to_chat(my_mind.current, "[usr.ckey] requested changes on your ambitions: [changes_wanted]. (VIEW)") + message_admins("[usr.ckey] requested changes in [ADMIN_TPMONTY(my_mind.current)]'s ambitions. (VIEW)") + if("discard_review") + var/action = alert(usr, "Are you sure you want to discard this review request (Use request changes if you want it changed instead)?", "", "Yes", "No") + if(action && action == "Yes" && admin_review_requested) + admin_review_requested = FALSE + admin_approval = FALSE + changed_after_approval = FALSE + last_requested_change = null + GLOB.ambitions_to_review -= src + to_chat(my_mind.current, "Your ambitions review request was discarded by [usr.ckey].") + message_admins("[ADMIN_TPMONTY(my_mind.current)]'s ambitions review request was DISCARDED by [usr.ckey]. (VIEW)") + if("approve") + admin_approval = TRUE + changed_after_approval = FALSE + last_requested_change = null + GLOB.ambitions_to_review -= src + log_action("APPROVED: Got an approval from [usr.ckey]", FALSE) + to_chat(my_mind.current, "Your ambitions were approved by [usr.ckey].") + message_admins("[ADMIN_TPMONTY(my_mind.current)]'s ambitions were approved by [usr.ckey]. (VIEW)") + submit() + if("logs") + var/datum/browser/popup = new(usr, "Ambition logging", "Ambition logs", 500, 200) + popup.set_content(text("[][]", "Ambition logs", log.Join("
"))) + popup.open() + return + + ShowPanel(usr, TRUE) + return TRUE + + if(href_list["pref"]) + switch(href_list["pref"]) + if("template") + ShowTemplatePanel(usr) + return + if("requested_done") + to_chat(src, "You notify admins that you have adressed the requested changes.") + message_admins("[ADMIN_TPMONTY(usr)] notifies that he has finished the requested changes in his ambitions. (VIEW)") + if("request_review") + admin_review_requested = TRUE + GLOB.ambitions_to_review[src] = 0 + log_action("--Requested an admin review--", FALSE) + message_admins("[ADMIN_TPMONTY(usr)] has requested a review of their ambitions. (VIEW)") + if("submit") + submit() + log_action("SUBMIT: Submitted their ambitions", FALSE) + message_admins("[ADMIN_TPMONTY(usr)] has submitted their ambitions. (VIEW)") + if("spice") + var/new_intensity = text2num(href_list["amount"]) + if(intensity == new_intensity) + return + var/string = "ERROR" + switch(intensity) + if(AMBITION_INTENSITY_STEALTH) + string = "Stealth" + if(AMBITION_INTENSITY_MILD) + string = "Mild" + if(AMBITION_INTENSITY_MEDIUM) + string = "Medium" + if(AMBITION_INTENSITY_SEVERE) + string = "Severe" + if(AMBITION_INTENSITY_EXTREME) + string = "Extreme" + log_action("INTENSITY: set to [string]") + if(submitted) + GLOB.total_intensity -= intensity + if(intensity) + GLOB.intensity_counts["[intensity]"] -= 1 + GLOB.total_intensity += new_intensity + if(new_intensity) + GLOB.intensity_counts["[new_intensity]"] += 1 + intensity = new_intensity + if("edit_admin_note") + var/msg = input(usr, "Set your note to admins!", "Note to admins", note_to_admins) as message|null + if(msg) + note_to_admins = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE) + log_action("NOTE: [note_to_admins]", FALSE) + if("set_narrative") + var/msg = input(usr, "Set your narrative!", "Narrative", narrative) as message|null + if(msg) + narrative = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE) + log_action("NARRATIVE - change: [narrative]") + if("remove_objective") + var/index = text2num(href_list["index"]) + if(length(objectives) < index) + return + log_action("OBJ - removed: [objectives[index]]") + objectives.Remove(objectives[index]) + if("edit_objective") + var/index = text2num(href_list["index"]) + if(length(objectives) < index) + return + var/old_obj = objectives[index] + var/msg = input(usr, "Edit objective:", "Objectives", old_obj) as message|null + if(msg) + if(length(objectives) < index) + return + objectives[index] = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE) + log_action("OBJ - edit: [old_obj] TO-> [objectives[index]]") + if("add_objective") + var/msg = input(usr, "Add new objective:", "Objectives", "") as message|null + if(msg) + var/new_obj = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE) + objectives += new_obj + log_action("OBJ - add: [new_obj]") + + ShowPanel(usr) + return TRUE + +/datum/ambitions/proc/log_action(text_content, clears_approval = TRUE) + if(admin_approval && clears_approval && !changed_after_approval) + changed_after_approval = TRUE + log += "[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")] CHANGED AFTER APPROVAL:" + log += "[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")] [text_content]" + +/datum/ambitions/proc/is_proper_ambitions() + if(intensity == 0 || length(objectives) == 0 || narrative == "") + return FALSE + return TRUE + +/datum/ambitions/proc/submit() + if(submitted) + return + submitted = TRUE + my_mind.ambition_submit() + GLOB.total_intensity += intensity + GLOB.intensity_counts["[intensity]"] += 1 + +/mob/proc/view_ambitions() + set name = "View Ambitions" + set category = "IC" + set desc = "View and edit your character's ambitions." + if(!mind) + return + if(!mind.my_ambitions) + return + mind.my_ambitions.ShowPanel(src) + +/datum/ambitions/proc/Action(action) + ShowPanel(usr, TRUE) + +#undef AMBITION_INTENSITY_MILD +#undef AMBITION_INTENSITY_MEDIUM +#undef AMBITION_INTENSITY_SEVERE +#undef AMBITION_INTENSITY_EXTREME diff --git a/modular_skyrat/modules/ambitions/code/ambition_templates.dm b/modular_skyrat/modules/ambitions/code/ambition_templates.dm new file mode 100644 index 00000000000..9f3cee5be70 --- /dev/null +++ b/modular_skyrat/modules/ambitions/code/ambition_templates.dm @@ -0,0 +1,25 @@ +/datum/ambition_template + ///Name of the template. Has to be unique + var/name + ///If defined, only the antags in the whitelists will see the template + var/list/antag_whitelist + ///If defined, only the jobs in the whitelist will see the template + var/list/job_whitelist + + ///Narrative given by the template + var/narrative = "" + ///Objectives given by the templates + var/list/objectives = list() + ///Intensity given by the template + var/intensity = 0 + ///Tips displayed to the antag + var/list/tips + +/datum/ambition_template/blank + name = "Blank" + +/datum/ambition_template/money_problems + name = "Money Problems" + narrative = "In need of money for personal reasons, tired of living like a drone, for measly wages, you're out to get some money to satisfy your needs and debts!" + objectives = list("Acquire 20,000 credits.") + tips = list("You should add an objective on your main money making plan!" , "You could buy a gun and mug people, but make sure to conceal your identity, you can do this with a mask from a chameleon kit, and agent ID, or you'll risk being wanted quite quickly", "Setting up a shop is not a bad idea! Consider partnering up with cargo or science people for goods or implants", "If you're feeling brave you can bust the vault up!") diff --git a/modular_skyrat/modules/ambitions/code/antag_datums.dm b/modular_skyrat/modules/ambitions/code/antag_datums.dm new file mode 100644 index 00000000000..382e9e683e6 --- /dev/null +++ b/modular_skyrat/modules/ambitions/code/antag_datums.dm @@ -0,0 +1,36 @@ +/datum/antagonist + ///Whether the antagonist uses ambitions + var/uses_ambitions = FALSE + +///This gets called after our ambitions are submitted, or the antag datum is given to someone with filled ambitions +/datum/antagonist/proc/ambitions_add() + return + +///This gets called to remove things from an antagonist, given that they had ambitions submitted (ie. remove powers from ling, remove uplink from traitors) +/datum/antagonist/proc/ambitions_removal() + return + +/datum/antagonist/traitor + uses_ambitions = TRUE + +/datum/antagonist/traitor/ambitions_add() + if(traitor_kind == TRAITOR_HUMAN && should_equip) + equip() + +/datum/antagonist/changeling + uses_ambitions = TRUE + +/datum/antagonist/changeling/ambitions_add() + create_actions() + reset_powers() + create_initial_profile() + +/datum/antagonist/changeling/ambitions_removal() + remove_changeling_powers() + +/datum/objective/ambitions + name = "ambitions" + explanation_text = "Open up ambitions from the IC tab and craft your unique antagonistic story." + +/datum/objective/ambitions/check_completion() + return TRUE diff --git a/modular_skyrat/modules/ambitions/code/mind.dm b/modular_skyrat/modules/ambitions/code/mind.dm new file mode 100644 index 00000000000..89092e617c7 --- /dev/null +++ b/modular_skyrat/modules/ambitions/code/mind.dm @@ -0,0 +1,7 @@ +/datum/mind + var/datum/ambitions/my_ambitions + +/datum/mind/proc/ambition_submit() + for(var/datum/antagonist/A in antag_datums) + if(A.uses_ambitions) + A.ambitions_add() diff --git a/tgstation.dme b/tgstation.dme index 3338383c605..83c7a4032f3 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -133,6 +133,7 @@ #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals.dm" #include "code\__DEFINES\research\anomalies.dm" +#include "code\__DEFINES\~skyrat_defines\ambitions.dm" #include "code\__DEFINES\~skyrat_defines\blueshield.dm" #include "code\__DEFINES\~skyrat_defines\DNA.dm" #include "code\__DEFINES\~skyrat_defines\jobs.dm" @@ -3612,4 +3613,8 @@ #include "modular_skyrat\modules\verbs\code\modules\client\verbs\looc.dm" #include "modular_skyrat\modules\verbs\code\modules\mob\say.dm" #include "modular_skyrat\modules\verbs\code\modules\mob\subtle.dm" +#include "modular_skyrat\modules\ambitions\code\ambition.dm" +#include "modular_skyrat\modules\ambitions\code\ambition_templates.dm" +#include "modular_skyrat\modules\ambitions\code\antag_datums.dm" +#include "modular_skyrat\modules\ambitions\code\mind.dm" // END_INCLUDE