From 412af67ede10595c11ecc7796f92eda8e09ea003 Mon Sep 17 00:00:00 2001 From: VerySoft Date: Fri, 6 Dec 2024 06:59:20 -0500 Subject: [PATCH 1/4] 0659 --- code/__defines/admin_vr.dm | 1 + code/modules/admin/verbs/smite.dm | 5 +- .../preference_setup/general/01_basic.dm | 2 + code/modules/client/stored_item.dm | 142 +++++++- code/modules/economy/coins_vr.dm | 13 + .../character_persistance_core.dm | 336 ++++++++++++++++++ .../living/Character Persist/item_storage.dm | 119 +++++++ code/modules/mob/living/Magic/healing.dm | 50 +++ code/modules/mob/living/Magic/magic.dm | 137 +++++++ vorestation.dme | 2 + 10 files changed, 788 insertions(+), 19 deletions(-) create mode 100644 code/modules/mob/living/Character Persist/character_persistance_core.dm create mode 100644 code/modules/mob/living/Character Persist/item_storage.dm create mode 100644 code/modules/mob/living/Magic/healing.dm create mode 100644 code/modules/mob/living/Magic/magic.dm diff --git a/code/__defines/admin_vr.dm b/code/__defines/admin_vr.dm index 70085fea8e3..f84b7521764 100644 --- a/code/__defines/admin_vr.dm +++ b/code/__defines/admin_vr.dm @@ -7,3 +7,4 @@ //RS Add #define SMITE_GIVECHEM "Give Reagent" #define SMITE_PURGECHEM "Purge All Reagents" +#define SMITE_XP "Grant XP" diff --git a/code/modules/admin/verbs/smite.dm b/code/modules/admin/verbs/smite.dm index 98eec056f13..5f2a472dae8 100644 --- a/code/modules/admin/verbs/smite.dm +++ b/code/modules/admin/verbs/smite.dm @@ -8,7 +8,7 @@ if(!istype(target)) return - var/list/smite_types = list(SMITE_BREAKLEGS,SMITE_BLUESPACEARTILLERY,SMITE_SPONTANEOUSCOMBUSTION,SMITE_LIGHTNINGBOLT, + var/list/smite_types = list(SMITE_XP,SMITE_BREAKLEGS,SMITE_BLUESPACEARTILLERY,SMITE_SPONTANEOUSCOMBUSTION,SMITE_LIGHTNINGBOLT, SMITE_SHADEKIN_ATTACK,SMITE_SHADEKIN_NOMF,SMITE_AD_SPAM,SMITE_REDSPACE_ABDUCT,SMITE_AUTOSAVE,SMITE_AUTOSAVE_WIDE,SMITE_GIVECHEM,SMITE_PURGECHEM) var/smite_choice = tgui_input_list(usr, "Select the type of SMITE for [target]","SMITE Type Choice", smite_types) @@ -164,6 +164,9 @@ if(SMITE_PURGECHEM) purge_chems(target, src) + if(SMITE_XP) //RS ADD + target.grant_xp() //RS ADD + else return //Injection? Don't print any messages. diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index f9423f088a4..eca1b85809e 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -103,7 +103,9 @@ if (!isnull(raw_name) && CanUseTopic(user)) var/new_name = sanitize_name(raw_name, pref.species, is_FBP()) if(new_name) + var/old_name = pref.real_name //RS ADD pref.real_name = new_name + user.etching_rename(old_name, new_name) //RS ADD return TOPIC_REFRESH else to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") diff --git a/code/modules/client/stored_item.dm b/code/modules/client/stored_item.dm index cd0f8829d29..a8fb2fa4b54 100644 --- a/code/modules/client/stored_item.dm +++ b/code/modules/client/stored_item.dm @@ -9,6 +9,7 @@ density = FALSE var/busy_bank = FALSE var/static/list/item_takers = list() + var/static/list/unlockable_takers = list() //RS ADD /obj/machinery/item_bank/proc/persist_item_savefile_path(mob/user) return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/persist_item.sav" @@ -51,6 +52,12 @@ F["persist name"] >> persist_name return persist_name +//RS ADD START +/obj/machinery/item_bank/proc/legacy_detect(mob/living/user) + if (fexists(src.persist_item_savefile_path(user))) + return TRUE + return FALSE +//RS ADD END /obj/machinery/item_bank/Initialize() . = ..() @@ -72,16 +79,22 @@ to_chat(user, "\The [src] is already in use.") return busy_bank = TRUE - var/I = persist_item_savefile_load(user, "type") - var/Iname = persist_item_savefile_load(user, "name") - var/choice = tgui_alert(user, "What would you like to do [src]?", "[src]", list("Check contents", "Retrieve item", "Info", "Cancel"), timeout = 10 SECONDS) + if(legacy_detect(user)) //RS EDIT START + if(tgui_alert(user, "A legacy item has been detected in storage. This item must be bound to a character. Would you like to add it to [user.real_name]'s general storage?", "[src] legacy item detected", list("Yes","No"), timeout = 10 SECONDS) == "Yes") + + var/itemname = persist_item_savefile_load(user, "name") + var/itemtype = persist_item_savefile_load(user, "type") + user.etching.legacy_conversion(itemname,itemtype) + var/path = src.persist_item_savefile_path(user) + fdel(path) + log_debug("[user]/[user.ckey] converted a legacy item persist file to an item_storage state. Item was, [itemname] - [itemtype]") + busy_bank = FALSE + return + var/choice = tgui_alert(user, "What would you like to do [src]?", "[src]", list("General", "Personal","Coin", "Info", "Cancel"), timeout = 10 SECONDS) if(!choice || choice == "Cancel" || !Adjacent(user) || inoperable() || panel_open) busy_bank = FALSE return - else if(choice == "Check contents" && I) - to_chat(user, "\The [src] has \the [Iname] for you!") - busy_bank = FALSE - else if(choice == "Retrieve item" && I) + else if(choice == "General") //RS EDIT END if(user.hands_are_full()) to_chat(user,"Your hands are full!") busy_bank = FALSE @@ -90,7 +103,17 @@ to_chat(user, "You have already taken something out of \the [src] this shift.") busy_bank = FALSE return - choice = tgui_alert(user, "If you remove this item from the bank, it will be unable to be stored again. Do you still want to remove it?", "[src]", list("No", "Yes"), timeout = 10 SECONDS) + var/list/our_item = list() //RS EDIT START + if(user.etching.item_storage.len) + our_item = tgui_input_list(user, "Which item would you like to retrieve?", "[src] - General Compartment",user.etching.item_storage) + if(!our_item) + busy_bank = FALSE + return + else + to_chat(user, "\The [src] doesn't seem to have anything for you...") + busy_bank = FALSE + return + choice = tgui_alert(user, "If you remove \the [our_item] from the bank, it will be unable to be stored again. Do you still want to remove it?", "[src]", list("No", "Yes"), timeout = 10 SECONDS) //RS EDIT END icon_state = "item_bank_o" if(!choice || choice == "No" || !Adjacent(user) || inoperable() || panel_open) busy_bank = FALSE @@ -100,26 +123,95 @@ busy_bank = FALSE icon_state = "item_bank" return - var/obj/N = new I(get_turf(src)) + var/ourtype = user.etching.item_storage[our_item] //RS EDIT + var/obj/N = new ourtype(get_turf(src)) //RS EDIT log_admin("[key_name_admin(user)] retrieved [N] from the item bank.") visible_message("\The [src] dispenses the [N] to \the [user].") user.put_in_hands(N) N.persist_storable = FALSE - var/path = src.persist_item_savefile_path(user) - var/savefile/F = new /savefile(src.persist_item_savefile_path(user)) - F["persist item"] << null - F["persist name"] << null - fdel(path) item_takers += user.ckey + user.etching.item_storage -= our_item //RS EDIT + user.etching.needs_saving = TRUE //RS EDIT busy_bank = FALSE icon_state = "item_bank" + else if(choice == "Info") - to_chat(user, "\The [src] can store a single item for you between shifts! Anything that has been retrieved from the bank cannot be stored again in the same shift. Anyone can withdraw from the bank one time per shift. Some items are not able to be accepted by the bank.") + to_chat(user, "\The [src] can store items for you between shifts! Anything that has been retrieved from the bank cannot be stored again in the same shift. Anyone can withdraw from the bank one time per shift. Some items are not able to be accepted by the bank.") //RS EDIT START busy_bank = FALSE return - else if(!I) - to_chat(user, "\The [src] doesn't seem to have anything for you...") + else if(choice == "Personal") + if(!user.etching.unlockables.len) + to_chat(user, "Your personal storage is empty...") + busy_bank = FALSE + return + var/our_item = tgui_input_list(user, "Which item would you like to retrieve?", "[src] - Personal Compartment",user.etching.unlockables) + if(!our_item) + busy_bank = FALSE + return + + icon_state = "item_bank_o" + if(!choice || choice == "No" || !Adjacent(user) || inoperable() || panel_open) + busy_bank = FALSE + icon_state = "item_bank" + return + + if("[user.real_name] - [our_item]" in unlockable_takers) + to_chat(user, "\The [src] buzzes. You have already claimed your [our_item] this shift.") + busy_bank = FALSE + return + + else if(!do_after(user, 10 SECONDS, src, exclusive = TASK_ALL_EXCLUSIVE) || inoperable()) + busy_bank = FALSE + icon_state = "item_bank" + return + var/ourtype = user.etching.unlockables[our_item] + var/obj/N = new ourtype(get_turf(src)) + log_admin("[key_name_admin(user)] retrieved [N] from the item bank.") + visible_message("\The [src] dispenses the [N] to \the [user].") + user.put_in_hands(N) + N.name = "[user]'s [N.name]" + N.persist_storable = FALSE + unlockable_takers += "[user.real_name] - [our_item]" busy_bank = FALSE + icon_state = "item_bank" + + else if(choice == "Coin") + if(user.etching) + var/datum/etching/E = user.etching + if(E.triangles <= 0) + to_chat(user, "You haven't got any coins banked...") + busy_bank = FALSE + return + else + var/ourtris = tgui_input_number(user, "How much would you like to withdraw? You have ◬:[E.triangles] banked.", "Withdraw", timeout = 10 SECONDS) + if(ourtris <= 0) + busy_bank = FALSE + return + if(ourtris > E.triangles) + to_chat(user, "\The [src] buzzes at you and flashes red. You do not have ◬:[ourtris] banked. You have a balance of ◬:[E.triangles]...") + busy_bank = FALSE + return + ourtris = round(ourtris) + E.triangles -= ourtris + visible_message("\The [src] rattles as it dispenses coins!") + busy_bank = FALSE + var/turf/here = get_turf(src) + var/obj/item/weapon/aliencoin/A + while(ourtris > 0) + if(ourtris >= 1000) + A = new /obj/item/weapon/aliencoin/exotic(here) + else if(ourtris >= 100) + A = new /obj/item/weapon/aliencoin/diamond(here) + else if(ourtris >= 20) + A = new /obj/item/weapon/aliencoin/phoron(here) + else if(ourtris >= 10) + A = new /obj/item/weapon/aliencoin/gold(here) + else if(ourtris >= 5) + A = new /obj/item/weapon/aliencoin/silver(here) + else + A = new /obj/item/weapon/aliencoin/basic(here) + ourtris -= A.value + //RS EDIT END /obj/machinery/item_bank/attackby(obj/item/O, mob/living/user) if(!ishuman(user)) @@ -128,6 +220,19 @@ to_chat(user, "\The [src] is already in use.") return busy_bank = TRUE + //RS EDIT BEGIN + if(istype(O, /obj/item/weapon/aliencoin)) + if(user.etching) + var/obj/item/weapon/aliencoin/coin = O + user.update_etching("triangles", coin.value) + user.drop_item() + to_chat(user, "\The [src] SCHLORPS up \the [O]!!!") + qdel(O) + busy_bank = FALSE + return + //RS EDIT END + user.etching.store_item(O,src) +/* //RS REMOVAL START - //Removed the old way of storing items, as it is no longer needed. var/I = persist_item_savefile_load(user, "type") if(!istool(O) && O.persist_storable) if(ispath(I)) @@ -158,6 +263,7 @@ else to_chat(user, "You cannot store \the [O]. \The [src] either does not accept that, or it has already been retrieved from storage this shift.") busy_bank = FALSE +*/ //RS REMOVAL END /////STORABLE ITEMS AND ALL THAT JAZZ///// //I am only really intending this to be used for single items. Mostly stuff you got right now, but can't/don't want to use right now. @@ -255,4 +361,4 @@ /obj/item/weapon/spacecasinocash persist_storable = FALSE /obj/item/device/personal_shield_generator - persist_storable = FALSE \ No newline at end of file + persist_storable = FALSE diff --git a/code/modules/economy/coins_vr.dm b/code/modules/economy/coins_vr.dm index 38ae0054cf6..9389eba4a6f 100644 --- a/code/modules/economy/coins_vr.dm +++ b/code/modules/economy/coins_vr.dm @@ -38,6 +38,19 @@ desc = "A curious triangular coin made primarily of some kind of dark, smooth metal. This one's markings appear to reveal a purple material underneath." value = 20 +//RS ADD START +/obj/item/weapon/aliencoin/diamond + name = "curious coin" + icon_state = "triangle-d" + desc = "A curious triangular coin made primarily of some kind of dark, smooth metal. This one's markings appear to reveal a shining material underneath." + value = 100 + +/obj/item/weapon/aliencoin/exotic + name = "curious coin" + icon_state = "triangle-e" + desc = "A curious triangular coin made primarily of some kind of dark, smooth metal. This one's markings appear to reveal a disturbing, absolutely black material underneath." + value = 1000 +//RS ADD END /obj/item/weapon/aliencoin/attack_self(mob/user as mob) var/result = rand(1, sides) diff --git a/code/modules/mob/living/Character Persist/character_persistance_core.dm b/code/modules/mob/living/Character Persist/character_persistance_core.dm new file mode 100644 index 00000000000..e8ee9a573ba --- /dev/null +++ b/code/modules/mob/living/Character Persist/character_persistance_core.dm @@ -0,0 +1,336 @@ +//RS FILE + +/mob/living + var/datum/etching/etching + var/admin_magic = FALSE + +/mob/living/Initialize() + . = ..() + init_etching() + +/mob/living/Login() + . = ..() + if(etching) + etching.load() + +/mob/living/Destroy() + if(etching && istype(etching, /datum/etching)) + etching.save(TRUE) + ..() + +/mob/living/Life() + . = ..() + if(etching) + etching.process_etching() + +/mob/living/proc/init_etching() + if((ishuman(src) && !(istype(src, /mob/living/carbon/human/dummy))) || isanimal(src)) + etching = new /datum/etching(src) + +/mob/living/proc/update_etching(mode,value) + if(etching) + etching.update_etching(mode,value) + +/mob/living/proc/grant_xp(kind,value) + if(!etching) + return + if(!kind || !value) + var/list/xp_list = list() + xp_list += etching.xp + xp_list += "New kind of XP" + kind = tgui_input_list(usr, "What kind of XP would you like to add?", "Grant XP", xp_list) + if(!kind) + return + if(kind == "New kind of XP") + kind = tgui_input_text(usr, "What kind of XP would you like to add?", "Grant XP", prevent_enter = TRUE) + value = tgui_input_number(usr, "How many [kind] should be granted?", "Grant [kind]") + if(!value) + return + + etching.grant_xp(kind,value) + +/mob/living/memory() + . = ..() + if(etching) + etching.report_status() + +/mob/proc/etching_rename(var/old_name,var/new_name) + var/old_path = "data/player_saves/[copytext(ckey, 1, 2)]/[ckey]/magic/[old_name]-etching.json" + if(!fexists(old_path)) + return + var/list/load = json_decode(file2text(old_path)) + + var/new_path = "data/player_saves/[copytext(ckey, 1, 2)]/[ckey]/magic/[new_name]-etching.json" + + if(isliving(src)) //We might be playing as the mob we want to rename + var/mob/living/L = src + if(L.real_name == old_name) //We are + var/datum/etching/E = L.etching + E.save_path = new_path //Update the save path, in case we need to save again later to the mob's new name + + var/json_to_file = json_encode(load) + if(!json_to_file) + log_debug("Saving: [new_path] failed jsonencode on rename function") + return + + //Write it out + rustg_file_write(json_to_file, new_path) + + if(!fexists(new_path)) + log_debug("Saving: [new_path] failed file write on rename function") + return + fdel(old_path) + if(fexists(old_path)) + log_debug("Saving: [old_path] failed to delete on rename function") + return + + +/datum/etching + var/mob/living/ourmob //Reference to the mob we are working with + var/event_character = FALSE //If true, saves to an alternative path and allows editing + + var/shutting_down = FALSE //If true it won't try to save again + var/save_path //The file path for the save/load function + var/list/xp = list() //A list of different experience values + + var/savable = TRUE //Will never save while false + var/needs_saving = FALSE //For if changes have occured, it will try to save if it can + var/save_cooldown = 0 + +/datum/etching/New(var/L) + log_debug("ETCHING STARTED") + if(!L) + log_debug("Etching: No target, delete self") + qdel(src) + return + if(!isliving(L)) + log_debug("Etching: Target [L] is not living, delete self") + qdel(src) + return + ourmob = L + log_debug("Etching: Registered to [ourmob.ckey]") + save_cooldown = rand(200,350) //Make the number be random so that there's less chance it tries to autosave everyone at the same time. + return ..() + +/datum/etching/Destroy() + . = ..() + ourmob = null + +/datum/etching/proc/process_etching() + if(savable) + if(save_cooldown <= 0) + save() + save_cooldown = rand(200,350) //Make the number be random so that there's less chance it tries to autosave everyone at the same time. + else + save_cooldown -- + +/datum/etching/proc/get_save_path() + + if(event_character) + save_path = "data/player_saves/[copytext(ourmob.ckey, 1, 2)]/[ourmob.ckey]/magic/[ourmob.real_name]-EVENT-etching.json" + else + save_path = "data/player_saves/[copytext(ourmob.ckey, 1, 2)]/[ourmob.ckey]/magic/[ourmob.real_name]-etching.json" + +/datum/etching/proc/load() + if(IsGuestKey(ourmob.key)) + return + if(!ourmob.ckey) + log_debug("Aborting etching load for [ourmob.real_name], no ckey") + savable = FALSE + return + + get_save_path() + + if(!save_path) + log_debug("Etching load failed: No save_path") + savable = FALSE + return + if(!fexists(save_path)) + log_debug("Etching load failed: No file '[save_path]' exists. Beginning setup.") + setup() + return + + var/content + try + content = file2text(save_path) + catch(var/exception/E_content) + error("Exception when loading etching content - Path: [save_path] - Content: [content]: [E_content]") + + if(!content) + log_debug("Etching failed to load for [ourmob.real_name], aborting and clearing save_path.") + save_path = null + savable = FALSE + return + + var/list/load + + try + load = json_decode(file2text(save_path)) + catch(var/exception/E_json_decode) + error("Exception decoding etching content - Path: [save_path] - Content: [content] - Load: [load]: [E_json_decode]") + + if(!load) + log_debug("Etching json_decode failed! File path: '[save_path]'. Load contents: '[content]'. Aborting and clearing save_path.") + save_path = null + savable = FALSE + return + + xp = null + xp = load["xp"] + + item_load(load) + + log_debug("Etching load complete for [ourmob.real_name].") + +/datum/etching/proc/save(delet = FALSE) + if(IsGuestKey(ourmob.key)) + return + + if((!savable && !event_character) || !needs_saving) + return + + if(shutting_down) //Don't try to save more than once if we're already saving and shutting down. + return + if(delet) //Our mob got deleted, so we're saving and quitting. + shutting_down = TRUE + + if(!save_path || !ishuman(ourmob) || istype(ourmob, /mob/living/carbon/human/dummy)) + if(shutting_down) + ourmob = null + qdel(src) + return + + var/list/to_save = list( + "xp" = xp + ) + + to_save += item_save() + + var/json_to_file + try + json_to_file = json_encode(to_save) + catch + error("Etching failed to encode to json for [ourmob.real_name]") + + if(!json_to_file) + log_debug("Saving: [save_path] failed json encode.") + return + + //Write it out + try + rustg_file_write(json_to_file, save_path) + catch + error("Etching failed to write to file for [ourmob.real_name]: [json_to_file] - [save_path]") + + if(!fexists(save_path)) + log_debug("Saving: [save_path] failed file write") + + needs_saving = FALSE + + if(shutting_down) + ourmob = null + qdel(src) + +/datum/etching/proc/setup() + + log_debug("setup") + + return + +/datum/etching/proc/update_etching(mode,value) + needs_saving = TRUE + +/datum/etching/proc/grant_xp(kind,value) + xp["[kind]"] += value + to_chat(ourmob,"You earned [value] [kind]!") + needs_saving = TRUE + +/datum/etching/proc/report_status() + if(!save_path) + return + + var/our_xp = report_xp() + if(our_xp) + . = our_xp + + to_chat(ourmob, .) + +/datum/etching/proc/report_xp() + for(var/thing in xp) + . += "[capitalize(thing)]: [xp[thing]]\n" + +/datum/etching/vv_edit_var(var_name, var_value) + to_world("[var_name]") + if(var_name == "event_character") + enable_event_character() + return + else if(var_name == "savable") + return FALSE + else if(var_name == "unlockables") + return FALSE + if(!event_character) + return FALSE + + else + needs_saving = TRUE + return ..() + +/datum/etching/get_view_variables_options() + return ..() + {" + + + + + "} + +/datum/etching/proc/enable_event_character() + event_character = TRUE + get_save_path() + savable = FALSE + +/client/view_var_Topic(href, href_list, hsrc) + . = ..() + + if(href_list["event_etching"]) + if(!check_rights(R_FUN)) return + + var/mob/living/L = locate(href_list["event_etching"]) + if(!L.etching) + to_chat(usr, "\The [L] has no etching.") + return + if(tgui_alert(usr, "Enable event mode for [L]'s etching? This will disable normal saving, but enable variable editing.","Confirm",list("Enable","Cancel")) != "Enable") return + + if(!L) + to_chat(usr, "\The [L] no longer exists.") + return + if(!L.etching) + to_chat(usr, "\The [L] has no etching.") + return + L.etching.enable_event_character() + if(href_list["save_etching"]) + if(!check_rights(R_FUN)) return + + var/mob/living/L = locate(href_list["save_etching"]) + if(!L.etching) + to_chat(usr, "\The [L] has no etching.") + return + if(!L.etching.savable && !L.etching.event_character) + to_chat(usr, "\The [L]'s etching can not be saved in this state.") + return + if(L.etching.event_character) + to_chat(usr, "Saving [L]'s event etching.") + else + to_chat(usr, "Saving [L]'s etching.") + L.etching.save() + if(href_list["load_etching"]) + if(!check_rights(R_FUN)) return + + var/mob/living/L = locate(href_list["load_etching"]) + if(!L.etching) + to_chat(usr, "\The [L] has no etching.") + return + if(L.etching.event_character) + to_chat(usr, "Loading [L]'s event etching.") + else + to_chat(usr, "Loading [L]'s etching.") + L.etching.load() diff --git a/code/modules/mob/living/Character Persist/item_storage.dm b/code/modules/mob/living/Character Persist/item_storage.dm new file mode 100644 index 00000000000..45e733530c6 --- /dev/null +++ b/code/modules/mob/living/Character Persist/item_storage.dm @@ -0,0 +1,119 @@ +//RS FILE +/* +TO DO: +Figure out how often the time codes get updated, to make sure multiple store instances won't duplicate the code +*/ + +#define item_storage_maximum 50 + +var/global/list/permanent_unlockables = list( + /obj/item/weapon/disk/nifsoft/compliance, + /obj/item/weapon/gun/energy/sizegun, + /obj/item/device/slow_sizegun, + /obj/item/weapon/gun/energy/mouseray, +) + +/datum/etching + var/triangles = 0 //Triangle money + var/list/item_storage = list() //Various items that are stored in the bank, these can only be stored and pulled out once + var/list/unlockables = list() //Scene items that, once stored, can be pulled once per round forever. + +/datum/etching/proc/store_item(item,var/obj/machinery/item_bank/bank) + if(!isobj(item)) + bank.busy_bank = FALSE + return + var/obj/O = item + if(!O.persist_storable) + to_chat(ourmob, "You cannot store \the [O]. \The [bank] either does not accept that, or it has already been retrieved from storage this shift.") + bank.busy_bank = FALSE + return + if(O.type in permanent_unlockables) + if(O.name in unlockables) + to_chat(ourmob, "\The [bank] has already catalogued \the [O] for you.") + bank.busy_bank = FALSE + return + unlockables += list(O.name = O.type) + to_chat(ourmob, "\The [bank] scans your [item]. It catalogues this to your personal storage! You will be able to retrieve \the [item] again in future shifts.") + needs_saving = TRUE + bank.unlockable_takers += "[ourmob.real_name] - [item]" + bank.busy_bank = FALSE + O.persist_storable = FALSE + return + + if(!istool(O)) + if(item_storage.len >= item_storage_maximum) + to_chat(ourmob, "You can not store \the [O]. Your lockbox is too full.") + bank.busy_bank = FALSE + return + var/choice = tgui_alert(ourmob, "If you store \the [O], anything it contains may be lost to \the [bank]. Are you sure?", "[bank]", list("Store", "Cancel"), timeout = 10 SECONDS) + if(!choice || choice == "Cancel" || !bank.Adjacent(ourmob) || bank.inoperable() || bank.panel_open) + bank.busy_bank = FALSE + return + for(var/obj/check in O.contents) + if(!check.persist_storable) + to_chat(ourmob, "\The [bank] buzzes. \The [O] contains [check], which cannot be stored. Please remove this item before attempting to store \the [O]. As a reminder, any contents of \the [O] will be lost if you store it with contents.") + bank.busy_bank = FALSE + return + ourmob.visible_message("\The [ourmob] begins storing \the [O] in \the [bank].","You begin storing \the [O] in \the [bank].") + bank.icon_state = "item_bank_o" + if(!do_after(ourmob, 10 SECONDS, bank, exclusive = TASK_ALL_EXCLUSIVE) || bank.inoperable()) + bank.busy_bank = FALSE + bank.icon_state = "item_bank" + return + save_item(O) + ourmob.visible_message("\The [ourmob] stores \the [O] in \the [bank].","You stored \the [O] in \the [bank].") + log_admin("[key_name_admin(ourmob)] stored [O] in the item bank.") + qdel(O) + bank.busy_bank = FALSE + bank.icon_state = "item_bank" + + else + to_chat(ourmob, "You cannot store \the [O]. \The [bank] either does not accept that, or it has already been retrieved from storage this shift.") + bank.busy_bank = FALSE + +/datum/etching/proc/save_item(var/obj/O) + item_storage += list("[initial(O.name)] - [time2text(world.realtime, "YYYYMMDDhhmmss")]" = O.type) + needs_saving = TRUE + +/datum/etching/proc/legacy_conversion(I_name,I_type) + item_storage += list("[I_name] - [time2text(world.realtime, "YYYYMMDDhhmmss")]" = I_type) + needs_saving = TRUE + +/datum/etching/update_etching(mode, value) + . = ..() + switch(mode) + if("triangles") + triangles += value + +/datum/etching/proc/report_money() + . = ": [triangles]\n\n" + return . + +/datum/etching/proc/item_load(var/list/load) + + if(!load) + return + + triangles = load["triangles"] + item_storage = null + item_storage = load["item_storage"] + unlockables = load["unlockables"] + +/datum/etching/proc/item_save() + var/list/to_save = list( + "triangles" = triangles, + "item_storage" = item_storage, + "unlockables" = unlockables + ) + + return to_save + +/datum/etching/report_status() + to_world("Hello from item") + . = ..() + + var/our_money = report_money() + if(our_money) + if(.) + . += "\n" + . += our_money diff --git a/code/modules/mob/living/Magic/healing.dm b/code/modules/mob/living/Magic/healing.dm new file mode 100644 index 00000000000..af2c60f426b --- /dev/null +++ b/code/modules/mob/living/Magic/healing.dm @@ -0,0 +1,50 @@ +//RS FILE +/////HEALING MAGIC///// + +#define HEALING_MAGIC "healing" + +/mob/living/proc/regenerate_other() + set name = "Regenerate" + set desc = "Spend energy to heal physical wounds in another creature." + set category = "Magic" + + if(!etching) + to_chat("You can't do magic.") //:C + return FALSE + + var/spell_lv = 1 //Determines how many slots you need devoted to this magic + var/spell_class = HEALING_MAGIC //Used with above, this is the kind of magic you need + var/req_standing = TRUE //If true, must be on your feet and unrestrained + var/req_corporeal = TRUE //If true, must not be phased out or otherwise ghostly + var/req_visible = TRUE //If true, must not be invisible + var/cost = 0 //Automatically determined by a variety of factors + + if(!admin_magic) + cost = etching.calculate_magic_cost(spell_class,spell_lv) + + if(!consider_magic(cost,spell_class,spell_lv,req_standing,req_corporeal,req_visible)) + return FALSE + + //Unique stuff goes beween here! + + var/list/viewed = oviewers(1) + var/list/targets = list() + for(var/mob/living/L in viewed) + targets += L + if(!targets.len) + to_chat(src,"Nobody nearby to mend!") + return FALSE + + var/mob/living/target = tgui_input_list(src,"Pick someone to mend:","Mend Other", targets) + if(!target) + return FALSE + + target.add_modifier(/datum/modifier/shadekin/heal_boop,1 MINUTE) + playsound(src, 'sound/effects/EMPulse.ogg', 75, 1) + visible_message("\The [src] touches \the [target]...") + face_atom(target) + + //STOP BEING UNIQUE + + consume_mana(cost, spell_lv) + return TRUE diff --git a/code/modules/mob/living/Magic/magic.dm b/code/modules/mob/living/Magic/magic.dm new file mode 100644 index 00000000000..68729e2ae29 --- /dev/null +++ b/code/modules/mob/living/Magic/magic.dm @@ -0,0 +1,137 @@ +//RS FILE +/* +TO DO: +make sure multiple instances of grant xp are additive, and don't overwrite +*/ + +#define BASE_MAGIC_COOLDOWN 15 +#define BASE_MAGIC_COST 33 + +/mob/living/proc/consider_magic(cost,spell_class,spell_lv,req_standing,req_corporeal,req_visible) + if(!etching.consider_magic(cost,spell_class,spell_lv)) + return FALSE + if(req_standing && (resting||weakened||buckled)) //Buckled is assuming that we might be restrained. Not bothering with checking carbon handcuffs, since nets exist and I am pretty sure that's just a buckle + to_chat(src, "You need to be standing and free to move around to do that!") + return FALSE + if(req_corporeal && incorporeal_move) + to_chat(src, "Can't do that while phased out!") + return FALSE + if(req_visible && invisibility) + to_chat(src, "Can't do that without revealing yourself!") + return FALSE + return TRUE + +/mob/living/proc/consume_mana(cost,spell_lv) + if(cost <= 0) + return + etching.consume_mana(cost,spell_lv) + +/datum/etching + var/true_name //Magic bs + var/mana = 0 //How much you have + var/max_mana = 0 //How much you could have + var/mana_regen = 0 //How fast it comes back + var/mana_cooldown = 0 //How soon you can do it again + var/mana_efficiency = 1 //Multiplier for how efficiently you use your mana + var/core //Head/body + var/l_arm + var/r_arm + var/l_leg + var/r_leg + +/datum/etching/Destroy() + . = ..() + ourmob = null + +/datum/etching/process_etching() + . = ..() + if(mana < max_mana) + mana += mana_regen + if(mana_cooldown) + mana_cooldown -- + +/datum/etching/proc/consume_mana(cost,spell_lv) + var/howmuch = mana - cost + if(howmuch < 0) + return FALSE + mana = howmuch + mana_cooldown = (BASE_MAGIC_COOLDOWN * spell_lv) //life tick * lv = about 30 seconds per level + return TRUE + +///datum/etching/update_etching(mode,value) +// . = ..() + +/datum/etching/proc/report_magic() + var/extra = FALSE + if(core) + . += "Core: [core]\n" + extra = TRUE + if(l_arm) + . += "[l_arm]\n" + extra = TRUE + if(r_arm) + . += "[r_arm]\n" + extra = TRUE + if(l_arm) + . += "[l_leg]\n" + extra = TRUE + if(r_leg) + . += "[r_leg]\n" + extra = TRUE + + if(extra) + . += "\n" + + return . + +/datum/etching/proc/consider_magic(cost,spell_class,spell_lv) + if(ourmob.admin_magic) + return TRUE + if(mana_cooldown) + to_chat(ourmob, "You are still recovering! (([mana_cooldown]))") + return FALSE + if(cost > mana) + to_chat(ourmob, "You haven't got enough mana! (([mana]/[cost]))") + return FALSE + +// if(not some_kind_of_level_check()) +// return FALSE + + return TRUE + +/datum/etching/proc/calculate_magic_cost(spell_class,spell_lv) + return (BASE_MAGIC_COST * spell_lv) * mana_efficiency + +/datum/etching/proc/magic_load(var/list/load) + + if(!load) + return + + true_name = load["true_name"] + core = load["core"] + l_arm = load["l_arm"] + r_arm = load["r_arm"] + l_leg = load["l_leg"] + r_leg = load["r_leg"] + +/datum/etching/proc/magic_save() + var/list/to_save = list( + "true_name" = true_name, + "core" = core, + "l_arm" = l_arm, + "r_arm" = r_arm, + "l_leg" = l_leg, + "r_leg" = r_leg + ) + + return to_save + +/datum/etching/report_status() + to_world("Hello from magic") + . = ..() + + var/our_magic = report_magic() + if(our_magic) + if(.) + . += "\n" + . += our_magic diff --git a/vorestation.dme b/vorestation.dme index 035518eb9ae..f063e53b456 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -3015,6 +3015,8 @@ #include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_powers.dm" #include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_species.dm" #include "code\modules\mob\living\carbon\human\species\xenomorphs\xenomorphs.dm" +#include "code\modules\mob\living\Character Persist\character_persistance_core.dm" +#include "code\modules\mob\living\Character Persist\item_storage.dm" #include "code\modules\mob\living\silicon\death.dm" #include "code\modules\mob\living\silicon\emote.dm" #include "code\modules\mob\living\silicon\laws.dm" From b11975ab227d3a8f6de28163206644785b601dc1 Mon Sep 17 00:00:00 2001 From: VerySoft Date: Sun, 8 Dec 2024 03:37:09 -0500 Subject: [PATCH 2/4] 0337 --- code/game/objects/random/misc_vr.dm | 24 +++++----- .../character_persistance_core.dm | 44 ++++++++++++++----- .../living/Character Persist/item_storage.dm | 5 ++- code/modules/mob/living/Magic/magic.dm | 1 - vorestation.dme | 2 +- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/code/game/objects/random/misc_vr.dm b/code/game/objects/random/misc_vr.dm index f16d2385d89..dc3193a8263 100644 --- a/code/game/objects/random/misc_vr.dm +++ b/code/game/objects/random/misc_vr.dm @@ -18,10 +18,10 @@ spawn_nothing_percentage = 50 /obj/random/awayloot/item_to_spawn() - return pick(prob(50);/obj/item/weapon/aliencoin/basic, - prob(40);/obj/item/weapon/aliencoin/silver, - prob(30);/obj/item/weapon/aliencoin/gold, - prob(20);/obj/item/weapon/aliencoin/phoron, + return pick(//prob(50);/obj/item/weapon/aliencoin/basic, //RS TEMP REMOVAL + //prob(40);/obj/item/weapon/aliencoin/silver, + //prob(30);/obj/item/weapon/aliencoin/gold, + //prob(20);/obj/item/weapon/aliencoin/phoron, prob(10);/obj/item/device/denecrotizer, prob(5);/obj/item/capture_crystal, prob(5);/obj/item/device/perfect_tele, @@ -54,10 +54,10 @@ /obj/random/awayloot/looseloot /obj/random/awayloot/looseloot/item_to_spawn() - return pick(prob(50);/obj/item/weapon/aliencoin, - prob(40);/obj/item/weapon/aliencoin/silver, - prob(30);/obj/item/weapon/aliencoin/gold, - prob(20);/obj/item/weapon/aliencoin/phoron, + return pick(//prob(50);/obj/item/weapon/aliencoin, //RS TEMP REMOVAL + //prob(40);/obj/item/weapon/aliencoin/silver, + //prob(30);/obj/item/weapon/aliencoin/gold, + //prob(20);/obj/item/weapon/aliencoin/phoron, prob(10);/obj/item/device/denecrotizer, prob(5);/obj/item/capture_crystal, prob(3);/obj/item/capture_crystal/great, @@ -109,10 +109,10 @@ spawn_nothing_percentage = 50 /obj/random/mainttoyloot/item_to_spawn() - return pick(prob(50);/obj/item/weapon/aliencoin/basic, - prob(40);/obj/item/weapon/aliencoin/silver, - prob(30);/obj/item/weapon/aliencoin/gold, - prob(20);/obj/item/weapon/aliencoin/phoron, + return pick(//prob(50);/obj/item/weapon/aliencoin/basic, //RS TEMP REMOVAL + //prob(40);/obj/item/weapon/aliencoin/silver, + //prob(30);/obj/item/weapon/aliencoin/gold, + //prob(20);/obj/item/weapon/aliencoin/phoron, prob(5);/obj/item/capture_crystal, prob(5);/obj/random/mouseray, prob(5);/obj/item/device/perfect_tele, diff --git a/code/modules/mob/living/Character Persist/character_persistance_core.dm b/code/modules/mob/living/Character Persist/character_persistance_core.dm index e8ee9a573ba..c6953a704c4 100644 --- a/code/modules/mob/living/Character Persist/character_persistance_core.dm +++ b/code/modules/mob/living/Character Persist/character_persistance_core.dm @@ -11,6 +11,7 @@ /mob/living/Login() . = ..() if(etching) + log_debug("Etching started: Registered to [ckey]") etching.load() /mob/living/Destroy() @@ -98,7 +99,6 @@ var/save_cooldown = 0 /datum/etching/New(var/L) - log_debug("ETCHING STARTED") if(!L) log_debug("Etching: No target, delete self") qdel(src) @@ -108,7 +108,6 @@ qdel(src) return ourmob = L - log_debug("Etching: Registered to [ourmob.ckey]") save_cooldown = rand(200,350) //Make the number be random so that there's less chance it tries to autosave everyone at the same time. return ..() @@ -135,7 +134,7 @@ if(IsGuestKey(ourmob.key)) return if(!ourmob.ckey) - log_debug("Aborting etching load for [ourmob.real_name], no ckey") + log_debug("Etching load failed: Aborting etching load for [ourmob.real_name], no ckey") savable = FALSE return @@ -179,7 +178,6 @@ xp = load["xp"] item_load(load) - log_debug("Etching load complete for [ourmob.real_name].") /datum/etching/proc/save(delet = FALSE) @@ -232,18 +230,20 @@ qdel(src) /datum/etching/proc/setup() - - log_debug("setup") - return /datum/etching/proc/update_etching(mode,value) needs_saving = TRUE -/datum/etching/proc/grant_xp(kind,value) +/datum/etching/proc/grant_xp(kind,value,quiet = FALSE,source) xp["[kind]"] += value - to_chat(ourmob,"You earned [value] [kind]!") + if(!quiet) + to_chat(ourmob,"You earned [value] [kind]! New total: ([xp["[kind]"]])") needs_saving = TRUE + if(source) + log_admin("earned [value] [kind] XP from [source]. Total: ([xp["[kind]"]])") + else + log_and_message_admins("granted [value] [kind] XP to [ourmob]/[ourmob.ckey]. Total: ([xp["[kind]"]])") /datum/etching/proc/report_status() if(!save_path) @@ -260,7 +260,6 @@ . += "[capitalize(thing)]: [xp[thing]]\n" /datum/etching/vv_edit_var(var_name, var_value) - to_world("[var_name]") if(var_name == "event_character") enable_event_character() return @@ -298,8 +297,8 @@ if(!L.etching) to_chat(usr, "\The [L] has no etching.") return - if(tgui_alert(usr, "Enable event mode for [L]'s etching? This will disable normal saving, but enable variable editing.","Confirm",list("Enable","Cancel")) != "Enable") return - + if(tgui_alert(usr, "Enable event mode for [L]'s etching? This will disable normal saving, but enable variable editing.","Confirm",list("Enable","Cancel")) != "Enable") + return if(!L) to_chat(usr, "\The [L] no longer exists.") return @@ -307,6 +306,7 @@ to_chat(usr, "\The [L] has no etching.") return L.etching.enable_event_character() + log_and_message_admins(" has enabled [L]'s etching event mode.") if(href_list["save_etching"]) if(!check_rights(R_FUN)) return @@ -322,6 +322,7 @@ else to_chat(usr, "Saving [L]'s etching.") L.etching.save() + log_and_message_admins(" saved [L]'s etching.") if(href_list["load_etching"]) if(!check_rights(R_FUN)) return @@ -334,3 +335,22 @@ else to_chat(usr, "Loading [L]'s etching.") L.etching.load() + log_and_message_admins(" has loaded [L]'s etching.") + +/* //Just for fun. UwU +/obj/belly/proc/xp(mob/living/ourprey) + if(!isliving(ourprey)) + return + + var/Pred = 0.01 + var/Prey = 0.01 + + if(owner.ckey) + Pred = 1 + if(ourprey.ckey) + Prey = 1 + if(Pred == 1) + owner.etching.grant_xp("Pred points",Prey,source = "eating [ourprey]") + if(Prey == 1) + ourprey.etching.grant_xp("Prey points",Pred,source = "being eaten by [owner]") +*/ diff --git a/code/modules/mob/living/Character Persist/item_storage.dm b/code/modules/mob/living/Character Persist/item_storage.dm index 45e733530c6..cefb53a81cb 100644 --- a/code/modules/mob/living/Character Persist/item_storage.dm +++ b/code/modules/mob/living/Character Persist/item_storage.dm @@ -38,6 +38,7 @@ var/global/list/permanent_unlockables = list( bank.unlockable_takers += "[ourmob.real_name] - [item]" bank.busy_bank = FALSE O.persist_storable = FALSE + log_admin("[key_name_admin(ourmob)] has unlocked [O]/[O.type] for [ourmob].") return if(!istool(O)) @@ -62,7 +63,7 @@ var/global/list/permanent_unlockables = list( return save_item(O) ourmob.visible_message("\The [ourmob] stores \the [O] in \the [bank].","You stored \the [O] in \the [bank].") - log_admin("[key_name_admin(ourmob)] stored [O] in the item bank.") + log_admin("[key_name_admin(ourmob)] stored [O]/[O.type] in the item bank for [ourmob].") qdel(O) bank.busy_bank = FALSE bank.icon_state = "item_bank" @@ -84,6 +85,7 @@ var/global/list/permanent_unlockables = list( switch(mode) if("triangles") triangles += value + needs_saving = TRUE /datum/etching/proc/report_money() . = ": [triangles]\n\n" @@ -109,7 +111,6 @@ var/global/list/permanent_unlockables = list( return to_save /datum/etching/report_status() - to_world("Hello from item") . = ..() var/our_money = report_money() diff --git a/code/modules/mob/living/Magic/magic.dm b/code/modules/mob/living/Magic/magic.dm index 68729e2ae29..1499ae525d0 100644 --- a/code/modules/mob/living/Magic/magic.dm +++ b/code/modules/mob/living/Magic/magic.dm @@ -127,7 +127,6 @@ make sure multiple instances of grant xp are additive, and don't overwrite return to_save /datum/etching/report_status() - to_world("Hello from magic") . = ..() var/our_magic = report_magic() diff --git a/vorestation.dme b/vorestation.dme index f063e53b456..6d9dac56efd 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -4342,7 +4342,6 @@ #include "maps\expedition_vr\beach\submaps\mountains_areas.dm" #include "maps\redgate\pizzaria\pizzaria_pois.dm" #include "maps\gateway_archive_vr\blackmarketpackers.dm" -#include "maps\groundbase\groundbase.dm" #include "maps\redgate\fantasy_items.dm" #include "maps\redgate\code\snowglobe_rs.dm" #include "maps\southern_cross\items\clothing\sc_accessory.dm" @@ -4351,6 +4350,7 @@ #include "maps\southern_cross\loadout\loadout_suit.dm" #include "maps\southern_cross\loadout\loadout_uniform.dm" #include "maps\southern_cross\loadout\loadout_vr.dm" +#include "maps\stellar_delight\stellar_delight.dm" #include "maps\submaps\_helpers.dm" #include "maps\submaps\_readme.dm" #include "maps\submaps\admin_use_vr\event_autonomous_drone.dm" From 18ddf8c821de332039aa79ceaa43be1434cd1024 Mon Sep 17 00:00:00 2001 From: VerySoft Date: Sun, 8 Dec 2024 17:09:52 -0500 Subject: [PATCH 3/4] attribution --- ATTRIBUTIONS.md | 5 +++++ icons/obj/aliencoins.dmi | Bin 913 -> 1194 bytes 2 files changed, 5 insertions(+) diff --git a/ATTRIBUTIONS.md b/ATTRIBUTIONS.md index d8f2553e640..5bc29e31819 100644 --- a/ATTRIBUTIONS.md +++ b/ATTRIBUTIONS.md @@ -329,3 +329,8 @@ **Link:** https://github.com/CHOMPStation2/CHOMPStation2/pull/9466
**License:** [CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)

