diff --git a/code/__DEFINES/~doppler_defines/loadout.dm b/code/__DEFINES/~doppler_defines/loadout.dm new file mode 100644 index 0000000000000..c018313eac038 --- /dev/null +++ b/code/__DEFINES/~doppler_defines/loadout.dm @@ -0,0 +1,18 @@ +/// Used to set custom descriptions. +#define INFO_DESCRIBED "description" + +/// Max amonut of misc / backpack items that are allowed. +#define MAX_ALLOWED_MISC_ITEMS 3 +/// The maximum allowed amount of erp items allowed in any given character's loadout +#define MAX_ALLOWED_ERP_ITEMS 7 + +/// Defines for extra info blurbs, for loadout items. +#define TOOLTIP_NO_ARMOR "Armorless" +#define TOOLTIP_NO_DAMAGE "CEREMONIAL - This item has very low force and is cosmetic." +#define TOOLTIP_RANDOM_COLOR "Random Color" +#define TOOLTIP_GREYSCALE "GREYSCALED - This item can be customized via the greyscale modification UI." +#define TOOLTIP_RENAMABLE "RENAMABLE - This item can be given a custom name." + +#define LOADOUT_OVERRIDE_JOB "Delete job items" +#define LOADOUT_OVERRIDE_BACKPACK "Move job to backpack" +#define LOADOUT_OVERRIDE_CASE "Place all in case" diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index ff76464bee56a..baca9a1235486 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -427,6 +427,15 @@ SUBSYSTEM_DEF(ticker) if(new_player_mob.client?.prefs?.should_be_random_hardcore(player_assigned_role, new_player_living.mind)) new_player_mob.client.prefs.hardcore_random_setup(new_player_living) SSquirks.AssignQuirks(new_player_living, new_player_mob.client) + + //DOPPLER EDIT ADDITION + if(ishuman(new_player_living)) + var/list/loadout = loadout_list_to_datums(new_player_mob.client?.prefs?.read_preference(/datum/preference/loadout)) + for(var/datum/loadout_item/item as anything in loadout) + if (item.restricted_roles && length(item.restricted_roles) && !(player_assigned_role.title in item.restricted_roles)) + continue + item.post_equip_item(new_player_mob.client?.prefs, new_player_living) + //DOPPLER EDIT END CHECK_TICK if(captainless) diff --git a/code/modules/loadout/categories/pocket.dm b/code/modules/loadout/categories/pocket.dm index fd3f11e112b27..4ae0ade2157ce 100644 --- a/code/modules/loadout/categories/pocket.dm +++ b/code/modules/loadout/categories/pocket.dm @@ -5,7 +5,7 @@ type_to_generate = /datum/loadout_item/pocket_items tab_order = /datum/loadout_category/head::tab_order + 5 /// How many pocket items are allowed - VAR_PRIVATE/max_allowed = 2 + var/max_allowed = 2 // DOPPLER EDIT CAHANGE - ORIGINAL: VAR_PRIVATE/max_allowed = 2 /datum/loadout_category/pocket/New() . = ..() diff --git a/code/modules/loadout/loadout_items.dm b/code/modules/loadout/loadout_items.dm index 37a457f06c5ef..28cd6e7ea05ca 100644 --- a/code/modules/loadout/loadout_items.dm +++ b/code/modules/loadout/loadout_items.dm @@ -256,6 +256,13 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) equipped_item.name = trim(item_details[INFO_NAMED], PREVENT_CHARACTER_TRIM_LOSS(MAX_NAME_LEN)) ADD_TRAIT(equipped_item, TRAIT_WAS_RENAMED, "Loadout") + // DOPPLER EDIT ADDITION START - Loadout item descriptions + if(can_be_named && item_details?[INFO_DESCRIBED] && !visuals_only) + equipped_item.desc = item_details[INFO_DESCRIBED] + ADD_TRAIT(equipped_item, TRAIT_WAS_RENAMED, "Loadout") + equipped_item.on_loadout_custom_described() + // DOPPLER EDIT ADDITION END + if(can_be_reskinned && item_details?[INFO_RESKIN]) var/skin_chosen = item_details[INFO_RESKIN] if(skin_chosen in equipped_item.unique_reskin) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 4db5ae888496c..fbece48ddab86 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -250,6 +250,15 @@ humanc.put_in_hands(new /obj/item/crowbar/large/emergency(get_turf(humanc))) //if hands full then just drops on the floor log_manifest(character.mind.key, character.mind, character, latejoin = TRUE) + //DOPPLER EDIT ADDITION + if(humanc) + var/list/loadout = loadout_list_to_datums(humanc.client?.prefs?.read_preference(/datum/preference/loadout)) + for(var/datum/loadout_item/item as anything in loadout) + if (item.restricted_roles && length(item.restricted_roles) && !(job.title in item.restricted_roles)) + continue + item.post_equip_item(humanc.client?.prefs, humanc) + //DOPPLER EDIT END + /mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee) //TODO: figure out a way to exclude wizards/nukeops/demons from this. for(var/C in GLOB.employmentCabinets) diff --git a/modular_doppler/loadout_categories/READEME.md b/modular_doppler/loadout_categories/READEME.md new file mode 100644 index 0000000000000..65985e5ac5d7d --- /dev/null +++ b/modular_doppler/loadout_categories/READEME.md @@ -0,0 +1,54 @@ +# LOADOUT CATEGORIES + +Most loadout categories are added in, if it is one that is stock TG just add in additional items in the respecitve files. + +If you need to add more categories or items the following format should be followed: + +## Format + +```DM +/datum/loadout_category/ + category_name = "" + category_ui_icon = FA_ICON_GLASSES // A Fontawesome icon to be used for the Category item + type_to_generate = /datum/loadout_item/ + tab_order = /datum/loadout_category/head::tab_order + 1 //This is where it will place the item in the tab order + +/datum/loadout_item/ + abstract_type = /datum/loadout_item/glasses + +/datum/loadout_item//insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.glasses) + LAZYADD(outfit.backpack_contents, outfit.glasses) // This will dictate if the item will go into the backpack if the slot is already occupied + outfit.glasses = item_path +``` + +```DM + /datum/loadout_item/pocket_items/ + name = "" + item_path = + /* Here there could be additional vars specified current list of possible vars as follows: + restricted_roles // If the item is only allowed on specific roles I.E Security Items + blacklisted_roles // If the item cannot be given to specific roles I.E. Prisoner + restricted_species // If the item would cause issues with a species + required_season = null // If the item is a seasonal one and should only show up then + erp_item = FALSE // If the item is suggestive + erp_box = FALSE // If the item is suggestive and should be put in a box + /* +``` + +## Helper Functions + +### Post equip Item + +`/datum/loadout_item/proc/post_equip_item` +This proc particulalrly is useful if you wish for a specific item to do something after it gets equipped to the character. As an exapmple take the wallet, equip it on the ID card slot then just put the ID into the wallet so you dont have to put your own ID in your wallet. Useful for that sort of thing. + +### Pre equip Item + +`/datum/loadout_item/proc/pre_equip_item` +Useful for doing checks on a item before it gets equipped for whatever reason, most of the time check to see if the slot would affect someone who has a item there they need to survive, I.E. Plasmamen. + +### Can be applied to + +`/datum/loadout_item/proc/can_be_applied_to` +Checkes if the item passes requirements and isn't blacklisted based on role or species or restricted to specific role diff --git a/modular_doppler/loadout_categories/categories/belts.dm b/modular_doppler/loadout_categories/categories/belts.dm new file mode 100644 index 0000000000000..6fd27013976d7 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/belts.dm @@ -0,0 +1,102 @@ +/datum/loadout_category/belt + category_name = "Belt" + category_ui_icon = FA_ICON_SCREWDRIVER_WRENCH + type_to_generate = /datum/loadout_item/belts + tab_order = /datum/loadout_category/accessories::tab_order + 1 + + +/* +* LOADOUT ITEM DATUMS FOR THE BELT SLOT +*/ +/datum/loadout_item/belts + abstract_type = /datum/loadout_item/belts + +/datum/loadout_item/belts/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.belt) + LAZYADD(outfit.backpack_contents, outfit.belt) + outfit.belt = item_path + + +/datum/loadout_item/belts/fanny_pack_black + name = "Black Fannypack" + item_path = /obj/item/storage/belt/fannypack/black + +/datum/loadout_item/belts/fanny_pack_blue + name = "Blue Fannypack" + item_path = /obj/item/storage/belt/fannypack/blue + +/datum/loadout_item/belts/fanny_pack_brown + name = "Brown Fannypack" + item_path = /obj/item/storage/belt/fannypack + +/datum/loadout_item/belts/fanny_pack_cyan + name = "Cyan Fannypack" + item_path = /obj/item/storage/belt/fannypack/cyan + +/datum/loadout_item/belts/fanny_pack_green + name = "Green Fannypack" + item_path = /obj/item/storage/belt/fannypack/green + +/datum/loadout_item/belts/fanny_pack_orange + name = "Orange Fannypack" + item_path = /obj/item/storage/belt/fannypack/orange + +/datum/loadout_item/belts/fanny_pack_pink + name = "Pink Fannypack" + item_path = /obj/item/storage/belt/fannypack/pink + +/datum/loadout_item/belts/fanny_pack_purple + name = "Purple Fannypack" + item_path = /obj/item/storage/belt/fannypack/purple + +/datum/loadout_item/belts/fanny_pack_red + name = "Red Fannypack" + item_path = /obj/item/storage/belt/fannypack/red + +/datum/loadout_item/belts/fanny_pack_yellow + name = "Yellow Fannypack" + item_path = /obj/item/storage/belt/fannypack/yellow + +/datum/loadout_item/belts/fanny_pack_white + name = "White Fannypack" + item_path = /obj/item/storage/belt/fannypack/white + +/datum/loadout_item/belts/lantern + name = "Lantern" + item_path = /obj/item/flashlight/lantern + +/datum/loadout_item/belts/candle_box + name = "Candle Box" + item_path = /obj/item/storage/fancy/candle_box + +/datum/loadout_item/belts/champion + name = "Champion's Belt" + item_path = /obj/item/storage/belt/champion + +// HOLSTERS + +/datum/loadout_item/belts/holster_shoulders + name = "Shoulder Holster" + item_path = /obj/item/storage/belt/holster + +// USEFUL BELTS + +/datum/loadout_item/belts/medical + name = "Medical Belt" + item_path = /obj/item/storage/belt/medical + +/datum/loadout_item/belts/security + name = "Security Belt" + item_path = /obj/item/storage/belt/security + +/datum/loadout_item/belts/utility + name = "Utility Belt" + item_path = /obj/item/storage/belt/utility + +/datum/loadout_item/belts/utility/chief + name = "Chief Engineer's Utility Belt" + item_path = /obj/item/storage/belt/utility/chief + +/datum/loadout_item/belts/mining + name = "Explorer's Webbing" + item_path = /obj/item/storage/belt/mining diff --git a/modular_doppler/loadout_categories/categories/clothing.dm b/modular_doppler/loadout_categories/categories/clothing.dm new file mode 100644 index 0000000000000..a0b9f22f3f0c0 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/clothing.dm @@ -0,0 +1,355 @@ +/datum/loadout_category/suit + category_name = "Suit" + category_ui_icon = FA_ICON_VEST + type_to_generate = /datum/loadout_item/suit + tab_order = /datum/loadout_category/neck::tab_order + 1 + +/* +* LOADOUT ITEM DATUMS FOR THE (EXO/OUTER)SUIT SLOT +*/ + +/datum/loadout_item/suit + abstract_type = /datum/loadout_item/suit + +/datum/loadout_item/suit/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) // don't bother storing in backpack, can't fit + if(initial(outfit_important_for_life.suit)) + return TRUE + +/datum/loadout_item/suit/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK) + if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only) + if(outfit.suit) + LAZYADD(outfit.backpack_contents, outfit.suit) + outfit.suit = item_path + else + outfit.suit = item_path + +/* +* WINTER COATS +*/ + +/datum/loadout_item/suit/winter_coat + name = "Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat + +/datum/loadout_item/suit/winter_coat_greyscale + name = "Greyscale Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/custom + +/* +* SUITS / SUIT JACKETS +*/ + +/datum/loadout_item/suit/recolorable + name = "Recolorable Formal Suit Jacket" + item_path = /obj/item/clothing/suit/toggle/lawyer/greyscale + +/datum/loadout_item/suit/black_suit_jacket + name = "Black Formal Suit Jacket" + item_path = /obj/item/clothing/suit/toggle/lawyer/black + +/datum/loadout_item/suit/blue_suit_jacket + name = "Blue Formal Suit Jacket" + item_path = /obj/item/clothing/suit/toggle/lawyer + +/datum/loadout_item/suit/purple_suit_jacket + name = "Purple Formal Suit Jacket" + item_path = /obj/item/clothing/suit/toggle/lawyer/purple + +/* +* SUSPENDERS +*/ + +/datum/loadout_item/suit/suspenders + name = "Recolorable Suspenders" + item_path = /obj/item/clothing/suit/toggle/suspenders + +/* +* DRESSES +*/ + +/datum/loadout_item/suit/white_dress + name = "White Dress" + item_path = /obj/item/clothing/suit/costume/whitedress + +/* +* LABCOATS +*/ + +/datum/loadout_item/suit/labcoat + name = "Labcoat" + item_path = /obj/item/clothing/suit/toggle/labcoat + +/datum/loadout_item/suit/labcoat_green + name = "Green Labcoat" + item_path = /obj/item/clothing/suit/toggle/labcoat/mad + +/* +* PONCHOS +*/ + +/datum/loadout_item/suit/poncho + name = "Poncho" + item_path = /obj/item/clothing/suit/costume/poncho + +/datum/loadout_item/suit/poncho_green + name = "Green Poncho" + item_path = /obj/item/clothing/suit/costume/poncho/green + +/datum/loadout_item/suit/poncho_red + name = "Red Poncho" + item_path = /obj/item/clothing/suit/costume/poncho/red + +/* +* JACKETS +*/ + +/datum/loadout_item/suit/bomber_jacket + name = "Bomber Jacket" + item_path = /obj/item/clothing/suit/jacket/bomber + +/datum/loadout_item/suit/military_jacket + name = "Military Jacket" + item_path = /obj/item/clothing/suit/jacket/miljacket + +/datum/loadout_item/suit/puffer_jacket + name = "Puffer Jacket" + item_path = /obj/item/clothing/suit/jacket/puffer + +/datum/loadout_item/suit/puffer_vest + name = "Puffer Vest" + item_path = /obj/item/clothing/suit/jacket/puffer/vest + +/datum/loadout_item/suit/leather_jacket + name = "Leather Jacket" + item_path = /obj/item/clothing/suit/jacket/leather + +/datum/loadout_item/suit/leather_jacket/biker + name = "Biker Jacket" + item_path = /obj/item/clothing/suit/jacket/leather/biker + +/datum/loadout_item/suit/jacket_sweater + name = "Recolorable Sweater Jacket" + item_path = /obj/item/clothing/suit/toggle/jacket/sweater + +/datum/loadout_item/suit/jacket_oversized + name = "Recolorable Oversized Jacket" + item_path = /obj/item/clothing/suit/jacket/oversized + +/datum/loadout_item/suit/jacket_fancy + name = "Recolorable Fancy Fur Coat" + item_path = /obj/item/clothing/suit/jacket/fancy + +/datum/loadout_item/suit/ethereal_raincoat + name = "Ethereal Raincoat" + item_path = /obj/item/clothing/suit/hooded/ethereal_raincoat + +/* +* COSTUMES +*/ + +/datum/loadout_item/suit/owl + name = "Owl Cloak" + item_path = /obj/item/clothing/suit/toggle/owlwings + +/datum/loadout_item/suit/griffin + name = "Griffon Cloak" + item_path = /obj/item/clothing/suit/toggle/owlwings/griffinwings + +/datum/loadout_item/suit/syndi + name = "Black And Red Space Suit Replica" + item_path = /obj/item/clothing/suit/syndicatefake + +/datum/loadout_item/suit/bee + name = "Bee Outfit" + item_path = /obj/item/clothing/suit/hooded/bee_costume + +/datum/loadout_item/suit/plague_doctor + name = "Plague Doctor Suit" + item_path = /obj/item/clothing/suit/bio_suit/plaguedoctorsuit + +/datum/loadout_item/suit/snowman + name = "Snowman Outfit" + item_path = /obj/item/clothing/suit/costume/snowman + +/datum/loadout_item/suit/chicken + name = "Chicken Suit" + item_path = /obj/item/clothing/suit/costume/chickensuit + +/datum/loadout_item/suit/monkey + name = "Monkey Suit" + item_path = /obj/item/clothing/suit/costume/monkeysuit + +/datum/loadout_item/suit/cardborg + name = "Cardborg Suit" + item_path = /obj/item/clothing/suit/costume/cardborg + +/datum/loadout_item/suit/xenos + name = "Xenos Suit" + item_path = /obj/item/clothing/suit/costume/xenos + +/datum/loadout_item/suit/ian_costume + name = "Corgi Costume" + item_path = /obj/item/clothing/suit/hooded/ian_costume + +/datum/loadout_item/suit/carp_costume + name = "Carp Costume" + item_path = /obj/item/clothing/suit/hooded/carp_costume + +/datum/loadout_item/suit/shark_costume + name = "Shark Costume" + item_path = /obj/item/clothing/suit/hooded/shark_costume + +/datum/loadout_item/suit/shork_costume + name = "Shork Costume" + item_path = /obj/item/clothing/suit/hooded/shork_costume + +/datum/loadout_item/suit/wizard + name = "Wizard Robe" + item_path = /obj/item/clothing/suit/wizrobe/fake + +/datum/loadout_item/suit/witch + name = "Witch Robe" + item_path = /obj/item/clothing/suit/wizrobe/marisa/fake + +/* +* MISC +*/ + +/datum/loadout_item/suit/recolorable_overalls + name = "Recolorable Overalls" + item_path = /obj/item/clothing/suit/apron/overalls + +/* +* HAWAIIAN +*/ + +/datum/loadout_item/suit/hawaiian_shirt + name = "Hawaiian Shirt" + item_path = /obj/item/clothing/suit/costume/hawaiian + +/* +* MISC +*/ + +/datum/loadout_item/suit/frontierjacket + abstract_type = /datum/loadout_item/suit/frontierjacket + +/* +* HOODIES +*/ +/datum/loadout_item/suit/hoodie + abstract_type = /datum/loadout_item/suit/hoodie + +/* +* JOB-LOCKED +*/ + +// WINTER COATS +/datum/loadout_item/suit/coat_med + name = "Medical Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/medical + +/datum/loadout_item/suit/coat_paramedic + name = "Paramedic Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/medical/paramedic + +/datum/loadout_item/suit/coat_robotics + name = "Robotics Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/science/robotics + +/datum/loadout_item/suit/coat_sci + name = "Science Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/science + +/datum/loadout_item/suit/coat_eng + name = "Engineering Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/engineering + +/datum/loadout_item/suit/coat_atmos + name = "Atmospherics Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos + +/datum/loadout_item/suit/coat_hydro + name = "Hydroponics Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/hydro + +/datum/loadout_item/suit/coat_cargo + name = "Cargo Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/cargo + +/datum/loadout_item/suit/coat_miner + name = "Mining Winter Coat" + item_path = /obj/item/clothing/suit/hooded/wintercoat/miner + +// JACKETS +/datum/loadout_item/suit/navybluejacketofficer + name = "Security Officer's Navy Blue Formal Jacket" + item_path = /obj/item/clothing/suit/jacket/officer/blue + restricted_roles = list(JOB_WARDEN, JOB_DETECTIVE, JOB_SECURITY_OFFICER, JOB_HEAD_OF_SECURITY) + +/datum/loadout_item/suit/navybluejacketwarden + name = "Warden's Navy Blue Formal Jacket" + item_path = /obj/item/clothing/suit/jacket/warden/blue + restricted_roles = list(JOB_WARDEN) + +/datum/loadout_item/suit/navybluejackethos + name = "Head of Security's Navy Blue Formal Jacket" + item_path = /obj/item/clothing/suit/jacket/hos/blue + restricted_roles = list(JOB_HEAD_OF_SECURITY) + +/datum/loadout_item/suit/qm_jacket + name = "Quartermaster's Overcoat" + item_path = /obj/item/clothing/suit/jacket/quartermaster + restricted_roles = list(JOB_QUARTERMASTER) + +/* +* FAMILIES +*/ + +/datum/loadout_item/suit/tmc + name = "TMC Coat" + item_path = /obj/item/clothing/suit/costume/tmc + +/datum/loadout_item/suit/pg + name = "PG Coat" + item_path = /obj/item/clothing/suit/costume/pg + +/datum/loadout_item/suit/deckers + name = "Deckers Hoodie" + item_path = /obj/item/clothing/suit/costume/deckers + +/datum/loadout_item/suit/soviet + name = "Soviet Coat" + item_path = /obj/item/clothing/suit/costume/soviet + +/datum/loadout_item/suit/yuri + name = "Yuri Coat" + item_path = /obj/item/clothing/suit/costume/yuri + +/* +* CHAPLAIN +*/ + +/datum/loadout_item/suit/chap_nun + name = "Nun's Habit" + item_path = /obj/item/clothing/suit/chaplainsuit/nun + +/datum/loadout_item/suit/chap_holiday + name = "Chaplain's Holiday Robe" + item_path = /obj/item/clothing/suit/chaplainsuit/holidaypriest + +/datum/loadout_item/suit/chap_brownmonk + name = "Monk's Brown Habit" + item_path = /obj/item/clothing/suit/hooded/chaplainsuit/monkhabit + +/datum/loadout_item/suit/chap_eastmonk + name = "Eastern Monk's Robe" + item_path = /obj/item/clothing/suit/chaplainsuit/monkrobeeast + +/datum/loadout_item/suit/chap_shrinehand + name = "Shrinehand Robe" + item_path = /obj/item/clothing/suit/chaplainsuit/shrinehand + +/datum/loadout_item/suit/chap_blackmonk + name = "Monk's Black Habit" + item_path = /obj/item/clothing/suit/chaplainsuit/habit diff --git a/modular_doppler/loadout_categories/categories/ears.dm b/modular_doppler/loadout_categories/categories/ears.dm new file mode 100644 index 0000000000000..f86fe518b2da9 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/ears.dm @@ -0,0 +1,25 @@ +/datum/loadout_category/ears + category_name = "Ears" + category_ui_icon = FA_ICON_EAR_LISTEN + type_to_generate = /datum/loadout_item/ears + tab_order = /datum/loadout_category/belt::tab_order + 1 + + +/* +* LOADOUT ITEM DATUMS FOR THE EAR SLOT +*/ +/datum/loadout_item/ears + abstract_type = /datum/loadout_item/ears + +/datum/loadout_item/ears/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.ears) + LAZYADD(outfit.backpack_contents, outfit.ears) + outfit.ears = item_path + +/datum/loadout_item/ears/headphones + name = "Headphones" + item_path = /obj/item/instrument/piano_synth/headphones + +/datum/loadout_item/ears/earmuffs + name = "Earmuffs" + item_path = /obj/item/clothing/ears/earmuffs diff --git a/modular_doppler/loadout_categories/categories/erp.dm b/modular_doppler/loadout_categories/categories/erp.dm new file mode 100644 index 0000000000000..7c7028eeebf8c --- /dev/null +++ b/modular_doppler/loadout_categories/categories/erp.dm @@ -0,0 +1,45 @@ +/datum/loadout_category/erp + category_name = "Erotic" + category_ui_icon = FA_ICON_HEART + erp_category = TRUE + type_to_generate = /datum/loadout_item/erp + tab_order = /datum/loadout_category/pocket::tab_order + 1 + var/max_allowed = MAX_ALLOWED_ERP_ITEMS + +/datum/loadout_category/erp/New() + . = ..() + category_info = "([MAX_ALLOWED_ERP_ITEMS] allowed)" + +/datum/loadout_category/erp/handle_duplicate_entires( + datum/preference_middleware/loadout/manager, + datum/loadout_item/conflicting_item, + datum/loadout_item/added_item, + list/datum/loadout_item/all_loadout_items, +) + var/list/datum/loadout_item/erp/other_items = list() + for(var/datum/loadout_item/erp/other_item in all_loadout_items) + other_items += other_item + + if(length(other_items) >= MAX_ALLOWED_ERP_ITEMS) + manager.deselect_item(other_items[1]) + return TRUE + +/datum/loadout_item/erp/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) + return FALSE + +/datum/loadout_item/erp + abstract_type = /datum/loadout_item/erp + erp_item = TRUE + erp_box = TRUE + +/* +* SEX TOYS +*/ + +/datum/loadout_item/erp/banana + name = "Banana" + item_path = /obj/item/food/grown/banana + +/datum/loadout_item/erp/pickle + name = "Pickle" + item_path = /obj/item/food/pickle diff --git a/modular_doppler/loadout_categories/categories/glasses.dm b/modular_doppler/loadout_categories/categories/glasses.dm new file mode 100644 index 0000000000000..c483d0df6c483 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/glasses.dm @@ -0,0 +1,7 @@ +/datum/loadout_item/glasses/monocle + name = "Monocle" + item_path = /obj/item/clothing/glasses/monocle + +/datum/loadout_item/glasses/welding + name = "Welding Goggles" + item_path = /obj/item/clothing/glasses/welding diff --git a/modular_doppler/loadout_categories/categories/gloves.dm b/modular_doppler/loadout_categories/categories/gloves.dm new file mode 100644 index 0000000000000..d3842ef96f019 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/gloves.dm @@ -0,0 +1,69 @@ +/* +* LOADOUT ITEM DATUMS FOR THE HAND SLOT +*/ + +/datum/loadout_category/hands + category_name = "Hands" + category_ui_icon = FA_ICON_HAND + type_to_generate = /datum/loadout_item/gloves + tab_order = /datum/loadout_category/feet::tab_order + 1 + +/datum/loadout_item/gloves + abstract_type = /datum/loadout_item/gloves + +/datum/loadout_item/gloves/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.gloves) + LAZYADD(outfit.backpack_contents, outfit.gloves) + outfit.gloves = item_path + +/datum/loadout_item/gloves/fingerless + name = "Fingerless Gloves" + item_path = /obj/item/clothing/gloves/fingerless + +/datum/loadout_item/gloves/black + name = "Black Gloves" + item_path = /obj/item/clothing/gloves/color/black + +/datum/loadout_item/gloves/blue + name = "Blue Gloves" + item_path = /obj/item/clothing/gloves/color/blue + +/datum/loadout_item/gloves/brown + name = "Brown Gloves" + item_path = /obj/item/clothing/gloves/color/brown + +/datum/loadout_item/gloves/green + name = "Green Gloves" + item_path = /obj/item/clothing/gloves/color/green + +/datum/loadout_item/gloves/grey + name = "Grey Gloves" + item_path = /obj/item/clothing/gloves/color/grey + +/datum/loadout_item/gloves/light_brown + name = "Light Brown Gloves" + item_path = /obj/item/clothing/gloves/color/light_brown + +/datum/loadout_item/gloves/orange + name = "Orange Gloves" + item_path = /obj/item/clothing/gloves/color/orange + +/datum/loadout_item/gloves/purple + name = "Purple Gloves" + item_path = /obj/item/clothing/gloves/color/purple + +/datum/loadout_item/gloves/red + name = "Red Gloves" + item_path = /obj/item/clothing/gloves/color/red + +/datum/loadout_item/gloves/white + name = "White Gloves" + item_path = /obj/item/clothing/gloves/color/white + +/datum/loadout_item/gloves/rainbow + name = "Rainbow Gloves" + item_path = /obj/item/clothing/gloves/color/rainbow + + + + diff --git a/modular_doppler/loadout_categories/categories/heads.dm b/modular_doppler/loadout_categories/categories/heads.dm new file mode 100644 index 0000000000000..c1dcb43bcb29d --- /dev/null +++ b/modular_doppler/loadout_categories/categories/heads.dm @@ -0,0 +1,47 @@ +/datum/loadout_item/head/chicken + name = "Chicken Hat" + item_path = /obj/item/clothing/head/costume/chicken + +/datum/loadout_item/head/griffin + name = "Griffin Hat" + item_path = /obj/item/clothing/head/costume/griffin + +/datum/loadout_item/head/tv_head + name = "TV Head" + item_path = /obj/item/clothing/head/costume/tv_head + +/datum/loadout_item/head/wizard + name = "Wizard Hat" + item_path = /obj/item/clothing/head/wizard/fake + +/datum/loadout_item/head/witch + name = "Witch Hat" + item_path = /obj/item/clothing/head/wizard/marisa/fake + +/datum/loadout_item/head/wig_random + name = "Random Wig" + item_path = /obj/item/clothing/head/wig/random + +/datum/loadout_item/head/cardborg + name = "Cardborg" + item_path = /obj/item/clothing/head/costume/cardborg + +/datum/loadout_item/head/pirate + name = "Pirate Hat" + item_path = /obj/item/clothing/head/costume/pirate + +/datum/loadout_item/head/cone + name = "Cone Hat" + item_path = /obj/item/clothing/head/cone + +/datum/loadout_item/head/party + name = "Party Hat" + item_path = /obj/item/clothing/head/costume/party + +/datum/loadout_item/head/rice_hat + name = "Rice Hat" + item_path = /obj/item/clothing/head/costume/rice_hat + +/datum/loadout_item/head/welding + name = "Welding Mask" + item_path = /obj/item/clothing/head/utility/welding diff --git a/modular_doppler/loadout_categories/categories/inhands.dm b/modular_doppler/loadout_categories/categories/inhands.dm new file mode 100644 index 0000000000000..61478e1754c7f --- /dev/null +++ b/modular_doppler/loadout_categories/categories/inhands.dm @@ -0,0 +1,24 @@ + +/datum/loadout_item/inhand/cane/crutch + name = "Crutch" + item_path = /obj/item/cane/crutch + +/datum/loadout_item/inhand/skateboard + name = "Skateboard" + item_path = /obj/item/melee/skateboard + +/datum/loadout_item/inhand/bouquet_mixed + name = "Mixed Bouquet" + item_path = /obj/item/bouquet + +/datum/loadout_item/inhand/bouquet_sunflower + name = "Sunflower Bouquet" + item_path = /obj/item/bouquet/sunflower + +/datum/loadout_item/inhand/bouquet_poppy + name = "Poppy Bouquet" + item_path = /obj/item/bouquet/poppy + +/datum/loadout_item/inhand/bouquet_rose + name = "Rose Bouquet" + item_path = /obj/item/bouquet/rose diff --git a/modular_doppler/loadout_categories/categories/masks.dm b/modular_doppler/loadout_categories/categories/masks.dm new file mode 100644 index 0000000000000..d17d4775becb3 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/masks.dm @@ -0,0 +1,61 @@ +/datum/loadout_category/face + category_name = "Face" + category_ui_icon = FA_ICON_MASK + type_to_generate = /datum/loadout_item/mask + tab_order = /datum/loadout_category/glasses::tab_order + 1 + +/* +* LOADOUT ITEM DATUMS FOR THE MASK SLOT +*/ +/datum/loadout_item/mask/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(initial(outfit_important_for_life.mask)) + ..() + return TRUE + +/datum/loadout_item/mask + abstract_type = /datum/loadout_item/mask + +/datum/loadout_item/mask/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.mask) + LAZYADD(outfit.backpack_contents, outfit.mask) + outfit.mask = item_path + +/datum/loadout_item/mask/face_mask + name = "Face Mask" + item_path = /obj/item/clothing/mask/breath + +/datum/loadout_item/mask/gas + name = "Gas Mask" + item_path = /obj/item/clothing/mask/gas + +/datum/loadout_item/mask/plaguedoctor + name = "Plague Doctor Mask" + item_path = /obj/item/clothing/mask/gas/plaguedoctor + +/datum/loadout_item/mask/clown + name = "Clown Mask" + item_path = /obj/item/clothing/mask/gas/clown_hat + +/datum/loadout_item/mask/balaclava + name = "Balaclava" + item_path = /obj/item/clothing/mask/balaclava + +/datum/loadout_item/mask/gas/atmos + name = "Atmos Gas Mask" + item_path = /obj/item/clothing/mask/gas/atmos + +/datum/loadout_item/mask/gas/explorer + name = "Explorer Gas Mask" + item_path = /obj/item/clothing/mask/gas/explorer + +/datum/loadout_item/mask/whistle + name = "Whistle" + item_path = /obj/item/clothing/mask/whistle + +/datum/loadout_item/mask/fakemoustache + name = "Fake Moustache" + item_path = /obj/item/clothing/mask/fakemoustache + +/datum/loadout_item/mask/surgical + name = "Surgical Mask" + item_path = /obj/item/clothing/mask/surgical diff --git a/modular_doppler/loadout_categories/categories/pockets.dm b/modular_doppler/loadout_categories/categories/pockets.dm new file mode 100644 index 0000000000000..3ea588abc8ea3 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/pockets.dm @@ -0,0 +1,233 @@ +/datum/loadout_category/pocket + max_allowed = MAX_ALLOWED_MISC_ITEMS + +// Because plushes have a second desc var that needs to be updated +/obj/item/toy/plush/on_loadout_custom_described() + normal_desc = desc + +// The wallet loadout item is special, and puts the player's ID and other small items into it on initialize (fancy!) +/datum/loadout_item/pocket_items/wallet + name = "Wallet" + item_path = /obj/item/storage/wallet + additional_displayed_text = list("Auto-Filled") + +// We add our wallet manually, later, so no need to put it in any outfits. +/datum/loadout_item/pocket_items/wallet/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only) + return FALSE + +// We didn't spawn any item yet, so nothing to call here. +/datum/loadout_item/pocket_items/wallet/on_equip_item( + obj/item/equipped_item, + datum/preferences/preference_source, + list/preference_list, + mob/living/carbon/human/equipper, + visuals_only = FALSE, +) + return FALSE + +// We add our wallet at the very end of character initialization (after quirks, etc) to ensure the backpack / their ID is all set by now. +/datum/loadout_item/pocket_items/wallet/post_equip_item(datum/preferences/preference_source, mob/living/carbon/human/equipper) + var/obj/item/card/id/advanced/id_card = equipper.get_item_by_slot(ITEM_SLOT_ID) + if(istype(id_card, /obj/item/storage/wallet)) + return + + var/obj/item/storage/wallet/wallet = new(equipper) + if(istype(id_card)) + equipper.temporarilyRemoveItemFromInventory(id_card, force = TRUE) + equipper.equip_to_slot_if_possible(wallet, ITEM_SLOT_ID, initial = TRUE) + id_card.forceMove(wallet) + + if(equipper.back) + var/list/backpack_stuff = equipper.back.atom_storage?.return_inv(FALSE) + for(var/obj/item/thing in backpack_stuff) + if(wallet.contents.len >= 3) + break + if(thing.w_class <= WEIGHT_CLASS_SMALL) + wallet.atom_storage.attempt_insert(src, thing, equipper, TRUE, FALSE) + else + if(!equipper.equip_to_slot_if_possible(wallet, slot = ITEM_SLOT_BACKPACK, initial = TRUE)) + wallet.forceMove(equipper.drop_location()) + +/* +* GUM +*/ + +/datum/loadout_item/pocket_items/gum_pack + name = "Pack of Gum" + item_path = /obj/item/storage/box/gum + +/datum/loadout_item/pocket_items/gum_pack_nicotine + name = "Pack of Nicotine Gum" + item_path = /obj/item/storage/box/gum/nicotine + +/datum/loadout_item/pocket_items/gum_pack_hp + name = "Pack of HP+ Gum" + item_path = /obj/item/storage/box/gum/happiness + +/* +* LIPSTICK +*/ + +/datum/loadout_item/pocket_items/lipstick_green + name = "Green Lipstick" + item_path = /obj/item/lipstick/green + +/datum/loadout_item/pocket_items/lipstick_white + name = "White Lipstick" + item_path = /obj/item/lipstick/white + +/datum/loadout_item/pocket_items/lipstick_blue + name = "Blue Lipstick" + item_path = /obj/item/lipstick/blue + +/datum/loadout_item/pocket_items/lipstick_black + name = "Black Lipstick" + item_path = /obj/item/lipstick/black + +/datum/loadout_item/pocket_items/lipstick_jade + name = "Jade Lipstick" + item_path = /obj/item/lipstick/jade + +/datum/loadout_item/pocket_items/lipstick_purple + name = "Purple Lipstick" + item_path = /obj/item/lipstick/purple + +/datum/loadout_item/pocket_items/lipstick_red + name = "Red Lipstick" + item_path = /obj/item/lipstick + +/* +* MISC +*/ + +/datum/loadout_item/pocket_items/rag + name = "Rag" + item_path = /obj/item/reagent_containers/cup/rag + +/datum/loadout_item/pocket_items/razor + name = "Razor" + item_path = /obj/item/razor + +/datum/loadout_item/pocket_items/matches + name = "Matchbox" + item_path = /obj/item/storage/box/matches + +/datum/loadout_item/pocket_items/cheaplighter + name = "Cheap Lighter" + item_path = /obj/item/lighter/greyscale + +/datum/loadout_item/pocket_items/zippolighter + name = "Zippo Lighter" + item_path = /obj/item/lighter + +/*/datum/loadout_item/pocket_items/ttsdevice //To be added + name = "Text-to-Speech Device" + item_path = /obj/item/ttsdevice*/ + +/datum/loadout_item/pocket_items/paicard + name = "Personal AI Device" + item_path = /obj/item/pai_card + +/datum/loadout_item/pocket_items/link_scryer + name = "MODlink Scryer" + item_path = /obj/item/clothing/neck/link_scryer/loaded + +/datum/loadout_item/pocket_items/cigarettes + name = "Cigarette Pack" + item_path = /obj/item/storage/fancy/cigarettes + +/datum/loadout_item/pocket_items/cigar //smoking is bad mkay + name = "Cigar" + item_path = /obj/item/cigarette/cigar + +/datum/loadout_item/pocket_items/flask + name = "Flask" + item_path = /obj/item/reagent_containers/cup/glass/flask + +/datum/loadout_item/pocket_items/multipen + name = "Multicolored Pen" + item_path = /obj/item/pen/fourcolor + +/datum/loadout_item/pocket_items/fountainpen + name = "Fancy Pen" + item_path = /obj/item/pen/fountain + +/datum/loadout_item/pocket_items/tapeplayer + name = "Universal Recorder" + item_path = /obj/item/taperecorder + +/datum/loadout_item/pocket_items/tape + name = "Spare Cassette Tape" + item_path = /obj/item/tape/random + +/datum/loadout_item/pocket_items/newspaper + name = "Newspaper" + item_path = /obj/item/newspaper + +/datum/loadout_item/pocket_items/clipboard + name = "Clipboard" + item_path = /obj/item/clipboard + +/datum/loadout_item/pocket_items/folder + name = "Folder" + item_path = /obj/item/folder + +/* +* UTILITY +*/ + +/datum/loadout_item/pocket_items/moth_mre + name = "Mothic Rations Pack" + item_path = /obj/item/storage/box/mothic_rations + +/datum/loadout_item/pocket_items/cloth_ten + name = "Ten Cloth Sheets" + item_path = /obj/item/stack/sheet/cloth/ten + +/datum/loadout_item/pocket_items/medkit + name = "First-Aid Kit" + item_path = /obj/item/storage/medkit/regular + +/datum/loadout_item/pocket_items/six_beer + name = "Beer Six-Pack" + item_path = /obj/item/storage/cans/sixbeer + +/datum/loadout_item/pocket_items/six_soda + name = "Soda Six-Pack" + item_path = /obj/item/storage/cans/sixsoda + +/datum/loadout_item/pocket_items/power_cell + name = "Standard Power Cell" + item_path = /obj/item/stock_parts/power_store/cell + +/datum/loadout_item/pocket_items/soap + name = "Bar of Soap" + item_path = /obj/item/soap + +/datum/loadout_item/pocket_items/mini_extinguisher + name = "Mini Fire Extinguisher" + item_path = /obj/item/extinguisher/mini + +/datum/loadout_item/pocket_items/binoculars + name = "Pair of Binoculars" + item_path = /obj/item/binoculars + +/datum/loadout_item/pocket_items/drugs_happy + name = "Happy Pills" + item_path = /obj/item/storage/pill_bottle/happy + +/datum/loadout_item/pocket_items/drugs_lsd + name = "Mindbreaker Pills" + item_path = /obj/item/storage/pill_bottle/lsd + +/datum/loadout_item/pocket_items/drugs_weed + name = "Cannabis Seeds" + item_path = /obj/item/seeds/cannabis + +/datum/loadout_item/pocket_items/drugs_reishi + name = "Reishi Seeds" + item_path = /obj/item/seeds/reishi + +/datum/loadout_item/pocket_items/drugs_liberty + name = "Liberty Cap Seeds" + item_path = /obj/item/seeds/liberty diff --git a/modular_doppler/loadout_categories/categories/shoes.dm b/modular_doppler/loadout_categories/categories/shoes.dm new file mode 100644 index 0000000000000..7c8cdcb2d2753 --- /dev/null +++ b/modular_doppler/loadout_categories/categories/shoes.dm @@ -0,0 +1,94 @@ +/datum/loadout_category/feet + category_name = "Feet" + category_ui_icon = FA_ICON_SHOE_PRINTS + type_to_generate = /datum/loadout_item/shoes + tab_order = /datum/loadout_category/head::tab_order + 1 + +/* +* LOADOUT ITEM DATUMS FOR THE SHOE SLOT +*/ +/datum/loadout_item/shoes + abstract_type = /datum/loadout_item/shoes + +/datum/loadout_item/shoes/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(initial(outfit_important_for_life.shoes)) + .. () + return TRUE + +/datum/loadout_item/shoes/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK) + if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only) + if(outfit.shoes) + LAZYADD(outfit.backpack_contents, outfit.shoes) + outfit.shoes = item_path + else + outfit.shoes = item_path + +/datum/loadout_item/shoes/sneakers + name = "Sneakers" + item_path = /obj/item/clothing/shoes/sneakers + +/datum/loadout_item/shoes/sneakers_rainbow + name = "Rainbow Sneakers" + item_path = /obj/item/clothing/shoes/sneakers/rainbow + +/datum/loadout_item/shoes/jackboots + name = "Jackboots" + item_path = /obj/item/clothing/shoes/jackboots + +/datum/loadout_item/shoes/workboots + name = "Work Boots" + item_path = /obj/item/clothing/shoes/workboots + +/datum/loadout_item/shoes/workboots_mining + name = "Mining Boots" + item_path = /obj/item/clothing/shoes/workboots/mining + +/datum/loadout_item/shoes/laceup + name = "Lace-Up Shoes" + item_path = /obj/item/clothing/shoes/laceup + +/datum/loadout_item/shoes/sandal + name = "Sandals" + item_path = /obj/item/clothing/shoes/sandal + +/datum/loadout_item/shoes/magboots + name = "Magboots" + item_path = /obj/item/clothing/shoes/magboots + +/datum/loadout_item/shoes/winterboots + name = "Winter Boots" + item_path = /obj/item/clothing/shoes/winterboots + +/datum/loadout_item/shoes/clown_shoes + name = "Clown Shoes" + item_path = /obj/item/clothing/shoes/clown_shoes + +/datum/loadout_item/shoes/jester_shoes + name = "Jester Shoes" + item_path = /obj/item/clothing/shoes/jester_shoes + +/datum/loadout_item/shoes/ducky_shoes + name = "Ducky Shoes" + item_path = /obj/item/clothing/shoes/ducky_shoes + +/datum/loadout_item/shoes/wheelys + name = "Wheelys" + item_path = /obj/item/clothing/shoes/wheelys + +/datum/loadout_item/shoes/cowboy + name = "Cowboy Boots" + item_path = /obj/item/clothing/shoes/cowboy + +/datum/loadout_item/shoes/cowboy/lizard + name = "Lizard Cowboy Boots" + item_path = /obj/item/clothing/shoes/cowboy/lizard + +/datum/loadout_item/shoes/russian + name = "Russian Boots" + item_path = /obj/item/clothing/shoes/russian + +/datum/loadout_item/shoes/pirate + name = "Pirate Boots" + item_path = /obj/item/clothing/shoes/pirate + + diff --git a/modular_doppler/loadout_categories/categories/weapons.dm b/modular_doppler/loadout_categories/categories/weapons.dm new file mode 100644 index 0000000000000..923dc94ca099c --- /dev/null +++ b/modular_doppler/loadout_categories/categories/weapons.dm @@ -0,0 +1,45 @@ +/// Inhand items (Moves overrided items to backpack) +/datum/loadout_category/weapons + category_name = "Weapons" + category_ui_icon = FA_ICON_GUN + type_to_generate = /datum/loadout_item/weapon + tab_order = /datum/loadout_category/inhands::tab_order + 1 + +/datum/loadout_item/weapon + abstract_type = /datum/loadout_item/weapon + +/datum/loadout_item/weapon/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.l_hand && !outfit.r_hand) + outfit.r_hand = item_path + else + if(outfit.l_hand) + LAZYADD(outfit.backpack_contents, outfit.l_hand) + outfit.l_hand = item_path + +/datum/loadout_item/weapon/toy_sword + name = "Toy Sword" + item_path = /obj/item/toy/sword + +/datum/loadout_item/weapon/toy_gun + name = "Toy Gun" + item_path = /obj/item/toy/gun + +/datum/loadout_item/weapon/toy_laser_red + name = "Red Toy Laser" + item_path = /obj/item/gun/energy/laser/redtag + +/datum/loadout_item/weapon/toy_laser_blue + name = "Blue Toy Laser" + item_path = /obj/item/gun/energy/laser/bluetag + +/datum/loadout_item/weapon/donk_pistol + name = "Donk Pistol" + item_path = /obj/item/gun/ballistic/automatic/pistol/toy + +/datum/loadout_item/weapon/donk_shotgun + name = "Donk Shotgun" + item_path = /obj/item/gun/ballistic/shotgun/toy/unrestricted + +/datum/loadout_item/weapon/donk_rifle + name = "Donk Rifle" + item_path = /obj/item/gun/ballistic/automatic/toy/unrestricted diff --git a/modular_doppler/loadout_categories/loadout_checkers.dm b/modular_doppler/loadout_categories/loadout_checkers.dm new file mode 100644 index 0000000000000..0adb23e74274e --- /dev/null +++ b/modular_doppler/loadout_categories/loadout_checkers.dm @@ -0,0 +1,162 @@ +// -- The loadout item datum and related procs. -- +/// Called after a loadout item gets a custom description +/atom/proc/on_loadout_custom_described() + return + +/* + * Generate a list of singleton loadout_item datums from all subtypes of [type_to_generate] + * + * returns a list of singleton datums. + */ +/proc/generate_loadout_items(type_to_generate) + RETURN_TYPE(/list) + + . = list() + if(!ispath(type_to_generate)) + CRASH("generate_loadout_items(): called with an invalid or null path as an argument!") + + for(var/datum/loadout_item/found_type as anything in subtypesof(type_to_generate)) + /// Any item without a name is "abstract" + if(isnull(initial(found_type.name))) + continue + + if(!ispath(initial(found_type.item_path))) + stack_trace("generate_loadout_items(): Attempted to instantiate a loadout item ([initial(found_type.name)]) with an invalid or null typepath! (got path: [initial(found_type.item_path)])") + continue + + var/datum/loadout_item/spawned_type = new found_type() + GLOB.all_loadout_datums[spawned_type.item_path] = spawned_type + . |= spawned_type + +/datum/loadout_category + var/erp_category = FALSE + +/datum/loadout_item + /// If set, is a list of job names of which can get the loadout item + var/list/restricted_roles + /// If set, is a list of job names of which can't get the loadout item + var/list/blacklisted_roles + /// If set, is a list of species which can get the loadout item + var/list/restricted_species + /// Whether the item requires a specific season in order to be available + var/required_season = null + /// If the item won't appear when the ERP config is disabled + var/erp_item = FALSE + /// If the item goes into the special erp box + var/erp_box = FALSE + +/* + * Place our [var/item_path] into [outfit]. + * + * By default, just adds the item into the outfit's backpack contents, if non-visual. + * + * equipper - If we're equipping our outfit onto a mob at the time, this is the mob it is equipped on. Can be null. + * outfit - The outfit we're equipping our items into. + * visual - If TRUE, then our outfit is only for visual use (for example, a preview). + * override_items - The type of override to use. + */ +/datum/loadout_item/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK) + if(!visuals_only) + LAZYADD(outfit.backpack_contents, item_path) + +/* + * To be called before insert_path_into_outfit() + * + * Checks if an important_for_life item exists and puts the loadout item into the backpack if they would take up the same slot as it. + * + * equipper - If we're equipping our outfit onto a mob at the time, this is the mob it is equipped on. Can be null. + * outfit - The outfit we're equipping our items into. + * outfit_important_for_life - The outfit whose slots we want to make sure we don't equip an item into. + * visual - If TRUE, then our outfit is only for visual use (for example, a preview). + * + * Returns TRUE if there is an important_for_life item in the slot that the loadout item would normally occupy, FALSE otherwise + */ +/datum/loadout_item/proc/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) + outfit_important_for_life = equipper.dna.species.outfit_important_for_life + if(!outfit_important_for_life || !pre_equip_item(outfit, outfit_important_for_life, src, visuals_only)) + insert_path_into_outfit(outfit, src, visuals_only) + if(!visuals_only) + LAZYADD(outfit.backpack_contents, item_path) + +/* + * Called after the item is equipped on [equipper], at the end of character setup. + */ +/datum/loadout_item/proc/post_equip_item(datum/preferences/preference_source, mob/living/carbon/human/equipper) + return FALSE + +/** + * Called before a loadout item is given to a mob, making sure that they're + * elligible to receive it, based on all of that item's restrictions, if any. + * + * Returns `TRUE` if `target` is allowed to receive this item, `FALSE` if not. + */ +/datum/loadout_item/proc/can_be_applied_to(mob/living/target, datum/preferences/preference_source, datum/job/equipping_job, silent = FALSE) + var/client/client = preference_source.parent + if(restricted_roles && equipping_job && !(equipping_job.title in restricted_roles)) + if(client && !silent) + to_chat(target, span_warning("You were unable to get a loadout item ([initial(item_path.name)]) due to job restrictions!")) + return FALSE + + if(blacklisted_roles && equipping_job && (equipping_job.title in blacklisted_roles)) + if(client && !silent) + to_chat(target, span_warning("You were unable to get a loadout item ([initial(item_path.name)]) due to job blacklists!")) + return FALSE + + if(iscarbon(target)) + var/mob/living/carbon/carbon_target = target + var/datum/dna/dna = carbon_target.dna + if(!istype(dna) || (restricted_species && !(dna.species.id in restricted_species))) + if(client && !silent) + to_chat(target, span_warning("You were unable to get a loadout item ([initial(item_path.name)]) due to species restrictions!")) + return FALSE + return TRUE + +/datum/loadout_item/get_ui_buttons() + var/list/buttons = ..() + + if(can_be_named) + UNTYPED_LIST_ADD(buttons, list( + "label" = "Change description", + "act_key" = "set_description", + "button_icon" = FA_ICON_PEN, + "active_key" = INFO_DESCRIBED, + )) + return buttons + +/datum/loadout_item/to_ui_data() + var/list/formatted_item = ..() + formatted_item["restricted_roles"] = restricted_roles + formatted_item["blacklisted_roles"] = blacklisted_roles + formatted_item["restricted_species"] = restricted_species + + return formatted_item + +/datum/loadout_item/handle_loadout_action(datum/preference_middleware/loadout/manager, mob/user, action, params) + if(action == "set_description" && can_be_named) + return set_description(manager, user) + return ..() + +/// Sets the description of the item. +/datum/loadout_item/proc/set_description(datum/preference_middleware/loadout/manager, mob/user) + var/list/loadout = manager.preferences.read_preference(/datum/preference/loadout) + var/input_desc = tgui_input_text( + user = user, + message = "What description do you want to give the [name]? Leave blank to clear.", + title = "[name] description", + default = loadout?[item_path]?[INFO_DESCRIBED], // plop in existing description (if any) + max_length = MAX_DESC_LEN, + ) + if(QDELETED(src) || QDELETED(user) || QDELETED(manager) || QDELETED(manager.preferences)) + return FALSE + + loadout = manager.preferences.read_preference(/datum/preference/loadout) // Make sure no shenanigans happened + if(!loadout?[item_path]) + return FALSE + + if(input_desc) + loadout[item_path][INFO_DESCRIBED] = input_desc + else if(input_desc == "") + loadout[item_path] -= INFO_DESCRIBED + + manager.preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout) + return TRUE diff --git a/tgstation.dme b/tgstation.dme index f851caa90d8f8..f36213a170dc7 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -400,6 +400,7 @@ #include "code\__DEFINES\~doppler_defines\is_helpers.dm" #include "code\__DEFINES\~doppler_defines\keybindings.dm" #include "code\__DEFINES\~doppler_defines\living.dm" +#include "code\__DEFINES\~doppler_defines\loadout.dm" #include "code\__DEFINES\~doppler_defines\obj_flags_doppler.dm" #include "code\__DEFINES\~doppler_defines\reagent_forging_tools.dm" #include "code\__DEFINES\~doppler_defines\reskin_defines.dm" @@ -6457,6 +6458,19 @@ #include "modular_doppler\indicators\code\sealed.dm" #include "modular_doppler\indicators\code\ssd_indicator.dm" #include "modular_doppler\languages\language_datums.dm" +#include "modular_doppler\loadout_categories\loadout_checkers.dm" +#include "modular_doppler\loadout_categories\categories\belts.dm" +#include "modular_doppler\loadout_categories\categories\clothing.dm" +#include "modular_doppler\loadout_categories\categories\ears.dm" +#include "modular_doppler\loadout_categories\categories\erp.dm" +#include "modular_doppler\loadout_categories\categories\glasses.dm" +#include "modular_doppler\loadout_categories\categories\gloves.dm" +#include "modular_doppler\loadout_categories\categories\heads.dm" +#include "modular_doppler\loadout_categories\categories\inhands.dm" +#include "modular_doppler\loadout_categories\categories\masks.dm" +#include "modular_doppler\loadout_categories\categories\pockets.dm" +#include "modular_doppler\loadout_categories\categories\shoes.dm" +#include "modular_doppler\loadout_categories\categories\weapons.dm" #include "modular_doppler\modular_antagonist\code\antag_datum.dm" #include "modular_doppler\modular_cosmetics\code\jacket_pockets.dm" #include "modular_doppler\modular_cosmetics\code\hands\rings.dm"