Skip to content

Commit

Permalink
Minor tweaks to tutorials (cmss13-devs#7312)
Browse files Browse the repository at this point in the history
# About the pull request

Restricts advanced tutorials until you do the basic ones
Moves tutorials from per-slot to full save

# Explain why it's good for the game

New players should be guided to doing the basic tutorials that teach
them the basic game mechanics

# Changelog
:cl:
add: Tutorials can be locked until a prerequisite tutorial is completed
code: Tutorials are saved in preferences instead of per character slot
/:cl:
  • Loading branch information
BeagleGaming1 authored Oct 16, 2024
1 parent 8dbd5b0 commit 1e51eb3
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 22 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/tutorial.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#define TUTORIAL_ATOM_FROM_TRACKING(path, varname) var##path/##varname = tracking_atoms[##path]
#define IS_TUTORIAL_COMPLETED(user, tutorial_id) (user.client && (tutorial_id in user.client.prefs.completed_tutorials))

#define TUTORIAL_CATEGORY_BASE "Base" // Shouldn't be used outside of base types
#define TUTORIAL_CATEGORY_SS13 "Space Station 13"
Expand Down
2 changes: 1 addition & 1 deletion code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
continue

if(abomination)
if(!(/datum/tutorial/xenomorph/abomination::tutorial_id in cur_obs.client.prefs.completed_tutorials))
if(!IS_TUTORIAL_COMPLETED(cur_obs, "xeno_abom_1"))
to_chat(cur_obs, SPAN_BOLDNOTICE("You were passed over for playing as an Abomination because you have not completed its tutorial."))
continue

Expand Down
4 changes: 3 additions & 1 deletion code/datums/tutorial/_tutorial.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
var/list/player_bind_dict = list()
/// If the tutorial has been completed. This doesn't need to be modified if you call end_tutorial() with a param of TRUE
var/completion_marked = FALSE
/// The tutorial_id of what tutorial has to be completed before being able to do this tutorial
var/required_tutorial

/datum/tutorial/Destroy(force, ...)
GLOB.ongoing_tutorials -= src
Expand Down Expand Up @@ -87,7 +89,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial)
remove_action(tutorial_mob, /datum/action/tutorial_end) // Just in case to make sure the client can't try and leave the tutorial while it's mid-cleanup
if(tutorial_mob.client?.prefs && (completed || completion_marked))
tutorial_mob.client.prefs.completed_tutorials |= tutorial_id
tutorial_mob.client.prefs.save_character()
tutorial_mob.client.prefs.save_preferences()
var/mob/new_player/new_player = new
if(!tutorial_mob.mind)
tutorial_mob.mind_initialize()
Expand Down
29 changes: 18 additions & 11 deletions code/datums/tutorial/_tutorial_menu.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
if(!length(categories))
var/list/categories_2 = list()
for(var/datum/tutorial/tutorial as anything in subtypesof(/datum/tutorial))
if(initial(tutorial.parent_path) == tutorial)
if(tutorial::parent_path == tutorial)
continue

if(!(initial(tutorial.category) in categories_2))
categories_2[initial(tutorial.category)] = list()
if(!(tutorial::category in categories_2))
categories_2[tutorial::category] = list()

categories_2[initial(tutorial.category)] += list(list(
"name" = initial(tutorial.name),
categories_2[tutorial::category] += list(list(
"name" = tutorial::name,
"path" = "[tutorial]",
"id" = initial(tutorial.tutorial_id),
"description" = initial(tutorial.desc),
"image" = initial(tutorial.icon_state),
"id" = tutorial::tutorial_id,
"description" = tutorial::desc,
"image" = tutorial::icon_state,
))

for(var/category in categories_2)
Expand All @@ -27,7 +27,6 @@
"tutorials" = categories_2[category],
))


/datum/tutorial_menu/proc/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
Expand All @@ -50,10 +49,18 @@
var/list/data = list()

data["tutorial_categories"] = categories
data["completed_tutorials"] = list()
data["locked_tutorials"] = list()

if(user.client?.prefs)
data["completed_tutorials"] = user.client.prefs.completed_tutorials
else
data["completed_tutorials"] = list()

for(var/datum/tutorial/tutorial as anything in subtypesof(/datum/tutorial))
if(tutorial::parent_path == tutorial)
continue
if(tutorial::required_tutorial)
if(!IS_TUTORIAL_COMPLETED(user, tutorial::required_tutorial))
data["locked_tutorials"] += tutorial::tutorial_id

return data

Expand Down
1 change: 1 addition & 0 deletions code/datums/tutorial/marine/basic_marine.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
var/clothing_items_to_vend = 8
/// How many items need to be vended from the gun vendor to continue
var/gun_items_to_vend = 2
required_tutorial = "ss13_intents_1"

// START OF SCRIPTING

Expand Down
1 change: 1 addition & 0 deletions code/datums/tutorial/marine/medical_basic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
desc = "Learn how to treat common injuries you may face as a marine."
tutorial_id = "marine_medical_1"
tutorial_template = /datum/map_template/tutorial/s7x7
required_tutorial = "marine_basic_1"

