mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-27 15:18:09 +01:00
Merge branch 'master' into protean-rework
This commit is contained in:
+11
-2
@@ -34,7 +34,16 @@ Unsure where to begin contributing to Chomp Station? You can start by looking th
|
||||
|
||||
### Chomp Station Coding Standards
|
||||
|
||||
Any code submissions that do not meet our coding standards are likely to be rejected, or at the very least, have a maintainer request changes on your PR. Save time and follow these standards from the start.
|
||||
Any code submissions that do not meet our coding standards are likely to be rejected, or at the very least, have a maintainer request changes on your PR. Save time and follow these standards from the start:
|
||||
|
||||
In an effort to make contributing easier to do, Black Major has started a modularity folder, https://github.com/CHOMPStation2/CHOMPStation2/tree/master/modular_chomp.
|
||||
Ideally, any content that can be written that is wholelly independant of vorestation's content, should be
|
||||
included in this modularity folder, and put into the associated folder that it would have appeared in among the standard files.
|
||||
|
||||
Ideally, the point of this is to make it slightly easier to differentiate chomp specific content from virgo content.
|
||||
|
||||
When should you use this?
|
||||
Mostly for chomp exclusive stuff, otherwise if you need to modify a base file for any reason or if it is expected to be a part of upstream as well, write it in the base files with the following standards/policies/guidelines in the meantime:
|
||||
|
||||
* If it is something like a bugfix that VoreStation or Polaris would want (the codebases we use), code it in their code and make the PR to them. We regularly update from them. They would want any general gameplay bugfixes, and things that are obviously intended to work one way, but do not. They do not have any of our fluff species (vulp, akula, fenn, etc) so do not make PRs related to that, or any vore content to them.
|
||||
* Never edit stock Polaris or Vore .DMI files. If you are confused about which .DMI files we have added and which were there originally, refer to their repository and and see if they exist (https://github.com/PolarisSS13/Polaris) (https://github.com/VOREStation/VOREStation). All PRs with edits to stock .DMI files might be rejected.
|
||||
@@ -42,7 +51,7 @@ Any code submissions that do not meet our coding standards are likely to be reje
|
||||
* For single-line changes: //CHOMPEdit - "Explanation" (Edit can also be Add for new lines or Removal if you are commenting the line out)
|
||||
* For multi-line additions: //CHOMPEdit - "Explanation" and then at the bottom of your changes, //CHOMPEdit End
|
||||
* For multi-line removals: Use a block comment (/\* xxx \*/) to comment out the existing code block (do not modify whitespace more than necessary) and at the start, it should contain /\* CHOMP Removal - "Reason"
|
||||
* If it is something like a bugfix that Polaris would want (the codebase we use), you may want to consider coding it there as well. They may want any general gameplay bugfixes, and things that are obviously intended to work one way, but do not. They do not have any of our fluff species (vulp, akula, fenn, etc) so do not make PRs related to that, or any vore content to them.
|
||||
* If it is something like a bugfix that Polaris or Vorestation would want (the codebase we use), you may want to consider coding it there as well. They may want any general gameplay bugfixes, and things that are obviously intended to work one way, but do not. They do not have any of our fluff species (vulp, akula, fenn, etc) so do not make PRs related to that, or any vore content to them.
|
||||
* Change whitespace as little as possible. Do not randomly add/remove whitespace.
|
||||
* Any new files should have "_ch" at the end. For example, "life_ch.dm". Just make them in the same location as the file they are related to.
|
||||
* Map changes must be in tgm format. See the [Mapmerge2 Readme] for details, or use [StrongDMM] which can automatically save maps as tgm.
|
||||
|
||||
@@ -36,6 +36,10 @@ labelPRBasedOnFilePath:
|
||||
"Type: .git or .github":
|
||||
- '.github/**'
|
||||
- '.git/**'
|
||||
|
||||
# Contains changes to the TGUI bundle
|
||||
"Type: TGUI Bundle":
|
||||
- 'tgui/public/**'
|
||||
|
||||
##### Greetings ########################################################################################################
|
||||
# Comment to be posted to welcome users when they open their first PR
|
||||
@@ -103,4 +107,4 @@ firstIssueWelcomeComment: >
|
||||
# # It helps avoid multiple heads in alembic migrations in a collaborative development project.
|
||||
# - airflow/migrations/*
|
||||
# - airflow/migrations/**/*
|
||||
# - airflow/alembic.ini
|
||||
# - airflow/alembic.ini
|
||||
|
||||
@@ -161,7 +161,16 @@
|
||||
|
||||
if(istype(target, /turf/simulated))
|
||||
var/turf/simulated/modeled_location = target
|
||||
|
||||
if(modeled_location.special_temperature)//First do special interactions then the usuall stuff
|
||||
|
||||
var/delta_temp = modeled_location.special_temperature - air.temperature//2200C - 20C = 2180K
|
||||
//assuming aluminium with thermal conductivity 235 W * K / m, Copper (400), Silver (430), steel (50), gold (320)
|
||||
var/heat_gain = 23500 * 100 * delta_temp
|
||||
air.add_thermal_energy(heat_gain)
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
if(modeled_location.blocks_air)
|
||||
|
||||
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
|
||||
|
||||
@@ -98,7 +98,8 @@
|
||||
else
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
environment_temperature = environment.temperature
|
||||
if(abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference)
|
||||
var/turf/simulated/loc_as_turf = loc
|
||||
if((abs(environment_temperature-pipe_air.temperature) > minimum_temperature_difference) || (loc_as_turf.special_temperature))
|
||||
parent.temperature_interact(loc, volume, thermal_conductivity)
|
||||
else if(istype(loc, /turf/space/))
|
||||
parent.radiate_heat_to_space(surface, 1)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// Methods of obtaining a circuit.
|
||||
#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and able to be printed in the IC printer.
|
||||
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it.
|
||||
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it.
|
||||
#define IC_SPAWN_ILLEGAL 3 // If the circuit design will be available if upgrading the IC printer illegally.
|
||||
+88
-120
@@ -1,121 +1,89 @@
|
||||
// Sorted alphabetically
|
||||
// Shamelessly yoinked from TGCode, luv u folks
|
||||
#define span_abductor(str) ("<span class='abductor'>" + str + "</span>")
|
||||
#define span_admin(str) ("<span class='admin'>" + str + "</span>")
|
||||
#define span_adminhelp(str) ("<span class='adminhelp'>" + str + "</span>")
|
||||
#define span_adminnotice(str) ("<span class='adminnotice'>" + str + "</span>")
|
||||
#define span_adminobserverooc(str) ("<span class='adminobserverooc'>" + str + "</span>")
|
||||
#define span_adminooc(str) ("<span class='adminooc'>" + str + "</span>")
|
||||
#define span_adminsay(str) ("<span class='adminsay'>" + str + "</span>")
|
||||
#define span_aiprivradio(str) ("<span class='aiprivradio'>" + str + "</span>")
|
||||
#define span_alert(str) ("<span class='alert'>" + str + "</span>")
|
||||
#define span_alertalien(str) ("<span class='alertalien'>" + str + "</span>")
|
||||
#define span_alertsyndie(str) ("<span class='alertsyndie'>" + str + "</span>")
|
||||
#define span_alertwarning(str) ("<span class='alertwarning'>" + str + "</span>")
|
||||
#define span_alien(str) ("<span class='alien'>" + str + "</span>")
|
||||
#define span_announce(str) ("<span class='announce'>" + str + "</span>")
|
||||
#define span_big(str) ("<span class='big'>" + str + "</span>")
|
||||
#define span_bigicon(str) ("<span class='bigicon'>" + str + "</span>")
|
||||
#define span_binarysay(str) ("<span class='binarysay'>" + str + "</span>")
|
||||
#define span_blue(str) ("<span class='blue'>" + str + "</span>")
|
||||
#define span_blueteamradio(str) ("<span class='blueteamradio'>" + str + "</span>")
|
||||
#define span_bold(str) ("<span class='bold'>" + str + "</span>")
|
||||
#define span_boldannounce(str) ("<span class='boldannounce'>" + str + "</span>")
|
||||
#define span_boldnotice(str) ("<span class='boldnotice'>" + str + "</span>")
|
||||
#define span_boldwarning(str) ("<span class='boldwarning'>" + str + "</span>")
|
||||
#define span_centcomradio(str) ("<span class='centcomradio'>" + str + "</span>")
|
||||
#define span_changeling(str) ("<span class='changeling'>" + str + "</span>")
|
||||
#define span_clown(str) ("<span class='clown'>" + str + "</span>")
|
||||
#define span_colossus(str) ("<span class='colossus'>" + str + "</span>")
|
||||
#define span_command_headset(str) ("<span class='command_headset'>" + str + "</span>")
|
||||
#define span_comradio(str) ("<span class='comradio'>" + str + "</span>")
|
||||
#define span_cult(str) ("<span class='cult'>" + str + "</span>")
|
||||
#define span_cultbold(str) ("<span class='cultbold'>" + str + "</span>")
|
||||
#define span_cultboldtalic(str) ("<span class='cultboldtalic'>" + str + "</span>")
|
||||
#define span_cultitalic(str) ("<span class='cultitalic'>" + str + "</span>")
|
||||
#define span_cultlarge(str) ("<span class='cultlarge'>" + str + "</span>")
|
||||
#define span_danger(str) ("<span class='danger'>" + str + "</span>")
|
||||
#define span_deadsay(str) ("<span class='deadsay'>" + str + "</span>")
|
||||
#define span_deconversion_message(str) ("<span class='deconversion_message'>" + str + "</span>")
|
||||
#define span_drone(str) ("<span class='drone'>" + str + "</span>")
|
||||
#define span_engradio(str) ("<span class='engradio'>" + str + "</span>")
|
||||
#define span_extremelybig(str) ("<span class='extremelybig'>" + str + "</span>")
|
||||
#define span_ghostalert(str) ("<span class='ghostalert'>" + str + "</span>")
|
||||
#define span_green(str) ("<span class='green'>" + str + "</span>")
|
||||
#define span_greenannounce(str) ("<span class='greenannounce'>" + str + "</span>")
|
||||
#define span_greenteamradio(str) ("<span class='greenteamradio'>" + str + "</span>")
|
||||
#define span_greentext(str) ("<span class='greentext'>" + str + "</span>")
|
||||
#define span_hear(str) ("<span class='hear'>" + str + "</span>")
|
||||
#define span_hidden(str) ("<span class='hidden'>" + str + "</span>")
|
||||
#define span_hierophant(str) ("<span class='hierophant'>" + str + "</span>")
|
||||
#define span_hierophant_warning(str) ("<span class='hierophant_warning'>" + str + "</span>")
|
||||
#define span_highlight(str) ("<span class='highlight'>" + str + "</span>")
|
||||
#define span_his_grace(str) ("<span class='his_grace'>" + str + "</span>")
|
||||
#define span_holoparasite(str) ("<span class='holoparasite'>" + str + "</span>")
|
||||
#define span_hypnophrase(str) ("<span class='hypnophrase'>" + str + "</span>")
|
||||
#define span_icon(str) ("<span class='icon'>" + str + "</span>")
|
||||
#define span_info(str) ("<span class='info'>" + str + "</span>")
|
||||
#define span_interface(str) ("<span class='interface'>" + str + "</span>")
|
||||
#define span_looc(str) ("<span class='looc'>" + str + "</span>")
|
||||
#define span_medal(str) ("<span class='medal'>" + str + "</span>")
|
||||
#define span_medradio(str) ("<span class='medradio'>" + str + "</span>")
|
||||
#define span_memo(str) ("<span class='memo'>" + str + "</span>")
|
||||
#define span_memoedit(str) ("<span class='memoedit'>" + str + "</span>")
|
||||
#define span_mind_control(str) ("<span class='mind_control'>" + str + "</span>")
|
||||
#define span_minorannounce(str) ("<span class='minorannounce'>" + str + "</span>")
|
||||
#define span_monkey(str) ("<span class='monkey'>" + str + "</span>")
|
||||
#define span_monkeyhive(str) ("<span class='monkeyhive'>" + str + "</span>")
|
||||
#define span_monkeylead(str) ("<span class='monkeylead'>" + str + "</span>")
|
||||
#define span_name(str) ("<span class='name'>" + str + "</span>")
|
||||
#define span_narsie(str) ("<span class='narsie'>" + str + "</span>")
|
||||
#define span_narsiesmall(str) ("<span class='narsiesmall'>" + str + "</span>")
|
||||
#define span_nicegreen(str) ("<span class='nicegreen'>" + str + "</span>")
|
||||
#define span_notice(str) ("<span class='notice'>" + str + "</span>")
|
||||
#define span_noticealien(str) ("<span class='noticealien'>" + str + "</span>")
|
||||
#define span_ooc(str) ("<span class='ooc'>" + str + "</span>")
|
||||
#define span_papyrus(str) ("<span class='papyrus'>" + str + "</span>")
|
||||
#define span_phobia(str) ("<span class='phobia'>" + str + "</span>")
|
||||
#define span_prefix(str) ("<span class='prefix'>" + str + "</span>")
|
||||
#define span_purple(str) ("<span class='purple'>" + str + "</span>")
|
||||
#define span_radio(str) ("<span class='radio'>" + str + "</span>")
|
||||
#define span_reallybig(str) ("<span class='reallybig'>" + str + "</span>")
|
||||
#define span_red(str) ("<span class='red'>" + str + "</span>")
|
||||
#define span_redteamradio(str) ("<span class='redteamradio'>" + str + "</span>")
|
||||
#define span_redtext(str) ("<span class='redtext'>" + str + "</span>")
|
||||
#define span_resonate(str) ("<span class='resonate'>" + str + "</span>")
|
||||
#define span_revenbignotice(str) ("<span class='revenbignotice'>" + str + "</span>")
|
||||
#define span_revenboldnotice(str) ("<span class='revenboldnotice'>" + str + "</span>")
|
||||
#define span_revendanger(str) ("<span class='revendanger'>" + str + "</span>")
|
||||
#define span_revenminor(str) ("<span class='revenminor'>" + str + "</span>")
|
||||
#define span_revennotice(str) ("<span class='revennotice'>" + str + "</span>")
|
||||
#define span_revenwarning(str) ("<span class='revenwarning'>" + str + "</span>")
|
||||
#define span_robot(str) ("<span class='robot'>" + str + "</span>")
|
||||
#define span_rose(str) ("<span class='rose'>" + str + "</span>")
|
||||
#define span_sans(str) ("<span class='sans'>" + str + "</span>")
|
||||
#define span_sciradio(str) ("<span class='sciradio'>" + str + "</span>")
|
||||
#define span_secradio(str) ("<span class='secradio'>" + str + "</span>")
|
||||
#define span_servradio(str) ("<span class='servradio'>" + str + "</span>")
|
||||
#define span_singing(str) ("<span class='singing'>" + str + "</span>")
|
||||
#define span_slime(str) ("<span class='slime'>" + str + "</span>")
|
||||
#define span_small(str) ("<span class='small'>" + str + "</span>")
|
||||
#define span_smallnotice(str) ("<span class='smallnotice'>" + str + "</span>")
|
||||
#define span_smallnoticeital(str) ("<span class='smallnoticeital'>" + str + "</span>")
|
||||
#define span_spider(str) ("<span class='spider'>" + str + "</span>")
|
||||
#define span_suicide(str) ("<span class='suicide'>" + str + "</span>")
|
||||
#define span_suppradio(str) ("<span class='suppradio'>" + str + "</span>")
|
||||
#define span_swarmer(str) ("<span class='swarmer'>" + str + "</span>")
|
||||
#define span_syndradio(str) ("<span class='syndradio'>" + str + "</span>")
|
||||
#define span_tape_recorder(str) ("<span class='tape_recorder'>" + str + "</span>")
|
||||
#define span_tinynotice(str) ("<span class='tinynotice'>" + str + "</span>")
|
||||
#define span_tinynoticeital(str) ("<span class='tinynoticeital'>" + str + "</span>")
|
||||
#define span_unconscious(str) ("<span class='unconscious'>" + str + "</span>")
|
||||
#define span_userdanger(str) ("<span class='userdanger'>" + str + "</span>")
|
||||
#define span_warning(str) ("<span class='warning'>" + str + "</span>")
|
||||
#define span_yell(str) ("<span class='yell'>" + str + "</span>")
|
||||
#define span_yellowteamradio(str) ("<span class='yellowteamradio'>" + str + "</span>"
|
||||
|
||||
// VORE Specific stuff after this point
|
||||
// Sorted by however I felt like it
|
||||
#define span_game_say(str) ("<span class='game_say'>" + str + "</span>"
|
||||
#define span_emote_subtle(str) ("<span class='emote_subtle'>" + str + "</span>"
|
||||
#define span_emote(str) ("<span class='emote'>" + str + "</span>"
|
||||
// We have two other ways of doing this, so why not a third. This one atleast has more span options.
|
||||
#define span_ooc(str) ("<span class='ooc'>" + str + "</span>")
|
||||
#define span_looc(str) ("<span class='looc'>" + str + "</span>")
|
||||
|
||||
#define span_deadsay(str) ("<span class='deadsay'>" + str + "</span>")
|
||||
#define span_radio(str) ("<span class='radio'>" + str + "</span>")
|
||||
#define span_deptradio(str) ("<span class='deptradio'>" + str + "</span>")
|
||||
#define span_newscaster(str) ("<span class='newscaster'>" + str + "</span>")
|
||||
|
||||
#define span_comradio(str) ("<span class='comradio'>" + str + "</span>")
|
||||
#define span_syndradio(str) ("<span class='syndradio'>" + str + "</span>")
|
||||
#define span_centradio(str) ("<span class='centradio'>" + str + "</span>"
|
||||
#define span_airadio(str) ("<span class='airadio'>" + str + "</span>")
|
||||
#define span_entradio(str) ("<span class='entradio'>" + str + "</span>")
|
||||
|
||||
#define span_secradio(str) ("<span class='secradio'>" + str + "</span>")
|
||||
#define span_engradio(str) ("<span class='engradio'>" + str + "</span>")
|
||||
#define span_medradio(str) ("<span class='medradio'>" + str + "</span>")
|
||||
#define span_sciradio(str) ("<span class='sciradio'>" + str + "</span>")
|
||||
#define span_supradio(str) ("<span class='supradio'>" + str + "</span>"
|
||||
#define span_srvradio(str) ("<span class='srvradio'>" + str + "</span>")
|
||||
#define span_expradio(str) ("<span class='expradio'>" + str + "</span>")
|
||||
|
||||
#define span_name(str) ("<span class='name'>" + str + "</span>")
|
||||
#define span_say(str) ("<span class='say'>" + str + "</span>")
|
||||
#define span_alert(str) ("<span class='alert'>" + str + "</span>")
|
||||
#define span_ghostalert(str) ("<span class='ghostalert'>" + str + "</span>")
|
||||
|
||||
|
||||
#define span_emote(str) ("<span class='emote'>" + str + "</span>")
|
||||
#define span_emote_subtle(str) ("<span class='emote_subtle'>" + str + "</span>")
|
||||
|
||||
#define span_attack(str) ("<span class='attack'>" + str + "</span>")
|
||||
#define span_moderate(str) ("<span class='moderate'>" + str + "</span>")
|
||||
#define span_disarm(str) ("<span class='disarm'>" + str + "</span>")
|
||||
#define span_passive(str) ("<span class='passive'>" + str + "</span>")
|
||||
|
||||
#define span_critical(str) ("<span class='critical'>" + str + "</span>")
|
||||
#define span_danger(str) ("<span class='danger'>" + str + "</span>")
|
||||
#define span_warning(str) ("<span class='warning'>" + str + "</span>")
|
||||
#define span_rose(str) ("<span class='rose'>" + str + "</span>")
|
||||
#define span_info(str) ("<span class='info'>" + str + "</span>")
|
||||
#define span_notice(str) ("<span class='notice'>" + str + "</span>")
|
||||
#define span_alium(str) ("<span class='alium'>" + str + "</span>")
|
||||
#define span_cult(str) ("<span class='cult'>" + str + "</span>")
|
||||
|
||||
#define span_reflex_shoot(str) ("<span class='reflex_shoot'>" + str + "</span>")
|
||||
|
||||
/* Languages */
|
||||
|
||||
#define span_alien(str) ("<span class='alien'>" + str + "</span>")
|
||||
#define span_tajaran(str) ("<span class='tajaran'>" + str + "</span>")
|
||||
#define span_tajaran_signlang(str) ("<span class='tajaran_signlang'>" + str + "</span>")
|
||||
#define span_akhani(str) ("<span class='akhani'>" + str + "</span>")
|
||||
#define span_skrell(str) ("<span class='skrell'>" + str + "</span>")
|
||||
#define span_skrellfar(str) ("<span class='skrellfar'>" + str + "</span>")
|
||||
#define span_soghun(str) ("<span class='soghun'>" + str + "</span>")
|
||||
#define span_solcom(str) ("<span class='solcom'>" + str + "</span>")
|
||||
#define span_changeling(str) ("<span class='changeling'>" + str + "</span>")
|
||||
#define span_sergal(str) ("<span class='sergal'>" + str + "</span>")
|
||||
#define span_birdsongc(str) ("<span class='birdsongc'>" + str + "</span>")
|
||||
#define span_vulpkanin(str) ("<span class='vulpkanin'>" + str + "</span>")
|
||||
#define span_enochian(str) ("<span class='enochian'>" + str + "</span>")
|
||||
#define span_daemon(str) ("<span class='daemon'>" + str + "</span>")
|
||||
#define span_bug(str) ("<span class='bug'>" + str + "</span>")
|
||||
#define span_vox(str) ("<span class='vox'>" + str + "</span>")
|
||||
#define span_zaddat(str) ("<span class='zaddat'>" + str + "</span>")
|
||||
#define span_promethean(str) ("<span class='promethean'>" + str + "</span>")
|
||||
#define span_rough(str) ("<span class='rough'>" + str + "</span>")
|
||||
#define span_say_quote(str) ("<span class='say_quote'>" + str + "</span>")
|
||||
#define span_terminus(str) ("<span class='terminus'>" + str + "</span>")
|
||||
#define span_interface(str) ("<span class='interface'>" + str + "</span>")
|
||||
#define span_spacer(str) ("<span class='spacer'>" + str + "</span>")
|
||||
#define span_blob(str) ("<span class='blob'>" + str + "</span>")
|
||||
|
||||
#define span_debug_error(str) ("<span class='debug_error'>" + str + "</span>")
|
||||
#define span_debug_warning(str) ("<span class='debug_warning'>" + str + "</span>")
|
||||
#define span_debug_info(str) ("<span class='debug_info'>" + str + "</span>")
|
||||
#define span_debug_debug(str) ("<span class='debug_debug'>" + str + "</span>")
|
||||
#define span_debug_trace(str) ("<span class='debug_trace'>" + str + "</span>")
|
||||
|
||||
#define span_black(str) ("<span class='black'>" + str + "</span>")
|
||||
#define span_darkgray(str) ("<span class='darkgray'>" + str + "</span>")
|
||||
#define span_gray(str) ("<span class='gray'>" + str + "</span>")
|
||||
#define span_red(str) ("<span class='red'>" + str + "</span>")
|
||||
#define span_orange(str) ("<span class='orange'>" + str + "</span>")
|
||||
#define span_blue(str) ("<span class='blue'>" + str + "</span>")
|
||||
#define span_green(str) ("<span class='green'>" + str + "</span>")
|
||||
@@ -111,6 +111,7 @@
|
||||
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
|
||||
#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
|
||||
#define ALT_TRANSMIT 512 // Language is not based on vision or sound (Todo: add this into the say code and use it for the rootspeak languages)
|
||||
#define INAUDIBLE 1024 // Language is not audible (similar to nonverbal) but is still using hearing-based recognition
|
||||
|
||||
#define SKIN_NORMAL 0
|
||||
#define SKIN_THREAT 1
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define LANGUAGE_SPACER "Spacer"
|
||||
#define LANGUAGE_CLOWNISH "Coulrian"
|
||||
#define LANGUAGE_TAVAN "Tavan"
|
||||
#define LANGUAGE_ECHOSONG "Echo Song"
|
||||
|
||||
#define LANGUAGE_CHIMPANZEE "Chimpanzee"
|
||||
#define LANGUAGE_NEAERA "Neaera"
|
||||
|
||||
@@ -151,9 +151,9 @@ Proc for attack log creation, because really why not
|
||||
/proc/get_exposed_defense_zone(var/atom/movable/target)
|
||||
var/obj/item/weapon/grab/G = locate() in target
|
||||
if(G && G.state >= GRAB_NECK) //works because mobs are currently not allowed to upgrade to NECK if they are grabbing two people.
|
||||
return pick("head", "l_hand", "r_hand", "l_foot", "r_foot", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
return pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG)
|
||||
else
|
||||
return pick("chest", "groin")
|
||||
return pick(BP_TORSO, BP_GROIN)
|
||||
|
||||
/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = FALSE, progress = TRUE, ignore_movement = FALSE, exclusive = FALSE)
|
||||
if(!user || !target)
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/client
|
||||
var/datum/managed_browser/changelingevolution/changelingevolution = null
|
||||
|
||||
/datum/managed_browser/changelingevolution
|
||||
base_browser_id = "evolution_tree"
|
||||
title = "Evolution Tree"
|
||||
size_x = 480
|
||||
size_y = 600
|
||||
var/textbody = null
|
||||
|
||||
/datum/managed_browser/changelingevolution/New(client/new_client)
|
||||
if(!new_client.mob || !new_client.mob.mind || !new_client.mob.mind.changeling)
|
||||
message_admins("[new_client] tried to access changeling evolutions while not changeling.")
|
||||
qdel(src)
|
||||
|
||||
..()
|
||||
|
||||
/datum/managed_browser/changelingevolution/Destroy()
|
||||
if(my_client)
|
||||
my_client.changelingevolution = null
|
||||
return ..()
|
||||
|
||||
/datum/managed_browser/changelingevolution/get_html()
|
||||
var/list/dat = list("<html><body>")
|
||||
var/geneticpoints_current = my_client.mob.mind.changeling.geneticpoints
|
||||
var/geneticpoints_max = my_client.mob.mind.changeling.max_geneticpoints
|
||||
|
||||
dat += "<center>Genetic Points Available: [geneticpoints_current] / [geneticpoints_max] <br>"
|
||||
dat += "Obtain more by feeding on your own kind. <br> <hr>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];tutorial=1'>What am I?</a><br><hr>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];inherent=1'>Inherent</a>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];armor=1'>Armor</a>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];weapons=1'>Weapons</a>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];stings=1'>Stings</a>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];shrieks=1'>Shrieks</a>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];health=1'>Health</a>"
|
||||
dat += "<a style='background-color:#c72121;' href='?src=\ref[src];enhancements=1'>Enhancements</a></center>"
|
||||
if(textbody)
|
||||
dat += "<table border='1' style='width:100%; background-color:#000000;'>"
|
||||
dat += "[textbody]"
|
||||
dat += "</table>"
|
||||
dat += "</body></html>"
|
||||
|
||||
return dat.Join()
|
||||
|
||||
/datum/managed_browser/changelingevolution/Topic(href, href_list[])
|
||||
if(!my_client)
|
||||
return FALSE
|
||||
|
||||
if(href_list["close"])
|
||||
return
|
||||
|
||||
if(href_list["inherent"])
|
||||
generate_abilitylist(CHANGELING_POWER_INHERENT)
|
||||
|
||||
if(href_list["armor"])
|
||||
generate_abilitylist(CHANGELING_POWER_ARMOR)
|
||||
|
||||
if(href_list["weapons"])
|
||||
generate_abilitylist(CHANGELING_POWER_WEAPONS)
|
||||
|
||||
if(href_list["stings"])
|
||||
generate_abilitylist(CHANGELING_POWER_STINGS)
|
||||
|
||||
if(href_list["shrieks"])
|
||||
generate_abilitylist(CHANGELING_POWER_SHRIEKS)
|
||||
|
||||
if(href_list["health"])
|
||||
generate_abilitylist(CHANGELING_POWER_HEALTH)
|
||||
|
||||
if(href_list["enhancements"])
|
||||
generate_abilitylist(CHANGELING_POWER_ENHANCEMENTS)
|
||||
|
||||
if(href_list["evolve"])
|
||||
var/datum/mind/M = my_client.mob.mind
|
||||
var/datum/changeling/C = my_client.mob.mind.changeling
|
||||
var/datum/power/changeling/Thepower = href_list["evolve"]
|
||||
|
||||
for (var/datum/power/changeling/P in powerinstances)
|
||||
if(P.name == Thepower)
|
||||
Thepower = P
|
||||
break
|
||||
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(Thepower == null)
|
||||
to_chat(M.current, "Purchase failed. Inform a dev of this error.")
|
||||
return
|
||||
|
||||
if(Thepower in C.purchased_powers)
|
||||
to_chat(M.current, "You already have this ability! Inform a dev of this error.") /// Should not be possible
|
||||
return
|
||||
|
||||
if(C.geneticpoints < Thepower.genomecost)
|
||||
to_chat(M.current, "We cannot evolve this... yet. We must acquire more DNA.")
|
||||
return
|
||||
|
||||
C.purchased_powers += Thepower /// Set it to purchased
|
||||
C.geneticpoints -= Thepower.genomecost
|
||||
generate_abilitylist(Thepower.power_category) /// Refresh the UI
|
||||
|
||||
my_client.mob.mind.changeling.purchasePower(M, Thepower)
|
||||
|
||||
if(href_list["tutorial"])
|
||||
textbody = "<tr><th><font color='#c72121'><center>What am I?</center></font><br></th></tr>"
|
||||
textbody += "<tr><td>"
|
||||
textbody += "<font color='#F7F7ED'>You are a changeling, a creature empowered with genetic-based abilities that change your body in bizarre ways."
|
||||
textbody += " It's probably best the crew doesn't know about your power -- at least not right away.</font><br><br>"
|
||||
textbody += "<font color='#F7F7ED'>What a changeling <i>is</i>, however, is up to you. Are you a strange alien impersonating crew? Are you a"
|
||||
textbody += " normal crewmember infected with a parasite? An experiment gone wrong? It's up to you to make the story.</font><br><br>"
|
||||
textbody += "<font color='#F7F7ED'>Of course, you need to know how it works to begin with.</font><br><br>"
|
||||
textbody += "<font color='#F7F7ED'>Your abilities cost chemicals that your body will slowly regenerate with varying speeds based on enhancements obtained."
|
||||
textbody += " There are a set of inherent abilities you will always have while the rest may be purchased through genomes.</font><br><br>"
|
||||
textbody += "<font color='#F7F7ED'>You may obtain more genomes if you find another changeling and absorb them, but this is not required. If you've found "
|
||||
textbody += "your abilities aren't to your liking, you have up to two re-adapts available, and these may be refilled by absorbing anyone -- including monkeys.</font><br><br>"
|
||||
textbody += "<font color='#F7F7ED'>Good luck and remember, killing isn't always the end goal.</font>"
|
||||
display()
|
||||
|
||||
/datum/managed_browser/changelingevolution/proc/generate_abilitylist(cat)
|
||||
var/list/ability_list = list()
|
||||
var/info = ""
|
||||
var/catname = ""
|
||||
for(var/datum/power/changeling/P in powerinstances)
|
||||
if(P.power_category == cat)
|
||||
ability_list[++ability_list.len] = P
|
||||
switch(cat)
|
||||
if(CHANGELING_POWER_INHERENT)
|
||||
catname = "Inherent"
|
||||
info = "These powers are inherent to your kind and will always be accessible, provided you have the chemicals to use them."
|
||||
if(CHANGELING_POWER_ARMOR)
|
||||
catname = "Armor"
|
||||
info = "These abilities will provide you with space protection -- and potentially armor."
|
||||
if(CHANGELING_POWER_WEAPONS)
|
||||
catname = "Weapons"
|
||||
info = "These abilities will provide you the means to fight back."
|
||||
if(CHANGELING_POWER_STINGS)
|
||||
catname = "Stings"
|
||||
info = "These abilities provide the means to sting organic beings for various effects -- though you must be close enough, and they must have exposed flesh."
|
||||
if(CHANGELING_POWER_SHRIEKS)
|
||||
catname = "Shrieks"
|
||||
info = "These abilities enhance your vocal chords, empowering your screams."
|
||||
if(CHANGELING_POWER_HEALTH)
|
||||
catname = "Health"
|
||||
info = "These abilities will enhance your health or aid you in mending your wounds."
|
||||
if(CHANGELING_POWER_ENHANCEMENTS)
|
||||
catname = "Enhancements"
|
||||
info = "These abilities enhance you in various ways."
|
||||
create_textbody(ability_list, catname, info)
|
||||
|
||||
/datum/managed_browser/changelingevolution/proc/create_textbody(ability_list, cat, catinfo)
|
||||
textbody = "<tr><th><font color='#c72121'><center>[cat] Skills</font><br></th></tr>"
|
||||
textbody += "<tr><td><font color='#F7F7ED'>[catinfo]</center></font><br><hr></td></tr>"
|
||||
for(var/A in ability_list)
|
||||
var/datum/power/changeling/powerdata = A
|
||||
textbody += "<tr><td><center><font color='#c72121'><b>[initial(powerdata.name)]</b></font><br></center>"
|
||||
textbody += "<font color='#F7F7ED'>[initial(powerdata.desc)]</font><br><br>"
|
||||
textbody += "<font color='#F7F7ED'><i>[powerdata.helptext]</i></font><br>"
|
||||
if(powerdata.enhancedtext != "")
|
||||
textbody += "<font color='#F7F7ED'><b>WHEN EHANCED: </b><i>[powerdata.enhancedtext]</i></font><br>"
|
||||
if(powerdata in my_client.mob.mind.changeling.purchased_powers)
|
||||
textbody += "<center><font color='#F7F7ED'><i><b>This ability is already evolved!</b></i></font></center>"
|
||||
else if(cat != "Inherent")
|
||||
textbody += "<center>Cost: [powerdata.genomecost]</center>"
|
||||
textbody += "<center><a style='background-color:#c72121;' href='?src=\ref[src];evolve=[A]'>Evolve</a></center>"
|
||||
textbody += "</td></tr>"
|
||||
display()
|
||||
@@ -26,6 +26,13 @@
|
||||
/obj/item/clothing/head/radiation = 3
|
||||
)
|
||||
|
||||
/datum/supply_pack/eng/dosimeter
|
||||
contains = list(/obj/item/weapon/storage/box/dosimeter = 6)
|
||||
name = "Dosimeters"
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "dosimeter crate"
|
||||
|
||||
/datum/supply_pack/eng/algae
|
||||
contains = list(/obj/item/stack/material/algae/ten)
|
||||
name = "Algae Sheets (10)"
|
||||
|
||||
@@ -24,14 +24,16 @@
|
||||
/proc/randmutb(var/mob/living/M)
|
||||
if(!M) return
|
||||
M.dna.check_integrity()
|
||||
var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK)
|
||||
//var/block = pick(GLASSESBLOCK,COUGHBLOCK,FAKEBLOCK,NERVOUSBLOCK,CLUMSYBLOCK,TWITCHBLOCK,HEADACHEBLOCK,BLINDBLOCK,DEAFBLOCK,HALLUCINATIONBLOCK) // Most of these are disabled anyway.
|
||||
var/block = pick(FAKEBLOCK,CLUMSYBLOCK,BLINDBLOCK,DEAFBLOCK)
|
||||
M.dna.SetSEState(block, 1)
|
||||
|
||||
// Give Random Good Mutation to M
|
||||
/proc/randmutg(var/mob/living/M)
|
||||
if(!M) return
|
||||
M.dna.check_integrity()
|
||||
var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK)
|
||||
//var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,NOBREATHBLOCK,REMOTEVIEWBLOCK,REGENERATEBLOCK,INCREASERUNBLOCK,REMOTETALKBLOCK,MORPHBLOCK,BLENDBLOCK,NOPRINTSBLOCK,SHOCKIMMUNITYBLOCK,SMALLSIZEBLOCK) // Much like above, most of these blocks are disabled in code.
|
||||
var/block = pick(HULKBLOCK,XRAYBLOCK,FIREBLOCK,TELEBLOCK,REGENERATEBLOCK,REMOTETALKBLOCK)
|
||||
M.dna.SetSEState(block, 1)
|
||||
|
||||
// Random Appearance Mutation
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
var/languages=null
|
||||
var/list/flavor=null
|
||||
var/gender = null
|
||||
var/list/body_descriptors = null
|
||||
var/list/body_descriptors = null // Guess we'll keep null.
|
||||
var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance.
|
||||
|
||||
/datum/dna2/record/proc/GetData()
|
||||
@@ -54,7 +54,8 @@
|
||||
newrecord.implant = implant
|
||||
newrecord.flavor = flavor
|
||||
newrecord.gender = gender
|
||||
newrecord.body_descriptors = body_descriptors.Copy()
|
||||
if(body_descriptors)
|
||||
newrecord.body_descriptors = body_descriptors.Copy()
|
||||
newrecord.genetic_modifiers = genetic_modifiers.Copy()
|
||||
return newrecord
|
||||
|
||||
|
||||
@@ -107,6 +107,9 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/guestpass/attackby(obj/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/card/id/guest))
|
||||
to_chat(user, "<span class='warning'>The guest pass terminal denies to accept the guest pass.</span>")
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/card/id))
|
||||
if(!giver && user.unEquip(I))
|
||||
I.forceMove(src)
|
||||
|
||||
@@ -47,4 +47,4 @@
|
||||
/decl/poster/tg_10
|
||||
name = "Hacking Guide"
|
||||
desc = "This poster details the internal workings of the common NanoTrasen airlock."
|
||||
icon_state="poster10"
|
||||
icon_state="poster10"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/decl/poster/tg_11 //CHOMPedit
|
||||
name = "Post This Ratvar"
|
||||
desc = "This poster seems to have an animated image on it. Truly an advancement in the wonders of technology."
|
||||
icon_state = "postvar"
|
||||
@@ -0,0 +1,73 @@
|
||||
var/global/list/global_used_pois = list()
|
||||
|
||||
|
||||
|
||||
/obj/effect/landmark/poi_loader
|
||||
name = "PoI Loader"
|
||||
var/size_x
|
||||
var/size_y
|
||||
var/poi_type = null
|
||||
var/remove_from_pool = TRUE
|
||||
|
||||
/obj/effect/landmark/poi_loader/New()
|
||||
INITIALIZE_IMMEDIATE(/obj/effect/landmark/poi_loader)
|
||||
|
||||
/obj/effect/landmark/poi_loader/Initialize()
|
||||
src.load_poi()
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/poi_loader/proc/get_turfs_to_clean()
|
||||
return block(locate(src.x, src.y, src.z), locate((src.x + size_x - 1), (src.y + size_y - 1), src.z))
|
||||
|
||||
/obj/effect/landmark/poi_loader/proc/annihilate_bounds()
|
||||
//var/deleted_atoms = 0
|
||||
//admin_notice("<span class='danger'>Annihilating objects in poi loading location.</span>", R_DEBUG)
|
||||
var/list/turfs_to_clean = get_turfs_to_clean()
|
||||
if(turfs_to_clean.len)
|
||||
for(var/x in 1 to 2) // Requires two passes to get everything.
|
||||
for(var/turf/T in turfs_to_clean)
|
||||
for(var/atom/movable/AM in T)
|
||||
//++deleted_atoms
|
||||
qdel(AM)
|
||||
//admin_notice("<span class='danger'>Annihilated [deleted_atoms] objects.</span>", R_DEBUG)
|
||||
|
||||
/obj/effect/landmark/poi_loader/proc/load_poi()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!isturf(T))
|
||||
to_world_log("[log_info_line(src)] not on a turf! Cannot place poi template.")
|
||||
return
|
||||
|
||||
// Choose a poi
|
||||
if(!poi_type)
|
||||
return
|
||||
|
||||
if(!(global_used_pois.len) || !(global_used_pois[poi_type]))
|
||||
global_used_pois[poi_type] = list()
|
||||
var/list/poi_list = global_used_pois[poi_type]
|
||||
for(var/map in SSmapping.map_templates)
|
||||
var/template = SSmapping.map_templates[map]
|
||||
if(istype(template, poi_type))
|
||||
poi_list += template
|
||||
|
||||
var/datum/map_template/template_to_use = null
|
||||
|
||||
var/list/our_poi_list = global_used_pois[poi_type]
|
||||
|
||||
if(!our_poi_list.len)
|
||||
return
|
||||
else
|
||||
template_to_use = pick(our_poi_list)
|
||||
|
||||
if(!template_to_use)
|
||||
return
|
||||
|
||||
//admin_notice("<span class='danger'>Chosen Predefined PoI Map: [chosen_type.name]</span>", R_DEBUG)
|
||||
|
||||
if(remove_from_pool)
|
||||
global_used_pois[poi_type] -= template_to_use
|
||||
|
||||
// Annihilate movable atoms
|
||||
annihilate_bounds()
|
||||
//CHECK_TICK //Don't let anything else happen for now
|
||||
// Actually load it
|
||||
template_to_use.load(T)
|
||||
@@ -340,6 +340,11 @@
|
||||
if("toggle_ringer")
|
||||
ringer = !ringer
|
||||
|
||||
if("set_ringer_tone")
|
||||
var/ringtone = tgui_input_text(usr, "Set Ringer Tone", "Ringer")
|
||||
if(ringtone)
|
||||
ttone = ringtone
|
||||
|
||||
if("selfie_mode")
|
||||
selfie_mode = !selfie_mode
|
||||
|
||||
|
||||
@@ -75,6 +75,20 @@ var/global/list/obj/item/device/communicator/all_communicators = list()
|
||||
// If you turn this on, it changes the way communicator video works. User configurable option.
|
||||
var/selfie_mode = FALSE
|
||||
|
||||
// Ringtones! (Based on the PDA ones)
|
||||
var/ttone = "beep" //The ringtone!
|
||||
var/list/ttone_sound = list("beep" = 'sound/machines/twobeep.ogg',
|
||||
"boom" = 'sound/effects/explosionfar.ogg',
|
||||
"slip" = 'sound/misc/slip.ogg',
|
||||
"honk" = 'sound/items/bikehorn.ogg',
|
||||
"SKREE" = 'sound/voice/shriek1.ogg',
|
||||
// "holy" = 'sound/items/PDA/ambicha4-short.ogg',
|
||||
"xeno" = 'sound/voice/hiss1.ogg',
|
||||
"dust" = 'sound/effects/supermatter.ogg',
|
||||
"spark" = 'sound/effects/sparks4.ogg',
|
||||
"rad" = 'sound/items/geiger/high1.ogg',
|
||||
"servo" = 'sound/machines/rig/rigservo.ogg')
|
||||
|
||||
// Proc: New()
|
||||
// Parameters: None
|
||||
// Description: Adds the new communicator to the global list of all communicators, sorts the list, obtains a reference to the Exonet node, then tries to
|
||||
|
||||
@@ -76,9 +76,15 @@
|
||||
return
|
||||
|
||||
if(ringer)
|
||||
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
|
||||
var/S
|
||||
if(ttone in ttone_sound)
|
||||
S = ttone_sound[ttone]
|
||||
else
|
||||
S = 'sound/machines/twobeep.ogg'
|
||||
|
||||
playsound(src, S, 50, 1)
|
||||
for (var/mob/O in hearers(2, loc))
|
||||
O.show_message(text("[bicon(src)] *beep*"))
|
||||
O.show_message(text("[bicon(src)] *[ttone]*"))
|
||||
|
||||
alert_called = 1
|
||||
update_icon()
|
||||
|
||||
@@ -43,7 +43,7 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
|
||||
return ..()
|
||||
|
||||
var/pai_name = input(user, "Choose your character's name", "Character Name") as text
|
||||
var/actual_pai_name = sanitize_name(pai_name)
|
||||
var/actual_pai_name = sanitize_name(pai_name, ,1)
|
||||
if(isnull(actual_pai_name))
|
||||
return ..()
|
||||
|
||||
@@ -360,3 +360,40 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
|
||||
var/rendered = "<span class='message'>[msg]</span>"
|
||||
pai.show_message(rendered, type)
|
||||
..()
|
||||
|
||||
|
||||
// VoreEdit: Living Machine Stuff after this.
|
||||
// This adds a var and proc for all machines to take a pAI. (The pAI can't control anything, it's just for RP.)
|
||||
// You need to add usage of the proc to each machine to actually add support. For an example of this, see code\modules\food\kitchen\microwave.dm
|
||||
/obj/machinery
|
||||
var/obj/item/device/paicard/paicard = null
|
||||
|
||||
/obj/machinery/proc/insertpai(mob/user, obj/item/device/paicard/card)
|
||||
//var/obj/item/paicard/card = I
|
||||
var/mob/living/silicon/pai/AI = card.pai
|
||||
if(paicard)
|
||||
to_chat(user, span_notice("This bot is already under PAI Control!"))
|
||||
return
|
||||
if(!istype(card)) // TODO: Add sleevecard support.
|
||||
return
|
||||
if(!card.pai)
|
||||
to_chat(user, span_notice("This card does not currently have a personality!"))
|
||||
return
|
||||
paicard = card
|
||||
user.unEquip(card)
|
||||
card.forceMove(src)
|
||||
AI.client.eye = src
|
||||
to_chat(AI, span_notice("Your location is [card.loc].")) // DEBUG. TODO: Make unfolding the chassis trigger an eject.
|
||||
name = AI.name
|
||||
to_chat(AI, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)]."))
|
||||
|
||||
/obj/machinery/proc/ejectpai(mob/user)
|
||||
if(paicard)
|
||||
var/mob/living/silicon/pai/AI = paicard.pai
|
||||
paicard.forceMove(src.loc)
|
||||
AI.client.eye = AI
|
||||
paicard = null
|
||||
name = initial(src.name)
|
||||
to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)]."))
|
||||
if(user)
|
||||
to_chat(user, span_notice("You eject the card from \the [initial(src.name)]."))
|
||||
@@ -240,7 +240,7 @@ HALOGEN COUNTER - Radcount on mobs
|
||||
continue
|
||||
// Broken limbs
|
||||
if(e.status & ORGAN_BROKEN)
|
||||
if((e.name in list("l_arm", "r_arm", "l_leg", "r_leg", "head", "chest", "groin")) && (!e.splinted))
|
||||
if((e.name in list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_HEAD, BP_TORSO, BP_GROIN)) && (!e.splinted))
|
||||
fracture_dat += "<span class='warning'>Unsecured fracture in subject [e.name]. Splinting recommended for transport.</span><br>"
|
||||
else if(advscan >= 1 && showadvscan == 1)
|
||||
fracture_dat += "<span class='warning'>Bone fractures detected in subject [e.name].</span><br>"
|
||||
@@ -277,7 +277,7 @@ HALOGEN COUNTER - Radcount on mobs
|
||||
dat += "<span class='danger'>Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span><br>"
|
||||
else
|
||||
dat += "<span class='notice'>Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]</span><br>"
|
||||
dat += "<span class='notice'>Subject's pulse: <font color='[H.pulse == PULSE_THREADY || H.pulse == PULSE_NONE ? "red" : "blue"]'>[H.get_pulse(GETPULSE_TOOL)] bpm.</font></span><br>" // CHOMP/VORE Edit: Missed a linebreak here.
|
||||
dat += "<span class='notice'>Subject's pulse: <font color='[H.pulse == PULSE_THREADY || H.pulse == PULSE_NONE ? "red" : "blue"]'>[H.get_pulse(GETPULSE_TOOL)] bpm.</font></span><br>" // VORE Edit: Missed a linebreak here.
|
||||
if(istype(H.species, /datum/species/xenochimera)) // VOREStation Edit Start: Visible feedback for medmains on Xenochimera.
|
||||
if(H.stat == DEAD && H.revive_ready == REVIVING_READY && !H.hasnutriment())
|
||||
dat += "<span class='danger'>WARNING: Protein levels low. Subject incapable of reconstitution.</span>"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/obj/item/selectable_item
|
||||
name = "selectable item"
|
||||
desc = "If you find this, you should definitely report this..."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "gift1"
|
||||
var/preface_string = "You are about to select an item. Are you sure you want to use it and select one?"
|
||||
var/preface_title = "selectable item"
|
||||
var/selection_string = "Select an item:"
|
||||
var/selection_title = "Item Selection"
|
||||
var/list/item_options = list("Gift" = /obj/item/weapon/a_gift,
|
||||
"Health Analyzer" = /obj/item/device/healthanalyzer)
|
||||
|
||||
/obj/item/selectable_item/attack_self(mob/user as mob)
|
||||
tgui_alert(user, {"[preface_string]"}, preface_title)
|
||||
var/chosen_item = tgui_input_list(usr, selection_string, selection_title, item_options)
|
||||
chosen_item = item_options[chosen_item]
|
||||
if(chosen_item)
|
||||
user.drop_item()
|
||||
var/obj/item/result = new chosen_item(get_turf(user))
|
||||
user.put_in_active_hand(result)
|
||||
result.add_fingerprint(user)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/selectable_item/chemistrykit
|
||||
icon = 'icons/obj/chemical_vr.dmi'
|
||||
icon_state = "chemkit"
|
||||
selection_string = "Select a chemical:"
|
||||
selection_title = "Chemical Selection"
|
||||
|
||||
/obj/item/selectable_item/chemistrykit/size
|
||||
name = "size chemistry kit"
|
||||
desc = "A pre-arranged home chemistry kit. This one is for rather specific set of size-altering chemicals."
|
||||
preface_string = "This kit can be used to create a vial of a size-altering chemical, but there's only enough material for one."
|
||||
preface_title = "Size Chemistry Kit"
|
||||
item_options = list("Macrocillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/macrocillin,
|
||||
"Microcillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/microcillin,
|
||||
"Normalcillin" = /obj/item/weapon/reagent_containers/glass/beaker/vial/normalcillin)
|
||||
|
||||
/obj/item/selectable_item/chemistrykit/gender
|
||||
name = "gender chemistry kit"
|
||||
desc = "A pre-arranged home chemistry kit. This one is for rather specific set of gender-altering chemicals."
|
||||
preface_string = "This kit can be used to create a vial of a gender-altering chemical, but there's only enough material for one."
|
||||
preface_title = "Gender Chemistry Kit"
|
||||
item_options = list("Androrovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/androrovir,
|
||||
"Gynorovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/gynorovir,
|
||||
"Androgynorovir" = /obj/item/weapon/reagent_containers/glass/beaker/vial/androgynorovir)
|
||||
@@ -1,13 +1,6 @@
|
||||
// Porting stack dragging/auto stacking from TG.
|
||||
|
||||
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
|
||||
if(uses_charge || S.uses_charge) // This should realistically never happen, but in case it does lets avoid breaking things.
|
||||
return
|
||||
if(S.stacktype != stacktype)
|
||||
return
|
||||
if(S.amount >= S.max_amount)
|
||||
return
|
||||
|
||||
var/transfer = get_amount()
|
||||
transfer = min(transfer, S.max_amount - S.amount)
|
||||
if(pulledby)
|
||||
@@ -18,7 +11,27 @@
|
||||
use(transfer)
|
||||
S.add(transfer)
|
||||
|
||||
/obj/item/stack/proc/can_merge(obj/item/stack/S)
|
||||
if(uses_charge || S.uses_charge) // This should realistically never happen, but in case it does lets avoid breaking things.
|
||||
return
|
||||
if(S.stacktype != stacktype)
|
||||
return
|
||||
if(S.amount >= S.max_amount)
|
||||
return
|
||||
if(!isturf(loc) || !isturf(S.loc))
|
||||
return FALSE
|
||||
if(src == S)
|
||||
return FALSE
|
||||
if(ismob(S.loc) || ismob(loc))
|
||||
return FALSE
|
||||
if(S.throwing || throwing)
|
||||
return FALSE
|
||||
if(S.amount < 1 || amount < 1)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/Crossed(var/atom/movable/AM)
|
||||
if(isturf(AM.loc) && AM != src && istype(AM, src.type) && !AM.throwing)
|
||||
merge(AM)
|
||||
if(istype(AM, src.type)) // Sanity so we don't try to merge non-stacks.
|
||||
if(can_merge(AM))
|
||||
merge(AM)
|
||||
return ..()
|
||||
@@ -203,9 +203,6 @@
|
||||
name = T_BOARD("sensors console")
|
||||
build_path = /obj/machinery/computer/ship/sensors
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/area_atmos
|
||||
name = T_BOARD("area air control console")
|
||||
build_path = /obj/machinery/computer/area_atmos
|
||||
@@ -224,4 +221,9 @@
|
||||
/obj/item/weapon/circuitboard/shutoff_monitor
|
||||
name = T_BOARD("automatic shutoff valve monitor")
|
||||
build_path = /obj/machinery/computer/shutoff_monitor
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
|
||||
/obj/item/weapon/circuitboard/stockexchange
|
||||
name = T_BOARD("stock exchange console")
|
||||
build_path = /obj/machinery/computer/stockexchange
|
||||
origin_tech = list(TECH_DATA = 2, TECH_MAGNET = 1)
|
||||
@@ -14,7 +14,7 @@
|
||||
max_storage_space = INVENTORY_POUCH_SPACE
|
||||
can_hold = null
|
||||
pocketable = TRUE
|
||||
|
||||
|
||||
var/insert_delay = 0 SECONDS
|
||||
var/remove_delay = 2 SECONDS
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
// No delay if you have the pouch in your hands
|
||||
if(user.get_active_hand() == src || user.get_inactive_hand() == src)
|
||||
return TRUE // Skip delay
|
||||
|
||||
|
||||
if(remove_delay && !do_after(user, remove_delay, src, needhand = TRUE, exclusive = TASK_USER_EXCLUSIVE))
|
||||
return FALSE // Moved while there is a delay
|
||||
|
||||
@@ -58,10 +58,10 @@
|
||||
|
||||
/obj/item/weapon/storage/pouch/ammo
|
||||
name = "storage pouch (ammo)"
|
||||
desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold ammunition and cells."
|
||||
desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold ammunition, cells, explosives, and grenades."
|
||||
icon_state = "ammo"
|
||||
max_storage_space = INVENTORY_POUCH_SPACE
|
||||
can_hold = list(/obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/cell/device/weapon)
|
||||
can_hold = list(/obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/cell/device/weapon, /obj/item/weapon/grenade, /obj/item/weapon/plastique) //Vorestation Add - make it more useful for non-sec/explo
|
||||
|
||||
/obj/item/weapon/storage/pouch/eng_tool
|
||||
name = "storage pouch (tools)"
|
||||
@@ -69,15 +69,35 @@
|
||||
icon_state = "engineering_tool"
|
||||
max_storage_space = INVENTORY_POUCH_SPACE
|
||||
can_hold = list(
|
||||
/obj/item/weapon/tool,
|
||||
/obj/item/weapon/tool/crowbar,
|
||||
/obj/item/weapon/tool/screwdriver,
|
||||
/obj/item/weapon/weldingtool,
|
||||
/obj/item/weapon/tool/wirecutters,
|
||||
/obj/item/weapon/tool/wrench,
|
||||
/obj/item/device/multitool,
|
||||
/obj/item/device/flashlight,
|
||||
/obj/item/weapon/cell/device,
|
||||
/obj/item/stack/cable_coil,
|
||||
/obj/item/device/t_scanner,
|
||||
/obj/item/device/analyzer,
|
||||
/obj/item/clothing/glasses,
|
||||
/obj/item/clothing/gloves,
|
||||
)
|
||||
/obj/item/device/pda,
|
||||
/obj/item/device/megaphone,
|
||||
/obj/item/taperoll,
|
||||
/obj/item/device/radio/headset,
|
||||
/obj/item/device/robotanalyzer,
|
||||
/obj/item/weapon/material/minihoe,
|
||||
/obj/item/weapon/material/knife/machete/hatchet,
|
||||
/obj/item/device/analyzer/plant_analyzer,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/weapon/tape_roll,
|
||||
/obj/item/device/integrated_electronics/wirer,
|
||||
/obj/item/device/integrated_electronics/debugger,
|
||||
/obj/item/weapon/shovel/spade,
|
||||
/obj/item/stack/nanopaste,
|
||||
/obj/item/device/geiger
|
||||
) //Vorestation Add - make it the same as the tool-belt why was it not like this to start with wtf
|
||||
|
||||
/obj/item/weapon/storage/pouch/eng_supply
|
||||
name = "storage pouch (supplies)"
|
||||
@@ -88,15 +108,19 @@
|
||||
/obj/item/weapon/cell/device,
|
||||
/obj/item/stack/cable_coil,
|
||||
/obj/item/taperoll,
|
||||
/obj/item/weapon/extinguisher/mini,
|
||||
/obj/item/weapon/tape_roll
|
||||
)
|
||||
/obj/item/weapon/extinguisher,
|
||||
/obj/item/weapon/tape_roll,
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/glass,
|
||||
/obj/item/device/lightreplacer,
|
||||
/obj/item/weapon/cell
|
||||
) //Vorestation Add - makes it actually useful lmao, adds sheets and cells as well as light replacers and lets you take any extinguisher that fits
|
||||
|
||||
/obj/item/weapon/storage/pouch/eng_parts
|
||||
name = "storage pouch (parts)"
|
||||
desc = "This storage pouch can be used to provide some additional storage for quick access. Can only hold machinery components."
|
||||
icon_state = "part_pouch"
|
||||
max_storage_space = INVENTORY_POUCH_SPACE
|
||||
max_storage_space = INVENTORY_POUCH_SPACE*2 //Vorestation Add - yeah lemme give up my pocket to hold FOUR CAPACITORS or have an inferior box... now you can hold eight in your pocket so its at least a box
|
||||
can_hold = list(
|
||||
/obj/item/weapon/stock_parts,
|
||||
/obj/item/stack/cable_coil,
|
||||
@@ -120,8 +144,20 @@
|
||||
/obj/item/weapon/storage/pill_bottle,
|
||||
/obj/item/stack/medical,
|
||||
/obj/item/weapon/reagent_containers/hypospray,
|
||||
/obj/item/weapon/storage/quickdraw/syringe_case
|
||||
)
|
||||
/obj/item/weapon/storage/quickdraw/syringe_case,
|
||||
/obj/item/weapon/syringe_cartridge,
|
||||
/obj/item/clothing/gloves/sterile,
|
||||
/obj/item/device/sleevemate,
|
||||
/obj/item/bodybag,
|
||||
/obj/item/clothing/mask/surgical,
|
||||
/obj/item/weapon/soap,
|
||||
/obj/item/stack/nanopaste,
|
||||
/obj/item/taperoll/medical,
|
||||
/obj/item/weapon/storage/box/freezer,
|
||||
/obj/item/clothing/mask/chewable/candy/lolli,
|
||||
) //Vorestation add - added a bunch of misc medical stuff
|
||||
max_storage_space = ITEMSIZE_COST_SMALL*3 //Vorestation Add - makes it slightly smaller since its a lot of stuff with pocket access
|
||||
remove_delay = 5 //Vorestation Add - .5 second delay, get the medical things faster because there is no reason to use this otherwise. still gotta stop moving to take things out.
|
||||
|
||||
/obj/item/weapon/storage/pouch/flares
|
||||
name = "storage pouch (flares)"
|
||||
@@ -145,7 +181,7 @@
|
||||
desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one normal sized weapon."
|
||||
icon_state = "pistol_holster"
|
||||
storage_slots = 1
|
||||
can_hold = list(/obj/item/weapon/gun)
|
||||
can_hold = list(/obj/item/weapon/gun) //this covers basically everything I think so its fine
|
||||
remove_delay = 0
|
||||
/obj/item/weapon/storage/pouch/holster/full_stunrevolver
|
||||
starts_with = list(/obj/item/weapon/gun/energy/stunrevolver)
|
||||
@@ -159,11 +195,11 @@
|
||||
..()
|
||||
|
||||
/obj/item/weapon/storage/pouch/baton
|
||||
name = "storage pouch (baton)"
|
||||
desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one standard baton."
|
||||
name = "storage pouch (melee)"
|
||||
desc = "This storage pouch can be used to provide some additional storage for quick access. Can hold one normal size melee." //Vorestation add - make it a melee pouch literally why would you hold ONE BATON
|
||||
icon_state = "baton_holster"
|
||||
storage_slots = 1
|
||||
can_hold = list(/obj/item/weapon/melee/baton)
|
||||
can_hold = list(/obj/item/weapon/melee, /obj/item/weapon/material, /obj/item/weapon/tool/wrench) //should be like, every melee weapon I could think of that was normal size. Can make it more specific if needed. Also wrench because I thought it was funny.
|
||||
remove_delay = 0
|
||||
/obj/item/weapon/storage/pouch/baton/full
|
||||
starts_with = list(/obj/item/weapon/melee/baton)
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//Spawner subtypes where the result begins with anomalous properties, primarily for PoI use.
|
||||
|
||||
/obj/random/maintenance/anom
|
||||
name = "random anomalous clutter"
|
||||
desc = "This is a random maintenance-style item with anomalous properties."
|
||||
icon_state = "anomaly"
|
||||
|
||||
/obj/random/maintenance/anom/item_to_spawn()
|
||||
return pick(prob(300);/obj/random/tech_supply/anom,
|
||||
prob(200);/obj/random/medical/anom,
|
||||
prob(100);/obj/random/firstaid/anom,
|
||||
prob(10);/obj/random/contraband/anom,
|
||||
prob(50);/obj/random/action_figure/anom,
|
||||
prob(50);/obj/random/plushie/anom,
|
||||
prob(200);/obj/random/junk/anom,
|
||||
prob(200);/obj/random/material/anom,
|
||||
prob(50);/obj/random/toy/anom,
|
||||
prob(100);/obj/random/tank/anom,
|
||||
prob(50);/obj/random/soap/anom,
|
||||
prob(60);/obj/random/drinkbottle/anom,
|
||||
prob(500);/obj/random/maintenance/clean/anom)
|
||||
|
||||
//Guns
|
||||
|
||||
/obj/random/gun/random/anomalous
|
||||
name = "random anomalous weapon"
|
||||
desc = "This is a random energy or ballistic weapon with anomalous properties."
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/gun/random/anomalous/item_to_spawn()
|
||||
return pick(prob(5);/obj/random/energy/anom,
|
||||
prob(5);/obj/random/projectile/random/anom)
|
||||
|
||||
/obj/random/energy/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/projectile/random/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
//Misc objects
|
||||
|
||||
/obj/random/tech_supply/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/medical/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/firstaid/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/contraband/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/action_figure/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/plushie/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/junk/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/material/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/material/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/toy/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/tank/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/soap/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/drinkbottle/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/maintenance/clean/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/technology_scanner/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/powercell/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/tool/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/tool/power/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/toolbox/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/tech_supply/component/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/medical/lite/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/tank/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/coin/anom
|
||||
start_anomalous = TRUE
|
||||
|
||||
/obj/random/mug/anom
|
||||
start_anomalous = TRUE
|
||||
@@ -132,6 +132,9 @@
|
||||
prob(1);/obj/item/capture_crystal/random,
|
||||
prob(1);/obj/random/unidentified_medicine
|
||||
)
|
||||
/obj/random/mainttoyloot/nofail
|
||||
spawn_nothing_percentage = 0
|
||||
|
||||
|
||||
/obj/random/maintenance/misc //Clutter and loot for maintenance and away missions
|
||||
name = "random maintenance item"
|
||||
@@ -150,7 +153,7 @@
|
||||
prob(300);/obj/random/maintenance/security,
|
||||
prob(300);/obj/random/maintenance/security,
|
||||
prob(50);/obj/random/maintenance/morestuff,
|
||||
prob(25);/obj/random/mainttoyloot,
|
||||
prob(25);/obj/random/mainttoyloot/nofail,
|
||||
prob(10);/obj/random/maintenance/foodstuff)
|
||||
|
||||
/obj/random/maintenance/foodstuff
|
||||
@@ -188,3 +191,27 @@
|
||||
prob(1);/obj/item/weapon/flame/lighter/random,
|
||||
prob(1);/obj/item/weapon/storage/wallet/random,
|
||||
prob(1);/obj/random/cutout)
|
||||
|
||||
/obj/random/instrument
|
||||
name = "random instrument"
|
||||
desc = "This is a random instrument."
|
||||
icon = 'icons/obj/musician.dmi'
|
||||
icon_state = "violin"
|
||||
spawn_nothing_percentage = 0
|
||||
|
||||
/obj/random/instrument/item_to_spawn()
|
||||
return pick(prob(5);/obj/item/instrument/violin,
|
||||
prob(5);/obj/item/instrument/banjo,
|
||||
prob(5);/obj/item/instrument/guitar,
|
||||
prob(5);/obj/item/instrument/eguitar,
|
||||
prob(5);/obj/item/instrument/accordion,
|
||||
prob(5);/obj/item/instrument/trumpet,
|
||||
prob(5);/obj/item/instrument/saxophone,
|
||||
prob(5);/obj/item/instrument/trombone,
|
||||
prob(5);/obj/item/instrument/recorder,
|
||||
prob(5);/obj/item/instrument/harmonica,
|
||||
prob(1);/obj/item/instrument/bikehorn,
|
||||
prob(5);/obj/item/instrument/piano_synth,
|
||||
prob(5);/obj/item/instrument/glockenspiel,
|
||||
prob(1);/obj/item/instrument/musicalmoth
|
||||
)
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
new /obj/item/stack/rods(get_turf(src))
|
||||
Destroy()
|
||||
|
||||
/obj/structure/catwalk/Crossed(atom/movable/AM as mob|obj)
|
||||
/obj/structure/catwalk/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(isliving(AM) && !AM.is_incorporeal())
|
||||
playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
|
||||
|
||||
@@ -242,6 +242,42 @@
|
||||
if((. = ..()))
|
||||
playsound(src, 'sound/machines/shutdown.ogg', 60, 1)
|
||||
|
||||
///////////////////
|
||||
//// COMPUTERS ////
|
||||
///////////////////
|
||||
|
||||
/obj/structure/salvageable/console
|
||||
name = "console"
|
||||
icon_state = "console0"
|
||||
salvageable_parts = list(
|
||||
/obj/item/stack/cable_coil{amount = 5} = 90,
|
||||
/obj/item/stack/material/glass{amount = 5} = 70,
|
||||
/obj/item/trash/material/circuit = 60,
|
||||
/obj/item/trash/material/metal = 60,
|
||||
/obj/item/weapon/stock_parts/capacitor = 40,
|
||||
/obj/item/weapon/stock_parts/capacitor = 40,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 40,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 40
|
||||
)
|
||||
|
||||
/obj/structure/salvageable/personal/Initialize()
|
||||
. = ..()
|
||||
icon_state = "console[rand(0,2)]"
|
||||
|
||||
/obj/structure/salvageable/shuttle_console
|
||||
name = "shuttle console"
|
||||
icon_state = "shuttle"
|
||||
salvageable_parts = list(
|
||||
/obj/item/stack/cable_coil{amount = 5} = 90,
|
||||
/obj/item/stack/material/glass{amount = 5} = 70,
|
||||
/obj/item/trash/material/circuit = 60,
|
||||
/obj/item/trash/material/metal = 60,
|
||||
/obj/item/weapon/stock_parts/capacitor = 40,
|
||||
/obj/item/weapon/stock_parts/capacitor = 40,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 40,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 40
|
||||
)
|
||||
|
||||
//////////////////
|
||||
//// ONE STAR ////
|
||||
//////////////////
|
||||
|
||||
@@ -254,7 +254,8 @@
|
||||
prob(2);/obj/item/weapon/storage/box/syndie_kit/spy,
|
||||
prob(2);/obj/item/weapon/grenade/anti_photon,
|
||||
prob(2);/obj/item/clothing/under/hyperfiber/bluespace,
|
||||
prob(2);/obj/item/weapon/reagent_containers/glass/beaker/vial/amorphorovir,
|
||||
prob(2);/obj/item/selectable_item/chemistrykit/size,
|
||||
prob(2);/obj/item/selectable_item/chemistrykit/gender,
|
||||
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
|
||||
prob(1);/obj/item/device/nif/bad,
|
||||
prob(1);/obj/item/device/radio_jammer,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/can_start_dirty = TRUE // If false, cannot start dirty roundstart
|
||||
var/dirty_prob = 2 // Chance of being dirty roundstart
|
||||
var/dirt = 0
|
||||
var/special_temperature //Used for turf HE-Pipe interaction
|
||||
|
||||
// This is not great.
|
||||
/turf/simulated/proc/wet_floor(var/wet_val = 1)
|
||||
|
||||
@@ -38,7 +38,7 @@ GLOBAL_LIST_EMPTY(fancy_shuttles)
|
||||
icon = 'icons/turf/fancy_shuttles/generic_preview.dmi'
|
||||
icon_state = "floors"
|
||||
plane = PLATING_PLANE
|
||||
layer = ABOVE_TURF_LAYER
|
||||
layer = DISPOSAL_LAYER
|
||||
alpha = 90
|
||||
|
||||
/obj/effect/fancy_shuttle_floor_preview/Initialize()
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
edge_blending_priority = -2
|
||||
movement_cost = 8
|
||||
depth = 2
|
||||
special_temperature = T0C - 5.5 //as cool as the atmosphere outside, if someone asks, its the phoron solved in the water that stops the freezing
|
||||
|
||||
/turf/simulated/floor/water/pool
|
||||
name = "pool"
|
||||
|
||||
@@ -117,6 +117,11 @@
|
||||
..()
|
||||
gear_tweaks += gear_tweak_free_color_choice
|
||||
|
||||
/datum/gear/accessory/dosimeter
|
||||
display_name = "Dosimeter"
|
||||
path = /obj/item/weapon/storage/box/dosimeter
|
||||
description = "A small device that will display dangerous levels of radiation."
|
||||
|
||||
/*
|
||||
Talon pin
|
||||
*/
|
||||
|
||||
@@ -74,3 +74,8 @@
|
||||
display_name = "bluespace bracelet"
|
||||
path = /obj/item/clothing/gloves/bluespace
|
||||
cost = 5
|
||||
|
||||
/datum/gear/utility/walkpod
|
||||
display_name = "podzu music player"
|
||||
path = /obj/item/device/walkpod
|
||||
cost = 2
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/obj/item/clothing/accessory/dosimeter
|
||||
name = "dosimeter"
|
||||
desc = "A small device used to measure body radiation and warning one after a certain threshold. \
|
||||
Read manual before use! Can be held, attached to the uniform or worn around the neck."
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
icon = 'icons/inventory/accessory/item_vr.dmi'
|
||||
icon_override = 'icons/inventory/accessory/item_vr.dmi'
|
||||
|
||||
icon_state = "dosimeter"
|
||||
item_state = "dosimeter"
|
||||
overlay_state = "dosimeter"
|
||||
|
||||
slot_flags = SLOT_TIE
|
||||
|
||||
var/obj/item/weapon/dosimeter_film/current_film = null
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/New()
|
||||
..()
|
||||
current_film = new /obj/item/weapon/dosimeter_film(src)
|
||||
update_state(current_film.state)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/Destroy()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/process()
|
||||
check_holder()
|
||||
if(current_film.state > 1)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/attack_hand(mob/user as mob)
|
||||
if(user.get_inactive_hand() == src)
|
||||
if(current_film)
|
||||
user.put_in_hands(current_film)
|
||||
current_film = null
|
||||
to_chat(user, "<span class='notice'>You pulled out the film out of \the [src].</span>")
|
||||
desc = "This seems like a dosimeter, but there is no film inside."
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_state(0)
|
||||
return
|
||||
..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/weapon/dosimeter_film))
|
||||
if(!current_film)
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
current_film = I
|
||||
update_state(current_film.state)
|
||||
|
||||
to_chat(user, "<span class='notice'>You inserted the film into \the [src].</span>")
|
||||
desc = "This seems like a dosimeter. It has a film inside."
|
||||
|
||||
if(current_film.state < 2)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] already has a film inside.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/proc/check_holder()
|
||||
if(wearer)
|
||||
if(current_film && (wearer.radiation >= 25) && (current_film.state == 0))
|
||||
update_state(1)
|
||||
visible_message("<span class='warning'>The film of \the [src] starts to darken.</span>")
|
||||
desc = "This seems like a dosimeter, but the film has darkened."
|
||||
sleep(30)
|
||||
else if(current_film && (wearer.radiation >= 50) && (current_film.state == 1))
|
||||
visible_message("<span class='warning'>The film of \the [src] has turned black!</span>")
|
||||
update_state(2)
|
||||
desc = "This seems like a dosimeter, but the film has turned black."
|
||||
|
||||
/obj/item/clothing/accessory/dosimeter/proc/update_state(var/tostate)
|
||||
if(current_film)
|
||||
current_film.state = tostate
|
||||
icon_state = "[initial(icon_state)][tostate]"
|
||||
current_film.icon_state = "dosimeter_film[tostate]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]-empty"
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/dosimeter_film
|
||||
name = "dosimeter film"
|
||||
desc = "These films can be inserted into dosimeters. It turns from white to black, depending on how much radiation it endured."
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
icon = 'icons/inventory/accessory/item_vr.dmi'
|
||||
icon_override = 'icons/inventory/accessory/item_vr.dmi'
|
||||
|
||||
icon_state = "dosimeter_film0"
|
||||
|
||||
var/state = 0 //0 - White, 1 - Darker, 2 - Black (same as iconstates)
|
||||
|
||||
/obj/item/weapon/dosimeter_film/proc/update_state(var/tostate)
|
||||
icon_state = tostate
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/paper/dosimeter_manual
|
||||
name = "Dosimeter manual"
|
||||
info = {"<h4>Dosimeter</h4>
|
||||
<h5>Usage</h5>
|
||||
<ol>
|
||||
<li>Insert film into dosimeter.</li>
|
||||
<li>Attach dosimeter to clothing or carry it.</li>
|
||||
<li>Replace film if current film turned black.</li>
|
||||
</ol>
|
||||
<br />
|
||||
<h5>Purpose</h5>
|
||||
<p>This device will let you know about any dangerous radiation levels, that your body is exposed to.
|
||||
A white film indicates that everything is alright. A darker film indicates, that the radiation level is starting to get dangerous for your body.
|
||||
The body has absorbed too much radiation if the film turned black.</p>"}
|
||||
|
||||
/obj/item/weapon/storage/box/dosimeter
|
||||
name = "dosimeter case"
|
||||
desc = "This case can only hold the Dosimeter, a few films and a manual."
|
||||
item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit")
|
||||
storage_slots = 5
|
||||
can_hold = list(/obj/item/weapon/paper/dosimeter_manual, /obj/item/clothing/accessory/dosimeter, /obj/item/weapon/dosimeter_film)
|
||||
max_storage_space = (ITEMSIZE_COST_SMALL * 2) + (ITEMSIZE_COST_TINY * 3)
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
/obj/item/weapon/storage/box/dosimeter/New()
|
||||
..()
|
||||
new /obj/item/weapon/paper/dosimeter_manual(src)
|
||||
new /obj/item/clothing/accessory/dosimeter(src)
|
||||
new /obj/item/weapon/dosimeter_film(src)
|
||||
new /obj/item/weapon/dosimeter_film(src)
|
||||
new /obj/item/weapon/dosimeter_film(src)
|
||||
@@ -228,13 +228,10 @@
|
||||
emote_message_3p_target = "trills at TARGET."
|
||||
emote_sound = 'sound/voice/teshtrill.ogg' // Copyright CC BY-NC 3.0 Arnaud Coutancier (freesound.org) for the source audio.
|
||||
|
||||
//CHOMPEdit Add Start
|
||||
/decl/emote/audible/prbt
|
||||
key = "prbt"
|
||||
emote_message_1p = "You prbt."
|
||||
emote_message_3p = "prbts."
|
||||
emote_message_1p_target = "You prbt at TARGET."
|
||||
emote_message_3p_target = "prbts at TARGET."
|
||||
emote_sound = 'sound/voice/prbt.ogg'
|
||||
|
||||
//CHOMPEdit Add End
|
||||
emote_sound = 'sound/voice/prbt.ogg'
|
||||
@@ -11,7 +11,7 @@
|
||||
. = ..()
|
||||
|
||||
/decl/emote/human/deathgasp/get_emote_message_3p(var/mob/living/carbon/human/user)
|
||||
return "USER [user.species.get_death_message(user)]"
|
||||
return "[user.species.get_death_message(user)]"
|
||||
|
||||
/decl/emote/human/swish
|
||||
key = "swish"
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/sorbitol
|
||||
name = "sorbitol bottle"
|
||||
desc = "A small bottle of sorbitol. Sickeningly sweet."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "bottle-3"
|
||||
prefill = list("sorbitol" = 60)
|
||||
@@ -206,7 +206,7 @@
|
||||
|
||||
var/obj/item/organ/external/E
|
||||
var/nopain
|
||||
if(ishuman(victim) && user.zone_sel.selecting != "groin" && user.zone_sel.selecting != "chest")
|
||||
if(ishuman(victim) && user.zone_sel.selecting != BP_GROIN && user.zone_sel.selecting != BP_TORSO)
|
||||
var/mob/living/carbon/human/H = victim
|
||||
E = H.get_organ(user.zone_sel.selecting)
|
||||
if(!E || E.species.flags & NO_PAIN)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
var/global/list/acceptable_items // List of the items you can put in
|
||||
var/global/list/available_recipes // List of the recipes you can use
|
||||
var/global/list/acceptable_reagents // List of the reagents you can put in
|
||||
|
||||
|
||||
var/global/max_n_of_items = 20
|
||||
var/appliancetype = MICROWAVE
|
||||
var/datum/looping_sound/microwave/soundloop
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/obj/machinery/microwave/Initialize()
|
||||
. = ..()
|
||||
|
||||
|
||||
reagents = new/datum/reagents(100)
|
||||
reagents.my_atom = src
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
for(var/datum/recipe/typepath as anything in subtypesof(/datum/recipe))
|
||||
if((initial(typepath.appliance) & appliancetype))
|
||||
available_recipes += new typepath
|
||||
|
||||
|
||||
acceptable_items = new
|
||||
acceptable_reagents = new
|
||||
for (var/datum/recipe/recipe in available_recipes)
|
||||
@@ -66,6 +66,8 @@
|
||||
soundloop = new(list(src), FALSE)
|
||||
|
||||
/obj/machinery/microwave/Destroy()
|
||||
if(paicard)
|
||||
ejectpai() // Lets not delete the pAI.
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
@@ -125,7 +127,8 @@
|
||||
to_chat(user, "<span class='warning'>It's dirty!</span>")
|
||||
return 1
|
||||
else if(is_type_in_list(O,acceptable_items))
|
||||
if(contents.len>=(max_n_of_items + component_parts.len + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var.
|
||||
var/list/workingList = cookingContents()
|
||||
if(workingList.len>=(max_n_of_items + circuit_item_capacity)) //Adds component_parts to the maximum number of items. changed 1 to actually just be the circuit item capacity var.
|
||||
to_chat(user, "<span class='warning'>This [src] is full of ingredients, you cannot put more.</span>")
|
||||
return 1
|
||||
if(istype(O, /obj/item/stack) && O:get_amount() > 1) // This is bad, but I can't think of how to change it
|
||||
@@ -180,6 +183,9 @@
|
||||
to_chat(user, "<span class='notice'>You decide not to do that.</span>")
|
||||
else if(default_part_replacement(user, O))
|
||||
return
|
||||
else if(istype(O, /obj/item/device/paicard))
|
||||
if(!paicard)
|
||||
insertpai(user, O)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You have no idea what you can cook with this [O].</span>")
|
||||
..()
|
||||
@@ -192,6 +198,10 @@
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/microwave/attack_hand(mob/user as mob)
|
||||
if(user.a_intent == I_GRAB)
|
||||
if(paicard)
|
||||
ejectpai(user)
|
||||
return
|
||||
user.set_machine(src)
|
||||
tgui_interact(user)
|
||||
|
||||
@@ -211,7 +221,7 @@
|
||||
data["operating"] = operating
|
||||
data["dirty"] = dirty == 100
|
||||
data["items"] = get_items_list()
|
||||
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/microwave/proc/get_items_list()
|
||||
@@ -220,7 +230,8 @@
|
||||
var/list/items_counts = list()
|
||||
var/list/items_measures = list()
|
||||
var/list/items_measures_p = list()
|
||||
for(var/obj/O in ((contents - component_parts) - circuit))
|
||||
//for(var/obj/O in ((contents - component_parts) - circuit))
|
||||
for(var/obj/O in cookingContents())
|
||||
var/display_name = O.name
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg))
|
||||
items_measures[display_name] = "egg"
|
||||
@@ -283,7 +294,7 @@
|
||||
if("dispose")
|
||||
dispose()
|
||||
return TRUE
|
||||
/*
|
||||
/*
|
||||
/obj/machinery/microwave/interact(mob/user as mob) // The microwave Menu
|
||||
var/dat = ""
|
||||
if(src.broken > 0)
|
||||
@@ -352,7 +363,7 @@
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
start()
|
||||
if(reagents.total_volume==0 && !(locate(/obj) in ((contents - component_parts) - circuit))) //dry run
|
||||
if(reagents.total_volume==0 && !(locate(/obj) in cookingContents())) //dry run
|
||||
if(!wzhzhzh(16)) //VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was 5)
|
||||
abort()
|
||||
return
|
||||
@@ -387,7 +398,7 @@
|
||||
cooked = fail()
|
||||
cooked.forceMove(src.loc)
|
||||
return
|
||||
|
||||
|
||||
//Making multiple copies of a recipe
|
||||
var/halftime = round(recipe.time*4/10/2) // VOREStation Edit - Quicker Microwaves (Undone during Auroraport, left note in case of reversion, was round(recipe.time/20/2))
|
||||
if(!wzhzhzh(halftime))
|
||||
@@ -430,7 +441,7 @@
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/S in cooked_items)
|
||||
reagents.trans_to_holder(S.reagents, total/cooked_items.len)
|
||||
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/S in contents)
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/S in cookingContents())
|
||||
S.cook()
|
||||
|
||||
dispose(0) //clear out anything left
|
||||
@@ -448,7 +459,7 @@
|
||||
|
||||
/obj/machinery/microwave/proc/has_extra_item() //- coded to have different microwaves be able to handle different items
|
||||
if(item_level == 0)
|
||||
for (var/obj/O in ((contents - component_parts) - circuit))
|
||||
for (var/obj/O in cookingContents())
|
||||
if ( \
|
||||
!istype(O,/obj/item/weapon/reagent_containers/food) && \
|
||||
!istype(O, /obj/item/weapon/grown) \
|
||||
@@ -456,7 +467,7 @@
|
||||
return 1
|
||||
return 0
|
||||
if(item_level == 1)
|
||||
for (var/obj/O in ((contents - component_parts) - circuit))
|
||||
for (var/obj/O in cookingContents())
|
||||
if ( \
|
||||
!istype(O, /obj/item/weapon/reagent_containers/food) && \
|
||||
!istype(O, /obj/item/weapon/grown) && \
|
||||
@@ -480,7 +491,7 @@
|
||||
icon_state = "mw"
|
||||
SStgui.update_uis(src)
|
||||
soundloop.stop()
|
||||
|
||||
|
||||
/obj/machinery/microwave/proc/stop()
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
operating = FALSE // Turn it off again aferwards
|
||||
@@ -490,7 +501,7 @@
|
||||
soundloop.stop()
|
||||
|
||||
/obj/machinery/microwave/proc/dispose(var/message = 1)
|
||||
for (var/atom/movable/A in ((contents-component_parts)-circuit))
|
||||
for (var/atom/movable/A in cookingContents())
|
||||
A.forceMove(loc)
|
||||
if (src.reagents.total_volume)
|
||||
src.dirty++
|
||||
@@ -524,11 +535,12 @@
|
||||
src.operating = 0 // Turn it off again aferwards
|
||||
SStgui.update_uis(src)
|
||||
soundloop.stop()
|
||||
src.ejectpai() // If it broke, time to yeet the PAI.
|
||||
|
||||
/obj/machinery/microwave/proc/fail()
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/badrecipe/ffuu = new(src)
|
||||
var/amount = 0
|
||||
for (var/obj/O in (((contents - ffuu) - component_parts) - circuit))
|
||||
for (var/obj/O in cookingContents() - ffuu)
|
||||
amount++
|
||||
if(O.reagents)
|
||||
var/id = O.reagents.get_master_reagent_id()
|
||||
@@ -555,14 +567,14 @@
|
||||
|
||||
if(!do_after(usr, 1 SECONDS, target = src))
|
||||
return
|
||||
|
||||
|
||||
if(operating)
|
||||
to_chat(usr, "<span class='warning'>You can't do that, [src] door is locked!</span>")
|
||||
return
|
||||
|
||||
usr.visible_message(
|
||||
"<span class='notice'>[usr] opened [src] and has taken out [english_list(((contents-component_parts)-circuit))].</span>" ,
|
||||
"<span class='notice'>You have opened [src] and taken out [english_list(((contents-component_parts)-circuit))].</span>"
|
||||
"<span class='notice'>[usr] opened [src] and has taken out [english_list(cookingContents())].</span>" ,
|
||||
"<span class='notice'>You have opened [src] and taken out [english_list(cookingContents())].</span>"
|
||||
)
|
||||
dispose()
|
||||
|
||||
@@ -591,7 +603,7 @@
|
||||
/obj/item/weapon/holder
|
||||
)
|
||||
result = /obj/effect/decal/cleanable/blood/gibs
|
||||
|
||||
|
||||
/datum/recipe/splat/before_cook(obj/container)
|
||||
if(istype(container, /obj/machinery/microwave))
|
||||
var/obj/machinery/microwave/M = container
|
||||
@@ -614,3 +626,14 @@
|
||||
var/obj/machinery/microwave/M = container
|
||||
M.muck_finish()
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/microwave/proc/cookingContents() //VOREEdit, this is a better way to deal with the contents of a microwave, since the previous method is stupid.
|
||||
var/list/workingList = contents.Copy() // Using the copy proc because otherwise the two lists seem to become soul bonded.
|
||||
workingList -= component_parts
|
||||
workingList -= circuit
|
||||
if(paicard)
|
||||
workingList -= paicard
|
||||
for(var/M in workingList)
|
||||
if(istype(M, circuit)) // Yes, we remove circuit twice. Yes, it's necessary. Yes, it's stupid.
|
||||
workingList -= M
|
||||
return workingList
|
||||
@@ -376,7 +376,7 @@
|
||||
if(battery)
|
||||
var/lost = battery.use(amount * CELLRATE)
|
||||
net_power -= lost
|
||||
return lost > 0
|
||||
return lost
|
||||
return FALSE
|
||||
|
||||
// Ditto for giving.
|
||||
|
||||
@@ -11,11 +11,21 @@
|
||||
var/debug = FALSE // If true, metal is infinite.
|
||||
|
||||
var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
|
||||
var/illegal_upgraded = FALSE // When hit with an illegal upgrade disk, will turn true, allowing it to print the illegal circuits.
|
||||
var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly. (Not implemented)
|
||||
// var/static/list/recipe_list = list()
|
||||
var/obj/item/device/electronic_assembly/assembly_to_clone = null // Not implemented x3
|
||||
var/dirty_items = FALSE
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/all_upgrades
|
||||
upgraded = TRUE
|
||||
illegal_upgraded = TRUE
|
||||
can_clone = TRUE
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/illegal
|
||||
illegal_upgraded = TRUE
|
||||
can_clone = TRUE
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/upgraded
|
||||
upgraded = TRUE
|
||||
can_clone = TRUE
|
||||
@@ -24,6 +34,7 @@
|
||||
name = "fractal integrated circuit printer"
|
||||
desc = "A portable(ish) machine that makes modular circuitry seemingly out of thin air."
|
||||
upgraded = TRUE
|
||||
illegal_upgraded = TRUE
|
||||
can_clone = TRUE
|
||||
debug = TRUE
|
||||
|
||||
@@ -68,6 +79,16 @@
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/illegal))
|
||||
if(illegal_upgraded)
|
||||
to_chat(user, span("warning", "\The [src] already has this upgrade."))
|
||||
return TRUE
|
||||
to_chat(user, span("notice", "You install \the [O] into \the [src]."))
|
||||
illegal_upgraded = TRUE
|
||||
dirty_items = TRUE
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/weapon/disk/integrated_circuit/upgrade/clone))
|
||||
if(can_clone)
|
||||
to_chat(user, span("warning", "\The [src] already has this upgrade."))
|
||||
@@ -110,6 +131,8 @@
|
||||
"name" = category,
|
||||
"items" = null
|
||||
)
|
||||
if(cat_obj["name"] == "Illegal Parts" && !illegal_upgraded)
|
||||
continue
|
||||
var/list/circuit_list = SScircuit.circuit_fabricator_recipe_list[category]
|
||||
var/list/items = list()
|
||||
for(var/path in circuit_list)
|
||||
@@ -212,6 +235,12 @@
|
||||
name = "integrated circuit printer upgrade disk - advanced designs"
|
||||
desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer."
|
||||
|
||||
/obj/item/weapon/disk/integrated_circuit/upgrade/illegal
|
||||
name = "integrated circuit printer upgrade disk - illegal designs"
|
||||
desc = "Install this into your integrated circuit printer to enhance it. This one adds new, but illegal designs to the printer."
|
||||
icon_state = "upgrade_disk_illegal"
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4, TECH_ILLEGAL = 1)
|
||||
|
||||
// To be implemented later.
|
||||
/obj/item/weapon/disk/integrated_circuit/upgrade/clone
|
||||
name = "integrated circuit printer upgrade disk - circuit cloner"
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
assembly.give_power(amount)
|
||||
else
|
||||
var/amount = assembly.draw_power(throughput)
|
||||
IO.add_avail(amount)
|
||||
IO.add_avail(amount / CELLRATE)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, IO.avail())
|
||||
set_pin_data(IC_OUTPUT, 2, IO.surplus())
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/obj/item/integrated_circuit/cryptography
|
||||
complexity = 3
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("result" = IC_PINTYPE_STRING)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Cryptography"
|
||||
power_draw_per_use = 10
|
||||
|
||||
// HASH FUNCTIONS
|
||||
|
||||
/obj/item/integrated_circuit/cryptography/hash_md5
|
||||
name = "MD5 hash circuit"
|
||||
desc = "Message-Digest Algorithm 5"
|
||||
extended_desc = "This circuit will take a string input and generates the MD5 hash of it."
|
||||
icon_state = "template"
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/cryptography/hash_md5/do_work()
|
||||
var/result = ""
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
I.pull_data()
|
||||
if(!isnull(I.data))
|
||||
result = md5(I.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/cryptography/hash_sha1
|
||||
name = "SHA1 hash circuit"
|
||||
desc = "Secure Hash Algorithm 1"
|
||||
extended_desc = "This circuit will take a string input and generates the SHA1 hash of it."
|
||||
icon_state = "template"
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/cryptography/hash_sha1/do_work()
|
||||
var/result = ""
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
I.pull_data()
|
||||
if(!isnull(I.data))
|
||||
result = sha1(I.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
// ENCRYPTION/DECRYPTION
|
||||
|
||||
/obj/item/integrated_circuit/cryptography/rot13
|
||||
name = "rot13 circuit"
|
||||
desc = "A very simple encryption circuit."
|
||||
extended_desc = "The 'rotation' field will default to 13 if no custom number is supplied. This circuit rotates every letter by X in the alphabet."
|
||||
icon_state = "template"
|
||||
inputs = list(
|
||||
"input" = IC_PINTYPE_STRING,
|
||||
"rotation" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/cryptography/rot13/do_work()
|
||||
var/result = ""
|
||||
|
||||
var/input = get_pin_data(IC_INPUT, 1)
|
||||
var/rotation = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
var/string_len = length(input)
|
||||
|
||||
if(!isnum(rotation))
|
||||
rotation = 13
|
||||
|
||||
for(var/i = 1, i <= string_len, i++)
|
||||
var/ascii = text2ascii(input, i)
|
||||
if(ascii >= 65 && ascii <= 90)
|
||||
ascii += rotation
|
||||
if(ascii > 90)
|
||||
ascii -= 26
|
||||
|
||||
else if(ascii >= 97 && ascii <= 122)
|
||||
ascii += rotation
|
||||
if(ascii > 122)
|
||||
ascii -= 26
|
||||
|
||||
result += ascii2text(ascii)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -0,0 +1,121 @@
|
||||
/obj/item/integrated_circuit/illegal
|
||||
complexity = 3
|
||||
category_text = "Illegal Parts"
|
||||
power_draw_per_use = 50
|
||||
|
||||
/* [WIP]
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Spoofer
|
||||
name = "\improper EPv2 Spoofer circuit"
|
||||
desc = "Enables the receiving of messages of other Exonet devices."
|
||||
extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be received using the \
|
||||
second pin, with additonal data reserved for the third pin. When a message is received, the second activation pin \
|
||||
will pulse whatever's connected to it. Pulsing the first activation pin will set the given EPv2 address.\
|
||||
\
|
||||
Note: Receiving messages could cause the circuit to accidentally send malformed data to the target address."
|
||||
icon_state = "signal_illegal"
|
||||
complexity = 6
|
||||
inputs = list("target EPv2 address" = IC_PINTYPE_STRING)
|
||||
outputs = list(
|
||||
"address received" = IC_PINTYPE_STRING,
|
||||
"data received" = IC_PINTYPE_STRING,
|
||||
"secondary text received" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("set spoof address" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH|IC_SPAWN_ILLEGAL
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_ILLEGAL = 2)
|
||||
power_draw_per_use = 200
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
var/address_spoofed = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Spoofer/New()
|
||||
..()
|
||||
exonet = new(src)
|
||||
exonet.make_address("EPv2_Spoofer_circuit-\ref[src]")
|
||||
desc += "<br>This circuit's EPv2 address is: [exonet.address]"
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Spoofer/Destroy()
|
||||
if(exonet)
|
||||
if(!address_spoofed) // We dont actually want to destroy the regular address
|
||||
exonet.remove_address()
|
||||
qdel(exonet)
|
||||
exonet = null
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Spoofer/do_work()
|
||||
var/target_address = get_pin_data(IC_INPUT, 1)
|
||||
|
||||
exonet.address = target_address
|
||||
address_spoofed = TRUE
|
||||
|
||||
/obj/item/integrated_circuit/illegal/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
set_pin_data(IC_OUTPUT, 1, origin_address)
|
||||
set_pin_data(IC_OUTPUT, 2, message)
|
||||
set_pin_data(IC_OUTPUT, 3, text)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
if(address_spoofed)
|
||||
var/random = rand(1,100)
|
||||
if(random > 70)
|
||||
exonet.send_message(origin_address, message, "[random]")
|
||||
*/
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Discoverer
|
||||
name = "\improper EPv2 Discovery circuit"
|
||||
desc = "Finds all Exonet devices currently connected to the node (even if not publicly listed)."
|
||||
extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be received using the \
|
||||
second pin, with additonal data reserved for the third pin. When a message is received, the second activation pin \
|
||||
will pulse whatever's connected to it. Pulsing the first activation pin will set the given EPv2 address.\
|
||||
\
|
||||
Note: Discovering Exonet Devices sends off a ping to each device, making it a 'noisy' circuit."
|
||||
icon_state = "signal_illegal"
|
||||
complexity = 3
|
||||
outputs = list("addresses found" = IC_PINTYPE_LIST)
|
||||
activators = list("start discovery" = IC_PINTYPE_PULSE_IN, "on addresses found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_ILLEGAL
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2, TECH_ILLEGAL = 1)
|
||||
power_draw_per_use = 300
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
var/obj/machinery/exonet_node/node = null
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Discoverer/proc/get_connection_to_tcomms()
|
||||
if(node && node.on)
|
||||
return can_telecomm(src,node)
|
||||
return 0
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Discoverer/New()
|
||||
..()
|
||||
exonet = new(src)
|
||||
exonet.make_address("EPv2_Discovery_circuit-\ref[src]")
|
||||
desc += "<br>This circuit's EPv2 address is: [exonet.address]"
|
||||
node = get_exonet_node()
|
||||
message_admins("A EPv2 Discovery circuit has been created. \ref[src]")
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Discoverer/Destroy()
|
||||
if(exonet)
|
||||
exonet.remove_address()
|
||||
qdel(exonet)
|
||||
exonet = null
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/illegal/EPv2_Discoverer/do_work()
|
||||
if(!get_connection_to_tcomms())
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
var/list/addresses = list()
|
||||
|
||||
for(var/datum/exonet_protocol/target_exonet in all_exonet_connections)
|
||||
if(target_exonet.address && istext(target_exonet.address))
|
||||
var/random = rand(200,350)
|
||||
random = random / 10
|
||||
exonet.send_message(target_exonet.address, "text", "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
|
||||
addresses += target_exonet.address
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, addresses)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -420,7 +420,7 @@
|
||||
name = "\improper EPv2 circuit"
|
||||
desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol."
|
||||
extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be send or received using the \
|
||||
second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activaiton pin \
|
||||
second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activation pin \
|
||||
will pulse whatever's connected to it. Pulsing the first activation pin will send a message.\
|
||||
\
|
||||
When messaging Communicators, you must set data to send to the string `text` to avoid errors in reception."
|
||||
@@ -441,12 +441,19 @@
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2)
|
||||
power_draw_per_use = 50
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
var/obj/machinery/exonet_node/node = null
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/proc/get_connection_to_tcomms()
|
||||
if(node && node.on)
|
||||
return can_telecomm(src,node)
|
||||
return 0
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/New()
|
||||
..()
|
||||
exonet = new(src)
|
||||
exonet.make_address("EPv2_circuit-\ref[src]")
|
||||
desc += "<br>This circuit's EPv2 address is: [exonet.address]"
|
||||
node = get_exonet_node()
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/Destroy()
|
||||
if(exonet)
|
||||
@@ -461,7 +468,15 @@
|
||||
var/text = get_pin_data(IC_INPUT, 3)
|
||||
|
||||
if(target_address && istext(target_address))
|
||||
exonet.send_message(target_address, message, text)
|
||||
if(!get_connection_to_tcomms())
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, "Error: Cannot connect to Exonet node.")
|
||||
set_pin_data(IC_OUTPUT, 3, "error")
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
exonet.send_message(target_address, message, text)
|
||||
|
||||
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
set_pin_data(IC_OUTPUT, 1, origin_address)
|
||||
|
||||
@@ -263,15 +263,28 @@
|
||||
/obj/item/integrated_circuit/output/video_camera
|
||||
name = "video camera circuit"
|
||||
desc = "This small camera allows a remote viewer to see what it sees."
|
||||
extended_desc = "The camera is linked to the Research camera network."
|
||||
var/list/networks = list(
|
||||
"research" = NETWORK_CIRCUITS,
|
||||
"engine" = NETWORK_ENGINE,
|
||||
"engineering" = NETWORK_ENGINEERING,
|
||||
"mining" = NETWORK_MINE,
|
||||
"medical" = NETWORK_MEDICAL,
|
||||
"entertainment" = NETWORK_THUNDER,
|
||||
"security" = NETWORK_SECURITY,
|
||||
"command" = NETWORK_COMMAND
|
||||
)
|
||||
icon_state = "video_camera"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
complexity = 10
|
||||
inputs = list(
|
||||
"camera name" = IC_PINTYPE_STRING,
|
||||
"camera network" = IC_PINTYPE_STRING,
|
||||
"camera active" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
inputs_default = list("1" = "video camera circuit")
|
||||
inputs_default = list(
|
||||
"1" = "video camera circuit",
|
||||
"2" = "research"
|
||||
)
|
||||
outputs = list()
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
@@ -280,6 +293,11 @@
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/New()
|
||||
..()
|
||||
extended_desc = list()
|
||||
extended_desc += "Network choices are; "
|
||||
extended_desc += jointext(networks, ", ")
|
||||
extended_desc += "."
|
||||
extended_desc = jointext(extended_desc, null)
|
||||
camera = new(src)
|
||||
on_data_written()
|
||||
|
||||
@@ -298,10 +316,20 @@
|
||||
/obj/item/integrated_circuit/output/video_camera/on_data_written()
|
||||
if(camera)
|
||||
var/cam_name = get_pin_data(IC_INPUT, 1)
|
||||
var/cam_active = get_pin_data(IC_INPUT, 2)
|
||||
var/cam_network = get_pin_data(IC_INPUT, 2)
|
||||
var/cam_active = get_pin_data(IC_INPUT, 3)
|
||||
if(!isnull(cam_name))
|
||||
camera.c_tag = cam_name
|
||||
camera.replace_networks(list(cam_network))
|
||||
set_camera_status(cam_active)
|
||||
if(isnull(cam_network))
|
||||
camera.clear_all_networks()
|
||||
return
|
||||
var/selected_network = networks[cam_network]
|
||||
if(!selected_network)
|
||||
camera.clear_all_networks()
|
||||
return
|
||||
camera.replace_networks(list(selected_network))
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/power_fail()
|
||||
if(camera)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
hardness = 5
|
||||
|
||||
|
||||
/datum/material/cloth/generate_recipes()
|
||||
/datum/material/cloth/generate_recipes() //Vorestation Add - adding some funny cool storage pouches to this so botany can do things other than food
|
||||
recipes = list(
|
||||
new /datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"),
|
||||
new /datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
@@ -29,6 +29,13 @@
|
||||
new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("pouch, small", /obj/item/weapon/storage/pouch/small, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, ammo", /obj/item/weapon/storage/pouch/ammo, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, tools", /obj/item/weapon/storage/pouch/eng_tool, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, parts", /obj/item/weapon/storage/pouch/eng_parts, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, supplies", /obj/item/weapon/storage/pouch/eng_supply, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, medical", /obj/item/weapon/storage/pouch/medical, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, flare", /obj/item/weapon/storage/pouch/flares, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"),
|
||||
new /datum/stack_recipe("painting canvas (11x11)", /obj/item/canvas, 2, time = 2 SECONDS, pass_stack_color = FALSE, supplied_material = "[name]"),
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("pouch, medium", /obj/item/weapon/storage/pouch, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, large", /obj/item/weapon/storage/pouch/large, 15, time = 30 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, holster", /obj/item/weapon/storage/pouch/holster, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, melee", /obj/item/weapon/storage/pouch/baton, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("crude [display_name] bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("[display_name] net", /obj/item/weapon/material/fishing_net, 10, time = 5 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE),
|
||||
new /datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE),
|
||||
|
||||
@@ -73,6 +73,13 @@
|
||||
new /datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white/craftable, 4, time = 5 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white/craftable, 8, time = 10 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white/craftable, 25, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("pouch, small", /obj/item/weapon/storage/pouch/small, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, ammo", /obj/item/weapon/storage/pouch/ammo, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, tools", /obj/item/weapon/storage/pouch/eng_tool, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, parts", /obj/item/weapon/storage/pouch/eng_parts, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, supplies", /obj/item/weapon/storage/pouch/eng_supply, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, medical", /obj/item/weapon/storage/pouch/medical, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("pouch, flare", /obj/item/weapon/storage/pouch/flares, 10, time = 20 SECONDS, pass_stack_color = FALSE, recycle_material = "[name]"), //vorestation Add
|
||||
new /datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]"),
|
||||
new /datum/stack_recipe("satchel", /obj/item/weapon/storage/backpack/satchel/craftable, 30, time = 1 MINUTE, pass_stack_color = TRUE, recycle_material = "[name]"),
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
desc = "A modified design of a proto-kinetic crusher, it is still little more of a combination of various mining tools cobbled together \
|
||||
and kit-bashed into a high-tech cleaver on a stick - with a handguard and a goliath hide grip. While it is still of little use to any \
|
||||
but the most skilled and/or suicidal miners against local fauna, it's an elegant weapon for a more civilized hunter."
|
||||
|
||||
|
||||
look gary there i am
|
||||
- hatterhat
|
||||
*/
|
||||
@@ -256,6 +256,9 @@
|
||||
backstab_bonus = 40 // 100
|
||||
thrown_bonus = 20 // 120
|
||||
update_item_state = FALSE
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/kinetic_crusher/machete/gauntlets
|
||||
@@ -275,6 +278,7 @@
|
||||
detonation_damage = 37 // 75
|
||||
backstab_bonus = 55 // 130
|
||||
var/obj/item/offhand/crushergauntlets/offhand
|
||||
slot_flags = null
|
||||
|
||||
/obj/item/weapon/kinetic_crusher/machete/gauntlets/equipped()
|
||||
. = ..()
|
||||
@@ -381,6 +385,7 @@
|
||||
thrown_bonus = 50 // 135 but you drop your knife because you threw it
|
||||
|
||||
|
||||
|
||||
//destablizing force
|
||||
/obj/item/projectile/destabilizer
|
||||
name = "destabilizing force"
|
||||
|
||||
@@ -27,11 +27,14 @@
|
||||
if(always_stars)
|
||||
piece = stars(piece)
|
||||
else if(!say_understands(speaker, SP.speaking))
|
||||
piece = saypiece_scramble(SP)
|
||||
if(isliving(speaker))
|
||||
var/mob/living/S = speaker
|
||||
if(istype(S.say_list) && length(S.say_list.speak))
|
||||
piece = pick(S.say_list.speak)
|
||||
if(SP.speaking.flags & INAUDIBLE)
|
||||
piece = ""
|
||||
else
|
||||
piece = saypiece_scramble(SP)
|
||||
if(isliving(speaker))
|
||||
var/mob/living/S = speaker
|
||||
if(istype(S.say_list) && length(S.say_list.speak))
|
||||
piece = pick(S.say_list.speak)
|
||||
|
||||
raw_msg += (piece + " ")
|
||||
|
||||
@@ -226,13 +229,13 @@
|
||||
final_message = "[time][final_message]"
|
||||
to_chat(src, final_message)
|
||||
|
||||
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null)
|
||||
/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/verb_understood = "gestures", var/datum/language/language, var/mob/speaker = null, var/speech_type = 1)
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(say_understands(speaker, language))
|
||||
message = "<B>[speaker]</B> [verb], \"[message]\""
|
||||
else
|
||||
message = "<B>[speaker]</B> [verb_understood], \"[message]\""
|
||||
else if(!(language.ignore_adverb))
|
||||
var/adverb
|
||||
var/length = length(message) * pick(0.8, 0.9, 1.0, 1.1, 1.2) //Adds a little bit of fuzziness
|
||||
switch(length)
|
||||
@@ -242,8 +245,10 @@
|
||||
if(48 to 90) adverb = " a lengthy message"
|
||||
else adverb = " a very lengthy message"
|
||||
message = "<B>[speaker]</B> [verb][adverb]."
|
||||
else
|
||||
message = "<B>[speaker]</B> [verb]."
|
||||
|
||||
show_message(message, type = 1) // Type 1 is visual message
|
||||
show_message(message, type = speech_type) // Type 1 is visual message
|
||||
|
||||
/mob/proc/hear_sleep(var/message)
|
||||
var/heard = ""
|
||||
|
||||
@@ -145,8 +145,9 @@
|
||||
// which is exactly what sign language does.
|
||||
/datum/language/sign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
|
||||
log_say("(SIGN) [message]", speaker)
|
||||
speaker.say_signlang(message, pick(signlang_verb), src)
|
||||
|
||||
var/verb_to_use = pick(signlang_verb)
|
||||
speaker.say_signlang(message, verb_to_use, verb_to_use, src)
|
||||
|
||||
|
||||
// Silly language for those times when you try to talk a languague you normally can't
|
||||
/datum/language/gibberish
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
var/exclaim_verb = "exclaims" // Used when sentence ends in a !
|
||||
var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead.
|
||||
var/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
|
||||
var/signlang_verb_understood = list("signs") // snowflake bs, used only for echo
|
||||
var/colour = "body" // CSS style to use for strings in this language.
|
||||
var/key = "x" // Character used to speak in language eg. :o for Unathi.
|
||||
var/flags = 0 // Various language flags.
|
||||
@@ -20,6 +21,7 @@
|
||||
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string
|
||||
var/machine_understands = 1 // Whether machines can parse and understand this language
|
||||
var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word
|
||||
var/ignore_adverb = FALSE // For inaudible languages that we dont want adverb for
|
||||
|
||||
/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2)
|
||||
if(!syllables || !syllables.len)
|
||||
@@ -235,7 +237,7 @@
|
||||
//TBD
|
||||
/mob/proc/check_lang_data()
|
||||
. = ""
|
||||
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
. += "<b>[L.name] ([get_language_prefix()][L.key])</b><br/>[L.desc]<br/><br/>"
|
||||
|
||||
@@ -96,7 +96,8 @@
|
||||
|
||||
/datum/language/tajsign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
|
||||
log_say("(SIGN) [message]", speaker)
|
||||
speaker.say_signlang(message, pick(signlang_verb), src)
|
||||
var/verb_to_use = pick(signlang_verb)
|
||||
speaker.say_signlang(message, verb_to_use, verb_to_use, src)
|
||||
|
||||
/datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
|
||||
var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this.
|
||||
|
||||
@@ -167,7 +167,24 @@
|
||||
exclaim_verb = "squeaks loudly"
|
||||
syllables = list ("sque", "uik", "squeak", "squee", "eak", "eek", "uek", "squik",
|
||||
"squeek", "sq", "squee", "ee", "ek", "ak", "ueak", "squea")
|
||||
colour = "tavan"
|
||||
colour = "tavan"
|
||||
|
||||
/datum/language/echosong
|
||||
name = LANGUAGE_ECHOSONG
|
||||
desc = "An ultrasound-based language, inaudible to those unable to understand it."
|
||||
key = "U"
|
||||
signlang_verb = list("opens their mouth soundlessly", "mouthes something silently")
|
||||
signlang_verb_understood = list("squeaks")
|
||||
colour = "echosong"
|
||||
flags = INAUDIBLE
|
||||
ignore_adverb = TRUE
|
||||
|
||||
/datum/language/echosong/scramble(var/input, var/list/known_languages)
|
||||
return stars(input)
|
||||
|
||||
/datum/language/echosong/broadcast(var/mob/living/speaker, var/message, var/speaker_mask)
|
||||
log_say("(INAUDIBLE) [message]", speaker)
|
||||
speaker.say_signlang(format_message(message), pick(signlang_verb), pick(signlang_verb_understood), src, 2)
|
||||
|
||||
/datum/language/unathi
|
||||
flags = 0
|
||||
|
||||
@@ -53,8 +53,33 @@
|
||||
autohiss_basic_map = list(
|
||||
"r" = list("rr", "rrr", "rrrr")
|
||||
)
|
||||
autohiss_exempt = list(LANGUAGE_SIIK,LANGUAGE_AKHANI)
|
||||
autohiss_exempt = list(LANGUAGE_SIIK,LANGUAGE_AKHANI,LANGUAGE_ALAI)
|
||||
|
||||
/datum/species/zaddat
|
||||
autohiss_basic_map = list(
|
||||
"f" = list("v","vh"),
|
||||
"ph" = list("v", "vh")
|
||||
)
|
||||
autohiss_extra_map = list(
|
||||
"s" = list("z", "zz", "zzz"),
|
||||
"ce" = list("z", "zz"),
|
||||
"ci" = list("z", "zz"),
|
||||
"v" = list("vv", "vvv")
|
||||
)
|
||||
autohiss_exempt = list(LANGUAGE_ZADDAT,LANGUAGE_VESPINAE)
|
||||
|
||||
/datum/species/zaddat
|
||||
autohiss_basic_map = list(
|
||||
"f" = list("v","vh"),
|
||||
"ph" = list("v", "vh")
|
||||
)
|
||||
autohiss_extra_map = list(
|
||||
"s" = list("z", "zz", "zzz"),
|
||||
"ce" = list("z", "zz"),
|
||||
"ci" = list("z", "zz"),
|
||||
"v" = list("vv", "vvv")
|
||||
)
|
||||
autohiss_exempt = list(LANGUAGE_ZADDAT)
|
||||
|
||||
//Yawn Wider Edit.
|
||||
/datum/species/spider
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/emagged = 0
|
||||
var/light_strength = 3
|
||||
var/busy = 0
|
||||
|
||||
var/obj/item/device/paicard/paicard = null
|
||||
var/obj/access_scanner = null
|
||||
var/list/req_access = list()
|
||||
var/list/req_one_access = list()
|
||||
@@ -73,10 +73,27 @@
|
||||
SetStunned(0)
|
||||
SetParalysis(0)
|
||||
|
||||
if(on && !client && !busy)
|
||||
if(on && !client && !busy && !paicard)
|
||||
spawn(0)
|
||||
handleAI()
|
||||
|
||||
/*
|
||||
/mob/living/bot/examine(mob/user)
|
||||
. = ..()
|
||||
if(health < maxHealth)
|
||||
if(health > maxHealth/3)
|
||||
. += "[src]'s parts look loose."
|
||||
else
|
||||
. += "[src]'s parts look very loose!"
|
||||
else
|
||||
. += "[src] is in pristine condition."
|
||||
. += span_notice("Its maintenance panel is [open ? "open" : "closed"].")
|
||||
. += span_info("You can use a <b>screwdriver</b> to [open ? "close" : "open"] it.")
|
||||
. += span_notice("Its control panel is [locked ? "locked" : "unlocked"].")
|
||||
if(paicard)
|
||||
. += span_notice("It has a pAI device installed.")
|
||||
if(open)
|
||||
. += span_info("You can use a <b>crowbar</b> to remove it.")
|
||||
*/
|
||||
/mob/living/bot/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
health = getMaxHealth()
|
||||
@@ -139,6 +156,17 @@
|
||||
qdel(O)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Unable to repair with the maintenance panel closed.</span>")
|
||||
else if(istype(O, /obj/item/device/paicard))
|
||||
if(open)
|
||||
insertpai(user, O)
|
||||
to_chat(user, span_notice("You slot the card into \the [initial(src.name)]."))
|
||||
else
|
||||
to_chat(user, span_notice("You must open the panel first!"))
|
||||
else if(O.is_crowbar())
|
||||
if(open && paicard)
|
||||
to_chat(user, span_notice("You are attempting to remove the pAI.."))
|
||||
if(do_after(user,10 * O.toolspeed))
|
||||
ejectpai(user)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -212,6 +240,13 @@
|
||||
if(LAZYLEN(can_go))
|
||||
if(step_towards(src, pick(can_go)))
|
||||
return
|
||||
for(var/mob in loc)
|
||||
if(istype(mob, /mob/living/bot) && mob != src) // Same as above, but we also don't want to have bots ontop of bots. Cleanbots shouldn't stack >:(
|
||||
var/turf/my_turf = get_turf(src)
|
||||
var/list/can_go = my_turf.CardinalTurfsWithAccess(botcard)
|
||||
if(LAZYLEN(can_go))
|
||||
if(step_towards(src, pick(can_go)))
|
||||
return
|
||||
handleIdle()
|
||||
|
||||
/mob/living/bot/proc/handleRegular()
|
||||
@@ -367,9 +402,14 @@
|
||||
update_icons()
|
||||
|
||||
/mob/living/bot/proc/explode()
|
||||
if(paicard)
|
||||
ejectpai()
|
||||
release_vore_contents()
|
||||
qdel(src)
|
||||
|
||||
/mob/living/bot/is_sentient()
|
||||
if(paicard)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/******************************************************************/
|
||||
@@ -458,3 +498,68 @@
|
||||
|
||||
/mob/living/bot/isSynthetic() //Robots are synthetic, no?
|
||||
return 1
|
||||
|
||||
/mob/living/bot/proc/insertpai(mob/user, obj/item/device/paicard/card)
|
||||
//var/obj/item/paicard/card = I
|
||||
var/mob/living/silicon/pai/AI = card.pai
|
||||
if(paicard)
|
||||
to_chat(user, span_notice("This bot is already under PAI Control!"))
|
||||
return
|
||||
if(!istype(card)) // TODO: Add sleevecard support.
|
||||
return
|
||||
if(client)
|
||||
to_chat(user, span_notice("Higher levels of processing are already present!"))
|
||||
return
|
||||
if(!card.pai)
|
||||
to_chat(user, span_notice("This card does not currently have a personality!"))
|
||||
return
|
||||
paicard = card
|
||||
user.unEquip(card)
|
||||
card.forceMove(src)
|
||||
src.ckey = AI.ckey
|
||||
name = AI.name
|
||||
ooc_notes = AI.ooc_notes
|
||||
to_chat(src, span_notice("You feel a tingle in your circuits as your systems interface with \the [initial(src.name)]."))
|
||||
if(AI.idcard.access)
|
||||
botcard.access |= AI.idcard.access
|
||||
|
||||
/mob/living/bot/proc/ejectpai(mob/user)
|
||||
if(paicard)
|
||||
var/mob/living/silicon/pai/AI = paicard.pai
|
||||
AI.ckey = src.ckey
|
||||
AI.ooc_notes = ooc_notes
|
||||
paicard.forceMove(src.loc)
|
||||
paicard = null
|
||||
name = initial(name)
|
||||
botcard.access = botcard_access.Copy()
|
||||
to_chat(AI, span_notice("You feel a tad claustrophobic as your mind closes back into your card, ejecting from \the [initial(src.name)]."))
|
||||
|
||||
if(user)
|
||||
to_chat(user, span_notice("You eject the card from \the [initial(src.name)]."))
|
||||
|
||||
/mob/living/bot/verb/bot_nom(var/mob/living/T in oview(1))
|
||||
set name = "Bot Nom"
|
||||
set category = "Bot Commands"
|
||||
set desc = "Allows you to eat someone. Yum."
|
||||
|
||||
if (stat != CONSCIOUS)
|
||||
return
|
||||
return feed_grabbed_to_self(src,T)
|
||||
|
||||
/mob/living/bot/verb/ejectself()
|
||||
set name = "Eject pAI"
|
||||
set category = "Bot Commands"
|
||||
set desc = "Eject your card, return to smole."
|
||||
|
||||
return ejectpai()
|
||||
|
||||
/mob/living/bot/Login()
|
||||
no_vore = FALSE // ROBOT VORE
|
||||
init_vore() // ROBOT VORE
|
||||
verbs |= /mob/living/proc/insidePanel
|
||||
|
||||
/mob/living/bot/Logout()
|
||||
no_vore = TRUE // ROBOT VORE
|
||||
release_vore_contents()
|
||||
init_vore() // ROBOT VORE
|
||||
verbs -= /mob/living/proc/insidePanel
|
||||
@@ -141,8 +141,8 @@
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
return
|
||||
//qdel(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/cleanbot/update_icons()
|
||||
if(busy)
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(Tsec)
|
||||
qdel(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/secbot/ed209/handleRangedTarget()
|
||||
RangedAttack(target)
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
return
|
||||
//qdel(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/cleanbot/edCLN/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
@@ -286,8 +286,8 @@
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
return
|
||||
//qdel(src)
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/bot/farmbot/confirmTarget(var/atom/targ)
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
data["on"] = on
|
||||
data["open"] = open
|
||||
data["locked"] = locked
|
||||
|
||||
|
||||
data["vocal"] = vocal
|
||||
data["amount"] = amount
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
/mob/living/bot/floorbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
|
||||
add_fingerprint(src)
|
||||
|
||||
switch(action)
|
||||
@@ -85,7 +85,7 @@
|
||||
else
|
||||
turn_on()
|
||||
. = TRUE
|
||||
|
||||
|
||||
if(locked && !issilicon(usr))
|
||||
return
|
||||
|
||||
@@ -302,7 +302,8 @@
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
//qdel(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/floorbot/proc/addTiles(var/am)
|
||||
amount += am
|
||||
|
||||
@@ -269,10 +269,10 @@
|
||||
/mob/living/bot/medbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
|
||||
usr.set_machine(src)
|
||||
add_fingerprint(usr)
|
||||
|
||||
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("power")
|
||||
@@ -349,8 +349,8 @@
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
qdel(src)
|
||||
return
|
||||
//qdel(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/medbot/handleRegular()
|
||||
. = ..()
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
/mob/living/bot/secbot/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
switch(action)
|
||||
@@ -380,7 +380,8 @@
|
||||
s.start()
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/oil(Tsec)
|
||||
qdel(src)
|
||||
//qdel(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/secbot/proc/target_name(mob/living/T)
|
||||
if(ishuman(T))
|
||||
|
||||
@@ -323,7 +323,7 @@ emp_act
|
||||
|
||||
if(!stat)
|
||||
switch(hit_zone)
|
||||
if("head")//Harder to score a stun but if you do it lasts a bit longer
|
||||
if(BP_HEAD)//Harder to score a stun but if you do it lasts a bit longer
|
||||
if(prob(effective_force))
|
||||
apply_effect(20, PARALYZE, blocked, soaked)
|
||||
visible_message("<span class='danger'>\The [src] has been knocked unconscious!</span>")
|
||||
@@ -337,7 +337,7 @@ emp_act
|
||||
if(glasses && prob(33))
|
||||
glasses.add_blood(src)
|
||||
update_inv_glasses(0)
|
||||
if("chest")//Easier to score a stun but lasts less time
|
||||
if(BP_TORSO)//Easier to score a stun but lasts less time
|
||||
if(prob(effective_force + 10))
|
||||
apply_effect(6, WEAKEN, blocked, soaked)
|
||||
visible_message("<span class='danger'>\The [src] has been knocked down!</span>")
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
autohiss_extra_map = list(
|
||||
"x" = list("ks", "kss", "ksss")
|
||||
),
|
||||
autohiss_exempt = list("Sinta'unathi"))
|
||||
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_vassilian) // CHOMPEdit: exclude vassillian hiss
|
||||
autohiss_exempt = list(LANGUAGE_UNATHI))
|
||||
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_vassilian, /datum/trait/neutral/autohiss_zaddat) // CHOMPEdit: exclude vassillian hiss
|
||||
|
||||
/datum/trait/neutral/autohiss_tajaran
|
||||
name = "Autohiss (Tajaran)"
|
||||
@@ -64,8 +64,26 @@
|
||||
autohiss_basic_map = list(
|
||||
"r" = list("rr", "rrr", "rrrr")
|
||||
),
|
||||
autohiss_exempt = list("Siik"))
|
||||
excludes = list(/datum/trait/neutral/autohiss_unathi, /datum/trait/neutral/autohiss_vassilian) // CHOMPEdit: exclude vassillian hiss
|
||||
autohiss_exempt = list(LANGUAGE_SIIK,LANGUAGE_AKHANI,LANGUAGE_ALAI))
|
||||
excludes = list(/datum/trait/neutral/autohiss_unathi, /datum/trait/neutral/autohiss_zaddat, /datum/trait/neutral/autohiss_vassilian) // CHOMPEdit: exclude vassillian hiss
|
||||
|
||||
/datum/trait/neutral/autohiss_zaddat
|
||||
name = "Autohiss (Zaddat)"
|
||||
desc = "You buzz your S's and F's."
|
||||
cost = 0
|
||||
var_changes = list(
|
||||
autohiss_basic_map = list(
|
||||
"f" = list("v","vh"),
|
||||
"ph" = list("v", "vh")
|
||||
),
|
||||
autohiss_extra_map = list(
|
||||
"s" = list("z", "zz", "zzz"),
|
||||
"ce" = list("z", "zz"),
|
||||
"ci" = list("z", "zz"),
|
||||
"v" = list("vv", "vvv")
|
||||
),
|
||||
autohiss_exempt = list(LANGUAGE_ZADDAT,LANGUAGE_VESPINAE))
|
||||
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_unathi)
|
||||
|
||||
/datum/trait/neutral/bloodsucker
|
||||
name = "Bloodsucker, Obligate"
|
||||
@@ -514,3 +532,13 @@
|
||||
/datum/trait/neutral/submit_to_prey/apply(var/datum/species/S,var/mob/living/carbon/human/H)
|
||||
..(S,H)
|
||||
H.verbs |= /mob/living/proc/lend_prey_control
|
||||
|
||||
/datum/trait/neutral/vertical_nom
|
||||
name = "Vertical Nom"
|
||||
desc = "Allows you to consume people from up above."
|
||||
cost = 0
|
||||
custom_only = FALSE
|
||||
|
||||
/datum/trait/neutral/vertical_nom/apply(var/datum/species/S,var/mob/living/carbon/human/H)
|
||||
..(S,H)
|
||||
H.verbs |= /mob/living/proc/vertical_nom
|
||||
|
||||
@@ -60,19 +60,19 @@
|
||||
var_changes = list("darksight" = 6) //CHOMP Edit
|
||||
*/
|
||||
/datum/trait/positive/melee_attack
|
||||
name = "Special Attack: Sharp Melee" // CHOMPEdit: Trait Organization for easier browsing. TODO: Proper categorization of 'health/ability/resist/etc'
|
||||
name = "Special Attack: Sharp Melee" // Trait Organization for easier browsing. TODO: Proper categorization of 'health/ability/resist/etc'
|
||||
desc = "Provides sharp melee attacks that do slightly more damage."
|
||||
cost = 1
|
||||
var_changes = list("unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp))
|
||||
|
||||
/datum/trait/positive/melee_attack_fangs
|
||||
name = "Special Attack: Sharp Melee & Numbing Fangs" // CHOMPEdit: Trait Organization for easier browsing. TODO: Proper categorization of 'health/ability/resist/etc'
|
||||
name = "Special Attack: Sharp Melee & Numbing Fangs" // Trait Organization for easier browsing. TODO: Proper categorization of 'health/ability/resist/etc'
|
||||
desc = "Provides sharp melee attacks that do slightly more damage, along with fangs that makes the person bit unable to feel their body or pain."
|
||||
cost = 2
|
||||
var_changes = list("unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp, /datum/unarmed_attack/bite/sharp/numbing))
|
||||
|
||||
/datum/trait/positive/fangs
|
||||
name = "Special Attack: Numbing Fangs" // CHOMPEdit: Trait Organization for easier browsing. TODO: Proper categorization of 'health/ability/resist/etc'
|
||||
name = "Special Attack: Numbing Fangs" // Trait Organization for easier browsing. TODO: Proper categorization of 'health/ability/resist/etc'
|
||||
desc = "Provides fangs that makes the person bit unable to feel their body or pain."
|
||||
cost = 1
|
||||
var_changes = list("unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite/sharp/numbing))
|
||||
|
||||
@@ -79,12 +79,23 @@
|
||||
return 1
|
||||
|
||||
/mob/living/verb/succumb()
|
||||
set hidden = 1
|
||||
if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable
|
||||
set name = "Succumb to death"
|
||||
set category = "IC"
|
||||
set desc = "Press this button if you are in crit and wish to die. Use this sparingly (ending a scene, no medical, etc.)"
|
||||
var/confirm1 = tgui_alert(usr, "Pressing this button will kill you instantenously! Are you sure you wish to proceed?", "Confirm wish to succumb", list("No","Yes"))
|
||||
var/confirm2 = "No"
|
||||
if(confirm1 == "Yes")
|
||||
confirm2 = tgui_alert(usr, "Pressing this buttom will really kill you, no going back", "Are you sure?", list("Yes", "No")) //Swapped answers to protect from accidental double clicks.
|
||||
if (src.health < 0 && stat != DEAD && confirm1 == "Yes" && confirm2 == "Yes") // Checking both confirm1 and confirm2 for good measure. I don't trust TGUI.
|
||||
src.death()
|
||||
to_chat(src, "<font color='blue'>You have given up life and succumbed to death.</font>")
|
||||
else
|
||||
to_chat(src, "<font color='blue'>You are not injured enough to succumb to death!</font>")
|
||||
if(stat == DEAD)
|
||||
to_chat(src, "<font color='blue'>As much as you'd like, you can't die when already dead</font>")
|
||||
else if(confirm1 == "No" || confirm2 == "No")
|
||||
to_chat(src, "<font color='blue'>You chose to live another day.</font>")
|
||||
else
|
||||
to_chat(src, "<font color='blue'>You are not injured enough to succumb to death!</font>")
|
||||
|
||||
/mob/living/proc/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
|
||||
@@ -300,7 +300,7 @@ var/list/channel_to_radio_key = new
|
||||
|
||||
//Handle nonverbal languages here
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
if(S.speaking.flags & NONVERBAL)
|
||||
if((S.speaking.flags & NONVERBAL) || (S.speaking.flags & INAUDIBLE))
|
||||
custom_emote(1, "[pick(S.speaking.signlang_verb)].")
|
||||
|
||||
//These will contain the main receivers of the message
|
||||
@@ -407,21 +407,33 @@ var/list/channel_to_radio_key = new
|
||||
log_say(message, src)
|
||||
return 1
|
||||
|
||||
/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language)
|
||||
/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/verb_understood="gestures", var/datum/language/language, var/type = 1)
|
||||
var/turf/T = get_turf(src)
|
||||
//We're in something, gesture to people inside the same thing
|
||||
if(loc != T)
|
||||
for(var/mob/M in loc)
|
||||
M.hear_signlang(message, verb, language, src)
|
||||
M.hear_signlang(message, verb, verb_understood, language, src, type)
|
||||
|
||||
//We're on a turf, gesture to visible as if we were a normal language
|
||||
else
|
||||
var/low_range = FALSE
|
||||
if(T && type == 2) // type 2 is audible signlang. yes. sue me.
|
||||
//Air is too thin to carry sound at all, contact speech only
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = environment ? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE)
|
||||
low_range = TRUE
|
||||
|
||||
var/list/potentials = get_mobs_and_objs_in_view_fast(T, world.view)
|
||||
var/list/mobs = potentials["mobs"]
|
||||
for(var/mob/M as anything in mobs)
|
||||
M.hear_signlang(message, verb, language, src)
|
||||
if(low_range && !(M in range(1, src)))
|
||||
continue
|
||||
M.hear_signlang(message, verb, verb_understood, language, src, type)
|
||||
var/list/objs = potentials["objs"]
|
||||
for(var/obj/O as anything in objs)
|
||||
if(low_range && !(O in range(1, src)))
|
||||
continue
|
||||
O.hear_signlang(message, verb, language, src)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -247,6 +247,9 @@
|
||||
|
||||
last_special = world.time + 100
|
||||
|
||||
if(istype(card.loc, /obj/machinery)) // VOREStation edit, this statement allows pAIs stuck in a machine to eject themselves.
|
||||
var/obj/machinery/M = card.loc
|
||||
M.ejectpai()
|
||||
//I'm not sure how much of this is necessary, but I would rather avoid issues.
|
||||
if(istype(card.loc,/obj/item/rig_module))
|
||||
to_chat(src, "There is no room to unfold inside this rig module. You're good and stuck.")
|
||||
|
||||
@@ -72,9 +72,86 @@
|
||||
// For really persistent looters
|
||||
src.emag = new /obj/item/weapon/gun/energy/retro/mounted(src)
|
||||
|
||||
var/datum/matter_synth/wood = new /datum/matter_synth/wood(25000)
|
||||
var/datum/matter_synth/wood = new /datum/matter_synth/wood(50000) //CHOMPEdit - "Buffing this to 50k on account of broken code not letting us pick up more stacks. Wee."
|
||||
synths += wood
|
||||
|
||||
var/obj/item/stack/material/cyborg/wood/W = new (src)
|
||||
W.synths = list(wood)
|
||||
src.modules += W
|
||||
src.modules += W
|
||||
|
||||
//CHOMPEdit - "Giving the gravekeeper drone more modules to allow it to actually do it's job."
|
||||
src.modules += new /obj/item/weapon/tool/wirecutters/cyborg(src) //Gotta clear those pesky landmines somehow. Also allows for deconstruction of things in the way!
|
||||
src.modules += new /obj/item/device/multitool(src)
|
||||
src.modules += new /obj/item/device/lightreplacer(src)
|
||||
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
|
||||
src.modules += new /obj/item/weapon/gripper(src)
|
||||
src.modules += new /obj/item/weapon/pickaxe(src)
|
||||
src.modules += new /obj/item/device/floor_painter(src)
|
||||
src.modules += new /obj/item/weapon/pen/robopen(src)
|
||||
src.modules += new /obj/item/weapon/form_printer(src)
|
||||
src.modules += new /obj/item/weapon/gripper/paperwork(src)
|
||||
src.modules += new /obj/item/weapon/hand_labeler(src)
|
||||
src.modules += new /obj/item/weapon/stamp(src)
|
||||
src.modules += new /obj/item/weapon/stamp/denied(src)
|
||||
|
||||
var/obj/item/weapon/flame/lighter/zippo/L = new /obj/item/weapon/flame/lighter/zippo(src)
|
||||
L.lit = 1
|
||||
src.modules += L
|
||||
|
||||
src.emag = new /obj/item/weapon/stamp/chameleon(src)
|
||||
src.emag = new /obj/item/weapon/pen/chameleon(src)
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal(50000)
|
||||
var/datum/matter_synth/glass = new /datum/matter_synth/glass(50000)
|
||||
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel(20000)
|
||||
var/datum/matter_synth/plastic = new /datum/matter_synth/plastic(50000)
|
||||
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
|
||||
synths += metal
|
||||
synths += glass
|
||||
synths += plasteel
|
||||
synths += plastic
|
||||
synths += wire
|
||||
|
||||
var/obj/item/weapon/matter_decompiler/MD = new /obj/item/weapon/matter_decompiler(src)
|
||||
MD.metal = metal
|
||||
MD.glass = glass
|
||||
src.modules += MD
|
||||
|
||||
var/obj/item/stack/material/cyborg/steel/M = new (src)
|
||||
M.synths = list(metal)
|
||||
src.modules += M
|
||||
|
||||
var/obj/item/stack/material/cyborg/glass/G = new (src)
|
||||
G.synths = list(glass)
|
||||
src.modules += G
|
||||
|
||||
var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
|
||||
rods.synths = list(metal)
|
||||
src.modules += rods
|
||||
|
||||
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
|
||||
C.synths = list(wire)
|
||||
src.modules += C
|
||||
|
||||
var/obj/item/stack/material/cyborg/plasteel/PS = new (src)
|
||||
PS.synths = list(plasteel)
|
||||
src.modules += PS
|
||||
|
||||
var/obj/item/stack/tile/wood/cyborg/WT = new /obj/item/stack/tile/wood/cyborg(src)
|
||||
WT.synths = list(wood)
|
||||
src.modules += WT
|
||||
|
||||
var/obj/item/stack/tile/floor/cyborg/S = new /obj/item/stack/tile/floor/cyborg(src)
|
||||
S.synths = list(metal)
|
||||
src.modules += S
|
||||
|
||||
var/obj/item/stack/tile/roofing/cyborg/CT = new /obj/item/stack/tile/roofing/cyborg(src)
|
||||
CT.synths = list(metal)
|
||||
src.modules += CT
|
||||
|
||||
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
|
||||
RG.synths = list(metal, glass)
|
||||
src.modules += RG
|
||||
|
||||
var/obj/item/stack/material/cyborg/plastic/PL = new (src)
|
||||
PL.synths = list(plastic)
|
||||
src.modules += PL //CHOMEdit End
|
||||
@@ -4,6 +4,7 @@
|
||||
real_name = "cockroach"
|
||||
desc = "This station is just crawling with bugs."
|
||||
tt_desc = "E Blattella germanica"
|
||||
icon = 'icons/mob/animal_vr.dmi'
|
||||
icon_state = "cockroach"
|
||||
item_state = "cockroach"
|
||||
icon_living = "cockroach"
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/event/proc/man()
|
||||
visible_message("<span class='warning'>\The [src] suddenly evolves!</span>")
|
||||
new /mob/living/simple_mob/vore/aggressive/lizardman(get_turf(src))
|
||||
qdel(src)
|
||||
var/mob/bigger = new /mob/living/simple_mob/vore/aggressive/lizardman(get_turf(src))
|
||||
|
||||
if(istype(loc,/obj/belly)){
|
||||
var/obj/belly/B = loc
|
||||
B.owner.visible_message("<span class='warning'><b>Something grows inside [B.owner]'s [lowertext(B.name)]!</b></span>")
|
||||
to_chat(B.owner, "<span class='warning'>\The [src] suddenly evolves inside your [lowertext(B.name)]!</span>")
|
||||
B.release_specific_contents(src, TRUE)
|
||||
B.nom_mob(bigger, null)
|
||||
qdel(src)
|
||||
}else{
|
||||
visible_message("<span class='warning'>\The [src] suddenly evolves!</span>")
|
||||
qdel(src)
|
||||
}
|
||||
|
||||
@@ -11,9 +11,20 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_mob/animal/passive/mouse/event/proc/rat()
|
||||
visible_message("<span class='warning'>\The [src] suddenly evolves!</span>")
|
||||
var/mob/bigger = null
|
||||
if(prob(99.5))
|
||||
new /mob/living/simple_mob/vore/aggressive/rat/event(get_turf(src))
|
||||
qdel(src)
|
||||
bigger = new /mob/living/simple_mob/vore/aggressive/rat/event(get_turf(src))
|
||||
else
|
||||
new /mob/living/simple_mob/vore/aggressive/chungus(get_turf(src))
|
||||
bigger = new /mob/living/simple_mob/vore/aggressive/chungus(get_turf(src))
|
||||
|
||||
if(istype(loc,/obj/belly)){
|
||||
var/obj/belly/B = loc
|
||||
B.owner.visible_message("<span class='warning'><b>Something grows inside [B.owner]'s [lowertext(B.name)]!</b></span>")
|
||||
to_chat(B.owner, "<span class='warning'>\The [src] suddenly evolves inside your [lowertext(B.name)]!</span>")
|
||||
B.release_specific_contents(src, TRUE)
|
||||
B.nom_mob(bigger, null)
|
||||
qdel(src)
|
||||
}else{
|
||||
visible_message("<span class='warning'>\The [src] suddenly evolves!</span>")
|
||||
qdel(src)
|
||||
}
|
||||
|
||||
@@ -604,34 +604,34 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
|
||||
|
||||
//The base miss chance for the different defence zones
|
||||
var/list/global/base_miss_chance = list(
|
||||
"head" = 40,
|
||||
"torso" = 10,
|
||||
"groin" = 20,
|
||||
"l_leg" = 20,
|
||||
"r_leg" = 20,
|
||||
"l_arm" = 20,
|
||||
"r_arm" = 20,
|
||||
"l_hand" = 50,
|
||||
"r_hand" = 50,
|
||||
"l_foot" = 50,
|
||||
"r_foot" = 50,
|
||||
) //CHOMPEDIT - Changed "chest" to "torso", as chest is a typo. How long has this bug been here?
|
||||
BP_HEAD = 40,
|
||||
BP_TORSO = 10,
|
||||
BP_GROIN = 20,
|
||||
BP_L_LEG = 20,
|
||||
BP_R_LEG = 20,
|
||||
BP_L_ARM = 20,
|
||||
BP_R_ARM = 20,
|
||||
BP_L_HAND = 50,
|
||||
BP_R_HAND = 50,
|
||||
BP_L_FOOT = 50,
|
||||
BP_R_FOOT = 50,
|
||||
)
|
||||
|
||||
//Used to weight organs when an organ is hit randomly (i.e. not a directed, aimed attack).
|
||||
//Also used to weight the protection value that armour provides for covering that body part when calculating protection from full-body effects.
|
||||
var/list/global/organ_rel_size = list(
|
||||
"head" = 25,
|
||||
"torso" = 70,
|
||||
"groin" = 30,
|
||||
"l_leg" = 25,
|
||||
"r_leg" = 25,
|
||||
"l_arm" = 25,
|
||||
"r_arm" = 25,
|
||||
"l_hand" = 10,
|
||||
"r_hand" = 10,
|
||||
"l_foot" = 10,
|
||||
"r_foot" = 10,
|
||||
) //CHOMPEDIT - Changed "chest" to "torso", as chest is a typo. How long has this bug been here?
|
||||
BP_HEAD = 25,
|
||||
BP_TORSO = 70,
|
||||
BP_GROIN = 30,
|
||||
BP_L_LEG = 25,
|
||||
BP_R_LEG = 25,
|
||||
BP_L_ARM = 25,
|
||||
BP_R_ARM = 25,
|
||||
BP_L_HAND = 10,
|
||||
BP_R_HAND = 10,
|
||||
BP_L_FOOT = 10,
|
||||
BP_R_FOOT = 10,
|
||||
)
|
||||
|
||||
/mob/proc/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
|
||||
return
|
||||
@@ -689,4 +689,4 @@ var/global/image/backplane
|
||||
item.screen_loc = screen_place
|
||||
|
||||
/mob/proc/can_feed()
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -135,6 +135,13 @@
|
||||
extra_overlay = "naga_markings"
|
||||
//icon_sprite_tag = "naga2c"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/naga/alt_2c
|
||||
name = "Naga alt style dual-color (Taur)"
|
||||
suit_sprites = 'icons/mob/taursuits_naga_alt_vr.dmi'
|
||||
icon_state = "altnaga_s"
|
||||
extra_overlay = "altnaga_markings"
|
||||
//icon_sprite_tag = "altnaga2c"
|
||||
|
||||
/datum/sprite_accessory/tail/taur/horse
|
||||
name = "Horse (Taur)"
|
||||
icon_state = "horse_s"
|
||||
|
||||
@@ -226,3 +226,12 @@
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "drago_wing_2"
|
||||
|
||||
/datum/sprite_accessory/wing/aeromorph_flat
|
||||
name = "aeromorph wings, flat"
|
||||
desc = ""
|
||||
icon_state = "aeromorph_flat"
|
||||
do_colouration = 1
|
||||
color_blend_mode = ICON_MULTIPLY
|
||||
extra_overlay = "aeromorph_flat_1"
|
||||
extra_overlay2 = "aeromorph_flat_2"
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
|
||||
// There are a few things that will make us want to ignore all other languages in - namely, HIVEMIND languages.
|
||||
var/datum/language/L = current[1]
|
||||
if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG))
|
||||
if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG || L.flags & INAUDIBLE))
|
||||
return new /datum/multilingual_say_piece(L, trim(sanitize(strip_prefixes(message))))
|
||||
|
||||
if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang
|
||||
|
||||
@@ -9,10 +9,12 @@
|
||||
switch(network)
|
||||
if(NETWORK_THUNDER)
|
||||
return 0
|
||||
if(NETWORK_ENGINE,NETWORK_ALARM_ATMOS,NETWORK_ALARM_FIRE,NETWORK_ALARM_POWER)
|
||||
if(NETWORK_ENGINE,NETWORK_ENGINEERING,NETWORK_ALARM_ATMOS,NETWORK_ALARM_FIRE,NETWORK_ALARM_POWER)
|
||||
return access_engine
|
||||
if(NETWORK_CIRCUITS)
|
||||
return access_research
|
||||
if(NETWORK_MINE)
|
||||
return access_qm
|
||||
if(NETWORK_ERT)
|
||||
return access_cent_specops
|
||||
//VOREStation Add Start
|
||||
|
||||
@@ -77,12 +77,16 @@ var/const/CE_STABLE_THRESHOLD = 0.5
|
||||
var/obj/item/organ/internal/heart/heart = internal_organs_by_name[O_HEART]
|
||||
|
||||
if(!heart)
|
||||
blood_volume_raw = 0
|
||||
blood_volume = 0
|
||||
else if(heart.is_broken())
|
||||
blood_volume_raw *= 0.3
|
||||
blood_volume *= 0.3
|
||||
else if(heart.is_bruised())
|
||||
blood_volume_raw *= 0.7
|
||||
blood_volume *= 0.7
|
||||
else if(heart.damage)
|
||||
blood_volume_raw *= 0.8
|
||||
blood_volume *= 0.8
|
||||
|
||||
//Effects of bloodloss
|
||||
|
||||
@@ -384,5 +384,6 @@
|
||||
|
||||
/obj/item/device/toner
|
||||
name = "toner cartridge"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "tonercartridge"
|
||||
var/toner_amount = 30
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
caliber = ".45 LC"
|
||||
icon_state = "rifle-casing"
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a45lc
|
||||
matter = list(DEFAULT_WALL_MATERIAL = 169)
|
||||
|
||||
/obj/item/ammo_casing/a45lc/rifle
|
||||
desc = "A long silver bullet... +P, and .45 LC stamped into the base."
|
||||
@@ -173,4 +174,5 @@
|
||||
|
||||
/obj/item/ammo_casing/a45lc/rubber
|
||||
desc = "A long silver bullet... Has a rubber tip, and .45 LC stamped into the base."
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a45lc/rubber
|
||||
projectile_type = /obj/item/projectile/bullet/rifle/a45lc/rubber
|
||||
|
||||
|
||||
@@ -51,6 +51,13 @@
|
||||
required_reagents = list("cordradaxon" = 1, "gastirodaxon" = 1, "hepanephrodaxon" = 1, "respirodaxon" = 1)
|
||||
result_amount = 12 //More phoron-efficient alternative recipe.
|
||||
|
||||
/decl/chemical_reaction/instant/sorbitol
|
||||
name = "Sorbitol"
|
||||
id = "sorbitol"
|
||||
result = "sorbitol"
|
||||
required_reagents = list("unsorbitol" = 1, "phoron" = 1)
|
||||
result_amount = 2
|
||||
|
||||
///SAP RECIPES//////
|
||||
|
||||
/decl/chemical_reaction/instant/myelamine_sap //This is the clotting agent used by clotting packs.
|
||||
|
||||
@@ -53,6 +53,30 @@
|
||||
name = "vial (amorphorovir)"
|
||||
prefill = list("amorphorovir" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/androrovir
|
||||
name = "vial (androrovir)"
|
||||
prefill = list("androrovir" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/gynorovir
|
||||
name = "vial (gynorovir)"
|
||||
prefill = list("gynorovir" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/androgynorovir
|
||||
name = "vial (androgynorovir)"
|
||||
prefill = list("androgynorovir" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/macrocillin
|
||||
name = "vial (macrocillin)"
|
||||
prefill = list("macrocillin" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/microcillin
|
||||
name = "vial (microcillin)"
|
||||
prefill = list("microcillin" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/normalcillin
|
||||
name = "vial (normalcillin)"
|
||||
prefill = list("normalcillin" = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/supermatter
|
||||
name = "vial (supermatter)"
|
||||
desc = "A glass vial containing the extremely dangerous results of grinding a shard of supermatter down to a fine powder."
|
||||
|
||||
@@ -151,6 +151,8 @@
|
||||
desc = "A rapid and safe way to administer small amounts of drugs by untrained or trained personnel."
|
||||
icon_state = "blue"
|
||||
item_state = "blue"
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_EARS
|
||||
amount_per_transfer_from_this = 5
|
||||
volume = 5
|
||||
filled = 1
|
||||
|
||||
@@ -14,6 +14,32 @@
|
||||
|
||||
if(prob(3))
|
||||
M.emote(pick("blush", "moan", "moan", "giggle"))
|
||||
|
||||
/datum/reagent/sorbitol
|
||||
name = "Sorbitol"
|
||||
id = "sorbitol"
|
||||
description = "A frothy green liquid, for causing cellular-level hetrogenous structure merging."
|
||||
reagent_state = LIQUID
|
||||
color = "#10881A"
|
||||
overdose = REAGENTS_OVERDOSE
|
||||
|
||||
/datum/reagent/sorbitol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.make_dizzy(1)
|
||||
|
||||
for(var/obj/belly/B as anything in M.vore_organs)
|
||||
|
||||
if(B.digest_mode == DM_UNABSORB) //Don't affect bellies set to unabsorb
|
||||
continue
|
||||
|
||||
for(var/mob/living/P in B)
|
||||
if(P.absorbed || !P.absorbable)
|
||||
continue
|
||||
|
||||
else if(prob(10))
|
||||
B.absorb_living(P)
|
||||
if(B.reagent_mode_flags & DM_FLAG_REAGENTSABSORB && B.reagents.total_volume < B.reagents.maximum_volume) //CHOMPedit: absorption reagent production
|
||||
B.GenerateBellyReagents_absorbed()
|
||||
|
||||
|
||||
///GENDER CHANGE REAGENTS////
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
|
||||
/obj/machinery/disposal/wall/cleaner/flush()
|
||||
flick("[icon_state]-flush", src)
|
||||
for(var/obj/item/weapon/storage/i in src)
|
||||
if(istype(i, /obj/item/weapon/storage))
|
||||
var/list/storage_items = i.return_inv()
|
||||
|
||||
for(var/obj/item/item in storage_items)
|
||||
item.decontaminate()
|
||||
|
||||
for(var/obj/item/i in src)
|
||||
if(istype(i, /obj/item))
|
||||
i.decontaminate()
|
||||
|
||||
@@ -33,7 +33,7 @@ If the spell_projectile is seeking, it will update its target every process and
|
||||
if(istype(projectile, /obj/item/projectile/spell_projectile))
|
||||
var/obj/item/projectile/spell_projectile/SP = projectile
|
||||
SP.carried = src //casting is magical
|
||||
projectile.def_zone = check_zone("chest")
|
||||
projectile.def_zone = check_zone(BP_TORSO)
|
||||
projectile.old_style_target(target)
|
||||
projectile.fire()
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/proc/consonant()
|
||||
return pick("B","C","D","F","G","H","J","K","L","M","N","P","Q","R","S","T","V","W","X","Y","Z")
|
||||
|
||||
/proc/vowel()
|
||||
return pick("A", "E", "I", "O", "U")
|
||||
|
||||
/proc/ucfirst(var/S)
|
||||
return "[uppertext(ascii2text(text2ascii(S, 1)))][copytext(S, 2)]"
|
||||
|
||||
/proc/ucfirsts(var/S)
|
||||
var/list/L = splittext(S, " ")
|
||||
var/list/M = list()
|
||||
for (var/P in L)
|
||||
M += ucfirst(P)
|
||||
return jointext(M, " ")
|
||||
|
||||
GLOBAL_LIST_EMPTY(FrozenAccounts)
|
||||
|
||||
/proc/list_frozen()
|
||||
for (var/A in GLOB.FrozenAccounts)
|
||||
to_chat(usr, "[A]: [length(GLOB.FrozenAccounts[A])] borrows")
|
||||
|
||||
/datum/article
|
||||
var/headline = "Something big is happening"
|
||||
var/subtitle = "Investors panic as stock market collapses"
|
||||
var/article = "God, it's going to be fun to randomly generate this."
|
||||
var/author = "P. Pubbie"
|
||||
var/spacetime = ""
|
||||
var/opinion = 0
|
||||
var/ticks = 0
|
||||
var/datum/stock/about = null
|
||||
var/outlet = ""
|
||||
var/static/list/outlets = list()
|
||||
var/static/list/default_tokens = list( \
|
||||
"buy" = list("buy!", "buy, buy, buy!", "get in now!", "ride the share value to the stars!"), \
|
||||
"company" = list("company", "corporation", "conglomerate", "enterprise", "venture"), \
|
||||
"complete" = list("complete", "total", "absolute", "incredible"), \
|
||||
"country" = list("Space", "Argentina", "Hungary", "United States of America", "United Space", "Space Federation", "Nanotrasen", "The Wizard Federation", "United Kingdom", "Poland", "The Syndicate", "Australia", "Serbia", "The European Union", "The Illuminati", "The New World Order", "Eurasian Union", "Asian Union", "United Arab Emirates", "Arabian League", "United States of Africa", "Mars Federation", "Allied Colonies of Jupiter", "Saturn's Ring", "Fringe Republic of Formerly Planet Pluto"), \
|
||||
"development" = list("development", "unfolding of events", "turn of events", "new shit"), \
|
||||
"dip" = list("dip", "fall", "plunge", "decrease"), \
|
||||
"excited" = list("excited", "euphoric", "exhilarated", "thrilled", "stimulated"), \
|
||||
"expand_influence" = list("expands their influence over", "continues to dominate", "gains traction in", "rolls their new product line out in"), \
|
||||
"failure" = list("failure", "meltdown", "breakdown", "crash", "defeat", "wreck"), \
|
||||
"famous" = list("famous", "prominent", "leading", "renowned", "expert"), \
|
||||
"hit_shelves" = list("hit the shelves", "appeared on the market", "came out", "was released"), \
|
||||
"industry" = list("industry", "sector"), \
|
||||
"industrial" = list("industrial"), \
|
||||
"jobs" = list("workers"), \
|
||||
"negative_outcome" = list("it's not leaving the shelves", "nobody seems to care", "it's a huge money sink", "they have already pulled all advertising and marketing support"), \
|
||||
"neutral_outcome" = list("it's not lifting off as expected", "it's not selling according to expectations", "it's only generating enough profit to cover the marketing and manufacturing costs", "it does not look like it will become a massive success", "it's experiencing modest sales"), \
|
||||
"positive_outcome" = list("it's already sold out", "it has already sold over one billion units", "suppliers cannot keep up with the wild demand", "several companies using this new technology are already reporting a projected increase in profits"), \
|
||||
"resounding" = list("resounding", "tremendous", "total", "massive", "terrific", "colossal"), \
|
||||
"rise" = list("rise", "increase", "fly off the positive side of the charts", "skyrocket", "lift off"), \
|
||||
"sell" = list("sell!", "sell, sell, sell!", "bail!", "abandon ship!", "get out before it's too late!", "evacuate!", "withdraw!"), \
|
||||
"signifying" = list("signifying", "indicating", "implying", "displaying", "suggesting"), \
|
||||
"sneak_peek" = list("review", "sneak peek", "preview", "exclusive look"), \
|
||||
"stock_market" = list("stock market", "stock exchange"), \
|
||||
"stockholder" = list("stockholder", "shareholder"), \
|
||||
"success" = list("success", "triumph", "victory"), \
|
||||
"this_time" = list("this week", "last week", "this month", "yesterday", "today", "a few days ago") \
|
||||
)
|
||||
|
||||
/datum/article/New()
|
||||
..()
|
||||
if ((outlets.len && !prob(100 / (outlets.len + 1))) || !outlets.len)
|
||||
var/ON = generateOutletName()
|
||||
if (!(ON in outlets))
|
||||
outlets[ON] = list()
|
||||
outlet = ON
|
||||
else
|
||||
outlet = pick(outlets)
|
||||
|
||||
var/list/authors = outlets[outlet]
|
||||
if ((authors.len && !prob(100 / (authors.len + 1))) || !authors.len)
|
||||
var/AN = generateAuthorName()
|
||||
outlets[outlet] += AN
|
||||
author = AN
|
||||
else
|
||||
author = pick(authors)
|
||||
|
||||
ticks = world.time
|
||||
|
||||
/datum/article/proc/generateOutletName()
|
||||
var/list/locations = list("Earth", "Luna", "Mars", "Saturn", "Jupiter", "Uranus", "Pluto", "Europa", "Io", "Phobos", "Deimos", "Space", "Venus", "Neptune", "Mercury", "Kalliope", "Ganymede", "Callisto", "Amalthea", "Himalia", "Orion", "Sybil", "Basil", "Badger", "Terry", "Artyom")
|
||||
var/list/nouns = list("Post", "Herald", "Sun", "Tribune", "Mail", "Times", "Journal", "Report")
|
||||
var/list/timely = list("Daily", "Hourly", "Weekly", "Biweekly", "Monthly", "Yearly")
|
||||
|
||||
switch(rand(1,2))
|
||||
if (1)
|
||||
return "The [pick(locations)] [pick(nouns)]"
|
||||
if (2)
|
||||
return "The [pick(timely)] [pick(nouns)]"
|
||||
|
||||
/datum/article/proc/generateAuthorName()
|
||||
switch(rand(1,3))
|
||||
if (1)
|
||||
return "[consonant()]. [pick(last_names)]"
|
||||
if (2)
|
||||
return "[prob(50) ? pick(first_names_male) : pick(first_names_female)] [consonant()].[prob(50) ? "[consonant()]. " : null] [pick(last_names)]"
|
||||
if (3)
|
||||
return "[prob(50) ? pick(first_names_male) : pick(first_names_female)] \"[prob(50) ? pick(first_names_male) : pick(first_names_female)]\" [pick(last_names)]"
|
||||
|
||||
/datum/article/proc/formatSpacetime()
|
||||
var/ticksc = round(ticks/100)
|
||||
ticksc = ticksc % 100000
|
||||
var/ticksp = "[ticksc]"
|
||||
while (length(ticksp) < 5)
|
||||
ticksp = "0[ticksp]"
|
||||
spacetime = "[ticksp][time2text(world.realtime, "MM")][time2text(world.realtime, "DD")][text2num(time2text(world.realtime, "YYYY"))+540]"
|
||||
|
||||
/datum/article/proc/formatArticle()
|
||||
if (spacetime == "")
|
||||
formatSpacetime()
|
||||
var/output = "<div class='article'><div class='headline'>[headline]</div><div class='subtitle'>[subtitle]</div><div class='article-body'>[article]</div><div class='author'>[author]</div><div class='timestamp'>[spacetime]</div></div>"
|
||||
return output
|
||||
|
||||
/datum/article/proc/detokenize(var/token_string, var/list/industry_tokens, var/list/product_tokens = list())
|
||||
var/list/T_list = default_tokens.Copy()
|
||||
for (var/I in industry_tokens)
|
||||
T_list[I] = industry_tokens[I]
|
||||
for (var/I in product_tokens)
|
||||
T_list[I] = list(product_tokens[I])
|
||||
for (var/I in T_list)
|
||||
token_string = replacetext(token_string, "%[I]%", pick(T_list[I]))
|
||||
return ucfirst(token_string)
|
||||
@@ -0,0 +1,336 @@
|
||||
/obj/machinery/computer/stockexchange
|
||||
name = "stock exchange computer"
|
||||
desc = "A console that connects to the galactic stock market. Stocks trading involves substantial risk of loss and is not suitable for every cargo technician."
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_state = "stockmarket"
|
||||
icon_screen = "stocks"
|
||||
icon_keyboard = "stockmarket_key"
|
||||
var/logged_in = "Cargo Department"
|
||||
var/vmode = 1
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
|
||||
/obj/machinery/computer/stockexchange/Initialize()
|
||||
. = ..()
|
||||
logged_in = "Cargo Department"
|
||||
|
||||
/obj/machinery/computer/stockexchange/attack_hand(mob/user)
|
||||
if(..(user))
|
||||
return
|
||||
|
||||
//if(!ai_control && issilicon(user))
|
||||
// to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
// return TRUE
|
||||
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/balance()
|
||||
if (!logged_in)
|
||||
return 0
|
||||
return SSsupply.points
|
||||
|
||||
///// MAIN TGUI SCREEN /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/tgui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
switch(action)
|
||||
if ("logout")
|
||||
logged_in = null
|
||||
|
||||
if("stocks_buy")
|
||||
var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks
|
||||
if (S)
|
||||
buy_some_shares(S, usr)
|
||||
|
||||
if("stocks_sell")
|
||||
var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks
|
||||
if (S)
|
||||
sell_some_shares(S, usr)
|
||||
|
||||
if("stocks_check")
|
||||
var/dat = "<html><head><title>Stock Transaction Logs</title></head><body><h2>Stock Transaction Logs</h2><div><a href='?src=[REF(src)];show_logs=1'>Refresh</a></div></br>"
|
||||
for(var/D in GLOB.stockExchange.logs)
|
||||
var/datum/stock_log/L = D
|
||||
if(istype(L, /datum/stock_log/buy))
|
||||
dat += "[L.time] | <b>[L.user_name]</b> bought <b>[L.stocks]</b> stocks at [L.shareprice] a share for <b>[L.money]</b> total credits in <b>[L.company_name]</b>.</br>"
|
||||
continue
|
||||
if(istype(L, /datum/stock_log/sell))
|
||||
dat += "[L.time] | <b>[L.user_name]</b> sold <b>[L.stocks]</b> stocks at [L.shareprice] a share for <b>[L.money]</b> total credits from <b>[L.company_name]</b>.</br>"
|
||||
continue
|
||||
if(istype(L, /datum/stock_log/borrow))
|
||||
dat += "[L.time] | <b>[L.user_name]</b> borrowed <b>[L.stocks]</b> stocks with a deposit of <b>[L.money]</b> credits in <b>[L.company_name]</b>.</br>"
|
||||
continue
|
||||
var/datum/browser/popup = new(usr, "stock_logs", "Stock Transaction Logs", 600, 400)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
if("stocks_archive")
|
||||
var/datum/stock/S = locate(params["share"])
|
||||
if (logged_in && logged_in != "")
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
LR[logged_in] = world.time
|
||||
var/dat = "<html><head><title>News feed for [S.name]</title></head><body><h2>News feed for [S.name]</h2><div><a href='?src=[REF(src)];archive=[REF(S)]'>Refresh</a></div>"
|
||||
dat += "<div><h3>Events</h3>"
|
||||
var/p = 0
|
||||
for (var/datum/stockEvent/E in S.events)
|
||||
if (E.hidden)
|
||||
continue
|
||||
if (p > 0)
|
||||
dat += "<hr>"
|
||||
dat += "<div><b>[E.current_title]</b></br>[E.current_desc]</div>"
|
||||
p++
|
||||
dat += "</div><hr><div><h3>Articles</h3>"
|
||||
p = 0
|
||||
for (var/datum/article/A in S.articles)
|
||||
if (p > 0)
|
||||
dat += "<hr>"
|
||||
dat += "<div><b>[A.headline]</b><br><i>[A.subtitle]</i><br><br>[A.article]<br>- [A.author], [A.spacetime] (via <i>[A.outlet]</i>)</div>"
|
||||
p++
|
||||
dat += "</div></body></html>"
|
||||
var/datum/browser/popup = new(usr, "archive_[S.name]", "Stock News", 600, 400)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
if("stocks_history")
|
||||
var/datum/stock/S = locate(params["share"]) in GLOB.stockExchange.stocks
|
||||
if (S)
|
||||
S.displayValues(usr)
|
||||
|
||||
if("stocks_cycle_view")
|
||||
vmode++
|
||||
if (vmode > 1)
|
||||
vmode = 0
|
||||
|
||||
/obj/machinery/computer/stockexchange/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["stationName"] = using_map.station_name
|
||||
data["balance"] = balance()
|
||||
|
||||
if (vmode)
|
||||
data["viewMode"] = "Full"
|
||||
else
|
||||
data["viewMode"] = "Compressed"
|
||||
|
||||
for (var/datum/stock/S in GLOB.stockExchange.last_read)
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
if (!(logged_in in LR))
|
||||
LR[logged_in] = 0
|
||||
|
||||
data["stocks"] = list()
|
||||
|
||||
if (vmode)
|
||||
for (var/datum/stock/S in GLOB.stockExchange.stocks)
|
||||
var/mystocks = 0
|
||||
if (logged_in && (logged_in in S.shareholders))
|
||||
mystocks = S.shareholders[logged_in]
|
||||
|
||||
var/value = 0
|
||||
if (!S.bankrupt)
|
||||
value = S.current_value
|
||||
|
||||
data["stocks"] += list(list(
|
||||
"REF" = REF(S),
|
||||
"valueChange" = S.disp_value_change, // > 0 is +, < 0 is -, else its =
|
||||
"bankrupt" = S.bankrupt,
|
||||
"ID" = S.short_name,
|
||||
"Name" = S.name,
|
||||
"Value" = value,
|
||||
"Owned" = mystocks,
|
||||
"Avail" = S.available_shares,
|
||||
"Products" = S.products,
|
||||
))
|
||||
|
||||
var/news = 0
|
||||
if (logged_in)
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
var/lrt = LR[logged_in]
|
||||
for (var/datum/article/A in S.articles)
|
||||
if (A.ticks > lrt)
|
||||
news = 1
|
||||
break
|
||||
if (!news)
|
||||
for (var/datum/stockEvent/E in S.events)
|
||||
if (E.last_change > lrt && !E.hidden)
|
||||
news = 1
|
||||
else
|
||||
for (var/datum/stock/S in GLOB.stockExchange.stocks)
|
||||
var/mystocks = 0
|
||||
if (logged_in && (logged_in in S.shareholders))
|
||||
mystocks = S.shareholders[logged_in]
|
||||
|
||||
var/unification = 0
|
||||
if (S.last_unification)
|
||||
unification = DisplayTimeText(world.time - S.last_unification)
|
||||
|
||||
data["stocks"] += list(list(
|
||||
"REF" = REF(S),
|
||||
"bankrupt" = S.bankrupt,
|
||||
"ID" = S.short_name,
|
||||
"Name" = S.name,
|
||||
"Owned" = mystocks,
|
||||
"Avail" = S.available_shares,
|
||||
"Unification" = unification,
|
||||
"Products" = S.products,
|
||||
))
|
||||
|
||||
var/news = 0
|
||||
if (logged_in)
|
||||
var/list/LR = GLOB.stockExchange.last_read[S]
|
||||
var/lrt = LR[logged_in]
|
||||
for (var/datum/article/A in S.articles)
|
||||
if (A.ticks > lrt)
|
||||
news = 1
|
||||
break
|
||||
if (!news)
|
||||
for (var/datum/stockEvent/E in S.events)
|
||||
if (E.last_change > lrt && !E.hidden)
|
||||
news = 1
|
||||
break
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/stockexchange/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StockExchange")
|
||||
ui.open()
|
||||
|
||||
///// HISTORY SCREEN /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/history/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StockExchangeHistory")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/stockexchange/history/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
//data["var"] = var
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/stockexchange/history/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("copypasta")
|
||||
//var/newvar = params["var"]
|
||||
// A demo of proper input sanitation.
|
||||
//var = CLAMP(newvar, min_val, max_val)
|
||||
. = TRUE
|
||||
|
||||
///// ARCHIVE SCREEN /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/archive/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StockExchangeArchive")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/stockexchange/archive/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
//data["var"] = var
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/stockexchange/archive/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("copypasta")
|
||||
//var/newvar = params["var"]
|
||||
// A demo of proper input sanitation.
|
||||
//var = CLAMP(newvar, min_val, max_val)
|
||||
. = TRUE
|
||||
|
||||
///// PROCS /////
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/sell_some_shares(var/datum/stock/S, var/mob/user)
|
||||
if (!user || !S)
|
||||
return
|
||||
var/li = logged_in
|
||||
if (!li)
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
var/b = SSsupply.points
|
||||
var/avail = S.shareholders[logged_in]
|
||||
if (!avail)
|
||||
to_chat(user, "<span class='danger'>This account does not own any shares of [S.name]!</span>")
|
||||
return
|
||||
var/price = S.current_value
|
||||
var/amt = round(input(user, "How many shares? \n(Have: [avail], unit price: [price])", "Sell shares in [S.name]", 0) as num|null)
|
||||
amt = min(amt, S.shareholders[logged_in])
|
||||
|
||||
if (!user || (!(user in range(1, src)) && iscarbon(user)))
|
||||
return
|
||||
if (!amt)
|
||||
return
|
||||
if (li != logged_in)
|
||||
return
|
||||
b = SSsupply.points
|
||||
if (!isnum(b))
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
|
||||
var/total = amt * S.current_value
|
||||
if (!S.sellShares(logged_in, amt))
|
||||
to_chat(user, "<span class='danger'>Could not complete transaction.</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>Sold [amt] shares of [S.name] at [S.current_value] a share for [total] credits.</span>")
|
||||
GLOB.stockExchange.add_log(/datum/stock_log/sell, user.name, S.name, amt, S.current_value, total)
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/buy_some_shares(var/datum/stock/S, var/mob/user)
|
||||
if (!user || !S)
|
||||
return
|
||||
var/li = logged_in
|
||||
if (!li)
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
var/b = balance()
|
||||
if (!isnum(b))
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
var/avail = S.available_shares
|
||||
var/price = S.current_value
|
||||
var/canbuy = round(b / price)
|
||||
var/amt = round(input(user, "How many shares? \n(Available: [avail], unit price: [price], can buy: [canbuy])", "Buy shares in [S.name]", 0) as num|null)
|
||||
if (!user || (!(user in range(1, src)) && iscarbon(user)))
|
||||
return
|
||||
if (li != logged_in)
|
||||
return
|
||||
b = balance()
|
||||
if (!isnum(b))
|
||||
to_chat(user, "<span class='danger'>No active account on the console!</span>")
|
||||
return
|
||||
|
||||
amt = min(amt, S.available_shares, round(b / S.current_value))
|
||||
if (!amt)
|
||||
return
|
||||
if (!S.buyShares(logged_in, amt))
|
||||
to_chat(user, "<span class='danger'>Could not complete transaction.</span>")
|
||||
return
|
||||
|
||||
var/total = amt * S.current_value
|
||||
to_chat(user, "<span class='notice'>Bought [amt] shares of [S.name] at [S.current_value] a share for [total] credits.</span>")
|
||||
GLOB.stockExchange.add_log(/datum/stock_log/buy, user.name, S.name, amt, S.current_value, total)
|
||||
|
||||
/obj/machinery/computer/stockexchange/proc/do_borrowing_deal(var/datum/borrow/B, var/mob/user)
|
||||
if (B.stock.borrow(B, logged_in))
|
||||
to_chat(user, "<span class='notice'>You successfully borrowed [B.share_amount] shares. Deposit: [B.deposit].</span>")
|
||||
GLOB.stockExchange.add_log(/datum/stock_log/borrow, user.name, B.stock.name, B.share_amount, B.deposit)
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Could not complete transaction. Check your account balance.</span>")
|
||||
|
||||
/obj/machinery/computer/stockexchange/Topic(href, href_list)
|
||||
if (..())
|
||||
return 1
|
||||
|
||||
if (!usr || (!(usr in range(1, src)) && iscarbon(usr)))
|
||||
usr.machine = src
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
src.updateUsrDialog()
|
||||
@@ -0,0 +1,233 @@
|
||||
#define TIME_MULTIPLIER 0.7 // so I can speed up/slow down shit
|
||||
|
||||
/datum/stockEvent
|
||||
var/name = "event"
|
||||
var/next_phase = 0
|
||||
var/datum/stock/company = null
|
||||
var/current_title = "A company holding a pangalactic conference in the Seattle Conference Center, Seattle, Earth"
|
||||
var/current_desc = "We will continue to monitor their stocks as the situation unfolds."
|
||||
var/phase_id = 0
|
||||
var/hidden = 0
|
||||
var/finished = 0
|
||||
var/last_change = 0
|
||||
|
||||
/datum/stockEvent/process()
|
||||
if (finished)
|
||||
return
|
||||
if (world.time > next_phase)
|
||||
transition()
|
||||
|
||||
/datum/stockEvent/proc/transition()
|
||||
return
|
||||
|
||||
/datum/stockEvent/proc/spacetime(var/ticks)
|
||||
var/seconds = round(ticks / 10)
|
||||
var/minutes = round(seconds / 60)
|
||||
seconds -= minutes * 60
|
||||
return "[minutes] minute(s) and [seconds] second(s)"
|
||||
|
||||
/datum/stockEvent/product
|
||||
name = "product"
|
||||
var/product_name = ""
|
||||
var/datum/article/product_article = null
|
||||
var/effect = 0
|
||||
|
||||
/datum/stockEvent/product/New(var/datum/stock/S)
|
||||
company = S
|
||||
var/mins = rand(5*TIME_MULTIPLIER,20*TIME_MULTIPLIER)
|
||||
next_phase = mins * (600*TIME_MULTIPLIER) + world.time
|
||||
current_title = "Product demo"
|
||||
current_desc = S.industry.detokenize("[S.name] will unveil a new product on an upcoming %industrial% conference held at spacetime [spacetime(next_phase)]")
|
||||
S.addEvent(src)
|
||||
|
||||
|
||||
/datum/stockEvent/product/transition()
|
||||
last_change = world.time
|
||||
switch (phase_id)
|
||||
if (0)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
product_name = company.industry.generateProductName(company.name)
|
||||
current_title = "Product release: [product_name]"
|
||||
current_desc = "[company.name] unveiled their newest product at a conference, [product_name]Product release is expected to happen at spacetime [spacetime(next_phase)]."
|
||||
var/datum/article/A = company.industry.generateInCharacterProductArticle(product_name, company)
|
||||
product_article = A
|
||||
effect = A.opinion + rand(-1, 1)
|
||||
company.affectPublicOpinion(effect)
|
||||
phase_id = 1
|
||||
if (1)
|
||||
finished = 1
|
||||
hidden = 1
|
||||
company.addArticle(product_article)
|
||||
effect += product_article.opinion * 5
|
||||
company.affectPublicOpinion(effect)
|
||||
phase_id = 2
|
||||
company.generateEvent(type)
|
||||
|
||||
/datum/stockEvent/bankruptcy
|
||||
name = "bankruptcy"
|
||||
var/effect = 0
|
||||
var/bailout_millions = 0
|
||||
|
||||
/datum/stockEvent/bankruptcy/New(var/datum/stock/S)
|
||||
hidden = 1
|
||||
company = S
|
||||
var/mins = rand(9*TIME_MULTIPLIER,60*TIME_MULTIPLIER)
|
||||
bailout_millions = rand(70, 190)
|
||||
next_phase = mins * 300*TIME_MULTIPLIER + world.time
|
||||
current_title = ""
|
||||
current_desc = ""
|
||||
S.addEvent(src)
|
||||
|
||||
/datum/stockEvent/bankruptcy/transition()
|
||||
switch (phase_id)
|
||||
if (0)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
var/datum/article/A = generateBankruptcyArticle()
|
||||
if (!A.opinion)
|
||||
effect = rand(5) * (prob(50) ? -1 : 1)
|
||||
else
|
||||
effect = prob(25) ? -A.opinion * rand(8) : A.opinion * rand(4)
|
||||
company.addArticle(A)
|
||||
company.affectPublicOpinion(rand(-6, -3))
|
||||
hidden = 0
|
||||
current_title = "Bailout pending due to bankruptcy"
|
||||
current_desc = "The government prepared a press release, which will occur at spacetime [spacetime(next_phase)]."
|
||||
phase_id = 1
|
||||
if (1)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
finished = 1
|
||||
if (effect <= -5 && prob(10))
|
||||
current_title = "[company.name]: Complete crash"
|
||||
current_desc = "The company had gone bankrupt, was not bailed out and could not recover. No further stock trade will take place. All shares in the company are effectively worthless."
|
||||
company.bankrupt = 1
|
||||
for (var/X in company.shareholders)
|
||||
var/amt = company.shareholders[X]
|
||||
GLOB.stockExchange.balanceLog(X, -amt * company.current_value)
|
||||
company.shareholders = list()
|
||||
company.current_value = 0
|
||||
company.borrow_brokers = list()
|
||||
GLOB.stockExchange.generateStocks(1)
|
||||
|
||||
var/bailout = (effect > 0 && prob(80)) || (effect < 0 && prob(20))
|
||||
current_title = "[company.name] [bailout ? "bailed out" : "on a painful rebound"]"
|
||||
if (bailout)
|
||||
current_desc = "The company has been bailed out by the government. Investors are highly optimistic."
|
||||
company.affectPublicOpinion(abs(effect) * 2)
|
||||
else
|
||||
current_desc = "The company was not bailed out, but managed to crawl out of bankruptcy. Stockholder trust is severely dented."
|
||||
company.affectPublicOpinion(-abs(effect) / 2)
|
||||
company.generateEvent(type)
|
||||
|
||||
/datum/stockEvent/bankruptcy/proc/generateBankruptcyArticle()
|
||||
var/datum/article/A = new
|
||||
var/list/bankrupt_reason = list("investor pessimism", "failure of product lines", "economic recession", "overblown inflation", "overblown deflation", "collapsed pyramid schemes", "a Ponzi scheme", "economic terrorism", "extreme hedonism", "unfavourable economic climate", "rampant government corruption", "divine conspiracy", "some total bullshit", "volatile plans")
|
||||
A.about = company
|
||||
A.headline = pick( "[company.name] filing for bankruptcy", \
|
||||
"[company.name] unable to pay, investors run", \
|
||||
"[company.name] crashes, in foreclosure", \
|
||||
"[company.name] in dire need of credits")
|
||||
A.subtitle = "Investors panic, bailout pending"
|
||||
if (prob(15))
|
||||
A.opinion = rand(-1, 1)
|
||||
var/article = "Another one might bite the dust: [company.current_trend > 0 ? "despite their positive trend" : "in line with their failing model"], [company.name] files for bankruptcy citing [pick(bankrupt_reason)]. The president of %country% has been asked to bail the company out, "
|
||||
if (!A.opinion)
|
||||
article += "but no answer has been given by the government to date. Our tip to stay safe is: %sell%"
|
||||
else if (A.opinion > 0)
|
||||
article += "and the government responded positively. When the share value hits its lowest, it is a safe bet to %buy%"
|
||||
else
|
||||
article += "but the outlook is not good. For investors, now would be an ideal time to %sell%"
|
||||
A.article = A.detokenize(article, company.industry.tokens)
|
||||
return A
|
||||
|
||||
/datum/stockEvent/arrest
|
||||
name = "arrest"
|
||||
var/female = 0
|
||||
var/tname = "Elvis Presley"
|
||||
var/position = "CEO"
|
||||
var/offenses = "murder"
|
||||
var/effect = 0
|
||||
|
||||
/datum/stockEvent/arrest/New(var/datum/stock/S)
|
||||
hidden = 1
|
||||
company = S
|
||||
var/mins = rand(10*TIME_MULTIPLIER, 35*TIME_MULTIPLIER)
|
||||
next_phase = mins * 600*TIME_MULTIPLIER + world.time
|
||||
current_title = ""
|
||||
current_desc = ""
|
||||
female = prob(50)
|
||||
if (prob(50))
|
||||
position = "C[prob(20) ? vowel() : consonant()]O"
|
||||
else
|
||||
position = ucfirsts(company.industry.detokenize("Lead %industrial% Engineer"))
|
||||
offenses = ""
|
||||
var/list/O = list("corruption", "murder", "grand theft", "assault", "battery", "drug possession", "burglary", "theft", "grand sabotage", "bribery",
|
||||
"disorderly conduct", "treason", "sedition", "shoplifting", "tax evasion", "tax fraud", "insurance fraud", "perjury", "kidnapping", "manslaughter", "vandalism", "forgery", "extortion", "embezzlement",
|
||||
"public indecency", "public intoxication", "trespassing", "loitering", "littering", "vigilantism", "squatting", "panhandling", "arson", "spacepodjacking", "shuttlejacking", "carjacking", "singularityjacking",
|
||||
"dereliction of duty", "spacecraft piracy", "music piracy", "tabletop game piracy", "software piracy", "escaping from space prison", "seniornapping", "clownnapping", "corginapping", "catnapping",
|
||||
"sleeping on the job", "terrorism", "counterterrorism", "drug distribution", "insubordination", "jaywalking", "owning a computer", "owning a cellphone", "owning a PDA", "owning a pAI", "adultery",
|
||||
"committing an unnatural act with another person", "corrupting public morals", "skateboarding without a license", "shitcurity", "bestiality", "erotic roleplay", "accidentally strangling a prostitute")
|
||||
while (prob(60) && O.len > 2)
|
||||
var/offense = pick(O)
|
||||
O -= offense
|
||||
offense = "[prob(20) ? "attempted " : (prob(20) ? "being accessory to " : null)][offense][prob(5) ? " of the [pick("first", "second", "third", "fourth", "fifth", "sixth")] degree" : null]"
|
||||
if (offenses == "")
|
||||
offenses = offense
|
||||
else
|
||||
offenses += ", [offense]"
|
||||
offenses += " and [prob(20) ? "attempted " : null][pick(O)]" // lazy
|
||||
S.addEvent(src)
|
||||
|
||||
/datum/stockEvent/arrest/transition()
|
||||
switch (phase_id)
|
||||
if (0)
|
||||
var/name_part1
|
||||
var/name_part2
|
||||
|
||||
name_part1 = pick("John ", "Jack ", "Jill ", "Peter ", "James ", "Lois ", "Zoey ")
|
||||
name_part2 = pick("Bull", "Palmer", "Glass", "Ruin", "McCory", "Batty", "Lane")
|
||||
tname = (name_part1 + name_part2)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
var/datum/article/A = generateArrestArticle()
|
||||
if (!A.opinion)
|
||||
effect = rand(5) * (prob(50) ? -1 : 1)
|
||||
else
|
||||
effect = prob(25) ? -A.opinion * rand(5) : A.opinion * rand(3)
|
||||
company.addArticle(A)
|
||||
company.affectPublicOpinion(rand(-3, -1))
|
||||
hidden = 0
|
||||
current_title = "Trial of [tname] ([position]) scheduled"
|
||||
current_desc = "[female ? "She": "He"] has been charged with [offenses]; the trial is scheduled to occur at spacetime [spacetime(next_phase)]."
|
||||
phase_id = 1
|
||||
if (1)
|
||||
next_phase = world.time + rand(300*TIME_MULTIPLIER, 600*TIME_MULTIPLIER) * (10*TIME_MULTIPLIER)
|
||||
finished = 1
|
||||
current_title = "[tname] [effect > 0 ? "acquitted" : "found guilty"]"
|
||||
if (effect > 0)
|
||||
current_desc = "The accused has been acquitted of all charges. Investors optimistic."
|
||||
else
|
||||
current_desc = "The accused has been found guilty of all charges. Investor trust takes massive hit."
|
||||
company.affectPublicOpinion(effect)
|
||||
company.generateEvent(type)
|
||||
|
||||
/datum/stockEvent/arrest/proc/generateArrestArticle()
|
||||
var/datum/article/A = new
|
||||
A.about = company
|
||||
A.headline = company.industry.detokenize(pick( \
|
||||
"[tname], [position] of [company.name] arrested", \
|
||||
"[position] of [company.name] facing jail time", \
|
||||
"[tname] behind bars", \
|
||||
"[position] of %industrial% company before trial", \
|
||||
"Police arrest [tname] in daring raid", \
|
||||
"Job vacancy ahead: [company.name]'s [position] in serious trouble"))
|
||||
A.subtitle = "[A.author] reporting directly from the courtroom"
|
||||
if (prob(15))
|
||||
A.opinion = rand(-1, 1)
|
||||
var/article = "[pick("Security", "Law enforcement")] forces issued a statement that [tname], the [position] of [company.name], the %famous% %industrial% %company% was arrested %this_time%. The trial has been scheduled and the statement reports that the arrested individual is being charged with [offenses]. "
|
||||
if (!A.opinion)
|
||||
article += "While we cannot predict the outcome of this trial, our tip to stay safe is: %sell%"
|
||||
else if (A.opinion > 0)
|
||||
article += "Our own investigation shows that these charges are baseless and the arrest is most likely a publicity stunt. Our advice? You should %buy%"
|
||||
else
|
||||
article += "[tname] has a prior history of similar misdeeds and we're confident the charges will stand. For investors, now would be an ideal time to %sell%"
|
||||
A.article = A.detokenize(article, company.industry.tokens)
|
||||
return A
|
||||
@@ -0,0 +1,233 @@
|
||||
/datum/industry
|
||||
var/name = "Industry"
|
||||
var/list/tokens = list()
|
||||
|
||||
var/list/title_templates = list("The brand new %product_name% by %company_name% will revolutionize %industry%", \
|
||||
"%jobs% rejoice as %product_name% hits shelves", \
|
||||
"Does %product_name% threaten to reorganize the %industrial% status quo?", \
|
||||
"%company_name% headed toward corporate renaissance with %product_name%")
|
||||
|
||||
var/list/title_templates_neutral = list("%product_name%: as if nothing happened", \
|
||||
"Nothing new but the name: %product_name% not quite exciting %jobs%", \
|
||||
"Same old %company_name%, same old product", \
|
||||
"%product_name% underwhelms, but sells")
|
||||
|
||||
var/list/title_templates_bad = list("%product_name% shaping up to be the disappointment of the century", \
|
||||
"Recipe for disaster: %company_name% releases %product_name%", \
|
||||
"Atrocious quality - %jobs% boycott %product_name%", \
|
||||
"%product_name%: Inside the worst product launch in recent history")
|
||||
|
||||
var/list/title_templates_ooc = list("%company_name% is looking to enter the %industry% playing field with %product_name%", \
|
||||
"%company_name% broadens spectrum, %product_name% is their latest and greatest")
|
||||
var/list/subtitle_templates = list( "%author% investigates whether or not you should invest!", \
|
||||
"%outlet%'s very own %author% takes it to the magnifying glass", \
|
||||
"%outlet% lets you know if you should use it", \
|
||||
"Read our top tips for investors", \
|
||||
"%author% wants you to know if it's a safe bet to buy")
|
||||
|
||||
/datum/industry/proc/generateProductName(var/company_name)
|
||||
return
|
||||
|
||||
/datum/industry/proc/generateInCharacterProductArticle(var/product_name, var/datum/stock/S)
|
||||
var/datum/article/A = new
|
||||
var/list/add_tokens = list("company_name" = S.name, "product_name" = product_name, "outlet" = A.outlet, "author" = A.author)
|
||||
A.about = S
|
||||
A.opinion = rand(-1, 1)
|
||||
|
||||
A.subtitle = A.detokenize(pick(subtitle_templates), tokens, add_tokens)
|
||||
var/article = {"%company_name% %expand_influence% %industry%. [ucfirst(product_name)] %hit_shelves% %this_time% "}
|
||||
if (A.opinion > 0)
|
||||
A.headline = A.detokenize(pick(title_templates), tokens, add_tokens)
|
||||
article += "but %positive_outcome%, %signifying% the %resounding% %success% the product is. The %stock_market% is %excited% over this %development%, and %stockholder% optimism is expected to %rise% as well as the stock value. Our advice: %buy%."
|
||||
else if (A.opinion == 0)
|
||||
A.headline = A.detokenize(pick(title_templates_neutral), tokens, add_tokens)
|
||||
article += "but %neutral_outcome%. For the average %stockholder%, no significant change on the market will be apparent over this %development%. Our advice is to continue investing as if this product was never released."
|
||||
else
|
||||
A.headline = A.detokenize(pick(title_templates_bad), tokens, add_tokens)
|
||||
article += "but %negative_outcome%. Following this %complete% %failure%, %stockholder% optimism and stock value are projected to %dip%. Our advice: %sell%."
|
||||
A.article = A.detokenize(article, tokens, add_tokens)
|
||||
return A
|
||||
|
||||
/datum/industry/proc/detokenize(var/str)
|
||||
for (var/T in tokens)
|
||||
str = replacetext(str, "%[T]%", pick(tokens[T]))
|
||||
return str
|
||||
|
||||
/datum/industry/agriculture
|
||||
name = "Agriculture"
|
||||
tokens = list( \
|
||||
"industry" = list("agriculture", "farming", "botany", "horticulture", "hydroponics"), \
|
||||
"industrial" = list("agricultural", "horticultural", "botanical"), \
|
||||
"jobs" = list("farmers", "agricultural experts", "botanists", "assistant gardeners")
|
||||
)
|
||||
title_templates = list( "The brand new %product_name% by %company_name% will revolutionize %industry%", \
|
||||
"%jobs% rejoice as %product_name% hits shelves", \
|
||||
"Does %product name% threaten to reorganize the %industrial% status quo?", \
|
||||
"Took it for a field trip: our first %sneak_peek% of %product_name%.", \
|
||||
"Reaping the fruits of %product_name% - %sneak_peek% by %author%", \
|
||||
"Cultivating a new %industrial% future with %product_name%", \
|
||||
"%company_name% grows and thrives: %product_name% now on the farmer's market", \
|
||||
"It's almost harvest season: %product_name% promises to ease your life", \
|
||||
"Become the best on the farmer's market with %product_name%", \
|
||||
"%product_name%: a gene-modified reimagination of an age-old classic")
|
||||
|
||||
title_templates_ooc = list( "%company_name% is looking to enter the %industry% playing field with %product_name%", \
|
||||
"A questionable decision: %product_name% grown on the soil of %company_name%", \
|
||||
"%company_name% broadens spectrum, %product_name% is their latest and greatest", \
|
||||
"Will %company_name% grow on %industrial% wasteland? Owners of %product_name% may decide", \
|
||||
"%company_name% looking to reap profits off the %industrial% sector with %product_name%")
|
||||
|
||||
/datum/industry/agriculture/generateProductName(var/company_name)
|
||||
var/list/products = list("water tank", "cattle prod", "scythe", "plough", "sickle", "cultivator", "loy", "spade", "hoe", "daisy grubber", "cotton gin")
|
||||
var/list/prefix = list("[company_name]'s ", "The [company_name] ", "The fully automatic ", "The full-duplex ", "The semi-automatic ", "The drone-mounted ", "The industry-leading ", "The world-class ")
|
||||
var/list/suffix = list(" of farming", " multiplex", " +[rand(1,15)]", " [consonant()][rand(1000, 9999)]", " hybrid", " maximus", " extreme")
|
||||
return "[pick(prefix)][pick(products)][pick(suffix)]. "
|
||||
|
||||
|
||||
|
||||
/datum/industry/it
|
||||
name = "Information Technology"
|
||||
tokens = list( \
|
||||
"industry" = list("information technology", "computing", "computer industry"), \
|
||||
"industrial" = list("information technological", "computing", "computer industrial"), \
|
||||
"jobs" = list("coders", "electricians", "engineers", "programmers", "devops experts", "developers")
|
||||
)
|
||||
|
||||
/datum/industry/it/proc/latin_number(n)
|
||||
if (n < 20 || !(n % 10))
|
||||
switch(n)
|
||||
if (0)
|
||||
return "Nihil"
|
||||
if (1)
|
||||
return "Unus"
|
||||
if (2)
|
||||
return "Duo"
|
||||
if (3)
|
||||
return "Tres"
|
||||
if (4)
|
||||
return "Quattour"
|
||||
if (5)
|
||||
return "Quinque"
|
||||
if (6)
|
||||
return "Sex"
|
||||
if (7)
|
||||
return "Septem"
|
||||
if (8)
|
||||
return "Octo"
|
||||
if (9)
|
||||
return "Novem"
|
||||
if (10)
|
||||
return "Decim"
|
||||
if (11)
|
||||
return "Undecim"
|
||||
if (12)
|
||||
return "Duodecim"
|
||||
if (13)
|
||||
return "Tredecim"
|
||||
if (14)
|
||||
return "Quattourdecim"
|
||||
if (15)
|
||||
return "Quindecim"
|
||||
if (16)
|
||||
return "Sedecim"
|
||||
if (17)
|
||||
return "Septdecim"
|
||||
if (18)
|
||||
return "Duodeviginti"
|
||||
if (19)
|
||||
return "Undeviginti"
|
||||
if (20)
|
||||
return "Viginti"
|
||||
if (30)
|
||||
return "Triginta"
|
||||
if (40)
|
||||
return "Quadriginta"
|
||||
if (50)
|
||||
return "Quinquaginta"
|
||||
if (60)
|
||||
return "Sexaginta"
|
||||
if (70)
|
||||
return "Septuaginta"
|
||||
if (80)
|
||||
return "Octoginta"
|
||||
if (90)
|
||||
return "Nonaginta"
|
||||
else
|
||||
return "[latin_number(n - (n % 10))] [lowertext(latin_number(n % 10))]"
|
||||
|
||||
/datum/industry/it/generateProductName(var/company_name)
|
||||
var/list/products = list("generator", "laptop", "keyboard", "memory card", "display", "operating system", "processor", "graphics card", "nanobots", "power supply", "pAI", "mech", "capacitor", "cell")
|
||||
var/list/prefix = list("The [company_name] ", "The high performance ", "The mobile ", "The portable ", "The professional ", "The extreme ", "The incredible ", "The blazing fast ", "The bleeding edge ", "The bluespace-powered ", null)
|
||||
var/L = pick(consonant(), "Seed ", "Radiant ", "Robust ", "Pentathon ", "Athlete ", "Phantom ", "Semper Fi ")
|
||||
var/N = rand(1, 99)
|
||||
var/prefix2 = "[L][N][prob(5) ? " " + latin_number(N) : null]"
|
||||
return "[pick(prefix)][prefix2] [pick(products)]. "
|
||||
|
||||
/datum/industry/communications
|
||||
name = "Communications"
|
||||
tokens = list( \
|
||||
"industry" = list("telecommunications", "telecomms"), \
|
||||
"industrial" = list("telecommunicational"), \
|
||||
"jobs" = list("electrical engineers", "microengineers", "developers")
|
||||
)
|
||||
|
||||
/datum/industry/communications/generateProductName(var/company_name)
|
||||
var/list/products = list("mobile phone", "PDA", "tablet computer", "newscaster", "social network")
|
||||
var/list/prefix = list("The [company_name] ", "The high performance ", "The mobile ", "The portable ", "The professional ", "The extreme ", "The incredible ", "The blazing fast ", "The bleeding edge ", null)
|
||||
var/L = pick("[lowertext(consonant())]Phone ", "Universe ", "Xperience ", "Next ", "Engin-Y ", "Cyborg ", "[consonant()]")
|
||||
var/N = rand(1,99)
|
||||
var/prefix2 = "[L][N][prob(25) ? pick(" Tiny", " Mini", " Micro", " Slim", " Water", " Air", " Fire", " Earth", " Nano", " Pico", " Femto", " Planck") : null]"
|
||||
return "[pick(prefix)][prefix2] [pick(products)]. "
|
||||
|
||||
/datum/industry/health
|
||||
name = "Medicine"
|
||||
tokens = list( \
|
||||
"industry" = list("medicine"), \
|
||||
"industrial" = list("medicinal"), \
|
||||
"jobs" = list("medical doctors", "nurses", "paramedics", "psychologists", "psychiatrists", "chemists")
|
||||
)
|
||||
|
||||
/datum/industry/health/generateProductName(var/company_name)
|
||||
var/list/prefix = list("amino", "nucleo", "nitro", "panto", "meth", "eth", "as", "algo", "coca", "hero", "lotsu", "opiod", "morph", "trinitro", "prop", "but", "acet", "acyclo", "lansop", "dyclo", "hydro", "oxycod", "vicod", "cannabi", "cryo", "dex", "chloro")
|
||||
var/list/suffix = list("phen", "pirin", "pyrine", "ane", "amphetamine", "prazoline", "ine", "yl", "amine", "aminophen", "one", "ide", "phenate", "anol", "toulene", "glycerine", "vir", "tol", "trinic", "oxide")
|
||||
var/list/uses = list("antidepressant", "analgesic", "anesthetic", "antiretroviral", "antiviral", "antibiotic", "cough drop", "depressant", "hangover cure", "homeopathic", "fertility drug", "hypnotic", "narcotic", "laxative", "multivitamin", "patch", "purgative", "relaxant", "steroid", "sleeping pill", "suppository", "tranquilizer")
|
||||
return "[pick(prefix)][pick(suffix)], the [pick(uses)]. "
|
||||
|
||||
/datum/industry/consumer
|
||||
name = "Consumer"
|
||||
tokens = list( \
|
||||
"industry" = list("shops", "stores"), \
|
||||
"industrial" = list("consumer industrial"), \
|
||||
"jobs" = list("shopkeepers", "assistants", "manual daytime hygiene engineers", "janitors", "chefs", "cooks")
|
||||
)
|
||||
|
||||
/datum/industry/consumer/generateProductName(var/company)
|
||||
var/list/meat = list("chicken", "lizard", "corgi", "monkey", "goat", "fly", "xenomorph", "human", "walrus", "wendigo", "bear", "clown", "turkey", "pork", "carp", "crab", "mimic", "mystery")
|
||||
var/list/qualifier = list("synthetic", "organic", "bio", "diet", "sugar-free", "paleolithic", "homeopathic", "recycled", "reclaimed", "vat-grown")
|
||||
return "The [pick(qualifier)] [pick(meat)] meat product line. "
|
||||
|
||||
/datum/industry/mining
|
||||
name = "Mining"
|
||||
tokens = list( \
|
||||
"industry" = list("mines", "large scale mining operations"), \
|
||||
"industrial" = list("resource acquisitional"), \
|
||||
"jobs" = list("shaft miners", "drill operators", "mining foremen")
|
||||
)
|
||||
|
||||
/datum/industry/mining/generateProductName(var/company)
|
||||
var/list/equipment = list("drill", "pickaxe", "shovel", "jackhammer", "mini-pickaxe", "power hammer", "power gloves", "power armor", "hardsuit", "kinetic accelerator", "resonator", "oxygen tank", "emergency bike horn")
|
||||
var/list/material = list("mauxite", "pharosium", "molitz", "adamantium", "mithril", "cobryl", "bohrum", "claretine", "viscerite", "syreline", "cerenkite", "plasmastone", "gold", "koshmarite", "phoron", "carbon dioxide", "powered")
|
||||
return "The [pick(material)] [pick(equipment)]. "
|
||||
|
||||
/datum/industry/defense
|
||||
name = "Defense"
|
||||
tokens = list ( \
|
||||
"industry" = list("defense", "warfare", "security", "law enforcement"), \
|
||||
"industrial" = list("defense"), \
|
||||
"jobs" = list("security officers", "government officials", "soldiers", "weapons engineers")
|
||||
)
|
||||
|
||||
/datum/industry/defense/generateProductName(var/company)
|
||||
var/list/equipment = list("energy gun", "laser gun", "machine gun", "grenade", "stun baton", "artillery", "bomb", "attack drone", "missile", "chem sprayer")
|
||||
var/list/material = list("bluespace", "stealth", "heat-seeking", "crime-seeking", "wide-range", "bioterror", "auto-reloading", "smart", "sentient", "rapid-fire", "species-targeting", "mass-market", "perpetual-motion", "nuclear", "fission", "fusion")
|
||||
return "The [pick(material)] [pick(equipment)]. "
|
||||
@@ -0,0 +1,14 @@
|
||||
/datum/stock_log
|
||||
var/user_name = ""
|
||||
var/company_name = ""
|
||||
var/shareprice
|
||||
var/money
|
||||
var/stocks
|
||||
var/time
|
||||
|
||||
|
||||
/datum/stock_log/buy
|
||||
|
||||
/datum/stock_log/sell
|
||||
|
||||
/datum/stock_log/borrow
|
||||
@@ -0,0 +1,168 @@
|
||||
/datum/stockMarket
|
||||
var/list/stocks = list()
|
||||
var/list/balances = list()
|
||||
var/list/last_read = list()
|
||||
var/list/stockBrokers = list()
|
||||
var/list/logs = list()
|
||||
|
||||
/datum/stockMarket/New()
|
||||
..()
|
||||
generateBrokers()
|
||||
generateStocks()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/stockMarket/proc/balanceLog(var/whose, var/net)
|
||||
if (!(whose in balances))
|
||||
balances[whose] = net
|
||||
else
|
||||
balances[whose] += net
|
||||
/datum/stockMarket/proc/generateBrokers()
|
||||
stockBrokers = list()
|
||||
var/list/fnames = list("Goldman", "Edward", "James", "Luis", "Alexander", "Walter", "Eugene", "Mary", "Morgan", "Jane", "Elizabeth", "Xavier", "Hayden", "Samuel", "Lee")
|
||||
var/list/names = list("Johnson", "Rothschild", "Sachs", "Stanley", "Hepburn", "Brown", "McColl", "Fischer", "Edwards", "Becker", "Witter", "Walker", "Lambert", "Smith", "Montgomery", "Lynch", "Roosevelt", "Lehman")
|
||||
var/list/locations = list("Earth", "Luna", "Mars", "Saturn", "Jupiter", "Uranus", "Pluto", "Europa", "Io", "Phobos", "Deimos", "Space", "Venus", "Neptune", "Mercury", "Kalliope", "Ganymede", "Callisto", "Amalthea", "Himalia", "Sybil", "Basil", "Badger", "Terry", "Artyom")
|
||||
var/list/first = list("The", "First", "Premier", "Finest", "Prime")
|
||||
var/list/company = list("Investments", "Securities", "Corporation", "Bank", "Brokerage", "& Co.", "Brothers", "& Sons", "Investement Firm", "Union", "Partners", "Capital", "Trade", "Holdings")
|
||||
for(var/i in 1 to 5)
|
||||
var/pname = ""
|
||||
switch (rand(1,5))
|
||||
if (1)
|
||||
pname = "[prob(10) ? pick(first) + " " : null][pick(names)] [pick(company)]"
|
||||
if (2)
|
||||
pname = "[pick(names)] & [pick(names)][prob(25) ? " " + pick(company) : null]"
|
||||
if (3)
|
||||
pname = "[prob(45) ? pick(first) + " " : null][pick(locations)] [pick(company)]"
|
||||
if (4)
|
||||
pname = "[prob(10) ? "The " : null][pick(names)] [pick(locations)] [pick(company)]"
|
||||
if (5)
|
||||
pname = "[prob(10) ? "The " : null][pick(fnames)] [pick(names)][prob(10) ? " " + pick(company) : null]"
|
||||
if (pname in stockBrokers)
|
||||
i--
|
||||
continue
|
||||
stockBrokers += pname
|
||||
|
||||
/datum/stockMarket/proc/generateDesignation(var/name)
|
||||
if (length(name) <= 4)
|
||||
return uppertext(name)
|
||||
var/list/w = splittext(name, " ")
|
||||
if (w.len >= 2)
|
||||
var/d = ""
|
||||
for(var/i in 1 to min(5, w.len))
|
||||
d += uppertext(ascii2text(text2ascii(w[i], 1)))
|
||||
return d
|
||||
else
|
||||
var/d = uppertext(ascii2text(text2ascii(name, 1)))
|
||||
for(var/i in 2 to length(name))
|
||||
if (prob(100 / i))
|
||||
d += uppertext(ascii2text(text2ascii(name, i)))
|
||||
return d
|
||||
|
||||
/datum/stockMarket/proc/generateStocks(var/amt = 15)
|
||||
var/list/fruits = list("Banana", "Mimana", "Watermelon", "Ambrosia", "Pomegranate", "Reishi", "Papaya", "Mango", "Tomato", "Conkerberry", "Wood", "Lychee", "Mandarin", "Harebell", "Pumpkin", "Rhubarb", "Tamarillo", "Yantok", "Ziziphus", "Oranges", "Gatfruit", "Daisy", "Kudzu")
|
||||
var/list/tech_prefix = list("Nano", "Cyber", "Funk", "Astro", "Fusion", "Tera", "Exo", "Star", "Virtual", "Plasma", "Robust", "Bit", "Future", "Hugbox", "Carbon", "Nerf", "Buff", "Nova", "Space", "Meta", "Cyber")
|
||||
var/list/tech_short = list("soft", "tech", "prog", "tec", "tek", "ware", "", "gadgets", "nics", "tric", "trasen", "tronic", "coin")
|
||||
var/list/random_nouns = list("Johnson", "Cluwne", "General", "Specific", "Master", "King", "Queen", "Table", "Rupture", "Dynamic", "Massive", "Mega", "Giga", "Certain", "Singulo", "State", "National", "International", "Interplanetary", "Sector", "Planet", "Burn", "Robust", "Exotic", "Solar", "Lunar", "Chelp", "Corgi", "Lag", "Lizard")
|
||||
var/list/company = list("Company", "Factory", "Incorporated", "Industries", "Group", "Consolidated", "GmbH", "LLC", "Ltd", "Inc.", "Association", "Limited", "Software", "Technology", "Programming", "IT Group", "Electronics", "Nanotechnology", "Farms", "Stores", "Mobile", "Motors", "Electric", "Designs", "Energy", "Pharmaceuticals", "Communications", "Wholesale", "Holding", "Health", "Machines", "Astrotech", "Gadgets", "Kinetics")
|
||||
for (var/i = 1, i <= amt, i++)
|
||||
var/datum/stock/S = new
|
||||
var/sname = ""
|
||||
switch (rand(1,6))
|
||||
if(1)
|
||||
while (sname == "" || sname == "FAG") // honestly it's a 0.6% chance per round this happens - or once in 166 rounds - so i'm accounting for it before someone yells at me
|
||||
sname = "[consonant()][vowel()][consonant()]"
|
||||
if (2)
|
||||
sname = "[pick(tech_prefix)][pick(tech_short)][prob(20) ? " " + pick(company) : null]"
|
||||
if (3 to 4)
|
||||
var/fruit = pick(fruits)
|
||||
fruits -= fruit
|
||||
sname = "[prob(10) ? "The " : null][fruit][prob(40) ? " " + pick(company): null]"
|
||||
if (5 to 6)
|
||||
var/pname = pick(random_nouns)
|
||||
random_nouns -= pname
|
||||
switch (rand(1,3))
|
||||
if (1)
|
||||
sname = "[pname] & [pname]"
|
||||
if (2)
|
||||
sname = "[pname] [pick(company)]"
|
||||
if (3)
|
||||
sname = "[pname]"
|
||||
S.name = sname
|
||||
S.short_name = generateDesignation(S.name)
|
||||
S.current_value = rand(10, 125)
|
||||
var/dv = rand(10, 40) / 10
|
||||
S.fluctuational_coefficient = prob(50) ? (1 / dv) : dv
|
||||
S.average_optimism = rand(-10, 10) / 100
|
||||
S.optimism = S.average_optimism + (rand(-40, 40) / 100)
|
||||
S.current_trend = rand(-200, 200) / 10
|
||||
S.last_trend = S.current_trend
|
||||
S.disp_value_change = rand(-1, 1)
|
||||
S.speculation = rand(-20, 20)
|
||||
S.average_shares = round(rand(500, 10000) / 10)
|
||||
S.outside_shareholders = rand(1000, 30000)
|
||||
S.available_shares = rand(200000, 800000)
|
||||
S.fluctuation_rate = rand(6, 20)
|
||||
S.generateIndustry()
|
||||
S.generateEvents()
|
||||
stocks += S
|
||||
last_read[S] = list()
|
||||
|
||||
/datum/stockMarket/process()
|
||||
for (var/stock in stocks)
|
||||
var/datum/stock/S = stock
|
||||
S.process()
|
||||
|
||||
/datum/stockMarket/proc/add_log(var/log_type, var/user, var/company_name, var/stocks, var/shareprice, var/money)
|
||||
var/datum/stock_log/L = new log_type
|
||||
L.user_name = user
|
||||
L.company_name = company_name
|
||||
L.stocks = stocks
|
||||
L.shareprice = shareprice
|
||||
L.money = money
|
||||
L.time = time2text(world.timeofday, "hh:mm")
|
||||
logs += L
|
||||
|
||||
GLOBAL_DATUM_INIT(stockExchange, /datum/stockMarket, new)
|
||||
|
||||
/proc/plotBarGraph(var/list/points, var/base_text, var/width=400, var/height=400)
|
||||
var/output = "<table style='border:1px solid black; border-collapse: collapse; width: [width]px; height: [height]px'>"
|
||||
if (points.len && height > 20 && width > 20)
|
||||
var/min = points[1]
|
||||
var/max = points[1]
|
||||
for (var/v in points)
|
||||
if (v < min)
|
||||
min = v
|
||||
if (v > max)
|
||||
max = v
|
||||
var/cells = (height - 20) / 20
|
||||
if (cells > round(cells))
|
||||
cells = round(cells) + 1
|
||||
var/diff = max - min
|
||||
var/ost = diff / cells
|
||||
if (min > 0)
|
||||
min = max(min - ost, 0)
|
||||
diff = max - min
|
||||
ost = diff / cells
|
||||
var/cval = max
|
||||
var/cwid = width / (points.len + 1)
|
||||
for (var/y = cells, y > 0, y--)
|
||||
if (y == cells)
|
||||
output += "<tr>"
|
||||
else
|
||||
output += "<tr style='border:none; border-top:1px solid #00ff00; height: 20px'>"
|
||||
for (var/x = 0, x <= points.len, x++)
|
||||
if (x == 0)
|
||||
output += "<td style='border:none; height: 20px; width: [cwid]px; font-size:10px; color:#00ff00; background:black; text-align:right; vertical-align:bottom'>[round(cval - ost)]</td>"
|
||||
else
|
||||
var/v = points[x]
|
||||
if (v >= cval)
|
||||
output += "<td style='border:none; height: 20px; width: [cwid]px; background:#0000ff'> </td>"
|
||||
else
|
||||
output += "<td style='border:none; height: 20px; width: [cwid]px; background:black'> </td>"
|
||||
output += "</tr>"
|
||||
cval -= ost
|
||||
output += "<tr><td style='font-size:10px; height: 20px; width: 100%; background:black; color:green; text-align:center' colspan='[points.len + 1]'>[base_text]</td></tr>"
|
||||
else
|
||||
output += "<tr><td style='width:[width]px; height:[height]px; background: black'></td></tr>"
|
||||
output += "<tr><td style='font-size:10px; background:black; color:green; text-align:center'>[base_text]</td></tr>"
|
||||
|
||||
return "[output]</table>"
|
||||
@@ -0,0 +1,308 @@
|
||||
/datum/borrow
|
||||
var/broker = ""
|
||||
var/borrower = ""
|
||||
var/datum/stock/stock = null
|
||||
var/lease_expires = 0
|
||||
var/lease_time = 0
|
||||
var/grace_time = 0
|
||||
var/grace_expires = 0
|
||||
var/share_amount = 0
|
||||
var/share_debt = 0
|
||||
var/deposit = 0
|
||||
var/offer_expires = 0
|
||||
|
||||
/datum/stock
|
||||
var/name = "Stock"
|
||||
var/short_name = "STK"
|
||||
var/desc = "A company that does not exist."
|
||||
var/list/values = list()
|
||||
var/current_value = 10
|
||||
var/last_value = 10
|
||||
var/list/products = list()
|
||||
|
||||
var/performance = 0 // The current performance of the company. Tends itself to 0 when no events happen.
|
||||
|
||||
// These variables determine standard fluctuational patterns for this stock.
|
||||
var/fluctuational_coefficient = 1 // How much the price fluctuates on an average daily basis
|
||||
var/average_optimism = 0 // The history of shareholder optimism of this stock
|
||||
var/current_trend = 0
|
||||
var/last_trend = 0
|
||||
var/speculation = 0
|
||||
var/bankrupt = 0
|
||||
|
||||
var/disp_value_change = 0
|
||||
var/optimism = 0
|
||||
var/last_unification = 0
|
||||
var/average_shares = 100
|
||||
var/outside_shareholders = 10000 // The amount of offstation people holding shares in this company. The higher it is, the more fluctuation it causes.
|
||||
var/available_shares = 500000
|
||||
|
||||
var/list/borrow_brokers = list()
|
||||
var/list/shareholders = list()
|
||||
var/list/borrows = list()
|
||||
var/list/events = list()
|
||||
var/list/articles = list()
|
||||
var/fluctuation_rate = 15
|
||||
var/fluctuation_counter = 0
|
||||
var/datum/industry/industry = null
|
||||
|
||||
/datum/stock/proc/addEvent(var/datum/stockEvent/E)
|
||||
events |= E
|
||||
|
||||
/datum/stock/proc/addArticle(var/datum/article/A)
|
||||
if (!(A in articles))
|
||||
articles.Insert(1, A)
|
||||
A.ticks = world.time
|
||||
|
||||
/datum/stock/proc/generateEvents()
|
||||
var/list/types = typesof(/datum/stockEvent) - /datum/stockEvent
|
||||
for (var/T in types)
|
||||
generateEvent(T)
|
||||
|
||||
/datum/stock/proc/generateEvent(var/T)
|
||||
var/datum/stockEvent/E = new T(src)
|
||||
addEvent(E)
|
||||
|
||||
/datum/stock/proc/affectPublicOpinion(var/boost)
|
||||
optimism += rand(0, 500) / 500 * boost
|
||||
average_optimism += rand(0, 150) / 5000 * boost
|
||||
speculation += rand(-1, 50) / 10 * boost
|
||||
performance += rand(0, 150) / 100 * boost
|
||||
|
||||
/datum/stock/proc/generateIndustry()
|
||||
if (findtext(name, "Farms"))
|
||||
industry = new /datum/industry/agriculture
|
||||
else if (findtext(name, "Software") || findtext(name, "Programming") || findtext(name, "IT Group") || findtext(name, "Electronics") || findtext(name, "Electric") || findtext(name, "Nanotechnology"))
|
||||
industry = new /datum/industry/it
|
||||
else if (findtext(name, "Mobile") || findtext(name, "Communications"))
|
||||
industry = new /datum/industry/communications
|
||||
else if (findtext(name, "Pharmaceuticals") || findtext(name, "Health"))
|
||||
industry = new /datum/industry/health
|
||||
else if (findtext(name, "Wholesale") || findtext(name, "Stores"))
|
||||
industry = new /datum/industry/consumer
|
||||
else
|
||||
var/ts = typesof(/datum/industry) - /datum/industry
|
||||
var/in_t = pick(ts)
|
||||
industry = new in_t
|
||||
for (var/i = 0, i < rand(2, 5), i++)
|
||||
products += industry.generateProductName(name)
|
||||
|
||||
/datum/stock/proc/frc(amt)
|
||||
var/shares = available_shares + outside_shareholders * average_shares
|
||||
var/fr = amt / 100 / shares * fluctuational_coefficient * fluctuation_rate * max(-(current_trend / 100), 1)
|
||||
if ((fr < 0 && speculation < 0) || (fr > 0 && speculation > 0))
|
||||
fr *= max(abs(speculation) / 5, 1)
|
||||
else
|
||||
fr /= max(abs(speculation) / 5, 1)
|
||||
return fr
|
||||
|
||||
/datum/stock/proc/supplyGrowth(amt)
|
||||
var/fr = frc(amt)
|
||||
available_shares += amt
|
||||
if (abs(fr) < 0.0001)
|
||||
return
|
||||
current_value -= fr * current_value
|
||||
|
||||
/datum/stock/proc/supplyDrop(amt)
|
||||
supplyGrowth(-amt)
|
||||
|
||||
/datum/stock/proc/fluctuate()
|
||||
var/change = rand(-100, 100) / 10 + optimism * rand(200) / 10
|
||||
optimism -= (optimism - average_optimism) * (rand(10,80) / 1000)
|
||||
var/shift_score = change + current_trend
|
||||
var/as_score = abs(shift_score)
|
||||
var/sh_change_dev = rand(-10, 10) / 10
|
||||
var/sh_change = shift_score / (as_score + 100) + sh_change_dev
|
||||
var/shareholder_change = round(sh_change)
|
||||
outside_shareholders += shareholder_change
|
||||
var/share_change = shareholder_change * average_shares
|
||||
if (as_score > 20 && prob(as_score / 4))
|
||||
var/avg_change_dev = rand(-10, 10) / 10
|
||||
var/avg_change = shift_score / (as_score + 100) + avg_change_dev
|
||||
average_shares += avg_change
|
||||
share_change += outside_shareholders * avg_change
|
||||
|
||||
var/cv = last_value
|
||||
supplyDrop(share_change)
|
||||
available_shares += share_change // temporary
|
||||
|
||||
if (prob(25))
|
||||
average_optimism = max(min(average_optimism + (rand(-3, 3) - current_trend * 0.15) / 100, 1), -1)
|
||||
|
||||
var/aspec = abs(speculation)
|
||||
if (prob((aspec - 75) * 2))
|
||||
speculation += rand(-4, 4)
|
||||
else
|
||||
if (prob(50))
|
||||
speculation += rand(-4, 4)
|
||||
else
|
||||
speculation += rand(-400, 0) / 1000 * speculation
|
||||
if (prob(1) && prob(5)) // pop that bubble
|
||||
speculation += rand(-4000, 0) / 1000 * speculation
|
||||
|
||||
if (current_value < 5)
|
||||
current_value = 5
|
||||
|
||||
if (performance != 0)
|
||||
performance = rand(900,1050) / 1000 * performance
|
||||
if (abs(performance) < 0.2)
|
||||
performance = 0
|
||||
|
||||
disp_value_change = (cv < current_value) ? 1 : ((cv > current_value) ? -1 : 0)
|
||||
last_value = current_value
|
||||
if (values.len >= 50)
|
||||
values.Cut(1,2)
|
||||
values += current_value
|
||||
|
||||
if (current_value < 10)
|
||||
unifyShares()
|
||||
|
||||
last_trend = current_trend
|
||||
current_trend += rand(-200, 200) / 100 + optimism * rand(200) / 10 + max(50 - abs(speculation), 0) / 50 * rand(0, 200) / 1000 * (-current_trend) + max(speculation - 50, 0) * rand(0, 200) / 1000 * speculation / 400
|
||||
|
||||
/datum/stock/proc/unifyShares()
|
||||
for (var/I in shareholders)
|
||||
var/shr = shareholders[I]
|
||||
if (shr % 2)
|
||||
sellShares(I, 1)
|
||||
shr -= 1
|
||||
shareholders[I] /= 2
|
||||
if (!shareholders[I])
|
||||
shareholders -= I
|
||||
for (var/datum/borrow/B in borrow_brokers)
|
||||
B.share_amount = round(B.share_amount / 2)
|
||||
B.share_debt = round(B.share_debt / 2)
|
||||
for (var/datum/borrow/B in borrows)
|
||||
B.share_amount = round(B.share_amount / 2)
|
||||
B.share_debt = round(B.share_debt / 2)
|
||||
average_shares /= 2
|
||||
available_shares /= 2
|
||||
current_value *= 2
|
||||
last_unification = world.time
|
||||
|
||||
/datum/stock/process()
|
||||
for (var/B in borrows)
|
||||
var/datum/borrow/borrow = B
|
||||
if (world.time > borrow.grace_expires)
|
||||
modifyAccount(borrow.borrower, -max(current_value * borrow.share_debt, 0), 1)
|
||||
borrows -= borrow
|
||||
if (borrow.borrower in GLOB.FrozenAccounts)
|
||||
GLOB.FrozenAccounts[borrow.borrower] -= borrow
|
||||
if (length(GLOB.FrozenAccounts[borrow.borrower]) == 0)
|
||||
GLOB.FrozenAccounts -= borrow.borrower
|
||||
qdel(borrow)
|
||||
else if (world.time > borrow.lease_expires)
|
||||
if (borrow.borrower in shareholders)
|
||||
var/amt = shareholders[borrow.borrower]
|
||||
if (amt > borrow.share_debt)
|
||||
shareholders[borrow.borrower] -= borrow.share_debt
|
||||
borrows -= borrow
|
||||
if (borrow.borrower in GLOB.FrozenAccounts)
|
||||
GLOB.FrozenAccounts[borrow.borrower] -= borrow
|
||||
if (length(GLOB.FrozenAccounts[borrow.borrower]) == 0)
|
||||
GLOB.FrozenAccounts -= borrow.borrower
|
||||
qdel(borrow)
|
||||
else
|
||||
shareholders -= borrow.borrower
|
||||
borrow.share_debt -= amt
|
||||
if (bankrupt)
|
||||
return
|
||||
for (var/B in borrow_brokers)
|
||||
var/datum/borrow/borrow = B
|
||||
if (borrow.offer_expires < world.time)
|
||||
borrow_brokers -= borrow
|
||||
qdel(borrow)
|
||||
if (prob(5))
|
||||
generateBrokers()
|
||||
fluctuation_counter++
|
||||
if (fluctuation_counter >= fluctuation_rate)
|
||||
for (var/E in events)
|
||||
var/datum/stockEvent/EV = E
|
||||
EV.process()
|
||||
fluctuation_counter = 0
|
||||
fluctuate()
|
||||
|
||||
/datum/stock/proc/generateBrokers()
|
||||
if (borrow_brokers.len > 2)
|
||||
return
|
||||
if (!GLOB.stockExchange.stockBrokers.len)
|
||||
GLOB.stockExchange.generateBrokers()
|
||||
var/broker = pick(GLOB.stockExchange.stockBrokers)
|
||||
var/datum/borrow/B = new
|
||||
B.broker = broker
|
||||
B.stock = src
|
||||
B.lease_time = rand(4, 7) * 600
|
||||
B.grace_time = rand(1, 3) * 600
|
||||
B.share_amount = rand(1, 10) * 100
|
||||
B.deposit = rand(20, 70) / 100
|
||||
B.share_debt = B.share_amount
|
||||
B.offer_expires = rand(5, 10) * 600 + world.time
|
||||
borrow_brokers += B
|
||||
|
||||
/datum/stock/proc/modifyAccount(whose, by, force=0)
|
||||
if (SSsupply.points)
|
||||
if (by < 0 && SSsupply.points + by < 0 && !force)
|
||||
return 0
|
||||
SSsupply.points += by
|
||||
GLOB.stockExchange.balanceLog(whose, by)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/stock/proc/borrow(var/datum/borrow/B, var/who)
|
||||
if (B.lease_expires)
|
||||
return 0
|
||||
B.lease_expires = world.time + B.lease_time
|
||||
var/old_d = B.deposit
|
||||
var/d_amt = B.deposit * current_value * B.share_amount
|
||||
if (!modifyAccount(who, -d_amt))
|
||||
B.lease_expires = 0
|
||||
B.deposit = old_d
|
||||
return 0
|
||||
B.deposit = d_amt
|
||||
if (!(who in shareholders))
|
||||
shareholders[who] = B.share_amount
|
||||
else
|
||||
shareholders[who] += B.share_amount
|
||||
borrow_brokers -= B
|
||||
borrows += B
|
||||
B.borrower = who
|
||||
B.grace_expires = B.lease_expires + B.grace_time
|
||||
if (!(who in GLOB.FrozenAccounts))
|
||||
GLOB.FrozenAccounts[who] = list(B)
|
||||
else
|
||||
GLOB.FrozenAccounts[who] += B
|
||||
return 1
|
||||
|
||||
/datum/stock/proc/buyShares(var/who, var/howmany)
|
||||
if (howmany <= 0)
|
||||
return
|
||||
howmany = round(howmany)
|
||||
var/loss = howmany * current_value
|
||||
if (available_shares < howmany)
|
||||
return 0
|
||||
if (modifyAccount(who, -loss))
|
||||
supplyDrop(howmany)
|
||||
if (!(who in shareholders))
|
||||
shareholders[who] = howmany
|
||||
else
|
||||
shareholders[who] += howmany
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/stock/proc/sellShares(var/whose, var/howmany)
|
||||
if (howmany < 0)
|
||||
return
|
||||
howmany = round(howmany)
|
||||
var/gain = howmany * current_value
|
||||
if (shareholders[whose] < howmany)
|
||||
return 0
|
||||
if (modifyAccount(whose, gain))
|
||||
supplyGrowth(howmany)
|
||||
shareholders[whose] -= howmany
|
||||
if (shareholders[whose] <= 0)
|
||||
shareholders -= whose
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/stock/proc/displayValues(var/mob/user)
|
||||
user << browse(plotBarGraph(values, "[name] share value per share"), "window=stock_[name];size=450x450")
|
||||
@@ -157,11 +157,13 @@ h1.alert, h2.alert {color: #000000;}
|
||||
.skrell {color: #00B0B3;}
|
||||
.skrellfar {color: #70FCFF;}
|
||||
.soghun {color: #50BA6C;}
|
||||
.solcom {color: #22228B;}
|
||||
.solcom {color: #3333CE;} /* VOREStation Edit */
|
||||
.changeling {color: #800080;}
|
||||
.sergal {color: #0077FF;}
|
||||
.birdsongc {color: #CC9900;}
|
||||
.vulpkanin {color: #B97A57;}
|
||||
.tavan {color: #f54298; font-family: Arial}
|
||||
.echosong {color: #826D8C;}
|
||||
.enochian {color: #848A33; letter-spacing:-1pt; word-spacing:4pt; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;}
|
||||
.daemon {color: #5E339E; letter-spacing:-1pt; word-spacing:0pt; font-family: "Courier New", Courier, monospace;}
|
||||
.drudakar {color: #bb2463; word-spacing:0pt; font-family: "High Tower Text", monospace;}
|
||||
@@ -180,7 +182,6 @@ h1.alert, h2.alert {color: #000000;}
|
||||
/* YW Edit End */
|
||||
.spacer {color: #9c660b;} /* VOREStation Add */
|
||||
.blob {color: #ff950d; font-weight: bold; font-style: italic;}
|
||||
.tavan {color: #f54298; font-family: Arial}
|
||||
|
||||
.black {color: #000000;}
|
||||
.darkgray {color: #808080;}
|
||||
|
||||
@@ -129,6 +129,8 @@
|
||||
/obj/vehicle/train/engine/turn_on()
|
||||
if(!key)
|
||||
return
|
||||
if(!cell)
|
||||
return
|
||||
else
|
||||
..()
|
||||
update_stats()
|
||||
@@ -230,7 +232,9 @@
|
||||
if (on)
|
||||
to_chat(usr, "You start [src]'s engine.")
|
||||
else
|
||||
if(cell.charge < charge_use)
|
||||
if(!cell)
|
||||
to_chat(usr, "[src] doesn't appear to have a power cell!")
|
||||
else if(cell.charge < charge_use)
|
||||
to_chat(usr, "[src] is out of power.")
|
||||
else
|
||||
to_chat(usr, "[src]'s engine won't start.")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user