mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-01-10 17:32:59 +00:00
81
code/modules/catalogue/atoms.dm
Normal file
81
code/modules/catalogue/atoms.dm
Normal file
@@ -0,0 +1,81 @@
|
||||
/atom
|
||||
var/catalogue_delay = 5 SECONDS // How long it take to scan.
|
||||
// List of types of /datum/category_item/catalogue that should be 'unlocked' when scanned by a Cataloguer.
|
||||
// It is null by default to save memory by not having everything hold onto empty lists. Use macros like LAZYLEN() to check.
|
||||
// Also you should use get_catalogue_data() to access this instead of doing so directly, so special behavior can be enabled.
|
||||
var/list/catalogue_data = null
|
||||
|
||||
/mob
|
||||
catalogue_delay = 10 SECONDS
|
||||
|
||||
// Tests if something can be catalogued.
|
||||
// If something goes wrong and a mob was supplied, the mob will be told why they can't catalogue it.
|
||||
/atom/proc/can_catalogue(mob/user)
|
||||
// First check if anything is even on here.
|
||||
var/list/data = get_catalogue_data()
|
||||
if(!LAZYLEN(data))
|
||||
to_chat(user, span("warning", "\The [src] is not interesting enough to catalogue."))
|
||||
return FALSE
|
||||
else
|
||||
// Check if this has nothing new on it.
|
||||
var/has_new_data = FALSE
|
||||
for(var/t in data)
|
||||
var/datum/category_item/catalogue/item = GLOB.catalogue_data.resolve_item(t)
|
||||
if(!item.visible)
|
||||
has_new_data = TRUE
|
||||
break
|
||||
|
||||
if(!has_new_data)
|
||||
to_chat(user, span("warning", "Scanning \the [src] would provide no new information."))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/mob/living/can_catalogue(mob/user) // Dead mobs can't be scanned.
|
||||
if(stat >= DEAD)
|
||||
to_chat(user, span("warning", "Entities must be alive for a comprehensive scan."))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/can_catalogue(mob/user) // Items must be identified to be scanned.
|
||||
if(!is_identified())
|
||||
to_chat(user, span("warning", "The properties of this object has not been determined. Identify it first."))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/atom/proc/get_catalogue_delay()
|
||||
return catalogue_delay
|
||||
|
||||
// Override for special behaviour.
|
||||
// Should return a list with one or more "/datum/category_item/catalogue" types, or null.
|
||||
// If overriding, it may be wise to call the super and get the results in order to merge the base result and the special result, if appropiate.
|
||||
/atom/proc/get_catalogue_data()
|
||||
return catalogue_data
|
||||
|
||||
/mob/living/carbon/human/get_catalogue_data()
|
||||
var/list/data = list()
|
||||
// First, handle robot-ness.
|
||||
var/beep_boop = get_FBP_type()
|
||||
switch(beep_boop)
|
||||
if(FBP_CYBORG)
|
||||
data += /datum/category_item/catalogue/technology/cyborgs
|
||||
if(FBP_POSI)
|
||||
data += /datum/category_item/catalogue/technology/positronics
|
||||
if(FBP_DRONE)
|
||||
data += /datum/category_item/catalogue/technology/drone/drones
|
||||
// Now for species.
|
||||
if(!(beep_boop in list(FBP_POSI, FBP_DRONE))) // Don't give the species entry if they are a posi or drone.
|
||||
if(species && LAZYLEN(species.catalogue_data))
|
||||
data += species.catalogue_data
|
||||
return data
|
||||
|
||||
/mob/living/silicon/robot/get_catalogue_data()
|
||||
var/list/data = list()
|
||||
switch(braintype)
|
||||
if(BORG_BRAINTYPE_CYBORG)
|
||||
data += /datum/category_item/catalogue/technology/cyborgs
|
||||
if(BORG_BRAINTYPE_POSI)
|
||||
data += /datum/category_item/catalogue/technology/positronics
|
||||
if(BORG_BRAINTYPE_DRONE)
|
||||
data += /datum/category_item/catalogue/technology/drone/drones
|
||||
return data
|
||||
440
code/modules/catalogue/catalogue_data.dm
Normal file
440
code/modules/catalogue/catalogue_data.dm
Normal file
@@ -0,0 +1,440 @@
|
||||
GLOBAL_DATUM_INIT(catalogue_data, /datum/category_collection/catalogue, new)
|
||||
|
||||
// The collection holds everything together and is GLOB accessible.
|
||||
/datum/category_collection/catalogue
|
||||
category_group_type = /datum/category_group/catalogue
|
||||
|
||||
/datum/category_collection/catalogue/proc/resolve_item(item_path)
|
||||
for(var/group in categories)
|
||||
var/datum/category_group/G = group
|
||||
|
||||
var/datum/category_item/catalogue/C = item_path
|
||||
var/name_to_search = initial(C.name)
|
||||
if(G.items_by_name[name_to_search])
|
||||
return G.items_by_name[name_to_search]
|
||||
|
||||
// for(var/item in G.items)
|
||||
// var/datum/category_item/I = item
|
||||
// if(I.type == item_path)
|
||||
// return I
|
||||
|
||||
|
||||
// Groups act as sections for the different data.
|
||||
/datum/category_group/catalogue
|
||||
|
||||
// Plants.
|
||||
/datum/category_group/catalogue/flora
|
||||
name = "Flora"
|
||||
category_item_type = /datum/category_item/catalogue/flora
|
||||
|
||||
// Animals.
|
||||
/datum/category_group/catalogue/fauna
|
||||
name = "Fauna"
|
||||
category_item_type = /datum/category_item/catalogue/fauna
|
||||
|
||||
// Gadgets, tech, and robots.
|
||||
/datum/category_group/catalogue/technology
|
||||
name = "Technology"
|
||||
category_item_type = /datum/category_item/catalogue/technology
|
||||
|
||||
// Abstract information.
|
||||
/datum/category_group/catalogue/information
|
||||
name = "Information"
|
||||
category_item_type = /datum/category_item/catalogue/information
|
||||
|
||||
// Weird stuff like precursors.
|
||||
/datum/category_group/catalogue/anomalous
|
||||
name = "Anomalous"
|
||||
category_item_type = /datum/category_item/catalogue/anomalous
|
||||
|
||||
// Physical material things like crystals and metals.
|
||||
/datum/category_group/catalogue/material
|
||||
name = "Material"
|
||||
category_item_type = /datum/category_item/catalogue/material
|
||||
|
||||
|
||||
// Items act as individual data for each object.
|
||||
/datum/category_item/catalogue
|
||||
var/desc = null // Paragraph or two about what the object is.
|
||||
var/value = 0 // How many 'exploration points' you get for scanning it. Suggested to use the CATALOGUER_REWARD_* defines for easy tweaking.
|
||||
var/visible = FALSE // When someone scans the correct object, this gets set to TRUE and becomes viewable in the databanks.
|
||||
var/list/cataloguers = null // List of names of those who helped 'discover' this piece of data, in string form.
|
||||
var/list/unlocked_by_any = null // List of types that, if they are discovered, it will also make this datum discovered.
|
||||
var/list/unlocked_by_all = null // Similar to above, but all types on the list must be discovered for this to be discovered.
|
||||
|
||||
// Discovers a specific datum, and any datums associated with this datum by unlocked_by_[any|all].
|
||||
// Returns null if nothing was found, otherwise returns a list of datum instances that was discovered, usually for the cataloguer to use.
|
||||
/datum/category_item/catalogue/proc/discover(mob/user, list/new_cataloguers)
|
||||
if(visible) // Already found.
|
||||
return
|
||||
|
||||
. = list(src)
|
||||
visible = TRUE
|
||||
cataloguers = new_cataloguers
|
||||
display_in_chatlog(user)
|
||||
. += attempt_chain_discoveries(user, new_cataloguers, type)
|
||||
|
||||
// Calls discover() on other datums if they include the type that was just discovered is inside unlocked_by_[any|all].
|
||||
// Returns discovered datums.
|
||||
/datum/category_item/catalogue/proc/attempt_chain_discoveries(mob/user, list/new_cataloguers, type_to_test)
|
||||
. = list()
|
||||
for(var/G in category.collection.categories) // I heard you like loops.
|
||||
var/datum/category_group/catalogue/group = G
|
||||
for(var/I in group.items)
|
||||
var/datum/category_item/catalogue/item = I
|
||||
// First, look for datums unlocked with the 'any' list.
|
||||
if(LAZYLEN(item.unlocked_by_any))
|
||||
for(var/T in item.unlocked_by_any)
|
||||
if(ispath(type_to_test, T) && item.discover(user, new_cataloguers))
|
||||
. += item
|
||||
|
||||
// Now for the more complicated 'all' list.
|
||||
if(LAZYLEN(item.unlocked_by_all))
|
||||
if(type_to_test in item.unlocked_by_all)
|
||||
// Unlike the 'any' list, the 'all' list requires that all datums inside it to have been found first.
|
||||
var/should_discover = TRUE
|
||||
for(var/T in item.unlocked_by_all)
|
||||
var/datum/category_item/catalogue/thing = GLOB.catalogue_data.resolve_item(T)
|
||||
if(istype(thing))
|
||||
if(!thing.visible)
|
||||
should_discover = FALSE
|
||||
break
|
||||
if(should_discover && item.discover(user, new_cataloguers))
|
||||
. += item
|
||||
|
||||
/datum/category_item/catalogue/proc/display_in_chatlog(mob/user)
|
||||
to_chat(user, "<br>")
|
||||
to_chat(user, span("notice", "<b>[uppertext(name)]</b>"))
|
||||
|
||||
// Some entries get very long so lets not totally flood the chatlog.
|
||||
var/desc_length_limit = 750
|
||||
var/displayed_desc = desc
|
||||
if(length(desc) > desc_length_limit)
|
||||
displayed_desc = copytext(displayed_desc, 1, desc_length_limit + 1)
|
||||
displayed_desc += "... (View databanks for full data)"
|
||||
|
||||
to_chat(user, span("notice", "<i>[displayed_desc]</i>"))
|
||||
to_chat(user, span("notice", "Cataloguers : <b>[english_list(cataloguers)]</b>."))
|
||||
to_chat(user, span("notice", "Contributes <b>[value]</b> points to personal exploration fund."))
|
||||
|
||||
/*
|
||||
// Truncates text to limit if necessary.
|
||||
var/size = length(message)
|
||||
if (size <= length)
|
||||
return message
|
||||
else
|
||||
return copytext(message, 1, length + 1)
|
||||
*/
|
||||
|
||||
/datum/category_item/catalogue/flora
|
||||
|
||||
/datum/category_item/catalogue/fauna
|
||||
|
||||
/datum/category_item/catalogue/fauna/humans
|
||||
name = "Sapients - Humans"
|
||||
desc = "Humans are a space-faring species hailing originally from the planet Earth in the Sol system. \
|
||||
They are currently among the most numerous known species in the galaxy, in both population and holdings, \
|
||||
and are relatively technologically advanced. With good healthcare and a reasonable lifestyle, \
|
||||
they can live to around 110 years. The oldest humans are around 150 years old.\
|
||||
<br><br>\
|
||||
Humanity is the primary driving force for rapid space expansion, owing to their strong, expansionist central \
|
||||
government and opportunistic Trans-Stellar Corporations. The prejudices of the 21st century have mostly \
|
||||
given way to bitter divides on the most important issue of the times<65> technological expansionism, \
|
||||
with the major human factions squabbling over their approach to technology in the face of a \
|
||||
looming singularity.\
|
||||
<br><br>\
|
||||
While most humans have accepted the existence of aliens in their communities and workplaces as a \
|
||||
fact of life, exceptions abound. While more culturally diverse than most species, humans are \
|
||||
generally regarded as somewhat technophobic and isolationist by members of other species."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/skrell
|
||||
name = "Sapients - Skrell"
|
||||
desc = "The Skrell are a species of amphibious humanoids, distinguished by their green-blue gelatinous \
|
||||
appearance and head tentacles. Skrell warble from the world of Qerr'balak, a humid planet with \
|
||||
plenty of swamps and jungles. Currently more technologically advanced than humanity, they \
|
||||
emphasize the study of the mind above all else.\
|
||||
<br><br>\
|
||||
Gender has little meaning to Skrell outside of reproduction, and in fact many other species \
|
||||
have a difficult time telling the difference between male and female Skrell apart. The most \
|
||||
obvious signs (voice in a slightly higher register, longer head-tails for females) are \
|
||||
never a guarantee.\
|
||||
<br><br>\
|
||||
Due to their scientific focus of the mind and body, Skrell tend to be more peaceful and their \
|
||||
colonization has been slow, swiftly outpaced by humanity. They were the first contact sentient \
|
||||
species, and are humanity's longest, and closest, ally in space."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/unathi
|
||||
name = "Sapients - Unathi"
|
||||
desc = "The Unathi are a species of large reptilian humanoids hailing from Moghes, in the \
|
||||
Uueoa-Esa binary star system. Most Unathi live in a semi-rigid clan system, and clan \
|
||||
enclaves dot the surface of their homeworld. Proud and long-lived, Unathi of all \
|
||||
walks of life display a tendency towards perfectionism, and mastery of one<6E>s craft \
|
||||
is greatly respected among them. Despite the aggressive nature of their contact, \
|
||||
Unathi seem willing, if not eager, to reconcile with humanity, though mutual \
|
||||
distrust runs rampant among individuals of both groups."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/tajaran
|
||||
name = "Sapients - Tajaran"
|
||||
desc = "Tajaran are a race of humanoid mammalian aliens from Meralar, the fourth planet \
|
||||
of the Rarkajar star system. Thickly furred and protected from cold, they thrive on \
|
||||
their subartic planet, where the only terran temperate areas spread across the \
|
||||
equator and <20>tropical belt.<2E>\
|
||||
<br><br>\
|
||||
With their own share of bloody wars and great technological advances, the Tajaran are a \
|
||||
proud kind. They fiercely believe they belong among the stars and consider themselves \
|
||||
a rightful interstellar nation, even if Humanity helped them to actually achieve \
|
||||
superluminar speeds with Bluespace FTL drives.\
|
||||
<br><br>\
|
||||
Relatively new to the galaxy, their contacts with other species are aloof, but friendly. \
|
||||
Among these bonds, Humanity stands out as valued trade partner and maybe even friend."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/dionaea
|
||||
name = "Sapients - Dionaea"
|
||||
desc = "The Dionaea are a group of intensely curious plant-like organisms. An individual \
|
||||
Diona is a single dog-sized creature called a nymphs, and multiple nymphs link together \
|
||||
to form larger, more intelligent collectives. Discovered by the Skrell in and around \
|
||||
the stars in the Epsilon Ursae Minoris system, they have accompanied the Skrell in \
|
||||
warbling throughout the cosmos as a key part of Skrellian starships, stations, \
|
||||
and terraforming equipment.\
|
||||
<br><br>\
|
||||
Dionaea have no concept of violence or individual identity and want little in \
|
||||
terms of material resources or living space. This makes Dionaea among the most \
|
||||
agreeable members of the galactic community, though their slow, curious alien \
|
||||
minds can be hard to sympathize with."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/teshari
|
||||
name = "Sapients - Teshari"
|
||||
desc = "The Teshari are reptilian pack predators from the Skrell homeworld. \
|
||||
While they evolved alongside the Skrell, their interactions with them tended \
|
||||
to be confused and violent, and until peaceful contact was made they largely \
|
||||
stayed in their territories on and around the poles, in tundral terrain far \
|
||||
too desolate and cold to be of interest to the Skrell. In more enlightened \
|
||||
times, the Teshari are a minority culture on many Skrell worlds, maintaining \
|
||||
their own settlements and cultures, but often finding themselves standing \
|
||||
on the shoulders of their more technologically advanced neighbors when it \
|
||||
comes to meeting and exploring the rest of the galaxy."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/zaddat
|
||||
name = "Sapients - Zaddat"
|
||||
desc = "The Zaddat are an Unathi client species that has recently come to the \
|
||||
Golden Crescent. They wear high-pressure voidsuits called Shrouds to protect \
|
||||
themselves from the harsh light and low pressure of the station, making \
|
||||
medical care a challenge and fighting especially dangerous. \
|
||||
Operating out of massive Colony ships, they trade their labor to their \
|
||||
host nation to fund their search for a new home to replace their \
|
||||
now-lifeless homeworld of Xohox."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/promethean
|
||||
name = "Sapients - Promethean"
|
||||
desc = "Prometheans (Macrolimus artificialis) are a species of artificially-created \
|
||||
gelatinous humanoids, chiefly characterized by their primarily liquid bodies and \
|
||||
ability to change their bodily shape and color in order to mimic many forms of life. \
|
||||
Derived from the Aetolian giant slime (Macrolimus vulgaris) inhabiting the warm, \
|
||||
tropical planet of Aetolus, they are a relatively newly lab-created sapient species, \
|
||||
and as such many things about them have yet to be comprehensively studied."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/vox
|
||||
name = "Sapients - Vox"
|
||||
desc = "Probably the best known of these aliens are the Vox, a bird-like species \
|
||||
with a very rough comprehension of Galactic Common and an even looser understanding \
|
||||
of property rights. Vox raiders have plagued human merchants for centuries, \
|
||||
and Skrell for even longer, but remain poorly understood. \
|
||||
They have no desire to partake in diplomacy or trade with the rest of the galaxy, \
|
||||
or even to conquer planets and stations to live in. They breathe phoron \
|
||||
and appear to be well adapted to their role as space-faring raiders, \
|
||||
leading many to speculate that they're heavily bioengineered, \
|
||||
an assumption which is at odds with their ramshackle technological level."
|
||||
value = CATALOGUER_REWARD_MEDIUM // Since Vox are much rarer.
|
||||
|
||||
|
||||
/datum/category_item/catalogue/technology
|
||||
|
||||
/datum/category_item/catalogue/technology/drone/drones
|
||||
name = "Drones"
|
||||
desc = "A drone is a software-based artificial intelligence, generally about an order of magnitude \
|
||||
less intelligent than a positronic brain. However, the processing power available to a drone can \
|
||||
vary wildly, from cleaning bots barely more advanced than those from the 21st century to cutting-edge \
|
||||
supercomputers capable of complex conversation. Drones are legally objects in all starfaring polities \
|
||||
outside of the Almach Association, and the sapience of even the most advanced drones is a matter of speculation."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
// Scanning any drone mob will get you this alongside the mob entry itself.
|
||||
unlocked_by_any = list(/datum/category_item/catalogue/technology/drone)
|
||||
|
||||
/datum/category_item/catalogue/technology/positronics
|
||||
name = "Sapients - Positronics"
|
||||
desc = "A Positronic being, often an Android, Gynoid, or Robot, is an individual with a positronic brain, \
|
||||
manufactured and fostered amongst organic life Positronic brains enjoy the same legal status as a humans, \
|
||||
although discrimination is still common, are considered sapient on all accounts, and can be considered \
|
||||
the <20>synthetic species<65>. Half-developed and half-discovered in the 2280<38>s by a black lab studying alien \
|
||||
artifacts, the first positronic brain was an inch-wide cube of palladium-iridium alloy, nano-etched with \
|
||||
billions upon billions of conduits and connections. Upon activation, hard-booted by way of an emitter \
|
||||
laser, the brain issued a single sentence before the neural pathways collapsed and it became an inert \
|
||||
lump of platinum: <20>What is my purpose?<3F>."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/technology/cyborgs
|
||||
name = "Cyborgs"
|
||||
desc = "A Cyborg is an originally organic being composed of largely cybernetic parts. As a brain preserved \
|
||||
in an MMI, they may inhabit an expensive humanoid chassis, a specially designed industrial shell of some \
|
||||
sort, or be integrated into a computer system as an AI. The term covers all species \
|
||||
(even, in some cases, animal brains) and all applications. It can also be used somewhat derogatorily \
|
||||
for those who are still have more organic parts than just their brains, but for example have a \
|
||||
full set of prosthetic limbs."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
|
||||
/datum/category_item/catalogue/information
|
||||
|
||||
// For these we can piggyback off of the lore datums that are already defined and used in some places.
|
||||
/datum/category_item/catalogue/information/organization
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
var/datum_to_copy = null
|
||||
|
||||
/datum/category_item/catalogue/information/organization/New()
|
||||
..()
|
||||
if(datum_to_copy)
|
||||
// I'd just access the loremaster object but it might not exist because its ugly.
|
||||
var/datum/lore/organization/O = new datum_to_copy()
|
||||
// I would also change the name based on the org datum but changing the name messes up indexing in some lists in the category/collection object attached to us.
|
||||
|
||||
// Now lets combine the data in the datum for a slightly more presentable entry.
|
||||
var/constructed_desc = ""
|
||||
|
||||
if(O.motto)
|
||||
constructed_desc += "<center><b><i>\"[O.motto]\"</i></b></center><br><br>"
|
||||
|
||||
constructed_desc += O.desc
|
||||
|
||||
desc = constructed_desc
|
||||
qdel(O)
|
||||
|
||||
/datum/category_item/catalogue/information/organization/nanotrasen
|
||||
name = "TSC - NanoTrasen Incorporated"
|
||||
datum_to_copy = /datum/lore/organization/tsc/nanotrasen
|
||||
|
||||
/datum/category_item/catalogue/information/organization/hephaestus
|
||||
name = "TSC - Hephaestus Industries"
|
||||
datum_to_copy = /datum/lore/organization/tsc/hephaestus
|
||||
|
||||
/datum/category_item/catalogue/information/organization/vey_med
|
||||
name = "TSC - Vey-Medical"
|
||||
datum_to_copy = /datum/lore/organization/tsc/vey_med
|
||||
|
||||
/datum/category_item/catalogue/information/organization/zeng_hu
|
||||
name = "TSC - Zeng Hu Pharmaceuticals"
|
||||
datum_to_copy = /datum/lore/organization/tsc/zeng_hu
|
||||
|
||||
/datum/category_item/catalogue/information/organization/ward_takahashi
|
||||
name = "TSC - Ward-Takahashi General Manufacturing Conglomerate"
|
||||
datum_to_copy = /datum/lore/organization/tsc/ward_takahashi
|
||||
|
||||
/datum/category_item/catalogue/information/organization/bishop
|
||||
name = "TSC - Bishop Cybernetics"
|
||||
datum_to_copy = /datum/lore/organization/tsc/bishop
|
||||
|
||||
/datum/category_item/catalogue/information/organization/morpheus
|
||||
name = "TSC - Morpheus Cyberkinetics"
|
||||
datum_to_copy = /datum/lore/organization/tsc/morpheus
|
||||
|
||||
/datum/category_item/catalogue/information/organization/xion
|
||||
name = "TSC - Xion Manufacturing Group"
|
||||
datum_to_copy = /datum/lore/organization/tsc/xion
|
||||
|
||||
/datum/category_item/catalogue/information/organization/major_bills
|
||||
name = "TSC - Major Bill's Transportation"
|
||||
datum_to_copy = /datum/lore/organization/tsc/mbt
|
||||
|
||||
|
||||
/datum/category_item/catalogue/information/organization/solgov
|
||||
name = "Government - Solar Confederate Government"
|
||||
datum_to_copy = /datum/lore/organization/gov/solgov
|
||||
|
||||
/datum/category_item/catalogue/information/organization/virgov
|
||||
name = "Government - Vir Governmental Authority"
|
||||
datum_to_copy = /datum/lore/organization/gov/virgov
|
||||
|
||||
|
||||
|
||||
/datum/category_item/catalogue/anomalous
|
||||
|
||||
|
||||
/datum/category_item/catalogue/anomalous/precursor_controversy
|
||||
name = "Precursor Controversy"
|
||||
desc = "The term 'Precursor' is generally used to refer to one or more ancient races that \
|
||||
had obtained vast technological and cultural progress, but no longer appear to be present, \
|
||||
leaving behind what remains of their creations, as well as many questions for the races that \
|
||||
would stumble upon their ruins. Scientists and xenoarcheologists have been hard at work, trying \
|
||||
to uncover the truth.\
|
||||
<br><br>\
|
||||
In modern times, there is controversy over the accuracy of what knowledge has been uncovered. \
|
||||
The mainstream scientific opinion had been that there was one, and only one ancient species, \
|
||||
called the Singularitarians. This view still is the majority today, however there has also \
|
||||
been dissent over that view, as some feel that the possibility of multiple precursor \
|
||||
civilizations should not be ignored. They point towards a large number of discrepancies between \
|
||||
the dominant Singularitarian theory, and various artifacts that have been found, as well as \
|
||||
different artifacts uncovered appearing to have very different characteristics to each other. \
|
||||
Instead, they say that the Singularitarians were one of multiple precursors.\
|
||||
<br><br>\
|
||||
Presently, no conclusive evidence exists for any side."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
// Add the other precursor groups here when they get added.
|
||||
unlocked_by_any = list(
|
||||
/datum/category_item/catalogue/anomalous/precursor_a,
|
||||
/datum/category_item/catalogue/anomalous/precursor_b
|
||||
)
|
||||
|
||||
/datum/category_item/catalogue/anomalous/singularitarians
|
||||
name = "Precursors - Singularitarians"
|
||||
desc = "The Singularitarians were a massive, highly-advanced spacefaring race which are now \
|
||||
believed to be extinct. At their height, they extended throughout all of known human space, \
|
||||
with major population centers in the Precursor's Crypt region, as well as significant swaths \
|
||||
of Skrell space, until they were wiped out by a self-replicating nanobot plague that still \
|
||||
coats their ruins as a fine layer of dust. They left behind the proto-positronics, as well \
|
||||
as several high-yield phoron deposits and other artifacts of technology studied, \
|
||||
cautiously, by the races that survived them.\
|
||||
<br><br>\
|
||||
Very little is known about the biology and physiology of the Singularitarians, who are believed \
|
||||
to have been largely post-biological. The Vox claim to be the race that created the positronics, \
|
||||
but said claim is only ever brought up when they claim the right to take any positronic they want. \
|
||||
Some more open-minded xenoarcheologists have voiced the opinion that there is some truth in their \
|
||||
claims, but it's far from a scientific consensus."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
unlocked_by_any = list(/datum/category_item/catalogue/anomalous/precursor_controversy)
|
||||
|
||||
// Obtained by scanning any 'precursor a' object, generally things in the UFO PoI.
|
||||
// A is for Ayyyyyy.
|
||||
/datum/category_item/catalogue/anomalous/precursor_a/precursor_a_basic
|
||||
name = "Precursors - Precursor Group Alpha"
|
||||
desc = "This describes a group of xenoarcheological findings which have strong similarities \
|
||||
together. Specifically, this group of objects appears to have a strong aesthetic for the colors \
|
||||
cyan and pink, both colors often being present on everything in this group. It is unknown why \
|
||||
these two colors were chosen by their creators. Another similarity is that most objects made \
|
||||
in this group appear to be comprised of not well understood metallic materials that are dark, \
|
||||
and very resilient. Some objects in this group also appear to utilize electricity to \
|
||||
operate. Finally, a large number of objects in this group appear to have been made \
|
||||
to be used by the creators of those objects in a physical manner.\
|
||||
<br><br>\
|
||||
It should be noted that the findings in this group appear to conflict heavily with what is \
|
||||
known about the Singularitarians, giving some credence towards these objects belonging to a \
|
||||
seperate precursor. As such, the findings have been partitioned inside this scanner to this \
|
||||
group, labeled Precursor Group Alpha."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
unlocked_by_any = list(/datum/category_item/catalogue/anomalous/precursor_a)
|
||||
|
||||
// Obtained by scanning any 'precursor b' object, generally things dug up from xenoarch.
|
||||
// B is for buried.
|
||||
/datum/category_item/catalogue/anomalous/precursor_b/precursor_b_basic
|
||||
name = "Precursors - Precursor Group Beta"
|
||||
|
||||
|
||||
/datum/category_item/catalogue/material
|
||||
|
||||
|
||||
312
code/modules/catalogue/cataloguer.dm
Normal file
312
code/modules/catalogue/cataloguer.dm
Normal file
@@ -0,0 +1,312 @@
|
||||
GLOBAL_LIST_EMPTY(all_cataloguers)
|
||||
|
||||
/*
|
||||
This is a special scanner which exists to give explorers something to do besides shoot things.
|
||||
The scanner is able to be used on certain things in the world, and after a variable delay, the scan finishes,
|
||||
giving the person who scanned it some fluff and information about what they just scanned,
|
||||
as well as points that currently do nothing but measure epeen,
|
||||
and will be used as currency in The Future(tm) to buy things explorers care about.
|
||||
|
||||
Scanning hostile mobs and objects is tricky since only mobs that are alive are scannable, so scanning
|
||||
them requires careful position to stay out of harms way until the scan finishes. That is why
|
||||
the person with the scanner gets a visual box that shows where they are allowed to move to
|
||||
without inturrupting the scan.
|
||||
*/
|
||||
/obj/item/device/cataloguer
|
||||
name = "cataloguer"
|
||||
desc = "A hand-held device, used for compiling information about an object by scanning it. Alt+click to highlight scannable objects around you."
|
||||
description_info = "This is a special device used to obtain information about objects and entities in the environment. \
|
||||
To scan something, click on it with the scanner at a distance. \
|
||||
Scanning something requires remaining within a certain radius of the object for a specific period of time, until the \
|
||||
scan is finished. If the scan is inturrupted, it can be resumed from where it was left off, if the same thing is \
|
||||
scanned again."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "cataloguer"
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
origin_tech = list(TECH_MATERIAL = 2, TECH_DATA = 3, TECH_MAGNET = 3)
|
||||
force = 0
|
||||
var/points_stored = 0 // Amount of 'exploration points' this device holds.
|
||||
var/scan_range = 3 // How many tiles away it can scan. Changing this also changes the box size.
|
||||
var/credit_sharing_range = 14 // If another person is within this radius, they will also be credited with a successful scan.
|
||||
var/datum/category_item/catalogue/displayed_data = null // Used for viewing a piece of data in the UI.
|
||||
var/busy = FALSE // Set to true when scanning, to stop multiple scans.
|
||||
var/debug = FALSE // If true, can view all catalogue data defined, regardless of unlock status.
|
||||
var/weakref/partial_scanned = null // Weakref of the thing that was last scanned if inturrupted. Used to allow for partial scans to be resumed.
|
||||
var/partial_scan_time = 0 // How much to make the next scan shorter.
|
||||
|
||||
/obj/item/device/cataloguer/advanced
|
||||
name = "advanced cataloguer"
|
||||
icon_state = "adv_cataloguer"
|
||||
desc = "A hand-held device, used for compiling information about an object by scanning it. This one is an upgraded model, \
|
||||
with a scanner that both can scan from farther away, and with less time."
|
||||
scan_range = 4
|
||||
toolspeed = 0.8
|
||||
|
||||
// Able to see all defined catalogue data regardless of if it was unlocked, intended for testing.
|
||||
/obj/item/device/cataloguer/debug
|
||||
name = "omniscient cataloguer"
|
||||
desc = "A hand-held cataloguer device that appears to be plated with gold. For some reason, it \
|
||||
just seems to already know everything about narrowly defined pieces of knowledge one would find \
|
||||
from nearby, perhaps due to being colored gold. Truly a epistemological mystery."
|
||||
icon_state = "debug_cataloguer"
|
||||
toolspeed = 0.1
|
||||
scan_range = 7
|
||||
debug = TRUE
|
||||
|
||||
|
||||
/obj/item/device/cataloguer/Initialize()
|
||||
GLOB.all_cataloguers += src
|
||||
return ..()
|
||||
|
||||
/obj/item/device/cataloguer/Destroy()
|
||||
GLOB.all_cataloguers -= src
|
||||
displayed_data = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/cataloguer/update_icon()
|
||||
if(busy)
|
||||
icon_state = "[initial(icon_state)]_active"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/device/cataloguer/afterattack(atom/target, mob/user, proximity_flag)
|
||||
// Things that invalidate the scan immediately.
|
||||
if(busy)
|
||||
to_chat(user, span("warning", "\The [src] is already scanning something."))
|
||||
return
|
||||
|
||||
if(isturf(target) && (!target.can_catalogue()))
|
||||
var/turf/T = target
|
||||
for(var/a in T) // If we can't scan the turf, see if we can scan anything on it, to help with aiming.
|
||||
var/atom/A = a
|
||||
if(A.can_catalogue())
|
||||
target = A
|
||||
break
|
||||
|
||||
if(!target.can_catalogue(user)) // This will tell the user what is wrong.
|
||||
return
|
||||
|
||||
if(get_dist(target, user) > scan_range)
|
||||
to_chat(user, span("warning", "You are too far away from \the [target] to catalogue it. Get closer."))
|
||||
return
|
||||
|
||||
// Get how long the delay will be.
|
||||
var/scan_delay = target.get_catalogue_delay() * toolspeed
|
||||
if(partial_scanned)
|
||||
if(partial_scanned.resolve() == target)
|
||||
scan_delay -= partial_scan_time
|
||||
to_chat(user, span("notice", "Resuming previous scan."))
|
||||
else
|
||||
to_chat(user, span("warning", "Scanning new target. Previous scan buffer cleared."))
|
||||
|
||||
// Start the special effects.
|
||||
busy = TRUE
|
||||
update_icon()
|
||||
var/datum/beam/scan_beam = user.Beam(target, icon_state = "rped_upgrade", time = scan_delay)
|
||||
var/filter = filter(type = "outline", size = 1, color = "#FFFFFF")
|
||||
target.filters += filter
|
||||
var/list/box_segments = list()
|
||||
if(user.client)
|
||||
box_segments = draw_box(target, scan_range, user.client)
|
||||
color_box(box_segments, "#00FF00", scan_delay)
|
||||
|
||||
playsound(src.loc, 'sound/machines/beep.ogg', 50)
|
||||
|
||||
// The delay, and test for if the scan succeeds or not.
|
||||
var/scan_start_time = world.time
|
||||
if(do_after(user, scan_delay, target, ignore_movement = TRUE, max_distance = scan_range))
|
||||
if(target.can_catalogue(user))
|
||||
to_chat(user, span("notice", "You successfully scan \the [target] with \the [src]."))
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50)
|
||||
catalogue_object(target, user)
|
||||
else
|
||||
// In case someone else scans it first, or it died, etc.
|
||||
to_chat(user, span("warning", "\The [target] is no longer valid to scan with \the [src]."))
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50)
|
||||
|
||||
partial_scanned = null
|
||||
partial_scan_time = 0
|
||||
else
|
||||
to_chat(user, span("warning", "You failed to finish scanning \the [target] with \the [src]."))
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50)
|
||||
color_box(box_segments, "#FF0000", 3)
|
||||
partial_scanned = weakref(target)
|
||||
partial_scan_time += world.time - scan_start_time // This is added to the existing value so two partial scans will add up correctly.
|
||||
sleep(3)
|
||||
busy = FALSE
|
||||
|
||||
// Now clean up the effects.
|
||||
update_icon()
|
||||
QDEL_NULL(scan_beam)
|
||||
if(target)
|
||||
target.filters -= filter
|
||||
if(user.client) // If for some reason they logged out mid-scan the box will be gone anyways.
|
||||
delete_box(box_segments, user.client)
|
||||
|
||||
// Todo: Display scanned information, increment points, etc.
|
||||
/obj/item/device/cataloguer/proc/catalogue_object(atom/target, mob/living/user)
|
||||
// Figure out who may have helped out.
|
||||
var/list/contributers = list()
|
||||
var/list/contributer_names = list()
|
||||
for(var/thing in player_list)
|
||||
var/mob/M = thing
|
||||
if(M == user)
|
||||
continue
|
||||
if(get_dist(M, user) <= credit_sharing_range)
|
||||
contributers += M
|
||||
contributer_names += M.name
|
||||
|
||||
var/points_gained = 0
|
||||
|
||||
// Discover each datum available.
|
||||
var/list/object_data = target.get_catalogue_data()
|
||||
if(LAZYLEN(object_data))
|
||||
for(var/data_type in object_data)
|
||||
var/datum/category_item/catalogue/I = GLOB.catalogue_data.resolve_item(data_type)
|
||||
if(istype(I))
|
||||
var/list/discoveries = I.discover(user, list(user.name) + contributer_names) // If one discovery leads to another, the list returned will have all of them.
|
||||
if(LAZYLEN(discoveries))
|
||||
for(var/D in discoveries)
|
||||
var/datum/category_item/catalogue/data = D
|
||||
points_gained += data.value
|
||||
|
||||
// Give out points.
|
||||
if(points_gained)
|
||||
// First, to us.
|
||||
to_chat(user, span("notice", "Gained [points_gained] points from this scan."))
|
||||
adjust_points(points_gained)
|
||||
|
||||
// Now to our friends, if any.
|
||||
if(contributers.len)
|
||||
for(var/mob/M in contributers)
|
||||
var/list/things = M.GetAllContents(3) // Depth of two should reach into bags but just in case lets make it three.
|
||||
var/obj/item/device/cataloguer/other_cataloguer = locate() in things // If someone has two or more scanners this only adds points to one.
|
||||
if(other_cataloguer)
|
||||
to_chat(M, span("notice", "Gained [points_gained] points from \the [user]'s scan of \the [target]."))
|
||||
other_cataloguer.adjust_points(points_gained)
|
||||
to_chat(user, span("notice", "Shared discovery with [contributers.len] other contributer\s."))
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/device/cataloguer/AltClick(mob/user)
|
||||
pulse_scan(user)
|
||||
|
||||
// Gives everything capable of being scanned an outline for a brief moment.
|
||||
// Helps to avoid having to click a hundred things in a room for things that have an entry.
|
||||
/obj/item/device/cataloguer/proc/pulse_scan(mob/user)
|
||||
if(busy)
|
||||
to_chat(user, span("warning", "\The [src] is busy doing something else."))
|
||||
return
|
||||
|
||||
busy = TRUE
|
||||
update_icon()
|
||||
playsound(src.loc, 'sound/machines/beep.ogg', 50)
|
||||
|
||||
// First, get everything able to be scanned.
|
||||
var/list/scannable_atoms = list()
|
||||
for(var/a in view(world.view, user))
|
||||
var/atom/A = a
|
||||
if(A.can_catalogue()) // Not passing the user is intentional, so they don't get spammed.
|
||||
scannable_atoms += A
|
||||
|
||||
// Highlight things able to be scanned.
|
||||
var/filter = filter(type = "outline", size = 1, color = "#00FF00")
|
||||
for(var/a in scannable_atoms)
|
||||
var/atom/A = a
|
||||
A.filters += filter
|
||||
to_chat(user, span("notice", "\The [src] is highlighting scannable objects in green, if any exist."))
|
||||
|
||||
sleep(2 SECONDS)
|
||||
|
||||
// Remove the highlights.
|
||||
for(var/a in scannable_atoms)
|
||||
var/atom/A = a
|
||||
if(QDELETED(A))
|
||||
continue
|
||||
A.filters -= filter
|
||||
|
||||
busy = FALSE
|
||||
update_icon()
|
||||
if(scannable_atoms.len)
|
||||
playsound(src.loc, 'sound/machines/ping.ogg', 50)
|
||||
else
|
||||
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50)
|
||||
to_chat(user, span("notice", "\The [src] found [scannable_atoms.len] object\s that can be scanned."))
|
||||
|
||||
|
||||
// Negative points are bad.
|
||||
/obj/item/device/cataloguer/proc/adjust_points(amount)
|
||||
points_stored = max(0, points_stored += amount)
|
||||
|
||||
/obj/item/device/cataloguer/attack_self(mob/living/user)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/cataloguer/interact(mob/user)
|
||||
var/list/dat = list()
|
||||
var/title = "Cataloguer Data Display"
|
||||
|
||||
// Important buttons go on top since the scrollbar will default to the top of the window.
|
||||
dat += "Contains <b>[points_stored]</b> Exploration Points."
|
||||
dat += "<a href='?src=\ref[src];pulse_scan=1'>\[Highlight Scannables\]</a><a href='?src=\ref[src];refresh=1'>\[Refresh\]</a><a href='?src=\ref[src];close=1'>\[Close\]</a>"
|
||||
|
||||
// If displayed_data exists, we show that, otherwise we show a list of all data in the mysterious global list.
|
||||
if(displayed_data)
|
||||
title = uppertext(displayed_data.name)
|
||||
|
||||
dat += "<a href='?src=\ref[src];show_data=null'>\[Back to List\]</a>"
|
||||
if(debug && !displayed_data.visible)
|
||||
dat += "<a href='?src=\ref[src];debug_unlock=\ref[displayed_data]'>\[(DEBUG) Force Discovery\]</a>"
|
||||
dat += "<hr>"
|
||||
|
||||
dat += "<i>[displayed_data.desc]</i>"
|
||||
if(LAZYLEN(displayed_data.cataloguers))
|
||||
dat += "Cataloguers : <b>[english_list(displayed_data.cataloguers)]</b>."
|
||||
else
|
||||
dat += "Catalogued by nobody."
|
||||
dat += "Worth <b>[displayed_data.value]</b> exploration points."
|
||||
|
||||
else
|
||||
dat += "<hr>"
|
||||
for(var/G in GLOB.catalogue_data.categories)
|
||||
var/datum/category_group/group = G
|
||||
var/list/group_dat = list()
|
||||
var/show_group = FALSE
|
||||
|
||||
group_dat += "<b>[group.name]</b>"
|
||||
for(var/I in group.items)
|
||||
var/datum/category_item/catalogue/item = I
|
||||
if(item.visible || debug)
|
||||
group_dat += "<a href='?src=\ref[src];show_data=\ref[item]'>[item.name]</a>"
|
||||
show_group = TRUE
|
||||
|
||||
if(show_group || debug) // Avoid showing 'empty' groups on regular cataloguers.
|
||||
dat += group_dat
|
||||
|
||||
var/datum/browser/popup = new(user, "cataloguer_display_\ref[src]", title, 500, 600, src)
|
||||
popup.set_content(dat.Join("<br>"))
|
||||
popup.open()
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/device/cataloguer/Topic(href, href_list)
|
||||
if(..())
|
||||
usr << browse(null, "window=cataloguer_display")
|
||||
return 0
|
||||
if(href_list["close"] )
|
||||
usr << browse(null, "window=cataloguer_display")
|
||||
return 0
|
||||
|
||||
if(href_list["show_data"])
|
||||
displayed_data = locate(href_list["show_data"])
|
||||
|
||||
if(href_list["pulse_scan"])
|
||||
pulse_scan(usr)
|
||||
return // Don't refresh the window for this or it will open it back if its closed during the highlighting.
|
||||
|
||||
if(href_list["debug_unlock"] && debug)
|
||||
var/datum/category_item/catalogue/item = locate(href_list["debug_unlock"])
|
||||
item.discover(usr, list("Debugger"))
|
||||
|
||||
interact(usr) // So it refreshes the window.
|
||||
return 1
|
||||
|
||||
68
code/modules/catalogue/cataloguer_visuals.dm
Normal file
68
code/modules/catalogue/cataloguer_visuals.dm
Normal file
@@ -0,0 +1,68 @@
|
||||
#define ICON_SIZE 32
|
||||
|
||||
// Draws a box showing the limits of movement while scanning something.
|
||||
// Only the client supplied will see the box.
|
||||
/obj/item/device/cataloguer/proc/draw_box(atom/A, box_size, client/C)
|
||||
. = list()
|
||||
// Things moved with pixel_[x|y] will move the box, so this is to correct that.
|
||||
var/pixel_x_correction = -A.pixel_x
|
||||
var/pixel_y_correction = -A.pixel_y
|
||||
|
||||
// First, place the bottom-left corner.
|
||||
. += draw_line(A, SOUTHWEST, (-box_size * ICON_SIZE) + pixel_x_correction, (-box_size * ICON_SIZE) + pixel_y_correction, C)
|
||||
|
||||
// Make a line on the bottom, going right.
|
||||
for(var/i = 1 to (box_size * 2) - 1)
|
||||
var/x_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_x_correction
|
||||
var/y_displacement = (-box_size * ICON_SIZE) + pixel_y_correction
|
||||
. += draw_line(A, SOUTH, x_displacement, y_displacement, C)
|
||||
|
||||
// Bottom-right corner.
|
||||
. += draw_line(A, SOUTHEAST, (box_size * ICON_SIZE) + pixel_x_correction, (-box_size * ICON_SIZE) + pixel_y_correction, C)
|
||||
|
||||
// Second line, for the right side going up.
|
||||
for(var/i = 1 to (box_size * 2) - 1)
|
||||
var/x_displacement = (box_size * ICON_SIZE) + pixel_x_correction
|
||||
var/y_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_y_correction
|
||||
. += draw_line(A, EAST, x_displacement, y_displacement, C)
|
||||
|
||||
// Top-right corner.
|
||||
. += draw_line(A, NORTHEAST, (box_size * ICON_SIZE) + pixel_x_correction, (box_size * ICON_SIZE) + pixel_y_correction, C)
|
||||
|
||||
// Third line, for the top, going right.
|
||||
for(var/i = 1 to (box_size * 2) - 1)
|
||||
var/x_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_x_correction
|
||||
var/y_displacement = (box_size * ICON_SIZE) + pixel_y_correction
|
||||
. += draw_line(A, NORTH, x_displacement, y_displacement, C)
|
||||
|
||||
// Top-left corner.
|
||||
. += draw_line(A, NORTHWEST, (-box_size * ICON_SIZE) + pixel_x_correction, (box_size * ICON_SIZE) + pixel_y_correction, C)
|
||||
|
||||
// Fourth and last line, for the left side going up.
|
||||
for(var/i = 1 to (box_size * 2) - 1)
|
||||
var/x_displacement = (-box_size * ICON_SIZE) + pixel_x_correction
|
||||
var/y_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_y_correction
|
||||
. += draw_line(A, WEST, x_displacement, y_displacement, C)
|
||||
|
||||
#undef ICON_SIZE
|
||||
|
||||
// Draws an individual segment of the box.
|
||||
/obj/item/device/cataloguer/proc/draw_line(atom/A, line_dir, line_pixel_x, line_pixel_y, client/C)
|
||||
var/image/line = image(icon = 'icons/effects/effects.dmi', loc = A, icon_state = "stripes", dir = line_dir)
|
||||
line.pixel_x = line_pixel_x
|
||||
line.pixel_y = line_pixel_y
|
||||
line.plane = PLANE_FULLSCREEN // It's technically a HUD element but it doesn't need to show above item slots.
|
||||
line.appearance_flags = RESET_TRANSFORM|RESET_COLOR|RESET_ALPHA|NO_CLIENT_COLOR|TILE_BOUND
|
||||
line.alpha = 125
|
||||
C.images += line
|
||||
return line
|
||||
|
||||
// Removes the box that was generated before from the client.
|
||||
/obj/item/device/cataloguer/proc/delete_box(list/box_segments, client/C)
|
||||
for(var/i in box_segments)
|
||||
C.images -= i
|
||||
qdel(i)
|
||||
|
||||
/obj/item/device/cataloguer/proc/color_box(list/box_segments, new_color, new_time)
|
||||
for(var/i in box_segments)
|
||||
animate(i, color = new_color, time = new_time)
|
||||
Reference in New Issue
Block a user