+**File**: `icons/obj/aliencoins.dmi`
+**Creator:** VerySoft
+**Link:** https://github.com/VOREStation/VOREStation/pull/10476 -
+**License:** Licensed for use by VOREStation, Rogue Star, and their downstreams; unlicensed for further use without permission of copyright holder
+
diff --git a/icons/obj/aliencoins.dmi b/icons/obj/aliencoins.dmi index 53bfd53d043a01f3e8c6b7703f21f821d8332a3a..1600f7fcb9a47ab1bfd666835a36ba3be60f25f3 100644 GIT binary patch delta 1013 zcmY*UeM}p57%nV?@7-c%bWEw5bYci$WCA+O-6kNb+hA7Fxo#_B1_)-YY_s6FUb0(g zCYckFw8Pb|Y>N(LI1*$?Db#K=3Xx*F51i!~q@@mf2mQLX_wn=4@P}{mzR&ai@jlP< zwkP%^OU~>oFH29!ND+xd>C#;#G6CmSJ87LTa{^rs0p4hr?8yWG2o!*t%ZOw~U~$J~ zZ}EN<6r6pD4dm@N{mtCg1Q ze5>h#&oJHCy<=lSaZ-G%q}rJTfNA1@)Hl%xx!q)1r3?OH+og*YhbGNtL0U9^IO{Z) z9vIWAx*UeUkqMlUydEK~g zGtGK(-d<=MVD4$e@ zzd`lv#YOSgq1E93R$db$4|DbzqLI?_u)Y~_qRaDv&J65CtPO3mF;(*#uTMQp+aj>u zEZ)vkc{o+6ab%Kz%-b(m_L8`-iZO(3V<<%sO2BPc6Mm-EyGVaQ7uSj>N5!{k>rITa zyTGqsO}$gk>L$LSa4Vv!V32zPaZVAw zQE@!B_QTB$8eZ|enzkBf+p=(VQfcNV*Wj4_WhNQ?-w_>gLrU9g0}9YhaB&QhNYpR zX{c-(`uTBAW$k~Y#2+2&kdW#c@xg~jkc0l!T+Do7Mtt2lB6B5qb(NNumt1?b>eN4W C<|!%w delta 730 zcmZ3*IgwqpGr-TCmrII^fq{Y7)59eQNFM-U4rU;k$~4CmNO@0G^^rJm;6Tw`Ml~Rp zu_VYZn8D%MjWi&qb7FsOz2ae>RMv2N@d5)T2Bq&2a@$+@co`U&;yqm)Ln`LHy?Z-o zwS!2@Lje}2CJBS~@Abi(H+!#7F}*c2YT2v*dC_WaK9O6iWXz-)7#fbRblImnXZ7{z zm9q6m!=7C2J|S%^zJ7n^?rW#ZmENC?*;5z#{_u8<&u+2x2A^wdx^Lxi+^=6W_x+o% zhoeKT9)2zGhhv-4`Z$+$>*6Q7Z+~z;~zlS^iu(cpDPpU-W~q)zvlmseFfb6 zel^y0eO^-Mc>ccq@&EVh|Ns2U1h%UpZRzjEOMjbo*W2%o-|+o?`tz)RaaWgr5W5Mq zZex8>_5ZrE`UmgspMNJVw*jQ)!?*Y8-?_D)e}BHfK4P-_>-fB%PrvWn36=tC|IQ8Z z!px=f`JX&H`J8!Y<*%O(W%d_V{QPtEjQ*l{jl29JcJe3Qu}?bBUUdCGGf>6<_zBf^ z6K?CTnQ=b8I=im^{Cdaw4Qlam_P^_E6t>5ou$MpaRvc{X0b_3<=WOLahrIm(R~OGX z-@PaB`uQ}wPk$Ka*&q1KzUVps9ldwQ6861+R{Vaw{b!IcSR(^h!Sl~I-~9c3^G=<@ z?A!cHil6_7aDUdD0sUxZSug(ich0|me{%zljk>yyo(gv;RR>gTe~ HDWM4f6O(o; From c1795bd298fd06e7f781c938ec77c5b8ea5e2820 Mon Sep 17 00:00:00 2001 From: VerySoft Date: Sun, 8 Dec 2024 17:39:57 -0500 Subject: [PATCH 4/4] finish --- .../living/Character Persist/item_storage.dm | 8 +- code/modules/mob/living/Magic/healing.dm | 50 ------- code/modules/mob/living/Magic/magic.dm | 136 ------------------ 3 files changed, 2 insertions(+), 192 deletions(-) delete mode 100644 code/modules/mob/living/Magic/healing.dm delete mode 100644 code/modules/mob/living/Magic/magic.dm diff --git a/code/modules/mob/living/Character Persist/item_storage.dm b/code/modules/mob/living/Character Persist/item_storage.dm index cefb53a81cb..8a7ce966bd4 100644 --- a/code/modules/mob/living/Character Persist/item_storage.dm +++ b/code/modules/mob/living/Character Persist/item_storage.dm @@ -1,8 +1,4 @@ //RS FILE -/* -TO DO: -Figure out how often the time codes get updated, to make sure multiple store instances won't duplicate the code -*/ #define item_storage_maximum 50 @@ -73,11 +69,11 @@ var/global/list/permanent_unlockables = list( bank.busy_bank = FALSE /datum/etching/proc/save_item(var/obj/O) - item_storage += list("[initial(O.name)] - [time2text(world.realtime, "YYYYMMDDhhmmss")]" = O.type) + item_storage += list("[initial(O.name)] - [time2text(world.timeofday, "YYYYMMDDhhmmss")]" = O.type) needs_saving = TRUE /datum/etching/proc/legacy_conversion(I_name,I_type) - item_storage += list("[I_name] - [time2text(world.realtime, "YYYYMMDDhhmmss")]" = I_type) + item_storage += list("[I_name] - [time2text(world.timeofday, "YYYYMMDDhhmmss")]" = I_type) needs_saving = TRUE /datum/etching/update_etching(mode, value) diff --git a/code/modules/mob/living/Magic/healing.dm b/code/modules/mob/living/Magic/healing.dm deleted file mode 100644 index af2c60f426b..00000000000 --- a/code/modules/mob/living/Magic/healing.dm +++ /dev/null @@ -1,50 +0,0 @@ -//RS FILE -/////HEALING MAGIC///// - -#define HEALING_MAGIC "healing" - -/mob/living/proc/regenerate_other() - set name = "Regenerate" - set desc = "Spend energy to heal physical wounds in another creature." - set category = "Magic" - - if(!etching) - to_chat("You can't do magic.") //:C - return FALSE - - var/spell_lv = 1 //Determines how many slots you need devoted to this magic - var/spell_class = HEALING_MAGIC //Used with above, this is the kind of magic you need - var/req_standing = TRUE //If true, must be on your feet and unrestrained - var/req_corporeal = TRUE //If true, must not be phased out or otherwise ghostly - var/req_visible = TRUE //If true, must not be invisible - var/cost = 0 //Automatically determined by a variety of factors - - if(!admin_magic) - cost = etching.calculate_magic_cost(spell_class,spell_lv) - - if(!consider_magic(cost,spell_class,spell_lv,req_standing,req_corporeal,req_visible)) - return FALSE - - //Unique stuff goes beween here! - - var/list/viewed = oviewers(1) - var/list/targets = list() - for(var/mob/living/L in viewed) - targets += L - if(!targets.len) - to_chat(src,"Nobody nearby to mend!") - return FALSE - - var/mob/living/target = tgui_input_list(src,"Pick someone to mend:","Mend Other", targets) - if(!target) - return FALSE - - target.add_modifier(/datum/modifier/shadekin/heal_boop,1 MINUTE) - playsound(src, 'sound/effects/EMPulse.ogg', 75, 1) - visible_message("\The [src] touches \the [target]...") - face_atom(target) - - //STOP BEING UNIQUE - - consume_mana(cost, spell_lv) - return TRUE diff --git a/code/modules/mob/living/Magic/magic.dm b/code/modules/mob/living/Magic/magic.dm deleted file mode 100644 index 1499ae525d0..00000000000 --- a/code/modules/mob/living/Magic/magic.dm +++ /dev/null @@ -1,136 +0,0 @@ -//RS FILE -/* -TO DO: -make sure multiple instances of grant xp are additive, and don't overwrite -*/ - -#define BASE_MAGIC_COOLDOWN 15 -#define BASE_MAGIC_COST 33 - -/mob/living/proc/consider_magic(cost,spell_class,spell_lv,req_standing,req_corporeal,req_visible) - if(!etching.consider_magic(cost,spell_class,spell_lv)) - return FALSE - if(req_standing && (resting||weakened||buckled)) //Buckled is assuming that we might be restrained. Not bothering with checking carbon handcuffs, since nets exist and I am pretty sure that's just a buckle - to_chat(src, "You need to be standing and free to move around to do that!") - return FALSE - if(req_corporeal && incorporeal_move) - to_chat(src, "Can't do that while phased out!") - return FALSE - if(req_visible && invisibility) - to_chat(src, "Can't do that without revealing yourself!") - return FALSE - return TRUE - -/mob/living/proc/consume_mana(cost,spell_lv) - if(cost <= 0) - return - etching.consume_mana(cost,spell_lv) - -/datum/etching - var/true_name //Magic bs - var/mana = 0 //How much you have - var/max_mana = 0 //How much you could have - var/mana_regen = 0 //How fast it comes back - var/mana_cooldown = 0 //How soon you can do it again - var/mana_efficiency = 1 //Multiplier for how efficiently you use your mana - var/core //Head/body - var/l_arm - var/r_arm - var/l_leg - var/r_leg - -/datum/etching/Destroy() - . = ..() - ourmob = null - -/datum/etching/process_etching() - . = ..() - if(mana < max_mana) - mana += mana_regen - if(mana_cooldown) - mana_cooldown -- - -/datum/etching/proc/consume_mana(cost,spell_lv) - var/howmuch = mana - cost - if(howmuch < 0) - return FALSE - mana = howmuch - mana_cooldown = (BASE_MAGIC_COOLDOWN * spell_lv) //life tick * lv = about 30 seconds per level - return TRUE - -///datum/etching/update_etching(mode,value) -// . = ..() - -/datum/etching/proc/report_magic() - var/extra = FALSE - if(core) - . += "Core: [core]\n" - extra = TRUE - if(l_arm) - . += "[l_arm]\n" - extra = TRUE - if(r_arm) - . += "[r_arm]\n" - extra = TRUE - if(l_arm) - . += "[l_leg]\n" - extra = TRUE - if(r_leg) - . += "[r_leg]\n" - extra = TRUE - - if(extra) - . += "\n" - - return . - -/datum/etching/proc/consider_magic(cost,spell_class,spell_lv) - if(ourmob.admin_magic) - return TRUE - if(mana_cooldown) - to_chat(ourmob, "You are still recovering! (([mana_cooldown]))") - return FALSE - if(cost > mana) - to_chat(ourmob, "You haven't got enough mana! (([mana]/[cost]))") - return FALSE - -// if(not some_kind_of_level_check()) -// return FALSE - - return TRUE - -/datum/etching/proc/calculate_magic_cost(spell_class,spell_lv) - return (BASE_MAGIC_COST * spell_lv) * mana_efficiency - -/datum/etching/proc/magic_load(var/list/load) - - if(!load) - return - - true_name = load["true_name"] - core = load["core"] - l_arm = load["l_arm"] - r_arm = load["r_arm"] - l_leg = load["l_leg"] - r_leg = load["r_leg"] - -/datum/etching/proc/magic_save() - var/list/to_save = list( - "true_name" = true_name, - "core" = core, - "l_arm" = l_arm, - "r_arm" = r_arm, - "l_leg" = l_leg, - "r_leg" = r_leg - ) - - return to_save - -/datum/etching/report_status() - . = ..() - - var/our_magic = report_magic() - if(our_magic) - if(.) - . += "\n" - . += our_magic