mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 07:46:20 +00:00
Add the ability to duplicate characters (#4743)
## About The Pull Request Lets you copy characters in the character customizer. This'll be useful if you ever want to create variants of your character or Need to move characters to different slots. This needs large scale testing, I couldn't break anything on local but given this involves tinkering with saves better safe than sorry. ## Why It's Good For The Game I saw a complaint on discord about having to delete characters to reorganize the list, this resolves that. This also lets you create a "base" character to use as a template or to generate variants of an existing character without making them from scratch or editing them. ## Proof Of Testing <details> <summary>Screenshots/Videos</summary> Soon.... </details> ## Changelog 🆑 qol: You can now copy your characters into other slots. /🆑 --------- Co-authored-by: xPokee <catmc8565@gmail.com>
This commit is contained in:
@@ -250,6 +250,21 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if ("remove_current_slot")
|
||||
remove_current_slot()
|
||||
return TRUE
|
||||
if ("duplicate_current_slot") //BUBBER ADDITION START - Character duplication
|
||||
save_character()
|
||||
if(sanitize_languages())
|
||||
save_character()
|
||||
var/list/character_list = create_character_profiles()
|
||||
var/list/slot_choices = list()
|
||||
for(var/i = 1, i <= character_list.len, i++)
|
||||
slot_choices += "Slot [i]: [character_list[i]]"
|
||||
var/target_slot = tgui_input_list(ui.user, "Pick a slot to copy to.", "Duplicate Character", slot_choices, null)
|
||||
if(!isnull(target_slot))
|
||||
duplicate_current_slot(slot_choices.Find(target_slot))
|
||||
tainted_character_profiles = TRUE
|
||||
else
|
||||
tgui_alert(ui.user, "Cancelled Duplication", "Duplicate Character")
|
||||
return TRUE //BUBBER ADDITION END - Character duplication
|
||||
if ("rotate")
|
||||
/* SKYRAT EDIT - Bi-directional prefs menu rotation - ORIGINAL:
|
||||
character_preview_view.dir = turn(character_preview_view.dir, -90)
|
||||
|
||||
@@ -389,14 +389,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
|
||||
return needs_update != -3 // BUBBER EDIT
|
||||
|
||||
/datum/preferences/proc/save_character(update) // Skyrat edit - Choose when to update (This is stupid)
|
||||
/datum/preferences/proc/save_character(update, override_slot) // Skyrat edit - Choose when to update (This is stupid) //Bubber Edit - duplication support
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
if(!path)
|
||||
return FALSE
|
||||
var/tree_key = "character[default_slot]"
|
||||
if(!(tree_key in savefile.get_entry()))
|
||||
savefile.set_entry(tree_key, list())
|
||||
var/save_data = savefile.get_entry(tree_key)
|
||||
var/save_data //BUBBER EDIT START - Original var/save_data = savefile.get_entry(tree_key)
|
||||
if(!isnull(override_slot))
|
||||
var/override_tree_key = "character[override_slot]"
|
||||
savefile.set_entry(override_tree_key, list())
|
||||
save_data = savefile.get_entry(override_tree_key)
|
||||
else
|
||||
save_data = savefile.get_entry(tree_key) //BUBBER EDIT END
|
||||
|
||||
for (var/datum/preference/preference as anything in get_preferences_in_priority_order())
|
||||
if (preference.savefile_identifier != PREFERENCE_CHARACTER)
|
||||
@@ -408,7 +414,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
recently_updated_keys -= preference.type
|
||||
|
||||
if (preference.type in value_cache)
|
||||
write_preference(preference, preference.serialize(value_cache[preference.type]))
|
||||
if(!isnull(override_slot)) //BUBBER EDIT ADDITION START - Original: write_preference(preference, preference.serialize(value_cache[preference.type]))
|
||||
write_preference_special(preference, preference.serialize(value_cache[preference.type]), override_slot)
|
||||
else
|
||||
write_preference(preference, preference.serialize(value_cache[preference.type])) //BUBBER EDIT ADDITION END
|
||||
|
||||
save_data["version"] = SAVEFILE_VERSION_MAX //load_character will sanitize any bad data, so assume up-to-date.
|
||||
|
||||
@@ -467,6 +476,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
tainted_character_profiles = TRUE
|
||||
switch_to_slot(closest_slot)
|
||||
|
||||
/datum/preferences/proc/duplicate_current_slot(target_slot)
|
||||
PRIVATE_PROC(TRUE)
|
||||
if(isnull(target_slot))
|
||||
return
|
||||
save_character(TRUE, target_slot)
|
||||
|
||||
/datum/preferences/proc/write_preference_special(datum/preference/preference, preference_value, override_slot)
|
||||
var/save_data = savefile.get_entry("character[override_slot]")
|
||||
var/new_value = preference.deserialize(preference_value, src)
|
||||
var/success = preference.write(save_data, new_value)
|
||||
if (success)
|
||||
value_cache[preference.type] = new_value
|
||||
return success
|
||||
|
||||
/datum/preferences/proc/sanitize_be_special(list/input_be_special)
|
||||
var/list/output = list()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { NoticeBox, Stack } from 'tgui-core/components';
|
||||
import { NoticeBox, Stack, Button } from 'tgui-core/components'; // BUBBER EDIT CHANGE - ORIGINAL : import { NoticeBox, Stack } from 'tgui-core/components';
|
||||
import { exhaustiveCheck } from 'tgui-core/exhaustive';
|
||||
|
||||
import { SideDropdown } from '../../../bubber_components/SideDropdown'; // BUBBER EDIT ADDITION
|
||||
@@ -138,6 +138,17 @@ export function CharacterPreferenceWindow(props) {
|
||||
profiles={data.character_profiles}
|
||||
/>
|
||||
</Stack.Item>
|
||||
{/* BUBBER EDIT ADDITION BEGIN */}
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() => {act('duplicate_current_slot');}}
|
||||
fontSize="13px"
|
||||
icon="copy"
|
||||
tooltip="Duplicate Current Character (Experimental)" //Delete this comment about being experimental before merge
|
||||
tooltipPosition="top"
|
||||
/>
|
||||
{/* BUBBER EDIT ADDITION END */}
|
||||
</Stack.Item>
|
||||
{!data.content_unlocked && (
|
||||
<Stack.Item grow align="center" mb={-1}>
|
||||
<NoticeBox color="grey">
|
||||
|
||||
Reference in New Issue
Block a user