#define ALL_SPELLS "All" #define OFFENSIVE_SPELLS "Offensive" #define DEFENSIVE_SPELLS "Defensive" #define UTILITY_SPELLS "Utility" #define SUPPORT_SPELLS "Support" var/list/all_technomancer_spells = typesof(/datum/technomancer/spell) - /datum/technomancer/spell var/list/all_technomancer_equipment = typesof(/datum/technomancer/equipment) - /datum/technomancer/equipment var/list/all_technomancer_consumables = typesof(/datum/technomancer/consumable) - /datum/technomancer/consumable var/list/all_technomancer_assistance = typesof(/datum/technomancer/assistance) - /datum/technomancer/assistance /datum/technomancer var/name = "technomancer thing" var/desc = "If you can see this, something broke." var/cost = 100 var/hidden = 0 var/obj_path = null var/ability_icon_state = null /datum/technomancer/spell var/category = ALL_SPELLS var/enhancement_desc = null var/spell_power_desc = null /obj/item/weapon/technomancer_catalog name = "catalog" desc = "A \"book\" featuring a holographic display, metal cover, and miniaturized teleportation device, allowing the user to \ requisition various things from.. where ever they came from." icon = 'icons/obj/storage.dmi' icon_state ="scientology" //placeholder w_class = ITEMSIZE_SMALL slot_flags = SLOT_BELT var/budget = 1000 var/max_budget = 1000 var/mob/living/carbon/human/owner = null var/list/spell_instances = list() var/list/equipment_instances = list() var/list/consumable_instances = list() var/list/assistance_instances = list() var/tab = 4 // Info tab, so new players can read it before doing anything. var/spell_tab = ALL_SPELLS var/show_scepter_text = 0 /obj/item/weapon/technomancer_catalog/apprentice name = "apprentice's catalog" budget = 700 max_budget = 700 /obj/item/weapon/technomancer_catalog/master //for badmins, I suppose name = "master's catalog" budget = 2000 max_budget = 2000 // Proc: bind_to_owner() // Parameters: 1 (new_owner - mob that the book is trying to bind to) // Description: Links the catalog to hopefully the technomancer, so that only they can access it. /obj/item/weapon/technomancer_catalog/proc/bind_to_owner(var/mob/living/carbon/human/new_owner) if(!owner && technomancers.is_antagonist(new_owner.mind)) owner = new_owner // Proc: New() // Parameters: 0 // Description: Sets up the catalog, as shown below. /obj/item/weapon/technomancer_catalog/New() ..() set_up() // Proc: set_up() // Parameters: 0 // Description: Instantiates all the catalog datums for everything that can be bought. /obj/item/weapon/technomancer_catalog/proc/set_up() if(!spell_instances.len) for(var/S in all_technomancer_spells) spell_instances += new S() if(!equipment_instances.len) for(var/E in all_technomancer_equipment) equipment_instances += new E() if(!consumable_instances.len) for(var/C in all_technomancer_consumables) consumable_instances += new C() if(!assistance_instances.len) for(var/A in all_technomancer_assistance) assistance_instances += new A() /obj/item/weapon/technomancer_catalog/apprentice/set_up() ..() for(var/datum/technomancer/assistance/apprentice/A in assistance_instances) assistance_instances.Remove(A) // Proc: show_categories() // Parameters: 1 (category - the category link to display) // Description: Shows an href link to go to a spell subcategory if the category is not already selected, otherwise is bold, to reduce // code duplicating. /obj/item/weapon/technomancer_catalog/proc/show_categories(var/category) if(category) if(spell_tab != category) return "[category]" else return "[category]" // Proc: attack_self() // Parameters: 1 (user - the mob clicking on the catalog) // Description: Shows an HTML window, to buy equipment and spells, if the user is the legitimate owner. Otherwise it cannot be used. /obj/item/weapon/technomancer_catalog/attack_self(mob/user) if(!user) return 0 if(owner && user != owner) to_chat(user, "\The [src] knows that you're not the original owner, and has locked you out of it!") return 0 else if(!owner) bind_to_owner(user) switch(tab) if(0) //Functions var/dat = "" user.set_machine(src) dat += "Functions | " dat += "Equipment | " dat += "Consumables | " dat += "Assistance | " dat += "Info
" dat += "You currently have a budget of [budget]/[max_budget].

" dat += "Refund Functions

" dat += "[show_categories(ALL_SPELLS)] | [show_categories(OFFENSIVE_SPELLS)] | [show_categories(DEFENSIVE_SPELLS)] | \ [show_categories(UTILITY_SPELLS)] | [show_categories(SUPPORT_SPELLS)]
" for(var/datum/technomancer/spell/spell in spell_instances) if(spell.hidden) continue if(spell_tab != ALL_SPELLS && spell.category != spell_tab) continue dat += "[spell.name]
" dat += "[spell.desc]
" if(spell.spell_power_desc) dat += "Spell Power: [spell.spell_power_desc]
" if(spell.enhancement_desc) dat += "Scepter Effect: [spell.enhancement_desc]
" if(spell.cost <= budget) dat += "Purchase ([spell.cost])

