diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm new file mode 100644 index 0000000000..37e6e478b7 --- /dev/null +++ b/code/citadel/custom_loadout/custom_items.dm @@ -0,0 +1,2 @@ + +//For custom items. diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm new file mode 100644 index 0000000000..64eec2ba06 --- /dev/null +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -0,0 +1,61 @@ + +//Proc that does the actual loading of items to mob +/*Itemlists are formatted as +"[typepath]" = number_of_it_to_spawn +*/ + +#define DROP_TO_FLOOR 0 +#define LOADING_TO_HUMAN 1 + +/proc/handle_roundstart_items(mob/living/M, ckey_override, job_override, special_override) + if(!istype(M) || (!M.ckey && !ckey_override) || (!M.mind && (!job_override || !special_override))) + return FALSE + return load_itemlist_to_mob(M, parse_custom_roundstart_items(ckey_override? ckey_override : M.ckey, M.name, job_override? job_override : M.mind.assigned_role, special_override? special_override : M.mind.special_role), TRUE, TRUE, FALSE) + +//Just incase there's extra mob selections in the future..... +/proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) + if(!istype(L) || !islist(itemlist)) + return FALSE + var/loading_mode = DROP_TO_FLOOR + var/turf/current_turf = get_turf(L) + if(ishuman(L)) + loading_mode = LOADING_TO_HUMAN + switch(loading_mode) + if(DROP_TO_FLOOR) + for(var/I in itemlist) + var/typepath = text2path(I) + if(!typepath) + continue + for(var/i = 0, i < itemlist[I], i++) + new typepath(current_turf) + return TRUE + if(LOADING_TO_HUMAN) + return load_itemlist_to_human(L, itemlist, drop_on_floor_if_full, load_to_all_slots, replace_slots) + +/proc/load_itemlist_to_human(mob/living/carbon/human/H, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) + if(!istype(H) || !islist(itemlist)) + return FALSE + var/turf/T = get_turf(H) + for(var/item in itemlist) + var/path = item + if(!ispath(path)) + path = text2path(path) + if(!path) + continue + var/amount = itemlist[item] + for(var/i in 1 to amount) + var/atom/movable/loaded_atom = new path + if(!istype(loaded_atom)) + QDEL_NULL(loaded_atom) + continue + if(!istype(loaded_atom, /obj/item)) + loaded_atom.forceMove(T) + continue + var/obj/item/loaded = loaded_atom + var/obj/item/storage/S = H.get_item_by_slot(slot_back) + if(istype(S)) + S.handle_item_insertion(loaded, TRUE, H) //Force it into their backpack + continue + if(!H.put_in_hands(loaded)) //They don't have one/somehow that failed, put it in their hands + loaded.forceMove(T) //Guess we're just dumping it on the floor! + return TRUE diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm new file mode 100644 index 0000000000..0ed38e8d41 --- /dev/null +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -0,0 +1,71 @@ + +GLOBAL_LIST(custom_item_list) +//Layered list in form of custom_item_list[ckey][job][items][amounts] +//ckey is key, job is specific jobs, or "ALL" for all jobs, items for items, amounts for amount of item. + +//File should be in the format of ckey|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount +//Each ckey should be in a different line +//if there's multiple entries of a single ckey the later ones will add to the earlier definitions. + +/proc/reload_custom_roundstart_items_list(custom_filelist) + if(!custom_filelist) + custom_filelist = "config/custom_roundstart_items.txt" + GLOB.custom_item_list = list() + var/list/file_lines = world.file2list(custom_filelist) + for(var/line in file_lines) + if(length(line) == 0) //Emptyline, no one cares. + continue + if(copytext(line,1,3) == "//") //Commented line, ignore. + continue + var/ckey_str_sep = findtext(line, "|") //Process our stuff.. + var/char_str_sep = findtext(line, "|", ckey_str_sep+1) + var/job_str_sep = findtext(line, "|", char_str_sep+1) + var/item_str_sep = findtext(line, "|", job_str_sep+1) + var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) + var/char_str = copytext(line, ckey_str_sep+1, char_str_sep) + var/job_str = copytext(line, char_str_sep+1, job_str_sep) + var/item_str = copytext(line, job_str_sep+1, item_str_sep) + if(!ckey_str || !char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str)) + log_admin("Errored custom_items_whitelist line: [line] - Component/separator missing!") + if(!islist(GLOB.custom_item_list[ckey_str])) + GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized.. + var/list/characters = splittext(char_str, "/") + for(var/character in characters) + if(!islist(GLOB.custom_item_list[ckey_str][character])) + GLOB.custom_item_list[ckey_str][character] = list() + var/list/jobs = splittext(job_str, "/") + for(var/job in jobs) + for(var/character in characters) + if(!islist(GLOB.custom_item_list[ckey_str][character][job])) + GLOB.custom_item_list[ckey_str][character][job] = list() //Initialize item list for this job of this ckey if not already initialized. + var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount + for(var/item_string in item_strings) + var/path_str_sep = findtext(item_string, "=") + var/path = copytext(item_string, 1, path_str_sep) //Path to spawn + var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn + //world << "DEBUG: Item string [item_string] processed" + amount = text2num(amount) + path = text2path(path) + if(!ispath(path) || !isnum(amount)) + log_admin("Errored custom_items_whitelist line: [line] - Path/number for item missing or invalid.") + for(var/character in characters) + for(var/job in jobs) + if(!GLOB.custom_item_list[ckey_str][character][job][path]) //Doesn't exist, make it exist! + GLOB.custom_item_list[ckey_str][character][job][path] = amount + else + GLOB.custom_item_list[ckey_str][character][job][path] += amount //Exists, we want more~ + return GLOB.custom_item_list + +/proc/parse_custom_roundstart_items(ckey, char_name = "ALL", job_name = "ALL", special_role) + var/list/ret = list() + if(GLOB.custom_item_list[ckey]) + for(var/char in GLOB.custom_item_list[ckey]) + if((char_name == char) || (char_name == "ALL") || (char == "ALL")) + for(var/job in GLOB.custom_item_list[ckey][char]) + if((job_name == job) || (job == "ALL") || (job_name == "ALL") || (special_role && (job == special_role))) + for(var/item_path in GLOB.custom_item_list[ckey][char][job]) + if(ret[item_path]) + ret[item_path] += GLOB.custom_item_list[ckey][char][job][item_path] + else + ret[item_path] = GLOB.custom_item_list[ckey][char][job][item_path] + return ret diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index c4d8335890..43b523fcd1 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -292,6 +292,7 @@ load("config/game_options.txt","game_options") load("config/policies.txt", "policies") loadsql("config/dbconfig.txt") + reload_custom_roundstart_items_list() if (maprotation) loadmaplist("config/maps.txt") diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index f28373ef22..012c2e33af 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -407,7 +407,7 @@ SUBSYSTEM_DEF(job) if(job && H) job.after_spawn(H, M) - + handle_roundstart_items(H, M.ckey, H.mind.assigned_role, H.mind.special_role) return H diff --git a/config/custom_roundstart_items.txt b/config/custom_roundstart_items.txt new file mode 100644 index 0000000000..dd3ed5f2c3 --- /dev/null +++ b/config/custom_roundstart_items.txt @@ -0,0 +1,9 @@ +//File should be in the format of ckey|exact character name/exact second character name/ALL for all chars|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount +//Each ckey should be in a different line +//if there's multiple entries of a single ckey the later ones will add to the earlier definitions. +//is obviously a comment. +//Recommend defining one job per line, but do what you want. +//test1|Secondary Memenamefortesting|testjob1/test job 2/ALL|/obj/item/gun/energy/laser=3;/obj/item/gun/energy/laser/retro=1;/obj/item/gun/energy=2 +//test1|Memename Lastname|testjob1|/obj/item/device/aicard=3;/obj/item/device/flightpack=1;/obj/item/gun/energy=3 +//kevinz000|Skylar Lineman|ALL|/obj/item/bikehorn/airhorn=1 +//kevinz000|ALL|Clown|/obj/item/bikehorn=1 diff --git a/tgstation.dme b/tgstation.dme index dbd48407ad..4a1a0f3925 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -173,6 +173,9 @@ #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" #include "code\citadel\dogborgstuff.dm" +#include "code\citadel\custom_loadout\custom_items.dm" +#include "code\citadel\custom_loadout\load_to_mob.dm" +#include "code\citadel\custom_loadout\read_from_file.dm" #include "code\citadel\organs\breasts.dm" #include "code\citadel\organs\eggsack.dm" #include "code\citadel\organs\genitals.dm"