// START OF SCRIPTING

Expand Down
3 changes: 2 additions & 1 deletion code/datums/tutorial/marine/reqs_line.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
name = "Marine - Requistions Line"
desc = "Learn how to tend to the requisitions line as a Cargo Technician."
icon_state = "cargotech"
tutorial_id = "requisitions_line"
tutorial_id = "marine_req_1"
tutorial_template = /datum/map_template/tutorial/reqs_line
required_tutorial = "marine_basic_1"

/// Current step of the tutorial we're at
var/stage = TUTORIAL_REQS_LINE_STAGE_STARTING
Expand Down
1 change: 1 addition & 0 deletions code/datums/tutorial/ss13/intents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
icon_state = "intents"
tutorial_id = "ss13_intents_1"
tutorial_template = /datum/map_template/tutorial/s7x7
required_tutorial = "ss13_basic_1"

// START OF SCRIPTING

Expand Down
1 change: 1 addition & 0 deletions code/datums/tutorial/xenomorph/abomination.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
tutorial_id = "xeno_abom_1"
tutorial_template = /datum/map_template/tutorial/s7x7
starting_xenomorph_type = /mob/living/carbon/xenomorph/predalien/tutorial
required_tutorial = "xeno_basic_1"
/// How many marines in the kill_marines stage have been killed
var/ending_marines_killed = 0

Expand Down
1 change: 1 addition & 0 deletions code/datums/tutorial/xenomorph/xenomorph_basic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
tutorial_id = "xeno_basic_1"
tutorial_template = /datum/map_template/tutorial/s12x12
starting_xenomorph_type = /mob/living/carbon/xenomorph/drone
required_tutorial = "ss13_intents_1"

// START OF SCRITPING

Expand Down
23 changes: 16 additions & 7 deletions code/modules/client/preferences_savefile.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#define SAVEFILE_VERSION_MIN 8
#define SAVEFILE_VERSION_MAX 27
#define SAVEFILE_VERSION_MAX 28

//handles converting savefiles to new formats
//MAKE SURE YOU KEEP THIS UP TO DATE!
Expand Down Expand Up @@ -171,6 +171,15 @@
chat_settings |= CHAT_FFATTACKLOGS
S["toggles_chat"] << chat_settings

if(savefile_version < 28)
var/tutorial_string = ""
S["completed_tutorials"] >> tutorial_string
tutorial_savestring_to_list(tutorial_string)
if("requisitions_line" in completed_tutorials)
completed_tutorials -= "requisitions_line"
completed_tutorials += "marine_req_1"
S["completed_tutorials"] << tutorial_list_to_savestring()

savefile_version = SAVEFILE_VERSION_MAX
return 1

Expand Down Expand Up @@ -289,6 +298,10 @@
S["tooltips"] >> tooltips
S["key_bindings"] >> key_bindings

var/tutorial_string = ""
S["completed_tutorials"] >> tutorial_string
tutorial_savestring_to_list(tutorial_string)

var/list/remembered_key_bindings
S["remembered_key_bindings"] >> remembered_key_bindings

Expand Down Expand Up @@ -488,6 +501,8 @@
S["no_radial_labels_preference"] << no_radial_labels_preference
S["custom_cursors"] << custom_cursors

S["completed_tutorials"] << tutorial_list_to_savestring()

return TRUE

/datum/preferences/proc/load_character(slot)
Expand Down Expand Up @@ -576,10 +591,6 @@
S["uplinklocation"] >> uplinklocation
S["exploit_record"] >> exploit_record

var/tutorial_string = ""
S["completed_tutorials"] >> tutorial_string
tutorial_savestring_to_list(tutorial_string)

//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
Expand Down Expand Up @@ -728,8 +739,6 @@
S["uplinklocation"] << uplinklocation
S["exploit_record"] << exploit_record

S["completed_tutorials"] << tutorial_list_to_savestring()

return 1

/// checks through keybindings for outdated unbound keys and updates them
Expand Down
6 changes: 5 additions & 1 deletion tgui/packages/tgui/interfaces/TutorialMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ type TutorialCategory = {
type BackendContext = {
tutorial_categories: TutorialCategory[];
completed_tutorials: string[];
locked_tutorials: string[];
};

export const TutorialMenu = (props) => {
const { data, act } = useBackend<BackendContext>();
const { tutorial_categories, completed_tutorials } = data;
const { tutorial_categories, completed_tutorials, locked_tutorials } = data;
const [chosenTutorial, setTutorial] = useState<Tutorial | null>(null);
const [categoryIndex, setCategoryIndex] = useState('Space Station 13');
return (
Expand Down Expand Up @@ -77,6 +78,9 @@ export const TutorialMenu = (props) => {
: 'default'
}
width="100%"
disabled={
!(locked_tutorials.indexOf(tutorial.id) === -1)
}
key={tutorial.id}
onClick={() => setTutorial(tutorial)}
>
Expand Down

0 comments on commit 1e51eb3

Please sign in to comment.