" else dat += "Cannot afford!

" user << browse(dat, "window=radio") onclose(user, "radio") if(1) //Equipment var/dat = "" user.set_machine(src) dat += "Functions | " dat += "Equipment | " dat += "Consumables | " dat += "Assistance | " dat += "Info
" dat += "You currently have a budget of [budget]/[max_budget].

" for(var/datum/technomancer/equipment/E in equipment_instances) dat += "[E.name]
" dat += "[E.desc]
" if(E.cost <= budget) dat += "Purchase ([E.cost])

" else dat += "Cannot afford!

" user << browse(dat, "window=radio") onclose(user, "radio") if(2) //Consumables var/dat = "" user.set_machine(src) dat += "Functions | " dat += "Equipment | " dat += "Consumables | " dat += "Assistance | " dat += "Info
" dat += "You currently have a budget of [budget]/[max_budget].

" for(var/datum/technomancer/consumable/C in consumable_instances) dat += "[C.name]
" dat += "[C.desc]
" if(C.cost <= budget) dat += "Purchase ([C.cost])

" else dat += "Cannot afford!

" user << browse(dat, "window=radio") onclose(user, "radio") if(3) //Assistance var/dat = "" user.set_machine(src) dat += "Functions | " dat += "Equipment | " dat += "Consumables | " dat += "Assistance | " dat += "Info
" dat += "You currently have a budget of [budget]/[max_budget].

" for(var/datum/technomancer/assistance/A in assistance_instances) dat += "[A.name]
" dat += "[A.desc]
" if(A.cost <= budget) dat += "Purchase ([A.cost])

" else dat += "Cannot afford!

" user << browse(dat, "window=radio") onclose(user, "radio") if(4) //Info var/dat = "" user.set_machine(src) dat += "Functions | " dat += "Equipment | " dat += "Consumables | " dat += "Assistance | " dat += "Info
" dat += "You currently have a budget of [budget]/[max_budget].

" dat += "
" dat += "

Manipulation Core Owner's Manual


" dat += "This brief entry in your catalog will try to explain what everything does. For starters, the thing you're \ probably wearing on your back is known as a Manipulation Core, or just a 'Core'. It allows you to do amazing \ things with almost no effort, depending on what functions you've purchased for it. Don't lose your core!
" dat += "
" dat += "There are a few things you need to keep in mind as you use your Core to manipulate the universe. The core \ requires a special type of energy, that is referred to as just 'Energy' in the catalog. All cores generate \ their own energy, some more than others. Most functions require energy be spent in order to work, so make sure not \ to run out in a critical moment. Besides waiting for your Core to recharge, you can buy certain functions which \ do something to generate energy.
" dat += "
" dat += "The second thing you need to know is that awesome power over the physical world has consquences, in the form \ of Instability. Instability is the result of your Core's energy being used to fuel it, and so little is \ understood about it, even among fellow Core owners, however it is almost always a bad thing to have. Instability will \ 'cling' to you as you use functions, with powerful functions creating lots of instability. The effects of holding onto \ instability are generally harmless or mildly annoying at low levels, with effects such as sparks in the air or forced \ blinking. Accumulating more and more instability will lead to worse things happening, which can easily be fatal, if not \ managed properly.
" dat += "
" dat += "Fortunately, all Cores come with a meter to tell you how much instability you currently hold. \ Instability will go away on its own as time goes on. You can tell if you have instability by the characteristic \ purple colored lightning that appears around something with instability lingering on it. High amounts of instability \ may cause the object afflicted with it to glow a dark purple, which is often known simply as Glow, which spreads \ the instability. You should stay far away from anyone afflicted by Glow, as they will be a danger to both themselves and \ anything nearby. Multiple sources of Glow can perpetuate the glow for a very long time if they are not seperated.
" dat += "
" dat += "You should strive to keep you and your apprentices' cores secure. To help with this, each core comes with a \ locking mechanism, which should make attempts at forceful removal by third parties (or you) futile, until it is \ unlocked again. Do note that there is a safety mechanism, which will automatically unlock the core if the wearer \ suffers death. There exists a secondary safety mechanism (safety for the core, not you) that is triggered when \ the core detects itself being carried, with the carrier not being authorized. It will respond by giving a \ massive amount of Instability to them, so be careful, or perhaps make use of that.
" dat += "
" dat += "You can refund functions, equipment items, and assistance items, so long as you are in your base. \ Once you leave, you can't refund anything, however you can still buy things if you still have points remaining. \ To refund functions, just click the 'Refund Functions' button on the top, when in the functions tabs. \ For equipment items, you need to hit it against the catalog.
" dat += "
" dat += "Your blue robes and hat are both stylish, and somewhat protective against hostile energies, which includes \ EXTERNAL instability sources (like Glow), and mundane electricity. If you're looking for protection against other \ things, it's suggested you purchase or otherwise obtain armor.
" dat += "
" dat += "There are a few terms you may not understand in the catalog, so this will try to explain them.
" dat += "A function can be thought of as a 'spell', that you use by holding in your hands and trying to use it on \ a target of your choice.
" dat += "Some functions can have their abilities enhanced by a special rod called the Scepter of Enhancement. \ If a function is able to be boosted with it, it will be shown underneath the description of the function as \ 'Scepter Effect:'. Note that you must hold the scepter for it to work, so try to avoid losing it.
" dat += "Functions can also be boosted with the core itself. A function that is able to benefit \ from this will have 'Spell Power:' underneath. Different Cores have different \ amounts of spell power.
" dat += "When a function refers to 'allies', it means you, your apprentices, currently controlled entities (with the \ Control function), and friendly simple-minded entities that you've summoned with the Scepter of Enhancement.
" dat += "A meter is equal to one 'tile'.
" user << browse(dat, "window=radio") onclose(user, "radio") // Proc: Topic() // Parameters: 2 (href - don't know, href_list - the choice that the person using the interface above clicked on.) // Description: Acts upon clicks on links for the catalog, if they are the rightful owner. /obj/item/weapon/technomancer_catalog/Topic(href, href_list) ..() var/mob/living/carbon/human/H = usr if(H.stat || H.restrained()) return if(!istype(H, /mob/living/carbon/human)) return 1 //why does this return 1? if(H != owner) to_chat(H, "\The [src] won't allow you to do that, as you don't own \the [src]!") return if(loc == H || (in_range(src, H) && istype(loc, /turf))) H.set_machine(src) if(href_list["tab_choice"]) tab = text2num(href_list["tab_choice"]) if(href_list["spell_category"]) spell_tab = href_list["spell_category"] if(href_list["spell_choice"]) var/datum/technomancer/new_spell = null //Locate the spell. for(var/datum/technomancer/spell/spell in spell_instances) if(spell.name == href_list["spell_choice"]) new_spell = spell break var/obj/item/weapon/technomancer_core/core = null if(istype(H.back, /obj/item/weapon/technomancer_core)) core = H.back if(new_spell && core) if(new_spell.cost <= budget) if(!core.has_spell(new_spell)) budget -= new_spell.cost to_chat(H, "You have just bought [new_spell.name].") core.add_spell(new_spell.obj_path, new_spell.name, new_spell.ability_icon_state) else //We already own it. to_chat(H, "You already have [new_spell.name]!") return else //Can't afford. to_chat(H, "You can't afford that!") return // This needs less copypasta. if(href_list["item_choice"]) var/datum/technomancer/desired_object = null for(var/datum/technomancer/O in equipment_instances + consumable_instances + assistance_instances) if(O.name == href_list["item_choice"]) desired_object = O break if(desired_object) if(desired_object.cost <= budget) budget -= desired_object.cost to_chat(H, "You have just bought \a [desired_object.name].") var/obj/O = new desired_object.obj_path(get_turf(H)) technomancer_belongings.Add(O) // Used for the Track spell. else //Can't afford. to_chat(H, "You can't afford that!") return if(href_list["refund_functions"]) var/turf/T = get_turf(H) if(T.z in using_map.player_levels) to_chat(H, "You can only refund at your base, it's too late now!") return var/obj/item/weapon/technomancer_core/core = null if(istype(H.back, /obj/item/weapon/technomancer_core)) core = H.back if(core) for(var/obj/spellbutton/spell in core.spells) for(var/datum/technomancer/spell/spell_datum in spell_instances) if(spell_datum.obj_path == spell.spellpath) budget += spell_datum.cost core.remove_spell(spell) break attack_self(H) /obj/item/weapon/technomancer_catalog/attackby(var/atom/movable/AM, var/mob/user) var/turf/T = get_turf(user) if(T.z in using_map.player_levels) to_chat(user, "You can only refund at your base, it's too late now!") return for(var/datum/technomancer/equipment/E in equipment_instances + assistance_instances) if(AM.type == E.obj_path) // We got a match. if(budget + E.cost > max_budget) to_chat(user, "\The [src] will not allow you to overflow your maximum budget by refunding that.") return else budget = budget + E.cost to_chat(user, "You've refunded \the [AM].") // We sadly need to do special stuff here or else people who refund cores with spells will lose points permanently. if(istype(AM, /obj/item/weapon/technomancer_core)) var/obj/item/weapon/technomancer_core/core = AM for(var/obj/spellbutton/spell in core.spells) for(var/datum/technomancer/spell/spell_datum in spell_instances) if(spell_datum.obj_path == spell.spellpath) budget += spell_datum.cost to_chat(user, "[spell.name] was inside \the [core], and was refunded.") core.remove_spell(spell) break qdel(AM) return to_chat(user, "\The [src] is unable to refund \the [AM].")