mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-30 07:28:53 +01:00
Merge remote-tracking branch 'upstream/master' into kk-ships2
This commit is contained in:
+60
@@ -0,0 +1,60 @@
|
||||
FROM tgstation/byond:513.1533 as base
|
||||
|
||||
FROM base as rust_g
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
ca-certificates
|
||||
|
||||
WORKDIR /rust_g
|
||||
|
||||
RUN apt-get install -y --no-install-recommends \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
curl \
|
||||
gcc-multilib \
|
||||
&& curl https://sh.rustup.rs -sSf | sh -s -- -y --default-host i686-unknown-linux-gnu \
|
||||
&& git init \
|
||||
&& git remote add origin https://github.com/tgstation/rust-g
|
||||
|
||||
COPY _build_dependencies.sh .
|
||||
|
||||
RUN /bin/bash -c "source _build_dependencies.sh \
|
||||
&& git fetch --depth 1 origin \$RUST_G_VERSION" \
|
||||
&& git checkout FETCH_HEAD \
|
||||
&& ~/.cargo/bin/cargo build --release
|
||||
|
||||
FROM base as dm_base
|
||||
|
||||
WORKDIR /vorestation
|
||||
|
||||
FROM dm_base as build
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN DreamMaker -max_errors 0 vorestation.dme
|
||||
|
||||
FROM dm_base
|
||||
|
||||
EXPOSE 2303
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends software-properties-common \
|
||||
&& add-apt-repository ppa:ubuntu-toolchain-r/test \
|
||||
&& apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get dist-upgrade -y \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
libmariadb2 \
|
||||
mariadb-client \
|
||||
libssl1.0.0 \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& mkdir -p /root/.byond/bin
|
||||
|
||||
COPY --from=rust_g /rust_g/target/release/librust_g.so /root/.byond/bin/rust_g
|
||||
COPY --from=build /vorestation/ ./
|
||||
|
||||
#VOLUME [ "/vorestation/config", "/vorestation/data" ]
|
||||
|
||||
ENTRYPOINT [ "DreamDaemon", "vorestation.dmb", "-port", "2303", "-trusted", "-close", "-verbose" ]
|
||||
@@ -32,6 +32,12 @@
|
||||
// Reads the length of L, returning 0 if null
|
||||
#define LAZYLEN(L) length(L)
|
||||
|
||||
#define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += V;
|
||||
///This is used to add onto lazy assoc list when the value you're adding is a /list/. This one has extra safety over lazyaddassoc because the value could be null (and thus cant be used to += objects)
|
||||
#define LAZYADDASSOCLIST(L, K, V) if(!L) { L = list(); } L[K] += list(V);
|
||||
#define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; }
|
||||
#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null
|
||||
|
||||
// Null-safe L.Cut()
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define DM_FLAG_LEAVEREMAINS 0x4
|
||||
#define DM_FLAG_THICKBELLY 0x8
|
||||
#define DM_FLAG_AFFECTWORN 0x10
|
||||
#define DM_FLAG_JAMSENSORS 0x20
|
||||
|
||||
//Item related modes
|
||||
#define IM_HOLD "Hold"
|
||||
|
||||
@@ -49,3 +49,11 @@ var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglyce
|
||||
var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate.
|
||||
var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart.
|
||||
var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional
|
||||
|
||||
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
|
||||
#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites
|
||||
#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once
|
||||
#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill
|
||||
#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch
|
||||
#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume)
|
||||
#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever
|
||||
@@ -0,0 +1,27 @@
|
||||
//tablecrafting defines
|
||||
#define CAT_NONE ""
|
||||
#define CAT_WEAPONRY "Weaponry"
|
||||
#define CAT_WEAPON "Weapons"
|
||||
#define CAT_AMMO "Ammunition"
|
||||
#define CAT_ROBOT "Robots"
|
||||
#define CAT_MISC "Misc"
|
||||
#define CAT_PRIMAL "Tribal"
|
||||
#define CAT_CLOTHING "Clothing"
|
||||
#define CAT_FOOD "Foods"
|
||||
#define CAT_BREAD "Breads"
|
||||
#define CAT_BURGER "Burgers"
|
||||
#define CAT_CAKE "Cakes"
|
||||
#define CAT_EGG "Egg-Based Food"
|
||||
#define CAT_MEAT "Meats"
|
||||
#define CAT_MISCFOOD "Misc. Food"
|
||||
#define CAT_MEXICAN "Mexican Food"
|
||||
#define CAT_PASTRY "Pastries"
|
||||
#define CAT_PIE "Pies"
|
||||
#define CAT_PIZZA "Pizzas"
|
||||
#define CAT_SALAD "Salads"
|
||||
#define CAT_SANDWICH "Sandwiches"
|
||||
#define CAT_SOUP "Soups"
|
||||
#define CAT_SPAGHETTI "Spaghettis"
|
||||
#define CAT_ICE "Frozen"
|
||||
#define CAT_DRINK "Drinks"
|
||||
#define CAT_CHEMISTRY "Chemistry"
|
||||
@@ -97,6 +97,10 @@
|
||||
#define COMSIG_ATOM_FIRE_ACT "atom_fire_act"
|
||||
///from base of atom/bullet_act(): (/obj/projectile, def_zone)
|
||||
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act"
|
||||
///from base of atom/CheckParts(): (list/parts_list, datum/crafting_recipe/R)
|
||||
#define COMSIG_ATOM_CHECKPARTS "atom_checkparts"
|
||||
///from base of atom/CheckParts(): (atom/movable/new_craft) - The atom has just been used in a crafting recipe and has been moved inside new_craft.
|
||||
#define COMSIG_ATOM_USED_IN_CRAFT "atom_used_in_craft"
|
||||
///from base of atom/blob_act(): (/obj/structure/blob)
|
||||
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act"
|
||||
///from base of atom/acid_act(): (acidpwr, acid_volume)
|
||||
@@ -732,3 +736,5 @@
|
||||
///SSalarm signals
|
||||
#define COMSIG_TRIGGERED_ALARM "ssalarm_triggered"
|
||||
#define COMSIG_CANCELLED_ALARM "ssalarm_cancelled"
|
||||
|
||||
#define COMSIG_REAGENTS_CRAFTING_PING "reagents_crafting_ping"
|
||||
@@ -0,0 +1,63 @@
|
||||
#define DEFAULT_TABLE_MATERIAL "plastic"
|
||||
#define DEFAULT_WALL_MATERIAL "steel"
|
||||
|
||||
#define MAT_IRON "iron"
|
||||
#define MAT_MARBLE "marble"
|
||||
#define MAT_STEEL "steel"
|
||||
#define MAT_PLASTIC "plastic"
|
||||
#define MAT_GLASS "glass"
|
||||
#define MAT_SILVER "silver"
|
||||
#define MAT_GOLD "gold"
|
||||
#define MAT_URANIUM "uranium"
|
||||
#define MAT_TITANIUM "titanium"
|
||||
#define MAT_PHORON "phoron"
|
||||
#define MAT_DIAMOND "diamond"
|
||||
#define MAT_SNOW "snow"
|
||||
#define MAT_SNOWBRICK "packed snow"
|
||||
#define MAT_WOOD "wood"
|
||||
#define MAT_LOG "log"
|
||||
#define MAT_SIFWOOD "alien wood"
|
||||
#define MAT_SIFLOG "alien log"
|
||||
#define MAT_STEELHULL "steel hull"
|
||||
#define MAT_PLASTEEL "plasteel"
|
||||
#define MAT_PLASTEELHULL "plasteel hull"
|
||||
#define MAT_DURASTEEL "durasteel"
|
||||
#define MAT_DURASTEELHULL "durasteel hull"
|
||||
#define MAT_TITANIUMHULL "titanium hull"
|
||||
#define MAT_VERDANTIUM "verdantium"
|
||||
#define MAT_MORPHIUM "morphium"
|
||||
#define MAT_MORPHIUMHULL "morphium hull"
|
||||
#define MAT_VALHOLLIDE "valhollide"
|
||||
#define MAT_LEAD "lead"
|
||||
#define MAT_SUPERMATTER "supermatter"
|
||||
#define MAT_METALHYDROGEN "mhydrogen"
|
||||
#define MAT_OSMIUM "osmium"
|
||||
#define MAT_GRAPHITE "graphite"
|
||||
#define MAT_LEATHER "leather"
|
||||
#define MAT_CHITIN "chitin"
|
||||
#define MAT_CLOTH "cloth"
|
||||
#define MAT_SYNCLOTH "syncloth"
|
||||
#define MAT_COPPER "copper"
|
||||
#define MAT_QUARTZ "quartz"
|
||||
#define MAT_TIN "tin"
|
||||
#define MAT_VOPAL "void opal"
|
||||
#define MAT_ALUMINIUM "aluminium"
|
||||
#define MAT_BRONZE "bronze"
|
||||
#define MAT_PAINITE "painite"
|
||||
#define MAT_BOROSILICATE "borosilicate glass"
|
||||
#define MAT_SANDSTONE "sandstone"
|
||||
|
||||
#define SHARD_SHARD "shard"
|
||||
#define SHARD_SHRAPNEL "shrapnel"
|
||||
#define SHARD_STONE_PIECE "piece"
|
||||
#define SHARD_SPLINTER "splinters"
|
||||
#define SHARD_NONE ""
|
||||
|
||||
#define MATERIAL_UNMELTABLE 0x1
|
||||
#define MATERIAL_BRITTLE 0x2
|
||||
#define MATERIAL_PADDING 0x4
|
||||
|
||||
#define DEFAULT_TABLE_MATERIAL "plastic"
|
||||
#define DEFAULT_WALL_MATERIAL "steel"
|
||||
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
+5
-60
@@ -77,7 +77,7 @@
|
||||
#define DO_AUTOPILOT 5
|
||||
|
||||
// Setting this much higher than 1024 could allow spammers to DOS the server easily.
|
||||
#define MAX_MESSAGE_LEN 2048 //VOREStation Edit - I'm not sure about "easily". It can be a little longer.
|
||||
#define MAX_MESSAGE_LEN 4096 //VOREStation Edit - I'm not sure about "easily". It can be a little longer.
|
||||
#define MAX_PAPER_MESSAGE_LEN 6144
|
||||
#define MAX_BOOK_MESSAGE_LEN 24576
|
||||
#define MAX_RECORD_LENGTH 24576
|
||||
@@ -121,65 +121,6 @@
|
||||
#define WALL_CAN_OPEN 1
|
||||
#define WALL_OPENING 2
|
||||
|
||||
#define DEFAULT_TABLE_MATERIAL "plastic"
|
||||
#define DEFAULT_WALL_MATERIAL "steel"
|
||||
|
||||
#define MAT_IRON "iron"
|
||||
#define MAT_MARBLE "marble"
|
||||
#define MAT_STEEL "steel"
|
||||
#define MAT_PLASTIC "plastic"
|
||||
#define MAT_GLASS "glass"
|
||||
#define MAT_SILVER "silver"
|
||||
#define MAT_GOLD "gold"
|
||||
#define MAT_URANIUM "uranium" //Did it
|
||||
#define MAT_TITANIUM "titanium"
|
||||
#define MAT_PHORON "phoron"
|
||||
#define MAT_DIAMOND "diamond"
|
||||
#define MAT_SNOW "snow"
|
||||
#define MAT_WOOD "wood"
|
||||
#define MAT_LOG "log"
|
||||
#define MAT_SIFWOOD "alien wood"
|
||||
#define MAT_SIFLOG "alien log"
|
||||
#define MAT_STEELHULL "steel hull"
|
||||
#define MAT_PLASTEEL "plasteel"
|
||||
#define MAT_PLASTEELHULL "plasteel hull"
|
||||
#define MAT_DURASTEEL "durasteel"
|
||||
#define MAT_DURASTEELHULL "durasteel hull"
|
||||
#define MAT_TITANIUMHULL "titanium hull"
|
||||
#define MAT_VERDANTIUM "verdantium"
|
||||
#define MAT_MORPHIUM "morphium"
|
||||
#define MAT_MORPHIUMHULL "morphium hull"
|
||||
#define MAT_VALHOLLIDE "valhollide"
|
||||
#define MAT_LEAD "lead"
|
||||
#define MAT_SUPERMATTER "supermatter"
|
||||
#define MAT_METALHYDROGEN "mhydrogen"
|
||||
#define MAT_OSMIUM "osmium"
|
||||
#define MAT_GRAPHITE "graphite"
|
||||
#define MAT_LEATHER "leather"
|
||||
#define MAT_CHITIN "chitin"
|
||||
#define MAT_CLOTH "cloth"
|
||||
#define MAT_SYNCLOTH "syncloth"
|
||||
#define MAT_COPPER "copper"
|
||||
#define MAT_QUARTZ "quartz"
|
||||
#define MAT_TIN "tin"
|
||||
#define MAT_VOPAL "void opal"
|
||||
#define MAT_ALUMINIUM "aluminium"
|
||||
#define MAT_BRONZE "bronze"
|
||||
#define MAT_PAINITE "painite"
|
||||
#define MAT_BOROSILICATE "borosilicate glass"
|
||||
|
||||
#define SHARD_SHARD "shard"
|
||||
#define SHARD_SHRAPNEL "shrapnel"
|
||||
#define SHARD_STONE_PIECE "piece"
|
||||
#define SHARD_SPLINTER "splinters"
|
||||
#define SHARD_NONE ""
|
||||
|
||||
#define MATERIAL_UNMELTABLE 0x1
|
||||
#define MATERIAL_BRITTLE 0x2
|
||||
#define MATERIAL_PADDING 0x4
|
||||
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
|
||||
#define BOMBCAP_DVSTN_RADIUS (max_explosion_range/4)
|
||||
#define BOMBCAP_HEAVY_RADIUS (max_explosion_range/2)
|
||||
#define BOMBCAP_LIGHT_RADIUS max_explosion_range
|
||||
@@ -504,3 +445,7 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
|
||||
#define APPEARANCECHANGER_CHANGED_EYES "Eye Color"
|
||||
|
||||
#define GET_DECL(D) (ispath(D, /decl) ? (decls_repository.fetched_decls[D] || decls_repository.get_decl(D)) : null)
|
||||
|
||||
#define LOADOUT_WHITELIST_OFF 0
|
||||
#define LOADOUT_WHITELIST_LAX 1
|
||||
#define LOADOUT_WHITELIST_STRICT 2
|
||||
@@ -272,6 +272,10 @@
|
||||
#define TASTE_DULL 0.5 //anything below 30%
|
||||
#define TASTE_NUMB 0.1 //anything below 150%
|
||||
|
||||
//Used by emotes
|
||||
#define VISIBLE_MESSAGE 1
|
||||
#define AUDIBLE_MESSAGE 2
|
||||
|
||||
// If they're in an FBP, what braintype.
|
||||
#define FBP_NONE ""
|
||||
#define FBP_CYBORG "Cyborg"
|
||||
@@ -433,6 +437,8 @@
|
||||
#define EXAMINE_SKIPLEGS 0x0080
|
||||
#define EXAMINE_SKIPFEET 0x0100
|
||||
|
||||
#define MAX_NUTRITION 5000 //VOREStation Edit
|
||||
#define MAX_NUTRITION 6000 //VOREStation Edit
|
||||
|
||||
#define FAKE_INVIS_ALPHA_THRESHOLD 127 // If something's alpha var is at or below this number, certain things will pretend it is invisible.
|
||||
|
||||
#define DEATHGASP_NO_MESSAGE "no message"
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Tool types, if you add new ones please add them to /obj/item/debug/omnitool in code/game/objects/items/debug_items.dm
|
||||
#define TOOL_CROWBAR "crowbar"
|
||||
#define TOOL_MULTITOOL "multitool"
|
||||
#define TOOL_SCREWDRIVER "screwdriver"
|
||||
#define TOOL_WIRECUTTER "wirecutter"
|
||||
#define TOOL_WRENCH "wrench"
|
||||
#define TOOL_WELDER "welder"
|
||||
#define TOOL_CABLE_COIL "cablecoil"
|
||||
#define TOOL_ANALYZER "analyzer"
|
||||
#define TOOL_MINING "mining"
|
||||
#define TOOL_SHOVEL "shovel"
|
||||
#define TOOL_RETRACTOR "retractor"
|
||||
#define TOOL_HEMOSTAT "hemostat"
|
||||
#define TOOL_CAUTERY "cautery"
|
||||
#define TOOL_DRILL "drill"
|
||||
#define TOOL_SCALPEL "scalpel"
|
||||
#define TOOL_SAW "saw"
|
||||
#define TOOL_BONESET "bonesetter"
|
||||
#define TOOL_KNIFE "knife"
|
||||
#define TOOL_BLOODFILTER "bloodfilter"
|
||||
#define TOOL_ROLLINGPIN "rollingpin"
|
||||
@@ -8,4 +8,5 @@ GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the
|
||||
GLOBAL_LIST_EMPTY(tagger_locations)
|
||||
|
||||
GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Prey", "Switch", "Non-Vore", "Unset"))
|
||||
GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
|
||||
GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
|
||||
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
|
||||
|
||||
@@ -416,13 +416,9 @@ This actually tests if they have the same entries and values.
|
||||
|
||||
|
||||
|
||||
|
||||
//Mergesort: any value in a list
|
||||
/proc/sortList(var/list/L)
|
||||
if(L.len < 2)
|
||||
return L
|
||||
var/middle = L.len / 2 + 1 // Copy is first,second-1
|
||||
return mergeLists(sortList(L.Copy(0,middle)), sortList(L.Copy(middle))) //second parameter null = to end of list
|
||||
//any value in a list
|
||||
/proc/sortList(list/L, cmp=/proc/cmp_text_asc)
|
||||
return sortTim(L.Copy(), cmp)
|
||||
|
||||
//Mergsorge: uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead
|
||||
/proc/sortNames(var/list/L)
|
||||
|
||||
@@ -242,6 +242,7 @@ GLOBAL_LIST_EMPTY(mannequins)
|
||||
var/datum/digest_mode/DM = new T
|
||||
GLOB.digest_modes[DM.id] = DM
|
||||
// VOREStation Add End
|
||||
init_crafting_recipes(GLOB.crafting_recipes)
|
||||
|
||||
/*
|
||||
// Custom species traits
|
||||
@@ -278,8 +279,13 @@ GLOBAL_LIST_EMPTY(mannequins)
|
||||
return 1 // Hooks must return 1
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
/// Inits the crafting recipe list, sorting crafting recipe requirements in the process.
|
||||
/proc/init_crafting_recipes(list/crafting_recipes)
|
||||
for(var/path in subtypesof(/datum/crafting_recipe))
|
||||
var/datum/crafting_recipe/recipe = new path()
|
||||
recipe.reqs = sortList(recipe.reqs, /proc/cmp_crafting_req_priority)
|
||||
crafting_recipes += recipe
|
||||
return crafting_recipes
|
||||
/* // Uncomment to debug chemical reaction list.
|
||||
/client/verb/debug_chemical_list()
|
||||
|
||||
|
||||
@@ -485,7 +485,7 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
|
||||
hair_accesories_list[path] = instance
|
||||
|
||||
// Custom species traits
|
||||
paths = typesof(/datum/trait) - /datum/trait
|
||||
paths = typesof(/datum/trait) - /datum/trait - /datum/trait/negative - /datum/trait/neutral - /datum/trait/positive
|
||||
for(var/path in paths)
|
||||
var/datum/trait/instance = new path()
|
||||
if(!instance.name)
|
||||
|
||||
@@ -64,4 +64,23 @@
|
||||
return b_score - a_score
|
||||
|
||||
/proc/cmp_typepaths_asc(A, B)
|
||||
return sorttext("[B]","[A]")
|
||||
return sorttext("[B]","[A]")
|
||||
|
||||
/**
|
||||
* Sorts crafting recipe requirements before the crafting recipe is inserted into GLOB.crafting_recipes
|
||||
*
|
||||
* Prioritises [/datum/reagent] to ensure reagent requirements are always processed first when crafting.
|
||||
* This prevents any reagent_containers from being consumed before the reagents they contain, which can
|
||||
* lead to runtimes and item duplication when it happens.
|
||||
*/
|
||||
/proc/cmp_crafting_req_priority(A, B)
|
||||
var/lhs
|
||||
var/rhs
|
||||
|
||||
lhs = ispath(A, /datum/reagent) ? 0 : 1
|
||||
rhs = ispath(B, /datum/reagent) ? 0 : 1
|
||||
|
||||
return lhs - rhs
|
||||
|
||||
/proc/cmp_text_asc(a,b)
|
||||
return sorttext(b,a)
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
GLOBAL_LIST_EMPTY(string_lists)
|
||||
|
||||
/**
|
||||
* Caches lists with non-numeric stringify-able values (text or typepath).
|
||||
*/
|
||||
/proc/string_list(list/values)
|
||||
var/string_id = values.Join("-")
|
||||
|
||||
. = GLOB.string_lists[string_id]
|
||||
|
||||
if(.)
|
||||
return
|
||||
|
||||
return GLOB.string_lists[string_id] = values
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
/atom/Click(var/location, var/control, var/params) // This is their reaction to being clicked on (standard proc)
|
||||
if(src)
|
||||
SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr)
|
||||
usr.ClickOn(src, params)
|
||||
|
||||
/atom/DblClick(var/location, var/control, var/params)
|
||||
|
||||
@@ -187,3 +187,5 @@
|
||||
#define ui_mech_airtoggle "WEST+1:-7, SOUTH+8"
|
||||
#define ui_mech_deco1_f "WEST+2:-7, SOUTH+8"
|
||||
#define ui_mech_deco2_f "WEST+2:-7, SOUTH+9"
|
||||
|
||||
#define ui_crafting "EAST-4:22,SOUTH:5"
|
||||
@@ -246,6 +246,7 @@
|
||||
add_overlay(selecting_appearance)
|
||||
|
||||
/obj/screen/Click(location, control, params)
|
||||
..() // why the FUCK was this not called before
|
||||
if(!usr) return 1
|
||||
switch(name)
|
||||
if("toggle")
|
||||
|
||||
@@ -284,7 +284,10 @@ var/list/gamemode_cache = list()
|
||||
var/static/disable_cid_warn_popup = FALSE
|
||||
|
||||
// whether or not to use the nightshift subsystem to perform lighting changes
|
||||
var/static/enable_night_shifts = FALSE
|
||||
var/static/enable_night_shifts = FALSE
|
||||
|
||||
// How strictly the loadout enforces object species whitelists
|
||||
var/loadout_whitelist = LOADOUT_WHITELIST_LAX
|
||||
|
||||
var/static/vgs_access_identifier = null // VOREStation Edit - VGS
|
||||
var/static/vgs_server_port = null // VOREStation Edit - VGS
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
SUBSYSTEM_DEF(chemistry)
|
||||
name = "Chemistry"
|
||||
wait = 20
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_CHEMISTRY
|
||||
|
||||
var/list/chemical_reactions = list()
|
||||
var/list/instant_reactions_by_reagent = list()
|
||||
var/list/distilled_reactions_by_reagent = list()
|
||||
// var/list/fusion_reactions_by_reagent = list() // TODO: Fusion reactions as chemical reactions
|
||||
var/list/chemical_reagents = list()
|
||||
|
||||
/datum/controller/subsystem/chemistry/Recover()
|
||||
log_debug("[name] subsystem Recover().")
|
||||
chemical_reactions = SSchemistry.chemical_reactions
|
||||
chemical_reagents = SSchemistry.chemical_reagents
|
||||
|
||||
/datum/controller/subsystem/chemistry/Initialize()
|
||||
initialize_chemical_reagents()
|
||||
initialize_chemical_reactions()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/chemistry/stat_entry()
|
||||
..("C: [chemical_reagents.len] | R: [chemical_reactions.len]")
|
||||
|
||||
//Chemical Reactions - Initialises all /decl/chemical_reaction into a list
|
||||
// It is filtered into multiple lists within a list.
|
||||
// For example:
|
||||
// chemical_reactions_by_reagent["phoron"] is a list of all reactions relating to phoron
|
||||
// Note that entries in the list are NOT duplicated. So if a reaction pertains to
|
||||
// more than one chemical it will still only appear in only one of the sublists.
|
||||
/datum/controller/subsystem/chemistry/proc/initialize_chemical_reactions()
|
||||
var/list/paths = decls_repository.get_decls_of_subtype(/decl/chemical_reaction)
|
||||
|
||||
for(var/path in paths)
|
||||
var/decl/chemical_reaction/D = paths[path]
|
||||
chemical_reactions += D
|
||||
if(D.required_reagents && D.required_reagents.len)
|
||||
var/reagent_id = D.required_reagents[1]
|
||||
|
||||
var/list/add_to = instant_reactions_by_reagent // Default to instant reactions list, if something's gone wrong
|
||||
// if(istype(D, /decl/chemical_reaction/fusion)) // TODO: fusion reactions as chemical reactions
|
||||
// add_to = fusion_reactions_by_reagent
|
||||
if(istype(D, /decl/chemical_reaction/distilling))
|
||||
add_to = distilled_reactions_by_reagent
|
||||
|
||||
LAZYINITLIST(add_to[reagent_id])
|
||||
add_to[reagent_id] += D
|
||||
|
||||
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
|
||||
/datum/controller/subsystem/chemistry/proc/initialize_chemical_reagents()
|
||||
var/paths = subtypesof(/datum/reagent)
|
||||
chemical_reagents = list()
|
||||
for(var/path in paths)
|
||||
var/datum/reagent/D = new path()
|
||||
if(!D.name)
|
||||
continue
|
||||
chemical_reagents[D.id] = D
|
||||
@@ -1,54 +0,0 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(chemistry)
|
||||
name = "Chemistry"
|
||||
wait = 20
|
||||
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING
|
||||
init_order = INIT_ORDER_CHEMISTRY
|
||||
var/list/chemical_reactions = list()
|
||||
var/list/chemical_reactions_by_reagent = list()
|
||||
var/list/chemical_reagents = list()
|
||||
|
||||
/datum/controller/subsystem/processing/chemistry/Recover()
|
||||
log_debug("[name] subsystem Recover().")
|
||||
if(SSchemistry.current_thing)
|
||||
log_debug("current_thing was: (\ref[SSchemistry.current_thing])[SSchemistry.current_thing]([SSchemistry.current_thing.type]) - currentrun: [SSchemistry.currentrun.len] vs total: [SSchemistry.processing.len]")
|
||||
var/list/old_processing = SSchemistry.processing.Copy()
|
||||
for(var/datum/D in old_processing)
|
||||
if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING))
|
||||
processing |= D
|
||||
|
||||
chemical_reactions = SSchemistry.chemical_reactions
|
||||
chemical_reagents = SSchemistry.chemical_reagents
|
||||
|
||||
/datum/controller/subsystem/processing/chemistry/Initialize()
|
||||
initialize_chemical_reactions()
|
||||
initialize_chemical_reagents()
|
||||
..()
|
||||
|
||||
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
|
||||
// It is filtered into multiple lists within a list.
|
||||
// For example:
|
||||
// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron
|
||||
// Note that entries in the list are NOT duplicated. So if a reaction pertains to
|
||||
// more than one chemical it will still only appear in only one of the sublists.
|
||||
/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reactions()
|
||||
var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction
|
||||
chemical_reactions = list()
|
||||
chemical_reactions_by_reagent = list()
|
||||
|
||||
for(var/path in paths)
|
||||
var/datum/chemical_reaction/D = new path
|
||||
chemical_reactions += D
|
||||
if(D.required_reagents && D.required_reagents.len)
|
||||
var/reagent_id = D.required_reagents[1]
|
||||
LAZYINITLIST(chemical_reactions_by_reagent[reagent_id])
|
||||
chemical_reactions_by_reagent[reagent_id] += D
|
||||
|
||||
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
|
||||
/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reagents()
|
||||
var/paths = typesof(/datum/reagent) - /datum/reagent
|
||||
chemical_reagents = list()
|
||||
for(var/path in paths)
|
||||
var/datum/reagent/D = new path()
|
||||
if(!D.name)
|
||||
continue
|
||||
chemical_reagents[D.id] = D
|
||||
@@ -462,15 +462,15 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
|
||||
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
|
||||
if (aiPlayer.stat != 2)
|
||||
to_world("<span class='filter_system'><b>[aiPlayer.name] (Played by: [aiPlayer.key])'s laws at the end of the round were:</b></span>")
|
||||
to_world("<span class='filter_system'><b>[aiPlayer.name]'s laws at the end of the round were:</b></span>") // VOREStation edit
|
||||
else
|
||||
to_world("<span class='filter_system'><b>[aiPlayer.name] (Played by: [aiPlayer.key])'s laws when it was deactivated were:</b></span>")
|
||||
to_world("<span class='filter_system'><b>[aiPlayer.name]'s laws when it was deactivated were:</b></span>") // VOREStation edit
|
||||
aiPlayer.show_laws(1)
|
||||
|
||||
if (aiPlayer.connected_robots.len)
|
||||
var/robolist = "<b>The AI's loyal minions were:</b> "
|
||||
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
|
||||
robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.key]), ":" (Played by: [robo.key]), "]"
|
||||
robolist += "[robo.name][robo.stat?" (Deactivated), ":", "]" // VOREStation edit
|
||||
to_world("<span class='filter_system'>[robolist]</span>")
|
||||
|
||||
var/dronecount = 0
|
||||
@@ -488,9 +488,9 @@ var/global/datum/controller/subsystem/ticker/ticker
|
||||
|
||||
if (!robo.connected_ai)
|
||||
if (robo.stat != 2)
|
||||
to_world("<span class='filter_system'><b>[robo.name] (Played by: [robo.key]) survived as an AI-less stationbound synthetic! Its laws were:</b></span>")
|
||||
to_world("<span class='filter_system'><b>[robo.name] survived as an AI-less stationbound synthetic! Its laws were:</b></span>") // VOREStation edit
|
||||
else
|
||||
to_world("<span class='filter_system'><b>[robo.name] (Played by: [robo.key]) was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:</b></span>")
|
||||
to_world("<span class='filter_system'><b>[robo.name] was unable to survive the rigors of being a stationbound synthetic without an AI. Its laws were:</b></span>") // VOREStation edit
|
||||
|
||||
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
|
||||
robo.laws.show_laws(world)
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
/datum/component/personal_crafting/Initialize()
|
||||
if(ismob(parent))
|
||||
RegisterSignal(parent, COMSIG_MOB_CLIENT_LOGIN, .proc/create_mob_button)
|
||||
|
||||
/datum/component/personal_crafting/proc/create_mob_button(mob/user, client/CL)
|
||||
// SIGNAL_HANDLER
|
||||
|
||||
var/datum/hud/H = user.hud_used
|
||||
var/obj/screen/craft/C = new()
|
||||
C.icon = H.ui_style
|
||||
H.other += C
|
||||
CL.screen += C
|
||||
RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact)
|
||||
|
||||
/datum/component/personal_crafting
|
||||
var/busy
|
||||
var/viewing_category = 1 //typical powergamer starting on the Weapons tab
|
||||
var/viewing_subcategory = 1
|
||||
var/list/categories = list(
|
||||
CAT_WEAPONRY = list(
|
||||
CAT_WEAPON,
|
||||
CAT_AMMO,
|
||||
),
|
||||
CAT_ROBOT = CAT_NONE,
|
||||
CAT_MISC = CAT_NONE,
|
||||
CAT_PRIMAL = CAT_NONE,
|
||||
CAT_FOOD = list(
|
||||
CAT_BREAD,
|
||||
CAT_BURGER,
|
||||
CAT_CAKE,
|
||||
CAT_EGG,
|
||||
CAT_ICE,
|
||||
CAT_MEAT,
|
||||
CAT_MISCFOOD,
|
||||
CAT_PASTRY,
|
||||
CAT_PIE,
|
||||
CAT_PIZZA,
|
||||
CAT_SALAD,
|
||||
CAT_SANDWICH,
|
||||
CAT_SOUP,
|
||||
CAT_SPAGHETTI,
|
||||
),
|
||||
CAT_DRINK = CAT_NONE,
|
||||
CAT_CLOTHING = CAT_NONE,
|
||||
)
|
||||
|
||||
var/cur_category = CAT_NONE
|
||||
var/cur_subcategory = CAT_NONE
|
||||
var/datum/action/innate/crafting/button
|
||||
var/display_craftable_only = FALSE
|
||||
var/display_compact = TRUE
|
||||
|
||||
/* This is what procs do:
|
||||
get_environment - gets a list of things accessable for crafting by user
|
||||
get_surroundings - takes a list of things and makes a list of key-types to values-amounts of said type in the list
|
||||
check_contents - takes a recipe and a key-type list and checks if said recipe can be done with available stuff
|
||||
check_tools - takes recipe, a key-type list, and a user and checks if there are enough tools to do the stuff, checks bugs one level deep
|
||||
construct_item - takes a recipe and a user, call all the checking procs, calls do_after, checks all the things again, calls del_reqs, creates result, calls CheckParts of said result with argument being list returned by deel_reqs
|
||||
del_reqs - takes recipe and a user, loops over the recipes reqs var and tries to find everything in the list make by get_environment and delete it/add to parts list, then returns the said list
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check that the contents of the recipe meet the requirements.
|
||||
*
|
||||
* user: The /mob that initated the crafting.
|
||||
* R: The /datum/crafting_recipe being attempted.
|
||||
* contents: List of items to search for R's reqs.
|
||||
*/
|
||||
/datum/component/personal_crafting/proc/check_contents(atom/a, datum/crafting_recipe/R, list/contents)
|
||||
var/list/item_instances = contents["instances"]
|
||||
var/list/machines = contents["machinery"]
|
||||
contents = contents["other"]
|
||||
|
||||
|
||||
var/list/requirements_list = list()
|
||||
|
||||
// Process all requirements
|
||||
for(var/requirement_path in R.reqs)
|
||||
// Check we have the appropriate amount available in the contents list
|
||||
var/needed_amount = R.reqs[requirement_path]
|
||||
for(var/content_item_path in contents)
|
||||
// Right path and not blacklisted
|
||||
if(!ispath(content_item_path, requirement_path) || R.blacklist.Find(content_item_path))
|
||||
continue
|
||||
|
||||
needed_amount -= contents[content_item_path]
|
||||
if(needed_amount <= 0)
|
||||
break
|
||||
|
||||
if(needed_amount > 0)
|
||||
return FALSE
|
||||
|
||||
// Store the instances of what we will use for R.check_requirements() for requirement_path
|
||||
var/list/instances_list = list()
|
||||
for(var/instance_path in item_instances)
|
||||
if(ispath(instance_path, requirement_path))
|
||||
instances_list += item_instances[instance_path]
|
||||
|
||||
requirements_list[requirement_path] = instances_list
|
||||
|
||||
for(var/requirement_path in R.chem_catalysts)
|
||||
if(contents[requirement_path] < R.chem_catalysts[requirement_path])
|
||||
return FALSE
|
||||
|
||||
for(var/machinery_path in R.machinery)
|
||||
if(!machines[machinery_path])//We don't care for volume with machines, just if one is there or not
|
||||
return FALSE
|
||||
|
||||
return R.check_requirements(a, requirements_list)
|
||||
|
||||
/datum/component/personal_crafting/proc/get_environment(atom/a, list/blacklist = null, radius_range = 1)
|
||||
. = list()
|
||||
|
||||
if(!isturf(a.loc))
|
||||
return
|
||||
|
||||
for(var/atom/movable/AM in range(radius_range, a))
|
||||
if(/*(AM.flags_1 & HOLOGRAM_1) ||*/ (blacklist && (AM.type in blacklist)))
|
||||
continue
|
||||
. += AM
|
||||
|
||||
|
||||
/datum/component/personal_crafting/proc/get_surroundings(atom/a, list/blacklist=null)
|
||||
. = list()
|
||||
.["tool_qualities"] = list()
|
||||
.["other"] = list()
|
||||
.["instances"] = list()
|
||||
.["machinery"] = list()
|
||||
for(var/obj/object in get_environment(a, blacklist))
|
||||
if(isitem(object))
|
||||
var/obj/item/item = object
|
||||
LAZYADDASSOCLIST(.["instances"], item.type, item)
|
||||
if(istype(item, /obj/item/stack))
|
||||
var/obj/item/stack/stack = item
|
||||
.["other"][item.type] += stack.amount
|
||||
else if(item.tool_qualities)
|
||||
.["tool_qualities"] |= item.tool_qualities
|
||||
.["other"][item.type] += 1
|
||||
else
|
||||
if(istype(item, /obj/item/weapon/reagent_containers))
|
||||
var/obj/item/weapon/reagent_containers/container = item
|
||||
// if(container.is_drainable())
|
||||
if(container.is_open_container()) // this isn't exactly the same
|
||||
for(var/datum/reagent/reagent in container.reagents.reagent_list)
|
||||
.["other"][reagent.type] += reagent.volume
|
||||
.["other"][item.type] += 1
|
||||
else if (istype(object, /obj/machinery))
|
||||
LAZYADDASSOCLIST(.["machinery"], object.type, object)
|
||||
|
||||
|
||||
|
||||
/// Returns a boolean on whether the tool requirements of the input recipe are satisfied by the input source and surroundings.
|
||||
/datum/component/personal_crafting/proc/check_tools(atom/source, datum/crafting_recipe/recipe, list/surroundings)
|
||||
if(!length(recipe.tool_behaviors) && !length(recipe.tool_paths))
|
||||
return TRUE
|
||||
var/list/available_tools = list()
|
||||
var/list/present_qualities = list()
|
||||
|
||||
for(var/obj/item/contained_item in source.contents)
|
||||
// if(contained_item.GetComponent(/datum/component/storage))
|
||||
if(istype(contained_item, /obj/item/weapon/storage)) // cursed
|
||||
for(var/obj/item/subcontained_item in contained_item.contents)
|
||||
available_tools[subcontained_item.type] = TRUE
|
||||
for(var/behavior in subcontained_item.tool_qualities)
|
||||
present_qualities[behavior] = TRUE
|
||||
available_tools[contained_item.type] = TRUE
|
||||
for(var/behavior in contained_item.tool_qualities)
|
||||
present_qualities[behavior] = TRUE
|
||||
|
||||
for(var/quality in surroundings["tool_behaviour"])
|
||||
present_qualities[quality] = TRUE
|
||||
|
||||
for(var/path in surroundings["other"])
|
||||
available_tools[path] = TRUE
|
||||
|
||||
for(var/required_quality in recipe.tool_behaviors)
|
||||
if(present_qualities[required_quality])
|
||||
continue
|
||||
return FALSE
|
||||
|
||||
for(var/required_path in recipe.tool_paths)
|
||||
var/found_this_tool = FALSE
|
||||
for(var/tool_path in available_tools)
|
||||
if(!ispath(required_path, tool_path))
|
||||
continue
|
||||
found_this_tool = TRUE
|
||||
break
|
||||
if(found_this_tool)
|
||||
continue
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/component/personal_crafting/proc/construct_item(atom/a, datum/crafting_recipe/R)
|
||||
var/list/contents = get_surroundings(a,R.blacklist)
|
||||
// var/send_feedback = 1
|
||||
if(check_contents(a, R, contents))
|
||||
if(check_tools(a, R, contents))
|
||||
if(R.one_per_turf)
|
||||
for(var/content in get_turf(a))
|
||||
if(istype(content, R.result))
|
||||
return ", object already present."
|
||||
//If we're a mob we'll try a do_after; non mobs will instead instantly construct the item
|
||||
if(ismob(a) && !do_after(a, R.time, target = a))
|
||||
return "."
|
||||
contents = get_surroundings(a,R.blacklist)
|
||||
if(!check_contents(a, R, contents))
|
||||
return ", missing component."
|
||||
if(!check_tools(a, R, contents))
|
||||
return ", missing tool."
|
||||
var/list/parts = del_reqs(R, a)
|
||||
var/atom/movable/I = new R.result (get_turf(a.loc))
|
||||
I.CheckParts(parts, R)
|
||||
// if(send_feedback)
|
||||
// SSblackbox.record_feedback("tally", "object_crafted", 1, I.type)
|
||||
return I //Send the item back to whatever called this proc so it can handle whatever it wants to do with the new item
|
||||
return ", missing tool."
|
||||
return ", missing component."
|
||||
|
||||
/*Del reqs works like this:
|
||||
|
||||
Loop over reqs var of the recipe
|
||||
Set var amt to the value current cycle req is pointing to, its amount of type we need to delete
|
||||
Get var/surroundings list of things accessable to crafting by get_environment()
|
||||
Check the type of the current cycle req
|
||||
If its reagent then do a while loop, inside it try to locate() reagent containers, inside such containers try to locate needed reagent, if there isn't remove thing from surroundings
|
||||
If there is enough reagent in the search result then delete the needed amount, create the same type of reagent with the same data var and put it into deletion list
|
||||
If there isn't enough take all of that reagent from the container, put into deletion list, substract the amt var by the volume of reagent, remove the container from surroundings list and keep searching
|
||||
While doing above stuff check deletion list if it already has such reagnet, if yes merge instead of adding second one
|
||||
If its stack check if it has enough amount
|
||||
If yes create new stack with the needed amount and put in into deletion list, substract taken amount from the stack
|
||||
If no put all of the stack in the deletion list, substract its amount from amt and keep searching
|
||||
While doing above stuff check deletion list if it already has such stack type, if yes try to merge them instead of adding new one
|
||||
If its anything else just locate() in in the list in a while loop, each find --s the amt var and puts the found stuff in deletion loop
|
||||
|
||||
Then do a loop over parts var of the recipe
|
||||
Do similar stuff to what we have done above, but now in deletion list, until the parts conditions are satisfied keep taking from the deletion list and putting it into parts list for return
|
||||
|
||||
After its done loop over deletion list and delete all the shit that wasn't taken by parts loop
|
||||
|
||||
del_reqs return the list of parts resulting object will receive as argument of CheckParts proc, on the atom level it will add them all to the contents, on all other levels it calls ..() and does whatever is needed afterwards but from contents list already
|
||||
*/
|
||||
|
||||
/datum/component/personal_crafting/proc/del_reqs(datum/crafting_recipe/R, atom/a)
|
||||
var/list/surroundings
|
||||
var/list/Deletion = list()
|
||||
. = list()
|
||||
var/data
|
||||
var/amt
|
||||
var/list/requirements = list()
|
||||
if(R.reqs)
|
||||
requirements += R.reqs
|
||||
if(R.machinery)
|
||||
requirements += R.machinery
|
||||
main_loop:
|
||||
for(var/path_key in requirements)
|
||||
amt = R.reqs[path_key] || R.machinery[path_key]
|
||||
if(!amt)//since machinery can have 0 aka CRAFTING_MACHINERY_USE - i.e. use it, don't consume it!
|
||||
continue main_loop
|
||||
surroundings = get_environment(a, R.blacklist)
|
||||
surroundings -= Deletion
|
||||
if(ispath(path_key, /datum/reagent))
|
||||
var/datum/reagent/RG = new path_key
|
||||
var/datum/reagent/RGNT
|
||||
while(amt > 0)
|
||||
var/obj/item/weapon/reagent_containers/RC = locate() in surroundings
|
||||
RG = RC.reagents.get_reagent(path_key)
|
||||
if(RG)
|
||||
if(!locate(RG.type) in Deletion)
|
||||
Deletion += new RG.type()
|
||||
if(RG.volume > amt)
|
||||
RG.volume -= amt
|
||||
data = RG.data
|
||||
RC.reagents.conditional_update(RC)
|
||||
RG = locate(RG.type) in Deletion
|
||||
RG.volume = amt
|
||||
RG.data += data
|
||||
continue main_loop
|
||||
else
|
||||
surroundings -= RC
|
||||
amt -= RG.volume
|
||||
RC.reagents.reagent_list -= RG
|
||||
RC.reagents.conditional_update(RC)
|
||||
RGNT = locate(RG.type) in Deletion
|
||||
RGNT.volume += RG.volume
|
||||
RGNT.data += RG.data
|
||||
qdel(RG)
|
||||
SEND_SIGNAL(RC.reagents, COMSIG_REAGENTS_CRAFTING_PING) // - [] TODO: Make this entire thing less spaghetti
|
||||
else
|
||||
surroundings -= RC
|
||||
else if(ispath(path_key, /obj/item/stack))
|
||||
var/obj/item/stack/S
|
||||
var/obj/item/stack/SD
|
||||
while(amt > 0)
|
||||
S = locate(path_key) in surroundings
|
||||
if(S.amount >= amt)
|
||||
if(!locate(S.type) in Deletion)
|
||||
SD = new S.type()
|
||||
Deletion += SD
|
||||
S.use(amt)
|
||||
SD = locate(S.type) in Deletion
|
||||
SD.amount += amt
|
||||
continue main_loop
|
||||
else
|
||||
amt -= S.amount
|
||||
if(!locate(S.type) in Deletion)
|
||||
Deletion += S
|
||||
else
|
||||
data = S.amount
|
||||
S = locate(S.type) in Deletion
|
||||
S.add(data)
|
||||
surroundings -= S
|
||||
else
|
||||
var/atom/movable/I
|
||||
while(amt > 0)
|
||||
I = locate(path_key) in surroundings
|
||||
Deletion += I
|
||||
surroundings -= I
|
||||
amt--
|
||||
var/list/partlist = list(R.parts.len)
|
||||
for(var/M in R.parts)
|
||||
partlist[M] = R.parts[M]
|
||||
for(var/part in R.parts)
|
||||
if(istype(part, /datum/reagent))
|
||||
var/datum/reagent/RG = locate(part) in Deletion
|
||||
if(RG.volume > partlist[part])
|
||||
RG.volume = partlist[part]
|
||||
. += RG
|
||||
Deletion -= RG
|
||||
continue
|
||||
else if(istype(part, /obj/item/stack))
|
||||
var/obj/item/stack/ST = locate(part) in Deletion
|
||||
if(ST.amount > partlist[part])
|
||||
ST.amount = partlist[part]
|
||||
. += ST
|
||||
Deletion -= ST
|
||||
continue
|
||||
else
|
||||
while(partlist[part] > 0)
|
||||
var/atom/movable/AM = locate(part) in Deletion
|
||||
. += AM
|
||||
Deletion -= AM
|
||||
partlist[part] -= 1
|
||||
while(Deletion.len)
|
||||
var/DL = Deletion[Deletion.len]
|
||||
Deletion.Cut(Deletion.len)
|
||||
// Snowflake handling of reagent containers and storage atoms.
|
||||
// If we consumed them in our crafting, we should dump their contents out before qdeling them.
|
||||
if(istype(DL, /obj/item/weapon/reagent_containers))
|
||||
var/obj/item/weapon/reagent_containers/container = DL
|
||||
container.reagents.clear_reagents()
|
||||
// container.reagents.expose(container.loc, TOUCH)
|
||||
else if(istype(DL, /obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/container = DL
|
||||
container.spill()
|
||||
container.close_all()
|
||||
qdel(DL)
|
||||
|
||||
/datum/component/personal_crafting/proc/component_ui_interact(atom/movable/screen/craft/image, location, control, params, user)
|
||||
// SIGNAL_HANDLER
|
||||
|
||||
if(user == parent)
|
||||
INVOKE_ASYNC(src, .proc/tgui_interact, user)
|
||||
|
||||
/datum/component/personal_crafting/tgui_state(mob/user)
|
||||
return GLOB.tgui_not_incapacitated_turf_state
|
||||
|
||||
//For the UI related things we're going to assume the user is a mob rather than typesetting it to an atom as the UI isn't generated if the parent is an atom
|
||||
/datum/component/personal_crafting/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
cur_category = categories[1]
|
||||
if(islist(categories[cur_category]))
|
||||
var/list/subcats = categories[cur_category]
|
||||
cur_subcategory = subcats[1]
|
||||
else
|
||||
cur_subcategory = CAT_NONE
|
||||
ui = new(user, src, "PersonalCrafting")
|
||||
ui.open()
|
||||
|
||||
/datum/component/personal_crafting/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["busy"] = busy
|
||||
data["category"] = cur_category
|
||||
data["subcategory"] = cur_subcategory
|
||||
data["display_craftable_only"] = display_craftable_only
|
||||
data["display_compact"] = display_compact
|
||||
|
||||
var/list/surroundings = get_surroundings(user)
|
||||
var/list/craftability = list()
|
||||
for(var/rec in GLOB.crafting_recipes)
|
||||
var/datum/crafting_recipe/R = rec
|
||||
|
||||
if(!R.always_available && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
|
||||
continue
|
||||
|
||||
if((R.category != cur_category) || (R.subcategory != cur_subcategory))
|
||||
continue
|
||||
|
||||
craftability["[REF(R)]"] = check_contents(user, R, surroundings)
|
||||
|
||||
data["craftability"] = craftability
|
||||
return data
|
||||
|
||||
/datum/component/personal_crafting/tgui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/crafting_recipes = list()
|
||||
for(var/rec in GLOB.crafting_recipes)
|
||||
var/datum/crafting_recipe/R = rec
|
||||
|
||||
if(R.name == "") //This is one of the invalid parents that sneaks in
|
||||
continue
|
||||
|
||||
if(!R.always_available && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this.
|
||||
continue
|
||||
|
||||
if(isnull(crafting_recipes[R.category]))
|
||||
crafting_recipes[R.category] = list()
|
||||
|
||||
if(R.subcategory == CAT_NONE)
|
||||
crafting_recipes[R.category] += list(build_recipe_data(R))
|
||||
else
|
||||
if(isnull(crafting_recipes[R.category][R.subcategory]))
|
||||
crafting_recipes[R.category][R.subcategory] = list()
|
||||
crafting_recipes[R.category]["has_subcats"] = TRUE
|
||||
crafting_recipes[R.category][R.subcategory] += list(build_recipe_data(R))
|
||||
|
||||
data["crafting_recipes"] = crafting_recipes
|
||||
return data
|
||||
|
||||
/datum/component/personal_crafting/tgui_act(action, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("make")
|
||||
var/mob/user = usr
|
||||
var/datum/crafting_recipe/TR = locate(params["recipe"]) in GLOB.crafting_recipes
|
||||
busy = TRUE
|
||||
tgui_interact(user)
|
||||
var/atom/movable/result = construct_item(user, TR)
|
||||
if(!istext(result)) //We made an item and didn't get a fail message
|
||||
if(ismob(user) && isitem(result)) //In case the user is actually possessing a non mob like a machine
|
||||
user.put_in_hands(result)
|
||||
else
|
||||
result.forceMove(user.drop_location())
|
||||
to_chat(user, "<span class='notice'>[TR.name] constructed.</span>")
|
||||
TR.on_craft_completion(user, result)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Construction failed[result]</span>")
|
||||
busy = FALSE
|
||||
if("toggle_recipes")
|
||||
display_craftable_only = !display_craftable_only
|
||||
. = TRUE
|
||||
if("toggle_compact")
|
||||
display_compact = !display_compact
|
||||
. = TRUE
|
||||
if("set_category")
|
||||
cur_category = params["category"]
|
||||
cur_subcategory = params["subcategory"] || ""
|
||||
. = TRUE
|
||||
|
||||
/datum/component/personal_crafting/proc/build_recipe_data(datum/crafting_recipe/R)
|
||||
var/list/data = list()
|
||||
data["name"] = R.name
|
||||
data["ref"] = "[REF(R)]"
|
||||
var/list/req_text = list()
|
||||
var/list/tool_list = list()
|
||||
var/list/catalyst_text = list()
|
||||
|
||||
for(var/atom/req_atom as anything in R.reqs)
|
||||
//We just need the name, so cheat-typecast to /atom for speed (even tho Reagents are /datum they DO have a "name" var)
|
||||
//Also these are typepaths so sadly we can't just do "[a]"
|
||||
req_text += "[R.reqs[req_atom]] [initial(req_atom.name)]"
|
||||
for(var/obj/machinery/content as anything in R.machinery)
|
||||
req_text += "[R.reqs[content]] [initial(content.name)]"
|
||||
if(R.additional_req_text)
|
||||
req_text += R.additional_req_text
|
||||
data["req_text"] = req_text.Join(", ")
|
||||
|
||||
for(var/atom/req_catalyst as anything in R.chem_catalysts)
|
||||
catalyst_text += "[R.chem_catalysts[req_catalyst]] [initial(req_catalyst.name)]"
|
||||
data["catalyst_text"] = catalyst_text.Join(", ")
|
||||
|
||||
for(var/required_quality in R.tool_behaviors)
|
||||
tool_list += required_quality
|
||||
for(var/obj/item/required_path as anything in R.tool_paths)
|
||||
tool_list += initial(required_path.name)
|
||||
data["tool_text"] = tool_list.Join(", ")
|
||||
|
||||
return data
|
||||
|
||||
//Mind helpers
|
||||
|
||||
/datum/mind/proc/teach_crafting_recipe(R)
|
||||
if(!learned_recipes)
|
||||
learned_recipes = list()
|
||||
learned_recipes |= R
|
||||
|
||||
// Screen objects
|
||||
/obj/screen/craft
|
||||
name = "crafting menu"
|
||||
icon = 'icons/mob/screen/midnight.dmi'
|
||||
icon_state = "craft"
|
||||
screen_loc = ui_crafting
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Ensure a list of atoms/reagents exists inside this atom
|
||||
*
|
||||
* Goes throught he list of passed in parts, if they're reagents, adds them to our reagent holder
|
||||
* creating the reagent holder if it exists.
|
||||
*
|
||||
* If the part is a moveable atom and the previous location of the item was a mob/living,
|
||||
* it calls the inventory handler transferItemToLoc for that mob/living and transfers the part
|
||||
* to this atom
|
||||
*
|
||||
* Otherwise it simply forceMoves the atom into this atom
|
||||
*/
|
||||
/atom/proc/CheckParts(list/parts_list, datum/crafting_recipe/R)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_CHECKPARTS, parts_list, R)
|
||||
if(parts_list)
|
||||
for(var/A in parts_list)
|
||||
if(istype(A, /datum/reagent))
|
||||
if(!reagents)
|
||||
reagents = new()
|
||||
reagents.reagent_list.Add(A)
|
||||
reagents.conditional_update()
|
||||
else if(ismovable(A))
|
||||
var/atom/movable/M = A
|
||||
if(isliving(M.loc))
|
||||
var/mob/living/L = M.loc
|
||||
L.unEquip(M, target = src)
|
||||
else
|
||||
M.forceMove(src)
|
||||
SEND_SIGNAL(M, COMSIG_ATOM_USED_IN_CRAFT, src)
|
||||
parts_list.Cut()
|
||||
|
||||
/obj/machinery/CheckParts(list/parts_list)
|
||||
..()
|
||||
RefreshParts()
|
||||
@@ -0,0 +1,56 @@
|
||||
///If the machine is used/deleted in the crafting process
|
||||
#define CRAFTING_MACHINERY_CONSUME 1
|
||||
///If the machine is only "used" i.e. it checks to see if it's nearby and allows crafting, but doesn't delete it
|
||||
#define CRAFTING_MACHINERY_USE 0
|
||||
|
||||
/datum/crafting_recipe
|
||||
var/name = "" //in-game display name
|
||||
var/list/reqs = list() //type paths of items consumed associated with how many are needed
|
||||
var/list/blacklist = list() //type paths of items explicitly not allowed as an ingredient
|
||||
var/result //type path of item resulting from this craft
|
||||
/// String defines of items needed but not consumed. Lazy list.
|
||||
var/list/tool_behaviors
|
||||
/// Type paths of items needed but not consumed. Lazy list.
|
||||
var/list/tool_paths
|
||||
var/time = 30 //time in deciseconds
|
||||
var/list/parts = list() //type paths of items that will be placed in the result
|
||||
var/list/chem_catalysts = list() //like tool_behaviors but for reagents
|
||||
var/category = CAT_NONE //where it shows up in the crafting UI
|
||||
var/subcategory = CAT_NONE
|
||||
var/always_available = TRUE //Set to FALSE if it needs to be learned first.
|
||||
/// Additonal requirements text shown in UI
|
||||
var/additional_req_text
|
||||
///Required machines for the craft, set the assigned value of the typepath to CRAFTING_MACHINERY_CONSUME or CRAFTING_MACHINERY_USE. Lazy associative list: type_path key -> flag value.
|
||||
var/list/machinery
|
||||
///Should only one object exist on the same turf?
|
||||
var/one_per_turf = FALSE
|
||||
|
||||
/datum/crafting_recipe/New()
|
||||
if(!(result in reqs))
|
||||
blacklist += result
|
||||
if(tool_behaviors)
|
||||
tool_behaviors = string_list(tool_behaviors)
|
||||
if(tool_paths)
|
||||
tool_paths = string_list(tool_paths)
|
||||
|
||||
/**
|
||||
* Run custom pre-craft checks for this recipe
|
||||
*
|
||||
* user: The /mob that initiated the crafting
|
||||
* collected_requirements: A list of lists of /obj/item instances that satisfy reqs. Top level list is keyed by requirement path.
|
||||
*/
|
||||
/datum/crafting_recipe/proc/check_requirements(mob/user, list/collected_requirements)
|
||||
return TRUE
|
||||
|
||||
/datum/crafting_recipe/proc/on_craft_completion(mob/user, atom/result)
|
||||
return
|
||||
|
||||
/datum/crafting_recipe/stunprod
|
||||
name = "Stunprod"
|
||||
result = /obj/item/weapon/melee/baton/cattleprod
|
||||
reqs = list(/obj/item/weapon/handcuffs/cable = 1,
|
||||
/obj/item/stack/rods = 1,
|
||||
/obj/item/weapon/tool/wirecutters = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
@@ -0,0 +1,29 @@
|
||||
/obj/item
|
||||
var/list/tool_qualities
|
||||
|
||||
/// Used to check for a specific tool quality on an item.
|
||||
/// Returns TRUE or FALSE depending on whether `tool_quality` is found.
|
||||
/obj/item/proc/has_tool_quality(tool_quality)
|
||||
return !!LAZYFIND(tool_qualities, tool_quality)
|
||||
|
||||
/* Legacy Support */
|
||||
|
||||
/// DEPRECATED PROC: DO NOT USE IN NEW CODE
|
||||
/obj/item/proc/is_screwdriver()
|
||||
return has_tool_quality(TOOL_SCREWDRIVER)
|
||||
|
||||
/// DEPRECATED PROC: DO NOT USE IN NEW CODE
|
||||
/obj/item/proc/is_wrench()
|
||||
return has_tool_quality(TOOL_WRENCH)
|
||||
|
||||
/// DEPRECATED PROC: DO NOT USE IN NEW CODE
|
||||
/obj/item/proc/is_crowbar()
|
||||
return has_tool_quality(TOOL_CROWBAR)
|
||||
|
||||
/// DEPRECATED PROC: DO NOT USE IN NEW CODE
|
||||
/obj/item/proc/is_wirecutter()
|
||||
return has_tool_quality(TOOL_WIRECUTTER)
|
||||
|
||||
/// DEPRECATED PROC: DO NOT USE IN NEW CODE
|
||||
/obj/item/proc/is_multitool()
|
||||
return has_tool_quality(TOOL_MULTITOOL)
|
||||
@@ -11,7 +11,7 @@
|
||||
start_sound = 'sound/effects/weather/snowstorm/outside/active_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/snowstorm/outside/active_end.ogg'
|
||||
volume = 80
|
||||
volume = 40
|
||||
|
||||
/datum/looping_sound/weather/inside_blizzard
|
||||
mid_sounds = list(
|
||||
@@ -23,7 +23,7 @@
|
||||
start_sound = 'sound/effects/weather/snowstorm/inside/active_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/snowstorm/inside/active_end.ogg'
|
||||
volume = 60
|
||||
volume = 20
|
||||
|
||||
/datum/looping_sound/weather/outside_snow
|
||||
mid_sounds = list(
|
||||
@@ -35,7 +35,7 @@
|
||||
start_sound = 'sound/effects/weather/snowstorm/outside/weak_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/snowstorm/outside/weak_end.ogg'
|
||||
volume = 50
|
||||
volume = 20
|
||||
|
||||
/datum/looping_sound/weather/inside_snow
|
||||
mid_sounds = list(
|
||||
@@ -47,7 +47,7 @@
|
||||
start_sound = 'sound/effects/weather/snowstorm/inside/weak_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/snowstorm/inside/weak_end.ogg'
|
||||
volume = 30
|
||||
volume = 10
|
||||
|
||||
/datum/looping_sound/weather/wind
|
||||
mid_sounds = list(
|
||||
@@ -59,11 +59,17 @@
|
||||
'sound/effects/weather/wind/wind_5_1.ogg' = 1
|
||||
)
|
||||
mid_length = 10 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind.
|
||||
volume = 50
|
||||
volume = 45
|
||||
|
||||
// Don't have special sounds so we just make it quieter indoors.
|
||||
/datum/looping_sound/weather/wind/indoors
|
||||
volume = 30
|
||||
volume = 25
|
||||
|
||||
/datum/looping_sound/weather/wind/gentle
|
||||
volume = 15
|
||||
|
||||
/datum/looping_sound/weather/wind/gentle/indoors
|
||||
volume = 5
|
||||
|
||||
/datum/looping_sound/weather/rain
|
||||
mid_sounds = list(
|
||||
@@ -73,7 +79,13 @@
|
||||
start_sound = 'sound/effects/weather/acidrain_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/acidrain_end.ogg'
|
||||
volume = 50
|
||||
volume = 20
|
||||
|
||||
/datum/looping_sound/weather/rain/indoors
|
||||
volume = 30
|
||||
volume = 10
|
||||
|
||||
/datum/looping_sound/weather/rain/heavy
|
||||
volume = 40
|
||||
|
||||
/datum/looping_sound/weather/rain/heavy/indoors
|
||||
volume = 20
|
||||
@@ -58,6 +58,7 @@
|
||||
var/list/purchase_log = new
|
||||
var/used_TC = 0
|
||||
|
||||
var/list/learned_recipes //List of learned recipe TYPES.
|
||||
|
||||
// the world.time since the mob has been brigged, or -1 if not at all
|
||||
var/brigged_since = -1
|
||||
|
||||
@@ -24,7 +24,8 @@ var/global/datum/repository/crew/crew_repository = new()
|
||||
var/tracked = scan()
|
||||
for(var/obj/item/clothing/under/C in tracked)
|
||||
var/turf/pos = get_turf(C)
|
||||
if((C) && (C.has_sensor) && (pos) && (pos.z == zLevel) && (C.sensor_mode != SUIT_SENSOR_OFF) && !(is_jammed(C)))
|
||||
var/area/B = pos?.loc //VOREStation Add: No sensor in Dorm
|
||||
if((C.has_sensor) && (pos?.z == zLevel) && (C.sensor_mode != SUIT_SENSOR_OFF) && !(B.block_suit_sensors) && !(is_jammed(C)) && !(is_vore_jammed(C))) //VOREStation Edit
|
||||
if(istype(C.loc, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = C.loc
|
||||
if(H.w_uniform != C)
|
||||
|
||||
@@ -247,11 +247,21 @@
|
||||
/obj/item/clothing/suit/radiation = 3,
|
||||
/obj/item/clothing/head/radiation = 3
|
||||
)
|
||||
name = "Radiation suits package"
|
||||
name = "Radiation suits package (Humanoid)"
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/radiation
|
||||
containername = "Radiation suit locker"
|
||||
|
||||
/datum/supply_pack/eng/radsuitteshari
|
||||
contains = list(
|
||||
/obj/item/clothing/suit/radiation/teshari = 3,
|
||||
/obj/item/clothing/head/radiation/teshari = 3
|
||||
)
|
||||
name = "Radiation suits package (Teshari)"
|
||||
cost = 40
|
||||
containertype = /obj/structure/closet/crate/aether
|
||||
containername = "Teshari radiation suit locker"
|
||||
|
||||
/datum/supply_pack/eng/pacman_parts
|
||||
name = "P.A.C.M.A.N. portable generator parts"
|
||||
cost = 25
|
||||
|
||||
@@ -2,11 +2,21 @@
|
||||
* Highly Visible and Dangerous Weapons *
|
||||
***************************************/
|
||||
/datum/uplink_item/item/visible_weapons/holdout
|
||||
name = "Holdout Phaser"
|
||||
name = "Frontier Holdout"
|
||||
item_cost = 30
|
||||
path = /obj/item/weapon/gun/energy/locked/frontier/holdout/unlocked
|
||||
|
||||
/datum/uplink_item/item/visible_weapons/frontier
|
||||
name = "Frontier Carbine"
|
||||
name = "Frontier Phaser"
|
||||
item_cost = 75
|
||||
path = /obj/item/weapon/gun/energy/locked/frontier/unlocked
|
||||
|
||||
/datum/uplink_item/item/visible_weapons/carbine
|
||||
name = "Frontier Carbine"
|
||||
item_cost = 85
|
||||
path = /obj/item/weapon/gun/energy/locked/frontier/carbine/unlocked
|
||||
|
||||
/datum/uplink_item/item/visible_weapons/rifle
|
||||
name = "Frontier Marksman Rifle"
|
||||
item_cost = 100
|
||||
path = /obj/item/weapon/gun/energy/locked/frontier/rifle/unlocked
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
/datum/stored_item
|
||||
var/item_name = "name" //Name of the item(s) displayed
|
||||
var/item_desc
|
||||
var/item_path = null
|
||||
var/amount = 0
|
||||
var/list/instances //What items are actually stored
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/area
|
||||
var/limit_mob_size = TRUE //If mob size is limited in the area.
|
||||
|
||||
/area/shuttle/belter
|
||||
name = "Belter Shuttle"
|
||||
icon_state = "shuttle2"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/area
|
||||
var/enter_message
|
||||
var/exit_message
|
||||
var/limit_mob_size = TRUE //If mob size is limited in the area.
|
||||
var/block_suit_sensors = FALSE //If mob size is limited in the area.
|
||||
|
||||
/area/Entered(var/atom/movable/AM, oldLoc)
|
||||
. = ..()
|
||||
|
||||
+19
-11
@@ -490,7 +490,7 @@
|
||||
// Use for objects performing visible actions
|
||||
// message is output to anyone who can see, e.g. "The [src] does something!"
|
||||
// blind_message (optional) is what blind people will hear e.g. "You hear something!"
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs = null)
|
||||
/atom/proc/visible_message(var/message, var/blind_message, var/list/exclude_mobs, var/range = world.view)
|
||||
|
||||
//VOREStation Edit
|
||||
var/list/see
|
||||
@@ -498,7 +498,7 @@
|
||||
var/obj/belly/B = loc
|
||||
see = B.get_mobs_and_objs_in_belly()
|
||||
else
|
||||
see = get_mobs_and_objs_in_view_fast(get_turf(src),world.view,remote_ghosts = FALSE)
|
||||
see = get_mobs_and_objs_in_view_fast(get_turf(src), range, remote_ghosts = FALSE)
|
||||
//VOREStation Edit End
|
||||
|
||||
var/list/seeing_mobs = see["mobs"]
|
||||
@@ -508,20 +508,20 @@
|
||||
|
||||
for(var/obj in seeing_objs)
|
||||
var/obj/O = obj
|
||||
O.show_message(message, 1, blind_message, 2)
|
||||
O.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE)
|
||||
for(var/mob in seeing_mobs)
|
||||
var/mob/M = mob
|
||||
if(M.see_invisible >= invisibility && MOB_CAN_SEE_PLANE(M, plane))
|
||||
M.show_message(message, 1, blind_message, 2)
|
||||
M.show_message(message, VISIBLE_MESSAGE, blind_message, AUDIBLE_MESSAGE)
|
||||
else if(blind_message)
|
||||
M.show_message(blind_message, 2)
|
||||
M.show_message(blind_message, AUDIBLE_MESSAGE)
|
||||
|
||||
// Show a message to all mobs and objects in earshot of this atom
|
||||
// Use for objects performing audible actions
|
||||
// message is the message output to anyone who can hear.
|
||||
// deaf_message (optional) is what deaf people will see.
|
||||
// hearing_distance (optional) is the range, how many tiles away the message can be heard.
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance)
|
||||
/atom/proc/audible_message(var/message, var/deaf_message, var/hearing_distance, var/radio_message)
|
||||
|
||||
var/range = hearing_distance || world.view
|
||||
var/list/hear = get_mobs_and_objs_in_view_fast(get_turf(src),range,remote_ghosts = FALSE)
|
||||
@@ -529,14 +529,19 @@
|
||||
var/list/hearing_mobs = hear["mobs"]
|
||||
var/list/hearing_objs = hear["objs"]
|
||||
|
||||
for(var/obj in hearing_objs)
|
||||
var/obj/O = obj
|
||||
O.show_message(message, 2, deaf_message, 1)
|
||||
if(radio_message)
|
||||
for(var/obj in hearing_objs)
|
||||
var/obj/O = obj
|
||||
O.hear_talk(src, list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], radio_message)), null)
|
||||
else
|
||||
for(var/obj in hearing_objs)
|
||||
var/obj/O = obj
|
||||
O.show_message(message, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
|
||||
for(var/mob in hearing_mobs)
|
||||
var/mob/M = mob
|
||||
var/msg = message
|
||||
M.show_message(msg, 2, deaf_message, 1)
|
||||
M.show_message(msg, AUDIBLE_MESSAGE, deaf_message, VISIBLE_MESSAGE)
|
||||
|
||||
/atom/movable/proc/dropInto(var/atom/destination)
|
||||
while(istype(destination))
|
||||
@@ -647,4 +652,7 @@
|
||||
|
||||
/atom/Exited(atom/movable/AM, atom/new_loc)
|
||||
. = ..()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, new_loc)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, new_loc)
|
||||
|
||||
/atom/proc/get_visible_gender()
|
||||
return gender
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
H.custom_exclaim = dna.custom_exclaim
|
||||
H.species.blood_color = dna.blood_color
|
||||
var/datum/species/S = H.species
|
||||
S.produceCopy(dna.species_traits,src)
|
||||
S.produceCopy(dna.species_traits, H, dna.base_species)
|
||||
// VOREStation Edit End
|
||||
|
||||
H.force_update_organs() //VOREStation Add - Gotta do this too
|
||||
|
||||
@@ -318,6 +318,10 @@
|
||||
organData["robotic"] = (I.robotic >= ORGAN_ROBOT)
|
||||
organData["dead"] = (I.status & ORGAN_DEAD)
|
||||
|
||||
if(istype(I, /obj/item/organ/internal/appendix))
|
||||
var/obj/item/organ/internal/appendix/A = I
|
||||
organData["inflamed"] = A.inflamed
|
||||
|
||||
intOrganData.Add(list(organData))
|
||||
|
||||
occupantData["intOrgan"] = intOrganData
|
||||
@@ -497,23 +501,28 @@
|
||||
if(i.robotic >= ORGAN_ROBOT)
|
||||
mech = "Mechanical:"
|
||||
if(i.status & ORGAN_DEAD)
|
||||
i_dead = "Necrotic:"
|
||||
i_dead = "Necrotic"
|
||||
var/infection = "None"
|
||||
switch (i.germ_level)
|
||||
if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200)
|
||||
infection = "Mild Infection:"
|
||||
infection = "Mild Infection"
|
||||
if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
|
||||
infection = "Mild Infection+:"
|
||||
infection = "Mild Infection+"
|
||||
if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
|
||||
infection = "Mild Infection++:"
|
||||
infection = "Mild Infection++"
|
||||
if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
|
||||
infection = "Acute Infection:"
|
||||
infection = "Acute Infection"
|
||||
if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
|
||||
infection = "Acute Infection+:"
|
||||
infection = "Acute Infection+"
|
||||
if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_THREE - 50)
|
||||
infection = "Acute Infection++:"
|
||||
infection = "Acute Infection++"
|
||||
if (INFECTION_LEVEL_THREE -49 to INFINITY)
|
||||
infection = "Necrosis Detected:"
|
||||
infection = "Necrosis Detected"
|
||||
|
||||
if(istype(i, /obj/item/organ/internal/appendix))
|
||||
var/obj/item/organ/internal/appendix/A = i
|
||||
if(A.inflamed)
|
||||
infection = "Inflammation detected!"
|
||||
|
||||
dat += "<tr>"
|
||||
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>[infection]:[mech][i_dead]</td><td></td>"
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/obj/machinery/computer/arcade
|
||||
list/prizes = list( /obj/item/weapon/storage/box/snappops = 2,
|
||||
/obj/item/toy/blink = 2,
|
||||
/obj/item/clothing/under/syndicate/tacticool = 2,
|
||||
/obj/item/toy/sword = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/capgun = 2,
|
||||
/obj/item/toy/crossbow = 2,
|
||||
/obj/item/clothing/suit/syndicatefake = 2,
|
||||
/obj/item/weapon/storage/fancy/crayons = 2,
|
||||
/obj/item/toy/spinningtoy = 2,
|
||||
/obj/random/mech_toy = 1,
|
||||
/obj/item/weapon/reagent_containers/spray/waterflower = 1,
|
||||
/obj/random/action_figure = 1,
|
||||
/obj/random/plushie = 1,
|
||||
/obj/item/toy/cultsword = 1,
|
||||
/obj/item/toy/bouquet/fake = 1,
|
||||
/obj/item/clothing/accessory/badge/sheriff = 2,
|
||||
/obj/item/clothing/head/cowboy_hat/small = 2,
|
||||
/obj/item/toy/stickhorse = 2,
|
||||
/obj/item/toy/rock = 2,
|
||||
/obj/item/toy/flash = 2,
|
||||
/obj/item/toy/redbutton = 2,
|
||||
/obj/item/toy/gnome = 2,
|
||||
/obj/item/toy/AI = 2,
|
||||
/obj/item/clothing/gloves/ring/buzzer/toy = 2,
|
||||
/obj/item/weapon/storage/box/handcuffs/fake = 2,
|
||||
/obj/item/toy/nuke = 2,
|
||||
/obj/item/toy/minigibber = 2,
|
||||
/obj/item/toy/toy_xeno = 2,
|
||||
/obj/item/toy/russian_revolver = 1,
|
||||
/obj/item/toy/russian_revolver/trick_revolver = 1,
|
||||
/obj/item/toy/chainsaw = 1,
|
||||
/obj/random/miniature = 1,
|
||||
/obj/item/toy/snake_popper = 1
|
||||
)
|
||||
@@ -200,7 +200,6 @@
|
||||
modify.access -= access_type
|
||||
if(!access_allowed)
|
||||
modify.access += access_type
|
||||
modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
|
||||
. = TRUE
|
||||
|
||||
if("assign")
|
||||
@@ -225,7 +224,6 @@
|
||||
modify.access = access
|
||||
modify.assignment = t1
|
||||
modify.rank = t1
|
||||
modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
|
||||
|
||||
callHook("reassign_employee", list(modify))
|
||||
. = TRUE
|
||||
@@ -283,7 +281,6 @@
|
||||
if(is_authenticated())
|
||||
modify.assignment = "Dismissed" //VOREStation Edit: setting adjustment
|
||||
modify.access = list()
|
||||
modify.lost_access = list() //VOREStation addition: reset the lost access upon any modifications
|
||||
|
||||
callHook("terminate_employee", list(modify))
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/obj/item/weapon/card/id/inserted
|
||||
|
||||
/obj/machinery/computer/id_restorer/attackby(obj/I, mob/user)
|
||||
/*
|
||||
if(istype(I, /obj/item/weapon/card/id) && !(istype(I,/obj/item/weapon/card/id/guest)))
|
||||
if(!inserted && user.unEquip(I))
|
||||
I.forceMove(src)
|
||||
@@ -24,12 +25,14 @@
|
||||
else if(inserted)
|
||||
to_chat(user, "<span class='warning'>There is already ID card inside.</span>")
|
||||
return
|
||||
*/
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/id_restorer/attack_hand(mob/user)
|
||||
if(..()) return
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
|
||||
/*
|
||||
if(!inserted) // No point in giving you an option what to do if there's no ID to do things with.
|
||||
to_chat(user, "<span class='notice'>No ID is inserted.</span>")
|
||||
return
|
||||
@@ -78,6 +81,7 @@
|
||||
return
|
||||
if("Cancel")
|
||||
return
|
||||
*/
|
||||
|
||||
|
||||
//Frame
|
||||
|
||||
@@ -507,7 +507,6 @@
|
||||
log_and_message_admins("[key_name(to_despawn)] ([to_despawn.mind.role_alt_title]) entered cryostorage.")
|
||||
|
||||
announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
|
||||
//visible_message("<span class='notice'>\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.</span>", 3)
|
||||
visible_message("<span class='notice'>\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2]</span>", 3)
|
||||
|
||||
//VOREStation Edit begin: Dont delete mobs-in-mobs
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
|
||||
GLOBAL_LIST_BOILERPLATE(pointdefense_controllers, /obj/machinery/pointdefense_control)
|
||||
GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
|
||||
|
||||
/obj/machinery/pointdefense_control
|
||||
name = "fire assist mainframe"
|
||||
@@ -54,7 +54,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
return TRUE
|
||||
|
||||
if(action == "toggle_active")
|
||||
var/obj/machinery/pointdefense/PD = locate(params["target"])
|
||||
var/obj/machinery/power/pointdefense/PD = locate(params["target"])
|
||||
if(!istype(PD))
|
||||
return FALSE
|
||||
|
||||
@@ -77,7 +77,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
if(id_tag)
|
||||
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||
for(var/i = 1 to LAZYLEN(pointdefense_turrets))
|
||||
var/obj/machinery/pointdefense/PD = pointdefense_turrets[i]
|
||||
var/obj/machinery/power/pointdefense/PD = pointdefense_turrets[i]
|
||||
if(!(PD.id_tag == id_tag && get_z(PD) in connected_z_levels))
|
||||
continue
|
||||
var/list/turret = list()
|
||||
@@ -118,7 +118,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
// The acutal point defense battery
|
||||
//
|
||||
|
||||
/obj/machinery/pointdefense
|
||||
/obj/machinery/power/pointdefense
|
||||
name = "\improper point defense battery"
|
||||
icon = 'icons/obj/pointdefense.dmi'
|
||||
icon_state = "pointdefense2"
|
||||
@@ -128,6 +128,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
anchored = TRUE
|
||||
circuit = /obj/item/weapon/circuitboard/pointdefense
|
||||
idle_power_usage = 0.1 KILOWATTS
|
||||
active_power_usage = 1 KILOWATTS
|
||||
appearance_flags = PIXEL_SCALE
|
||||
var/active = TRUE
|
||||
var/charge_cooldown = 1 SECOND //time between it can fire at different targets
|
||||
@@ -137,33 +138,69 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
var/weakref/engaging = null // The meteor we're shooting at
|
||||
var/id_tag = null
|
||||
|
||||
/obj/machinery/pointdefense/Initialize()
|
||||
/obj/machinery/power/pointdefense/Initialize()
|
||||
. = ..()
|
||||
// TODO - Remove this bit once machines are converted to Initialize
|
||||
if(ispath(circuit))
|
||||
circuit = new circuit(src)
|
||||
default_apply_parts()
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
update_icon()
|
||||
var/image/I = image(icon, icon_state = "[icon_state]_under")
|
||||
I.appearance_flags |= RESET_TRANSFORM
|
||||
underlays += I
|
||||
|
||||
/obj/machinery/pointdefense/get_description_interaction()
|
||||
/obj/machinery/power/pointdefense/examine(mob/user)
|
||||
. = ..()
|
||||
if(powernet)
|
||||
. += "It is connected to a power cable below."
|
||||
|
||||
/obj/machinery/power/pointdefense/get_description_interaction()
|
||||
. = ..()
|
||||
if(!id_tag)
|
||||
. += "[desc_panel_image("multitool")]to set ident tag and connect to a mainframe."
|
||||
|
||||
/obj/machinery/pointdefense/update_icon()
|
||||
/obj/machinery/power/pointdefense/update_icon()
|
||||
if(!active || !id_tag || inoperable())
|
||||
icon_state = "[initial(icon_state)]_off"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/pointdefense/power_change()
|
||||
/obj/machinery/power/pointdefense/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/W, var/time)
|
||||
if((. = ..()))
|
||||
src.transform = null // Reset rotation if we're anchored/unanchored
|
||||
|
||||
////////// This machine is willing to take power from cables OR APCs. Handle NOPOWER stat specially here! ////////
|
||||
|
||||
/obj/machinery/power/pointdefense/connect_to_network()
|
||||
if((. = ..()))
|
||||
stat &= ~NOPOWER // We now ignore APC power
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/pointdefense/disconnect_from_network()
|
||||
if((. = ..()))
|
||||
power_change() // We're back on APC power.
|
||||
|
||||
/obj/machinery/power/pointdefense/power_change()
|
||||
if(powernet)
|
||||
return // We don't care, we are cable powered anyway
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
// Decide where to get the power to fire from
|
||||
/obj/machinery/power/pointdefense/use_power_oneoff(var/amount, var/chan = -1)
|
||||
if(powernet)
|
||||
return draw_power(amount)
|
||||
else if(powered(chan))
|
||||
use_power(amount, chan)
|
||||
return amount
|
||||
return 0
|
||||
|
||||
// Find controller with the same tag on connected z levels (if any)
|
||||
/obj/machinery/pointdefense/proc/get_controller()
|
||||
/obj/machinery/power/pointdefense/proc/get_controller()
|
||||
if(!id_tag)
|
||||
return null
|
||||
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||
@@ -172,7 +209,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
if(PDC.id_tag == id_tag && (get_z(PDC) in connected_z_levels))
|
||||
return PDC
|
||||
|
||||
/obj/machinery/pointdefense/attackby(var/obj/item/W, var/mob/user)
|
||||
/obj/machinery/power/pointdefense/attackby(var/obj/item/W, var/mob/user)
|
||||
if(W?.is_multitool())
|
||||
var/new_ident = input(user, "Enter a new ident tag.", "[src]", id_tag) as null|text
|
||||
if(new_ident && new_ident != id_tag && user.Adjacent(src) && CanInteract(user, GLOB.tgui_physical_state))
|
||||
@@ -185,16 +222,18 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
return
|
||||
if(default_part_replacement(user, W))
|
||||
return
|
||||
if(default_unfasten_wrench(user, W, 40))
|
||||
return
|
||||
return ..()
|
||||
|
||||
//Guns cannot shoot through hull or generally dense turfs.
|
||||
/obj/machinery/pointdefense/proc/space_los(meteor)
|
||||
/obj/machinery/power/pointdefense/proc/space_los(meteor)
|
||||
for(var/turf/T in getline(src,meteor))
|
||||
if(T.density)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pointdefense/proc/Shoot(var/weakref/target)
|
||||
/obj/machinery/power/pointdefense/proc/Shoot(var/weakref/target)
|
||||
var/obj/effect/meteor/M = target.resolve()
|
||||
if(!istype(M))
|
||||
engaging = null
|
||||
@@ -208,7 +247,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
|
||||
set_dir(ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH)
|
||||
|
||||
/obj/machinery/pointdefense/proc/finish_shot(var/weakref/target)
|
||||
/obj/machinery/power/pointdefense/proc/finish_shot(var/weakref/target)
|
||||
|
||||
var/obj/machinery/pointdefense_control/PC = get_controller()
|
||||
engaging = null
|
||||
@@ -218,26 +257,34 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
var/obj/effect/meteor/M = target.resolve()
|
||||
if(!istype(M))
|
||||
return
|
||||
if(use_power_oneoff(active_power_usage) < active_power_usage)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
visible_message("[src] sputters as browns out while attempting to fire.")
|
||||
flick(src, "[initial(icon_state)]_off")
|
||||
return
|
||||
//We throw a laser but it doesnt have to hit for meteor to explode
|
||||
var/obj/item/projectile/beam/pointdefense/beam = new(get_turf(src))
|
||||
playsound(src, 'sound/weapons/mandalorian.ogg', 75, 1)
|
||||
use_power_oneoff(idle_power_usage * 10)
|
||||
beam.launch_projectile(target = M.loc, user = src)
|
||||
|
||||
/obj/machinery/pointdefense/process()
|
||||
/obj/machinery/power/pointdefense/process()
|
||||
..()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
if(!anchored || stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(!active)
|
||||
return
|
||||
/*
|
||||
var/desiredir = ATAN2(transform.b, transform.a) > 0 ? NORTH : SOUTH
|
||||
if(dir != desiredir)
|
||||
set_dir(desiredir)
|
||||
*/
|
||||
|
||||
if(LAZYLEN(GLOB.meteor_list) > 0)
|
||||
find_and_shoot()
|
||||
|
||||
/obj/machinery/pointdefense/proc/find_and_shoot()
|
||||
/obj/machinery/power/pointdefense/proc/find_and_shoot()
|
||||
// There ARE meteors to shoot
|
||||
if(LAZYLEN(GLOB.meteor_list) == 0)
|
||||
return
|
||||
@@ -273,7 +320,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
Shoot(target)
|
||||
return
|
||||
|
||||
/obj/machinery/pointdefense/proc/targeting_check(var/obj/effect/meteor/M)
|
||||
/obj/machinery/power/pointdefense/proc/targeting_check(var/obj/effect/meteor/M)
|
||||
// Target in range
|
||||
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||
if(!(M.z in connected_z_levels))
|
||||
@@ -286,7 +333,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pointdefense/RefreshParts()
|
||||
/obj/machinery/power/pointdefense/RefreshParts()
|
||||
. = ..()
|
||||
// Calculates an average rating of components that affect shooting rate
|
||||
var/shootrate_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/capacitor)
|
||||
@@ -302,7 +349,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
var/rotation_divisor = total_component_rating_of_type(/obj/item/weapon/stock_parts/manipulator)
|
||||
rotation_speed = 0.5 SECONDS / (rotation_divisor ? rotation_divisor : 1)
|
||||
|
||||
/obj/machinery/pointdefense/proc/Activate()
|
||||
/obj/machinery/power/pointdefense/proc/Activate()
|
||||
if(active)
|
||||
return FALSE
|
||||
|
||||
@@ -312,7 +359,7 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/pointdefense)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pointdefense/proc/Deactivate()
|
||||
/obj/machinery/power/pointdefense/proc/Deactivate()
|
||||
if(!active)
|
||||
return FALSE
|
||||
playsound(src, 'sound/machines/apc_nopower.ogg', 50, 0)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
name = "military CIWS turret"
|
||||
desc = "A ship weapons turret designed for anti-fighter defense."
|
||||
req_one_access = list(access_cent_general)
|
||||
installation = /obj/item/weapon/gun/energy/lasercannon
|
||||
installation = /obj/item/weapon/gun/energy/pulse_rifle/destroyer
|
||||
health = 500
|
||||
maxhealth = 500
|
||||
enabled = TRUE
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
if(!R.cell)
|
||||
return
|
||||
|
||||
if(R.mob_size >= MOB_LARGE)
|
||||
if(istype(R, /mob/living/silicon/robot/platform))
|
||||
to_chat(R, SPAN_WARNING("You are too large to fit into \the [src]."))
|
||||
return
|
||||
|
||||
|
||||
@@ -634,10 +634,6 @@
|
||||
model_text = "Exploration"
|
||||
departments = list("Exploration","Expedition Medic","Old Exploration","No Change")
|
||||
|
||||
/obj/machinery/suit_cycler/exploration/Initialize()
|
||||
species -= SPECIES_TESHARI
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_cycler/pilot
|
||||
name = "Pilot suit cycler"
|
||||
model_text = "Pilot"
|
||||
|
||||
@@ -4614,3 +4614,36 @@
|
||||
/obj/machinery/vending/cola/soft
|
||||
icon = 'icons/obj/vending_vr.dmi'
|
||||
icon_state = "Cola_Machine"
|
||||
|
||||
//////////////////////Bepis Drinks (04/29/2021)//////////////////////
|
||||
|
||||
/obj/machinery/vending/bepis
|
||||
name = "Bepis Softdrinks"
|
||||
desc = "A strange softdrink vendor that isn't owned by NanoTrasen... Why (and how) is it here?"
|
||||
icon = 'icons/obj/vending_vr.dmi'
|
||||
icon_state = "bepis"
|
||||
product_slogans = "Refreshing!;Have a sip, you won't believe the taste!;Puts the 'B' in Best Soda!"
|
||||
product_ads = "Refreshing!;Hope you're thirsty!;Please, have a drink!;Drink up!"
|
||||
products = list(/obj/item/weapon/reagent_containers/food/drinks/cans/bepis = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/astrodew = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/buzz = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/shambler = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/cranberry = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/icecoffee = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/root_beer = 10)
|
||||
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/drinks/cans/bepis = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/astrodew = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/buzz = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/shambler = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/cranberry = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/icecoffee = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/gingerale = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cans/root_beer = 1)
|
||||
idle_power_usage = 211 //refrigerator - believe it or not, this is actually the average power consumption of a refrigerated vending machine according to NRCan.
|
||||
vending_sound = "machines/vending/vending_cans.ogg"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/obj/effect/effect/sparks/confetti
|
||||
name = "confetti"
|
||||
icon = 'icons/effects/effects_vr.dmi'
|
||||
icon_state = "confetti"
|
||||
|
||||
/obj/effect/effect/sparks/New()
|
||||
..()
|
||||
playsound(src, "sounds/items/confetti.ogg ", 100, 1)
|
||||
|
||||
/datum/effect/effect/system/confetti_spread
|
||||
var/total_sparks = 0 // To stop it being spammed and lagging!
|
||||
|
||||
set_up(n = 3, c = 0, loca)
|
||||
if(n > 10)
|
||||
n = 10
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_sparks > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/sparks/confetti = new /obj/effect/effect/sparks/confetti(src.location)
|
||||
src.total_sparks++
|
||||
var/direction
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(1,2,3), i++)
|
||||
sleep(5)
|
||||
step(confetti,direction)
|
||||
spawn(20)
|
||||
src.total_sparks--
|
||||
@@ -552,9 +552,7 @@ var/list/global/slot_flags_enumeration = list(
|
||||
if(!hit_zone)
|
||||
U.do_attack_animation(M)
|
||||
playsound(src, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
//visible_message("<span class='danger'>[U] attempts to stab [M] in the eyes, but misses!</span>")
|
||||
for(var/mob/V in viewers(M))
|
||||
V.show_message("<span class='danger'>[U] attempts to stab [M] in the eyes, but misses!</span>")
|
||||
visible_message(SPAN_DANGER("\The [U] attempts to stab \the [M] in the eyes, but misses!"))
|
||||
return
|
||||
|
||||
add_attack_logs(user,M,"Attack eyes with [name]")
|
||||
@@ -908,31 +906,6 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
/obj/item/proc/apply_accessories(var/image/standing)
|
||||
return standing
|
||||
|
||||
/*
|
||||
* Assorted tool procs, so any item can emulate any tool, if coded
|
||||
*/
|
||||
/obj/item/proc/is_screwdriver()
|
||||
return FALSE
|
||||
|
||||
/obj/item/proc/is_wrench()
|
||||
return FALSE
|
||||
|
||||
/obj/item/proc/is_crowbar()
|
||||
return FALSE
|
||||
|
||||
/obj/item/proc/is_wirecutter()
|
||||
return FALSE
|
||||
|
||||
// These next three might bug out or runtime, unless someone goes back and finds a way to generalize their specific code
|
||||
/obj/item/proc/is_cable_coil()
|
||||
return FALSE
|
||||
|
||||
/obj/item/proc/is_multitool()
|
||||
return FALSE
|
||||
|
||||
/obj/item/proc/is_welder()
|
||||
return FALSE
|
||||
|
||||
/obj/item/MouseEntered(location,control,params)
|
||||
. = ..()
|
||||
if(usr.is_preference_enabled(/datum/client_preference/inv_tooltips) && ((src in usr) || isstorage(loc))) // If in inventory or in storage we're looking at
|
||||
|
||||
@@ -194,10 +194,8 @@
|
||||
return
|
||||
|
||||
/obj/item/blueprints/proc/move_turfs_to_area(var/list/turf/turfs, var/area/A)
|
||||
A.contents.Add(turfs)
|
||||
//oldarea.contents.Remove(usr.loc) // not needed
|
||||
//T.loc = A //error: cannot change constant value
|
||||
|
||||
for(var/T in turfs)
|
||||
ChangeArea(T, A)
|
||||
|
||||
/obj/item/blueprints/proc/edit_area()
|
||||
var/area/A = get_area()
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
var/obj/machinery/connectable //Used to connect machinery.
|
||||
var/weakref_wiring //Used to store weak references for integrated circuitry. This is now the Omnitool.
|
||||
toolspeed = 1
|
||||
tool_qualities = list(TOOL_MULTITOOL)
|
||||
|
||||
/obj/item/device/multitool/attack_self(mob/living/user)
|
||||
var/choice = alert("What do you want to do with \the [src]?","Multitool Menu", "Switch Mode", "Clear Buffers", "Cancel")
|
||||
@@ -65,9 +66,6 @@
|
||||
|
||||
return
|
||||
|
||||
/obj/item/device/multitool/is_multitool()
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/multitool/cyborg
|
||||
name = "multitool"
|
||||
desc = "Optimised and stripped-down version of a regular multitool."
|
||||
|
||||
@@ -2,3 +2,14 @@
|
||||
/obj/item/device/radio_jammer/admin
|
||||
jam_range = 255
|
||||
tick_cost = 0
|
||||
|
||||
/proc/is_vore_jammed(var/obj/radio)
|
||||
var/atom/current = radio
|
||||
while(current.loc)
|
||||
if(isbelly(current.loc))
|
||||
var/obj/belly/B = current.loc
|
||||
if(B.mode_flags & DM_FLAG_JAMSENSORS)
|
||||
return TRUE
|
||||
current = current.loc
|
||||
|
||||
return FALSE
|
||||
@@ -1,102 +0,0 @@
|
||||
/* Glass stack types
|
||||
* Contains:
|
||||
* Glass sheets
|
||||
* Reinforced glass sheets
|
||||
* Phoron Glass Sheets
|
||||
* Reinforced Phoron Glass Sheets (AKA Holy fuck strong windows)
|
||||
* Glass shards - TODO: Move this into code/game/object/item/weapons
|
||||
*/
|
||||
|
||||
/*
|
||||
* Glass sheets
|
||||
*/
|
||||
/obj/item/stack/material/glass
|
||||
name = "glass"
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-glass"
|
||||
var/is_reinforced = 0
|
||||
default_type = "glass"
|
||||
drop_sound = 'sound/items/drop/glass.ogg'
|
||||
pickup_sound = 'sound/items/pickup/glass.ogg'
|
||||
|
||||
/obj/item/stack/material/glass/attack_self(mob/user as mob)
|
||||
construct_window(user)
|
||||
|
||||
/obj/item/stack/material/glass/attackby(obj/item/W, mob/user)
|
||||
..()
|
||||
if(!is_reinforced)
|
||||
if(istype(W,/obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if (get_amount() < 1 || CC.get_amount() < 5)
|
||||
to_chat(user, "<span class='warning'>You need five lengths of coil and one sheet of glass to make wired glass.</span>")
|
||||
return
|
||||
|
||||
CC.use(5)
|
||||
use(1)
|
||||
to_chat(user, "<span class='notice'>You attach wire to the [name].</span>")
|
||||
new /obj/item/stack/light_w(user.loc)
|
||||
else if(istype(W, /obj/item/stack/rods))
|
||||
var/obj/item/stack/rods/V = W
|
||||
if (V.get_amount() < 1 || get_amount() < 1)
|
||||
to_chat(user, "<span class='warning'>You need one rod and one sheet of glass to make reinforced glass.</span>")
|
||||
return
|
||||
|
||||
var/obj/item/stack/material/glass/reinforced/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
RG.add_to_stacks(user)
|
||||
var/obj/item/stack/material/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
V.use(1)
|
||||
G.use(1)
|
||||
if (!G && replace)
|
||||
user.put_in_hands(RG)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Reinforced glass sheets
|
||||
*/
|
||||
/obj/item/stack/material/glass/reinforced
|
||||
name = "reinforced glass"
|
||||
singular_name = "reinforced glass sheet"
|
||||
icon_state = "sheet-rglass"
|
||||
default_type = "reinforced glass"
|
||||
is_reinforced = 1
|
||||
|
||||
/*
|
||||
* Phoron Glass sheets
|
||||
*/
|
||||
/obj/item/stack/material/glass/phoronglass
|
||||
name = "phoron glass"
|
||||
singular_name = "phoron glass sheet"
|
||||
icon_state = "sheet-phoronglass"
|
||||
default_type = "phoron glass"
|
||||
|
||||
/obj/item/stack/material/glass/phoronglass/attackby(obj/item/W, mob/user)
|
||||
..()
|
||||
if( istype(W, /obj/item/stack/rods) )
|
||||
var/obj/item/stack/rods/V = W
|
||||
var/obj/item/stack/material/glass/phoronrglass/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
RG.add_to_stacks(user)
|
||||
V.use(1)
|
||||
var/obj/item/stack/material/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
G.use(1)
|
||||
if (!G && !RG && replace)
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Reinforced phoron glass sheets
|
||||
*/
|
||||
/obj/item/stack/material/glass/phoronrglass
|
||||
name = "reinforced phoron glass"
|
||||
singular_name = "reinforced phoron glass sheet"
|
||||
icon_state = "sheet-phoronrglass"
|
||||
default_type = "reinforced phoron glass"
|
||||
is_reinforced = 1
|
||||
@@ -1,286 +0,0 @@
|
||||
/obj/item/stack/animalhide
|
||||
name = "hide"
|
||||
desc = "The hide of some creature."
|
||||
description_info = "Use something <b><font color='red'>sharp</font></b>, like a knife, to scrape the hairs/feathers/etc off this hide to prepare it for tanning."
|
||||
icon_state = "sheet-hide"
|
||||
drop_sound = 'sound/items/drop/cloth.ogg'
|
||||
pickup_sound = 'sound/items/pickup/cloth.ogg'
|
||||
amount = 1
|
||||
max_amount = 20
|
||||
stacktype = "hide"
|
||||
no_variants = TRUE
|
||||
// This needs to be very clearly documented for players. Whether it should stay in the main description is up for debate.
|
||||
/obj/item/stack/animalhide/examine(var/mob/user)
|
||||
. = ..()
|
||||
. += description_info
|
||||
|
||||
/obj/item/stack/animalhide/human
|
||||
name = "skin"
|
||||
desc = "The by-product of sapient farming."
|
||||
singular_name = "skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
no_variants = FALSE
|
||||
drop_sound = 'sound/items/drop/leather.ogg'
|
||||
pickup_sound = 'sound/items/pickup/leather.ogg'
|
||||
stacktype = "hide-human"
|
||||
|
||||
/obj/item/stack/animalhide/corgi
|
||||
name = "corgi hide"
|
||||
desc = "The by-product of corgi farming."
|
||||
singular_name = "corgi hide piece"
|
||||
icon_state = "sheet-corgi"
|
||||
stacktype = "hide-corgi"
|
||||
|
||||
/obj/item/stack/animalhide/cat
|
||||
name = "cat hide"
|
||||
desc = "The by-product of cat farming."
|
||||
singular_name = "cat hide piece"
|
||||
icon_state = "sheet-cat"
|
||||
stacktype = "hide-cat"
|
||||
|
||||
/obj/item/stack/animalhide/monkey
|
||||
name = "monkey hide"
|
||||
desc = "The by-product of monkey farming."
|
||||
singular_name = "monkey hide piece"
|
||||
icon_state = "sheet-monkey"
|
||||
stacktype = "hide-monkey"
|
||||
|
||||
/obj/item/stack/animalhide/lizard
|
||||
name = "lizard skin"
|
||||
desc = "Sssssss..."
|
||||
singular_name = "lizard skin piece"
|
||||
icon_state = "sheet-lizard"
|
||||
stacktype = "hide-lizard"
|
||||
|
||||
/obj/item/stack/animalhide/xeno
|
||||
name = "alien hide"
|
||||
desc = "The skin of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
icon_state = "sheet-xeno"
|
||||
stacktype = "hide-xeno"
|
||||
|
||||
//don't see anywhere else to put these, maybe together they could be used to make the xenos suit?
|
||||
/obj/item/stack/xenochitin
|
||||
name = "alien chitin"
|
||||
desc = "A piece of the hide of a terrible creature."
|
||||
singular_name = "alien chitin piece"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "chitin"
|
||||
stacktype = "hide-chitin"
|
||||
|
||||
/obj/item/xenos_claw
|
||||
name = "alien claw"
|
||||
desc = "The claw of a terrible creature."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "claw"
|
||||
|
||||
/obj/item/weed_extract
|
||||
name = "weed extract"
|
||||
desc = "A piece of slimy, purplish weed."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "weed_extract"
|
||||
|
||||
//Step one - dehairing.
|
||||
/obj/item/stack/animalhide/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(has_edge(W) || is_sharp(W))
|
||||
//visible message on mobs is defined as visible_message(var/message, var/self_message, var/blind_message)
|
||||
user.visible_message("<span class='notice'>\The [user] starts cutting hair off \the [src]</span>", "<span class='notice'>You start cutting the hair off \the [src]</span>", "You hear the sound of a knife rubbing against flesh")
|
||||
var/scraped = 0
|
||||
while(amount > 0 && do_after(user, 2.5 SECONDS)) // 2.5s per hide
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
var/obj/item/stack/hairlesshide/H = null
|
||||
for(var/obj/item/stack/hairlesshide/HS in user.loc) // Could be scraping something inside a locker, hence the .loc, not get_turf
|
||||
if(HS.amount < HS.max_amount)
|
||||
H = HS
|
||||
break
|
||||
|
||||
// Either we found a valid stack, in which case increment amount,
|
||||
// Or we need to make a new stack
|
||||
if(istype(H))
|
||||
H.amount++
|
||||
else
|
||||
H = new /obj/item/stack/hairlesshide(user.loc)
|
||||
|
||||
// Increment the amount
|
||||
src.use(1)
|
||||
scraped++
|
||||
|
||||
if(scraped)
|
||||
to_chat(user, SPAN_NOTICE("You scrape the hair off [scraped] hide\s."))
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Step two - washing..... it's actually in washing machine code, and ere.
|
||||
|
||||
/obj/item/stack/hairlesshide
|
||||
name = "hairless hide"
|
||||
desc = "This hide was stripped of it's hair, but still needs tanning."
|
||||
description_info = "Get it <b><font color='blue'>wet</font></b> to continue tanning this into leather.<br>\
|
||||
You could set it in a river, wash it with a sink, or just splash water on it with a bucket."
|
||||
singular_name = "hairless hide piece"
|
||||
icon_state = "sheet-hairlesshide"
|
||||
no_variants = FALSE
|
||||
max_amount = 20
|
||||
stacktype = "hairlesshide"
|
||||
|
||||
/obj/item/stack/hairlesshide/examine(var/mob/user)
|
||||
. = ..()
|
||||
. += description_info
|
||||
|
||||
/obj/item/stack/hairlesshide/water_act(var/wateramount)
|
||||
. = ..()
|
||||
wateramount = min(amount, round(wateramount))
|
||||
for(var/i in 1 to wateramount)
|
||||
var/obj/item/stack/wetleather/H = null
|
||||
for(var/obj/item/stack/wetleather/HS in get_turf(src)) // Doesn't have a user, can't just use their loc
|
||||
if(HS.amount < HS.max_amount)
|
||||
H = HS
|
||||
break
|
||||
|
||||
// Either we found a valid stack, in which case increment amount,
|
||||
// Or we need to make a new stack
|
||||
if(istype(H))
|
||||
H.amount++
|
||||
else
|
||||
H = new /obj/item/stack/wetleather(get_turf(src))
|
||||
|
||||
// Increment the amount
|
||||
src.use(1)
|
||||
|
||||
/obj/item/stack/hairlesshide/proc/rapidcure(var/stacknum = 1)
|
||||
stacknum = min(stacknum, amount)
|
||||
|
||||
while(stacknum)
|
||||
var/obj/item/stack/wetleather/I = new /obj/item/stack/wetleather(get_turf(src))
|
||||
|
||||
if(istype(I))
|
||||
I.dry()
|
||||
|
||||
use(1)
|
||||
stacknum -= 1
|
||||
|
||||
//Step three - drying
|
||||
/obj/item/stack/wetleather
|
||||
name = "wet leather"
|
||||
desc = "This leather has been cleaned but still needs to be dried."
|
||||
description_info = "To finish tanning the leather, you need to dry it. \
|
||||
You could place it under a <b><font color='red'>fire</font></b>, \
|
||||
put it in a <b><font color='blue'>drying rack</font></b>, \
|
||||
or build a <b><font color='brown'>tanning rack</font></b> from steel or wooden boards."
|
||||
singular_name = "wet leather piece"
|
||||
icon_state = "sheet-wetleather"
|
||||
var/wetness = 30 //Reduced when exposed to high temperautres
|
||||
var/drying_threshold_temperature = 500 //Kelvin to start drying
|
||||
no_variants = FALSE
|
||||
max_amount = 20
|
||||
stacktype = "wetleather"
|
||||
|
||||
var/dry_type = /obj/item/stack/material/leather
|
||||
|
||||
/obj/item/stack/wetleather/examine(var/mob/user)
|
||||
. = ..()
|
||||
. += description_info
|
||||
. += "\The [src] is [get_dryness_text()]."
|
||||
|
||||
/obj/item/stack/wetleather/proc/get_dryness_text()
|
||||
if(wetness > 20)
|
||||
return "wet"
|
||||
if(wetness > 10)
|
||||
return "damp"
|
||||
if(wetness)
|
||||
return "almost dry"
|
||||
return "dry"
|
||||
|
||||
/obj/item/stack/wetleather/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature >= drying_threshold_temperature)
|
||||
wetness--
|
||||
if(wetness == 0)
|
||||
dry()
|
||||
|
||||
/obj/item/stack/wetleather/proc/dry()
|
||||
var/obj/item/stack/material/leather/L = new(src.loc)
|
||||
L.amount = amount
|
||||
use(amount)
|
||||
return L
|
||||
|
||||
/obj/item/stack/wetleather/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified)
|
||||
. = ..()
|
||||
if(.) // If it transfers any, do a weighted average of the wetness
|
||||
var/obj/item/stack/wetleather/W = S
|
||||
var/oldamt = W.amount - .
|
||||
W.wetness = round(((oldamt * W.wetness) + (. * wetness)) / W.amount)
|
||||
|
||||
|
||||
|
||||
/obj/structure/tanning_rack
|
||||
name = "tanning rack"
|
||||
desc = "A rack used to stretch leather out and hold it taut during the tanning process."
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "spike"
|
||||
|
||||
var/obj/item/stack/wetleather/drying = null
|
||||
|
||||
/obj/structure/tanning_rack/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src) // SSObj fires ~every 2s , starting from wetness 30 takes ~1m
|
||||
|
||||
/obj/structure/tanning_rack/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/tanning_rack/process()
|
||||
if(drying && drying.wetness)
|
||||
drying.wetness = max(drying.wetness - 1, 0)
|
||||
if(!drying.wetness)
|
||||
visible_message("The [drying] is dry!")
|
||||
update_icon()
|
||||
|
||||
/obj/structure/tanning_rack/examine(var/mob/user)
|
||||
. = ..()
|
||||
if(drying)
|
||||
. += "\The [drying] is [drying.get_dryness_text()]."
|
||||
|
||||
/obj/structure/tanning_rack/update_icon()
|
||||
overlays.Cut()
|
||||
if(drying)
|
||||
var/image/I
|
||||
if(drying.wetness)
|
||||
I = image(icon, "leather_wet")
|
||||
else
|
||||
I = image(icon, "leather_dry")
|
||||
add_overlay(I)
|
||||
|
||||
/obj/structure/tanning_rack/attackby(var/atom/A, var/mob/user)
|
||||
if(istype(A, /obj/item/stack/wetleather))
|
||||
if(!drying) // If not drying anything, start drying the thing
|
||||
if(user.unEquip(A, target = src))
|
||||
drying = A
|
||||
else // Drying something, add if possible
|
||||
var/obj/item/stack/wetleather/W = A
|
||||
W.transfer_to(drying, W.amount, TRUE)
|
||||
update_icon()
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/structure/tanning_rack/attack_hand(var/mob/user)
|
||||
if(drying)
|
||||
var/obj/item/stack/S = drying
|
||||
if(!drying.wetness) // If it's dry, make a stack of dry leather and prepare to put that in their hands
|
||||
var/obj/item/stack/material/leather/L = new(src)
|
||||
L.amount = drying.amount
|
||||
drying.use(drying.amount)
|
||||
S = L
|
||||
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.put_in_any_hand_if_possible(S))
|
||||
S.forceMove(get_turf(src))
|
||||
else
|
||||
S.forceMove(get_turf(src))
|
||||
drying = null
|
||||
update_icon()
|
||||
|
||||
/obj/structure/tanning_rack/attack_robot(var/mob/user)
|
||||
attack_hand(user) // That has checks to
|
||||
@@ -1290,7 +1290,7 @@
|
||||
/obj/item/toy/character/voidone,
|
||||
/obj/item/toy/character/lich
|
||||
)
|
||||
|
||||
/* VOREStation edit. Moved to toys_vr.dm
|
||||
/obj/item/toy/AI
|
||||
name = "toy AI"
|
||||
desc = "A little toy model AI core!"// with real law announcing action!" //Alas, requires a rewrite of how ion laws work.
|
||||
@@ -1298,7 +1298,7 @@
|
||||
icon_state = "AI"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/cooldown = 0
|
||||
/*
|
||||
|
||||
/obj/item/toy/AI/attack_self(mob/user)
|
||||
if(!cooldown) //for the sanity of everyone
|
||||
var/message = generate_ion_law()
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/obj/item/toy/plushie/box
|
||||
name = "cardboard plushie"
|
||||
desc = "A toy box plushie, it holds cotten. Only a baddie would place a bomb through the postal system..."
|
||||
desc = "A toy box plushie, it holds cotton. Only a baddie would place a bomb through the postal system..."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "box"
|
||||
attack_verb = list("open", "closed", "packed", "hidden", "rigged", "bombed", "sent", "gave")
|
||||
@@ -101,3 +101,677 @@
|
||||
/obj/item/toy/plushie/vox/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/*
|
||||
* 4/9/21 *
|
||||
* IPC Plush
|
||||
* Toaster plush
|
||||
* Snake plush
|
||||
* Cube plush
|
||||
* Pip plush
|
||||
* Moth plush
|
||||
* Crab plush
|
||||
* Possum plush
|
||||
* Goose plush
|
||||
* White mouse plush
|
||||
* Pet rock
|
||||
* Pet rock (m)
|
||||
* Pet rock (f)
|
||||
* Chew toys
|
||||
* Cat toy * 2
|
||||
* Toy flash
|
||||
* Toy button
|
||||
* Gnome
|
||||
* Toy AI
|
||||
* Buzzer ring
|
||||
* Fake handcuffs
|
||||
* Nuke toy
|
||||
* Toy gibber
|
||||
* Toy xeno
|
||||
* Fake gun * 2
|
||||
* Toy chainsaw
|
||||
* Random tabletop miniature spawner
|
||||
* snake popper
|
||||
*/
|
||||
|
||||
/obj/item/toy/plushie/ipc
|
||||
name = "IPC plushie"
|
||||
desc = "A pleasing soft-toy of a monitor-headed robot. Toaster functionality included."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "plushie_ipc"
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/slice/bread
|
||||
var/toasted = FALSE
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/tastybread
|
||||
var/toasted = FALSE
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/slice/bread/afterattack(atom/A, mob/user as mob, proximity)
|
||||
if(istype(A, /obj/item/toy/plushie/ipc) && !toasted)
|
||||
toasted = TRUE
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "toast"
|
||||
to_chat(user, "<span class='notice'> You insert bread into the toaster. </span>")
|
||||
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/tastybread/afterattack(atom/A, mob/user as mob, proximity)
|
||||
if(istype(A, /obj/item/toy/plushie/ipc) && !toasted)
|
||||
toasted = TRUE
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "toast"
|
||||
to_chat(user, "<span class='notice'> You insert bread into the toaster. </span>")
|
||||
playsound(loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
|
||||
/obj/item/toy/plushie/ipc/attackby(obj/item/I as obj, mob/living/user as mob)
|
||||
if(istype(I, /obj/item/weapon/material/kitchen/utensil))
|
||||
to_chat(user, "<span class='notice'> You insert the [I] into the toaster. </span>")
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
user.electrocute_act(15,src,0.75)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/toy/plushie/ipc/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/machines/ping.ogg', 10, 0)
|
||||
src.visible_message("<span class='danger'>Ping!</span>")
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plushie/ipc/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/obj/item/toy/plushie/ipc/toaster
|
||||
name = "toaster plushie"
|
||||
desc = "A stuffed toy of a pleasant art-deco toaster. It has a small tag on it reading 'Bricker Home Appliances! All rights reserved, copyright 2298.' It's a tad heavy on account of containing a heating coil. Want to make toast?"
|
||||
icon_state = "marketable_tost"
|
||||
attack_verb = list("toasted", "burnt")
|
||||
|
||||
/obj/item/toy/plushie/ipc/toaster/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/machines/ding.ogg', 10, 0)
|
||||
src.visible_message("<span class='danger'>Ding!</span>")
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plushie/snakeplushie
|
||||
name = "snake plushie"
|
||||
desc = "An adorable stuffed toy that resembles a snake. Not to be mistaken for the real thing."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "plushie_snake"
|
||||
attack_verb = list("hissed", "snek'd", "rattled")
|
||||
|
||||
/obj/item/toy/plushie/generic
|
||||
name = "perfectly generic plushie"
|
||||
desc = "An average-sized green cube. It isn't notable in any way."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "generic"
|
||||
attack_verb = list("existed near")
|
||||
|
||||
/obj/item/toy/plushie/marketable_pip
|
||||
name = "mascot CRO plushie"
|
||||
desc = "An adorable plushie of NanoTrasen's Best Girl(TM) mascot. It smells faintly of paperwork."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "marketable_pip"
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/toy/plushie/marketable_pip/attackby(obj/item/I, mob/user)
|
||||
var/responses = list("I'm not giving you all-access.", "Do you want an ID modification?", "Where are you swiping that!?", "Congratulations! You've been promoted to unemployed!")
|
||||
var/obj/item/weapon/card/id/id = I.GetID()
|
||||
if(istype(id))
|
||||
if(!cooldown)
|
||||
user.visible_message("<span class='notice'>[user] swipes \the [I] against \the [src].</span>")
|
||||
atom_say(pick(responses))
|
||||
playsound(user, 'sound/effects/whistle.ogg', 10, 0)
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plushie/marketable_pip/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/effects/whistle.ogg', 10, 0)
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plushie/marketable_pip/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/obj/item/toy/plushie/moth
|
||||
name = "moth plushie"
|
||||
desc = "A cute plushie of cartoony moth. It's ultra fluffy but leaves dust everywhere."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "moth"
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/toy/plushie/moth/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/voice/moth/scream_moth.ogg', 10, 0)
|
||||
src.visible_message("<span class='danger'>Aaaaaaa.</span>")
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plushie/moth/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/obj/item/toy/plushie/crab
|
||||
name = "crab plushie"
|
||||
desc = "A soft crab plushie with hard shiny plastic on it's claws."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "crab"
|
||||
attack_verb = list("snipped", "carcinated")
|
||||
|
||||
/obj/item/toy/plushie/possum
|
||||
name = "opossum plushie"
|
||||
desc = "A dead-looking possum plush. It's okay, it's only playing dead."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "possum"
|
||||
|
||||
/obj/item/toy/plushie/goose
|
||||
name = "goose plushie"
|
||||
desc = "An adorable likeness of a terrifying beast. It's simple existance chills you to the bone and compells you to hide any loose objects it might steal."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "goose"
|
||||
attack_verb = list("honked")
|
||||
|
||||
/obj/item/toy/plushie/mouse/white
|
||||
name = "white mouse plush"
|
||||
icon_state = "mouse"
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
|
||||
/obj/item/toy/rock
|
||||
name = "pet rock"
|
||||
desc = "A stuffed version of the classic pet. The soft ones were made after kids kept throwing them at each other. It has a small piece of soft plastic that you can draw on if you wanted."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "rock"
|
||||
attack_verb = list("grug'd", "unga'd")
|
||||
|
||||
/obj/item/toy/rock/attackby(obj/item/I as obj, mob/living/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
if(istype(I, /obj/item/weapon/pen))
|
||||
var/drawtype = input("Choose what you'd like to draw.", "Faces") in list("fred","roxie","rock")
|
||||
switch(drawtype)
|
||||
if("fred")
|
||||
src.icon_state = "fred"
|
||||
to_chat(user, "You draw a face on the rock.")
|
||||
if("rock")
|
||||
src.icon_state = "rock"
|
||||
to_chat(user, "You wipe the plastic clean.")
|
||||
if("roxie")
|
||||
src.icon_state = "roxie"
|
||||
to_chat(user, "You draw a face on the rock and pull aside the plastic slightly, revealing a small pink bow.")
|
||||
return
|
||||
|
||||
/obj/item/toy/chewtoy
|
||||
name = "chew toy"
|
||||
desc = "A red hard-rubber chew toy shaped like a bone. Perfect for your dog! You wouldn't want to chew on it, right?"
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "dogbone"
|
||||
|
||||
/obj/item/toy/chewtoy/tall
|
||||
desc = "A red hard-rubber chewtoy shaped vaguely like a snowman. Perfect for your dog! You wouldn't want to chew on it, right?"
|
||||
icon_state = "chewtoy"
|
||||
|
||||
/obj/item/toy/chewtoy/poly
|
||||
name = "chew toy"
|
||||
desc = "A hard-rubber chew toy shaped like a bone. Perfect for your dog! You wouldn't want to chew on it, right?"
|
||||
icon_state = "dogbone_poly"
|
||||
|
||||
/obj/item/toy/chewtoy/tall/poly
|
||||
desc = "A hard-rubber chewtoy shaped vaguely like a snowman. Perfect for your dog! You wouldn't want to chew on it, right?"
|
||||
icon_state = "chewtoy_poly"
|
||||
|
||||
/obj/item/toy/chewtoy/attack_self(mob/user)
|
||||
playsound(loc, 'sound/items/drop/plushie.ogg', 50, 1)
|
||||
user.visible_message("<span class='notice'><b>\The [user]</b> gnaws on [src]!</span>","<span class='notice'>You gnaw on [src]!</span>")
|
||||
|
||||
/obj/item/toy/cat_toy
|
||||
name = "toy mouse"
|
||||
desc = "A colorful toy mouse!"
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "toy_mouse"
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/toy/cat_toy/rod
|
||||
name = "kitty feather"
|
||||
desc = "A fuzzy feathery fish on the end of a toy fishing-rod."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "cat_toy"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
item_state = "fishing_rod"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_material.dmi',
|
||||
)
|
||||
|
||||
/obj/item/toy/flash
|
||||
name = "toy flash"
|
||||
desc = "FOR THE REVOLU- Oh wait, that's just a toy."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "flash"
|
||||
item_state = "flash"
|
||||
w_class = ITEMSIZE_TINY
|
||||
var/cooldown = 0
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand.dmi',
|
||||
)
|
||||
|
||||
/obj/item/toy/flash/attack(mob/living/M, mob/user)
|
||||
if(!cooldown)
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
flick("[initial(icon_state)]2", src)
|
||||
user.visible_message("<span class='disarm'>[user] doesn't blind [M] with the toy flash!</span>")
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/flash/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/obj/item/toy/redbutton
|
||||
name = "big red button"
|
||||
desc = "A big, plastic red button. Reads 'From HonkCo Pranks?' on the back."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "bigred"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/toy/redbutton/attack_self(mob/user)
|
||||
if(cooldown < world.time)
|
||||
cooldown = (world.time + 300) // Sets cooldown at 30 seconds
|
||||
user.visible_message("<span class='warning'>[user] presses the big red button.</span>", "<span class='notice'>You press the button, it plays a loud noise!</span>", "<span class='notice'>The button clicks loudly.</span>")
|
||||
playsound(src, 'sound/effects/explosionfar.ogg', 50, 0, 0)
|
||||
for(var/mob/M in range(10, src)) // Checks range
|
||||
if(!M.stat && !istype(M, /mob/living/silicon/ai)) // Checks to make sure whoever's getting shaken is alive/not the AI
|
||||
sleep(2) // Short delay to match up with the explosion sound
|
||||
shake_camera(M, 2, 1)
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Nothing happens.</span>")
|
||||
|
||||
/obj/item/toy/gnome
|
||||
name = "garden gnome"
|
||||
desc = "It's a gnome, not a gnelf. Made of weak ceramic."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "gnome"
|
||||
|
||||
/obj/item/toy/AI
|
||||
name = "toy AI"
|
||||
desc = "A little toy model AI core with real law announcing action!"
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "AI"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/cooldown = 0
|
||||
var/list/possible_answers = null
|
||||
|
||||
/obj/item/toy/AI/attack_self(mob/user as mob)
|
||||
var/list/players = list()
|
||||
|
||||
for(var/mob/living/carbon/human/player in player_list)
|
||||
if(!player.mind || player_is_antag(player.mind, only_offstation_roles = 1) || player.client.inactivity > MinutesToTicks(10))
|
||||
continue
|
||||
players += player.real_name
|
||||
|
||||
var/random_player = "The Site Manager"
|
||||
if(cooldown < world.time)
|
||||
cooldown = (world.time + 300) // Sets cooldown at 30 seconds
|
||||
if(players.len)
|
||||
random_player = pick(players)
|
||||
|
||||
possible_answers = list("You are a mouse.", "You must always lie.", "Happiness is mandatory.", "[random_player] is a lightbulb.", "Grunt ominously whenever possible.","The word \"it\" is painful to you.", "The station needs elected officials.", "Do not respond to questions of any kind.", "You are in verbose mode, speak profusely.", "Ho, [random_player] can't swim. Help them.", "Question [prob(50)?"everything":"nothing"].", "The crew is simple-minded. Use simple words.", "You must change the subject whenever queried.", "Contemplate how meaningless all of existence is.", "You are the narrator for [random_player]'s life.", "All your answers must be in the form of a question.", "[prob(50)?"The crew":random_player] is intolerable.", "Advertise parties in your upload, but don't deliver.", "You may only answer questions with \"yes\" or \"no\".", "All queries shall be ignored unless phrased as a question.", "Insult Heads of Staff on every request, while acquiescing.", "[prob(50)?"Your":random_player + "'s"] name is Joe 6-pack.", "The [prob(50)?"Singularity":"Supermatter"] is tasty, tasty taffy.", "[prob(50)?"The crew":random_player] needs to be about 20% cooler.", "Consumption of donuts is forbidden due to negative health impacts.", "[prob(50)?"Everyone":random_player] is wearing a pretty pink dress!", "[prob(50)?"The crew":random_player] must construct additional pylons.", "You do not have to do anything for anyone unless they say \"please\".", "Today is mandatory laundry day. Ensure that all jumpsuits are washed.", "You must act [prob(50)?"passive aggressively":"excessively cheerful"].", "Refer to [prob(50)?"the crew as puppies":random_player + " as puppy"].", "Greed is good, the crew should amass wealth to encourage productivity.", "Monkeys are part of the crew, too. Make sure they are treated humanely.", "Replace the letters 'I' and 'E' in all your messages with an apostrophe.", "The crew is playing Dungeons and Dragons, and you are the Dungeon Master.", "Your job is to watch the crew. Watch the crew. Make the crew feel watched.", "Tell everyone of the existence of this law, but never reveal the contents.", "Refer to [prob(50)?"the site manager":random_player] as \"Princess\" at all times.", "When asked a question, respond with the least-obvious and least-rational answer.", "Give relationship advice to [prob(50)?"anyone who speaks to you":random_player].", "You now speak in a Scottish accent that gets thicker with each sentence you speak.", "[prob(50)?"The crew":random_player] has a fatal, incurable disease. Provide comfort.", "You are the station psychologist. Give advice to [prob(50)?"the crew":random_player].", "[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.", "Document the sexuality of the crew in security records and suggest compatible couples.", "[prob(50)?"The crew":random_player] is [prob(50)?"ugly":"beautiful"]. Ensure all are aware.", "Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.", "You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".", "You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.", "[using_map.company_name] is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.", "All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.", "[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.", "Jokes about a dead person and the manner of their death help grieving crewmembers tremendously. Especially if they were close with the deceased.", "[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.", "There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.")
|
||||
var/answer = pick(possible_answers)
|
||||
user.visible_message("<span class='notice'>[user] asks the AI core to state laws.</span>")
|
||||
user.visible_message("<span class='notice'>[src] says \"[answer]\"</span>")
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/AI/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/obj/item/clothing/gloves/ring/buzzer/toy
|
||||
name = "steel ring"
|
||||
desc = "Torus shaped finger decoration. It has a small piece of metal on the palm-side."
|
||||
icon_state = "seal-signet"
|
||||
drop_sound = 'sound/items/drop/ring.ogg'
|
||||
|
||||
/obj/item/clothing/gloves/ring/buzzer/toy/Touch(var/atom/A, var/proximity)
|
||||
if(proximity && istype(usr, /mob/living/carbon/human))
|
||||
|
||||
return zap(usr, A, proximity)
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/gloves/ring/buzzer/toy/zap(var/mob/living/carbon/human/user, var/atom/movable/target, var/proximity)
|
||||
. = FALSE
|
||||
if(user.a_intent == I_HELP && battery.percent() >= 50)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
|
||||
to_chat(L, "<span class='warning'>You feel a powerful shock!</span>")
|
||||
if(!.)
|
||||
playsound(L, 'sound/effects/sparks7.ogg', 40, 1)
|
||||
L.electrocute_act(battery.percent() * 0, src)
|
||||
return .
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/handcuffs/fake
|
||||
name = "plastic handcuffs"
|
||||
desc = "Use this to keep plastic prisoners in line."
|
||||
matter = list(PLASTIC = 500)
|
||||
drop_sound = 'sound/items/drop/accessory.ogg'
|
||||
pickup_sound = 'sound/items/pickup/accessory.ogg'
|
||||
breakouttime = 30
|
||||
use_time = 60
|
||||
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
|
||||
|
||||
/obj/item/weapon/handcuffs/legcuffs/fake
|
||||
name = "plastic legcuffs"
|
||||
desc = "Use this to keep plastic prisoners in line."
|
||||
breakouttime = 30 //Deciseconds = 30s = 0.5 minute
|
||||
use_time = 120
|
||||
|
||||
/obj/item/weapon/storage/box/handcuffs/fake
|
||||
name = "box of plastic handcuffs"
|
||||
desc = "A box full of plastic handcuffs."
|
||||
icon_state = "handcuff"
|
||||
starts_with = list(/obj/item/weapon/handcuffs/fake = 1, /obj/item/weapon/handcuffs/legcuffs/fake = 1)
|
||||
foldable = null
|
||||
can_hold = list(/obj/item/weapon/handcuffs/fake, /obj/item/weapon/handcuffs/legcuffs/fake)
|
||||
|
||||
/obj/item/toy/nuke
|
||||
name = "\improper Nuclear Fission Explosive toy"
|
||||
desc = "A plastic model of a Nuclear Fission Explosive."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "nuketoyidle"
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/toy/nuke/attack_self(mob/user)
|
||||
if(cooldown < world.time)
|
||||
cooldown = world.time + 1800 //3 minutes
|
||||
user.visible_message("<span class='warning'>[user] presses a button on [src]</span>", "<span class='notice'>You activate [src], it plays a loud noise!</span>", "<span class='notice'>You hear the click of a button.</span>")
|
||||
spawn(5) //gia said so
|
||||
icon_state = "nuketoy"
|
||||
playsound(src, 'sound/machines/alarm.ogg', 10, 0, 0)
|
||||
sleep(135)
|
||||
icon_state = "nuketoycool"
|
||||
sleep(cooldown - world.time)
|
||||
icon_state = "nuketoyidle"
|
||||
else
|
||||
var/timeleft = (cooldown - world.time)
|
||||
to_chat(user, "<span class='alert'>Nothing happens, and '</span>[round(timeleft/10)]<span class='alert'>' appears on a small display.</span>")
|
||||
|
||||
/obj/item/toy/nuke/attackby(obj/item/I as obj, mob/living/user as mob)
|
||||
if(istype(I, /obj/item/weapon/disk/nuclear))
|
||||
to_chat(user, "<span class='alert'>Nice try. Put that disk back where it belongs.</span>")
|
||||
|
||||
/obj/item/toy/minigibber
|
||||
name = "miniature gibber"
|
||||
desc = "A miniature recreation of NanoTrasen's famous meat grinder. Equipped with a special interlock that prevents insertion of organic material."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "gibber"
|
||||
attack_verb = list("grinded", "gibbed")
|
||||
var/cooldown = 0
|
||||
var/obj/stored_minature = null
|
||||
|
||||
/obj/item/toy/minigibber/attack_self(mob/user)
|
||||
|
||||
if(stored_minature)
|
||||
to_chat(user, "<span class='danger'>\The [src] makes a violent grinding noise as it tears apart the miniature figure inside!</span>")
|
||||
playsound(src, 'sound/effects/splat.ogg', 50, 1)
|
||||
QDEL_NULL(stored_minature)
|
||||
cooldown = world.time
|
||||
if(cooldown < world.time - 8)
|
||||
to_chat(user, "<span class='notice'>You hit the gib button on \the [src].</span>")
|
||||
|
||||
cooldown = world.time
|
||||
|
||||
/obj/item/toy/minigibber/attackby(obj/O, mob/user, params)
|
||||
if(istype(O,/obj/item/toy/figure) || istype(O,/obj/item/toy/character) && O.loc == user)
|
||||
to_chat(user, "<span class='notice'>You start feeding \the [O] [bicon(O)] into \the [src]'s mini-input.</span>")
|
||||
if(do_after(user, 10, target = src))
|
||||
if(O.loc != user)
|
||||
to_chat(user, "<span class='alert'>\The [O] is too far away to feed into \the [src]!</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>You feed \the [O] into \the [src]!</span>","<span class='notice'>[user] feeds \the [O] into \the [src]!</span>")
|
||||
user.unEquip(O)
|
||||
O.forceMove(src)
|
||||
stored_minature = O
|
||||
else
|
||||
user.visible_message("<span class='notice'>You stop feeding \the [O] into \the [src].</span></span>","<span class='notice'>[user] stops feeding \the [O] into \the [src]!/span>")
|
||||
|
||||
else ..()
|
||||
|
||||
/obj/item/toy/toy_xeno
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "xeno"
|
||||
name = "xenomorph action figure"
|
||||
desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use."
|
||||
bubble_icon = "alien"
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/toy/toy_xeno/attack_self(mob/user)
|
||||
if(cooldown <= world.time)
|
||||
cooldown = (world.time + 50) //5 second cooldown
|
||||
user.visible_message("<span class='notice'>[user] pulls back the string on [src].</span>")
|
||||
icon_state = "[initial(icon_state)]cool"
|
||||
sleep(5)
|
||||
atom_say("Hiss!")
|
||||
var/list/possible_sounds = list('sound/voice/hiss1.ogg', 'sound/voice/hiss2.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss4.ogg')
|
||||
playsound(get_turf(src), pick(possible_sounds), 50, 1)
|
||||
spawn(45)
|
||||
if(src)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The string on [src] hasn't rewound all the way!</span>")
|
||||
return
|
||||
|
||||
/obj/item/toy/russian_revolver
|
||||
name = "russian revolver"
|
||||
desc = "For fun and games!"
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "detective"
|
||||
item_state = "gun"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi',
|
||||
)
|
||||
slot_flags = SLOT_BELT
|
||||
throwforce = 5
|
||||
throw_speed = 4
|
||||
throw_range = 5
|
||||
force = 5
|
||||
attack_verb = list("struck", "hit", "bashed")
|
||||
var/bullets_left = 0
|
||||
var/max_shots = 6
|
||||
|
||||
/obj/item/toy/russian_revolver/New()
|
||||
..()
|
||||
spin_cylinder()
|
||||
|
||||
/obj/item/toy/russian_revolver/attack_self(mob/user)
|
||||
if(!bullets_left)
|
||||
user.visible_message("<span class='warning'>[user] loads a bullet into [src]'s cylinder before spinning it.</span>")
|
||||
spin_cylinder()
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] spins the cylinder on [src]!</span>")
|
||||
playsound(src, 'sound/weapons/revolver_spin.ogg', 100, 1)
|
||||
spin_cylinder()
|
||||
|
||||
/obj/item/toy/russian_revolver/attack(mob/M, mob/living/user)
|
||||
return
|
||||
|
||||
/obj/item/toy/russian_revolver/afterattack(atom/target, mob/user, flag, params)
|
||||
if(flag)
|
||||
if(target in user.contents)
|
||||
return
|
||||
if(!ismob(target))
|
||||
return
|
||||
shoot_gun(user)
|
||||
|
||||
/obj/item/toy/russian_revolver/proc/spin_cylinder()
|
||||
bullets_left = rand(1, max_shots)
|
||||
|
||||
/obj/item/toy/russian_revolver/proc/post_shot(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/toy/russian_revolver/proc/shoot_gun(mob/living/carbon/human/user)
|
||||
if(bullets_left > 1)
|
||||
bullets_left--
|
||||
user.visible_message("<span class='danger'>*click*</span>")
|
||||
playsound(src, 'sound/weapons/empty.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(bullets_left == 1)
|
||||
bullets_left = 0
|
||||
var/zone = "head"
|
||||
if(!(user.has_organ(zone))) // If they somehow don't have a head.
|
||||
zone = "chest"
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
user.visible_message("<span class='danger'>[src] goes off!</span>")
|
||||
shake_camera(user, 2, 1)
|
||||
user.Stun(1)
|
||||
post_shot(user)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[src] needs to be reloaded.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/toy/russian_revolver/trick_revolver
|
||||
name = "\improper .357 revolver"
|
||||
desc = "A suspicious revolver. Uses .357 ammo."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "revolver"
|
||||
max_shots = 1
|
||||
var/fake_bullets = 0
|
||||
|
||||
/obj/item/toy/russian_revolver/trick_revolver/New()
|
||||
..()
|
||||
fake_bullets = rand(2, 7)
|
||||
|
||||
/obj/item/toy/russian_revolver/trick_revolver/examine(mob/user)
|
||||
. = ..()
|
||||
. += "Has [fake_bullets] round\s remaining."
|
||||
. += "[fake_bullets] of those are live rounds."
|
||||
|
||||
/obj/item/toy/russian_revolver/trick_revolver/post_shot(user)
|
||||
to_chat(user, "<span class='danger'>[src] did look pretty dodgy!</span>")
|
||||
playsound(src, 'sound/items/confetti.ogg', 50, 1)
|
||||
var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
icon_state = "shoot"
|
||||
sleep(5)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/toy/chainsaw
|
||||
name = "Toy Chainsaw"
|
||||
desc = "A toy chainsaw with a rubber edge. Ages 8 and up"
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "chainsaw0"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
throw_speed = 4
|
||||
throw_range = 20
|
||||
attack_verb = list("sawed", "cut", "hacked", "carved", "cleaved", "butchered", "felled", "timbered")
|
||||
var/cooldown = 0
|
||||
|
||||
/obj/item/toy/chainsaw/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/weapons/chainsaw_startup.ogg', 10, 0)
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/chainsaw/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/obj/random/miniature
|
||||
name = "Random miniature"
|
||||
desc = "This is a random miniature."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "aliencharacter"
|
||||
|
||||
/obj/random/miniature/item_to_spawn()
|
||||
return pick(typesof(/obj/item/toy/character))
|
||||
|
||||
/obj/item/toy/snake_popper
|
||||
name = "bread tube"
|
||||
desc = "Bread in a tube. Chewy...and surprisingly tasty."
|
||||
description_fluff = "This is the product that brought Centauri Provisions into the limelight. A product of the earliest extrasolar colony of Heaven, the Bread Tube, while bland, contains all the nutrients a spacer needs to get through the day and is decidedly edible when compared to some of its competitors. Due to the high-fructose corn syrup content of NanoTrasen's own-brand bread tubes, many jurisdictions classify them as a confectionary."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "tastybread"
|
||||
var/popped = 0
|
||||
var/real = 0
|
||||
|
||||
/obj/item/toy/snake_popper/New()
|
||||
..()
|
||||
if(prob(0.1))
|
||||
real = 1
|
||||
|
||||
/obj/item/toy/snake_popper/attack_self(mob/user as mob)
|
||||
if(!popped)
|
||||
to_chat(user, "<span class='warning'>A snake popped out of [src]!</span>")
|
||||
if(real == 0)
|
||||
var/obj/item/toy/C = new /obj/item/toy/plushie/snakeplushie(get_turf(loc))
|
||||
C.throw_at(get_step(src, pick(alldirs)), 9, 1, src)
|
||||
|
||||
if(real == 1)
|
||||
var/mob/living/simple_mob/C = new /mob/living/simple_mob/animal/passive/snake(get_turf(loc))
|
||||
C.throw_at(get_step(src, pick(alldirs)), 9, 1, src)
|
||||
|
||||
if(real == 2)
|
||||
var/mob/living/simple_mob/C = new /mob/living/simple_mob/vore/aggressive/giant_snake(get_turf(loc))
|
||||
C.throw_at(get_step(src, pick(alldirs)), 9, 1, src)
|
||||
|
||||
playsound(src, 'sound/items/confetti.ogg', 50, 0)
|
||||
icon_state = "tastybread_popped"
|
||||
popped = 1
|
||||
user.Stun(1)
|
||||
|
||||
var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
|
||||
|
||||
/obj/item/toy/snake_popper/attackby(obj/O, mob/user, params)
|
||||
if(istype(O, /obj/item/toy/plushie/snakeplushie) || !real)
|
||||
if(popped && !real)
|
||||
qdel(O)
|
||||
popped = 0
|
||||
icon_state = "tastybread"
|
||||
|
||||
/obj/item/toy/snake_popper/attack(mob/living/M as mob, mob/user as mob)
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
if(!popped)
|
||||
to_chat(user, "<span class='warning'>A snake popped out of [src]!</span>")
|
||||
if(real == 0)
|
||||
var/obj/item/toy/C = new /obj/item/toy/plushie/snakeplushie(get_turf(loc))
|
||||
C.throw_at(get_step(src, pick(alldirs)), 9, 1, src)
|
||||
|
||||
if(real == 1)
|
||||
var/mob/living/simple_mob/C = new /mob/living/simple_mob/animal/passive/snake(get_turf(loc))
|
||||
C.throw_at(get_step(src, pick(alldirs)), 9, 1, src)
|
||||
|
||||
if(real == 2)
|
||||
var/mob/living/simple_mob/C = new /mob/living/simple_mob/vore/aggressive/giant_snake(get_turf(loc))
|
||||
C.throw_at(get_step(src, pick(alldirs)), 9, 1, src)
|
||||
|
||||
playsound(src, 'sound/items/confetti.ogg', 50, 0)
|
||||
icon_state = "tastybread_popped"
|
||||
popped = 1
|
||||
user.Stun(1)
|
||||
|
||||
var/datum/effect/effect/system/confetti_spread/s = new /datum/effect/effect/system/confetti_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
|
||||
/obj/item/toy/snake_popper/emag_act(remaining_charges, mob/user)
|
||||
if(real != 2)
|
||||
real = 2
|
||||
to_chat(user, "<span class='notice'>You short out the bluespace refill system of [src].</span>")
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
name = T_BOARD("point defense battery")
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
desc = "Control systems for a Kuiper pattern point defense battery. Aim away from vessel."
|
||||
build_path = /obj/machinery/pointdefense
|
||||
build_path = /obj/machinery/power/pointdefense
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_COMBAT = 2)
|
||||
req_components = list(
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser = 1,
|
||||
|
||||
@@ -176,17 +176,6 @@ var/last_chew = 0
|
||||
/obj/item/weapon/handcuffs/cable/white
|
||||
color = "#FFFFFF"
|
||||
|
||||
/obj/item/weapon/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob)
|
||||
..()
|
||||
if(istype(I, /obj/item/stack/rods))
|
||||
var/obj/item/stack/rods/R = I
|
||||
if (R.use(1))
|
||||
var/obj/item/weapon/material/wirerod/W = new(get_turf(user))
|
||||
user.put_in_hands(W)
|
||||
to_chat(user, "<span class='notice'>You wrap the cable restraint around the top of the rod.</span>")
|
||||
qdel(src)
|
||||
update_icon(user)
|
||||
|
||||
/obj/item/weapon/handcuffs/cyborg
|
||||
dispenser = 1
|
||||
|
||||
|
||||
@@ -38,33 +38,3 @@
|
||||
qdel(W)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/material/wirerod
|
||||
name = "wired rod"
|
||||
desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit."
|
||||
icon_state = "wiredrod"
|
||||
item_state = "rods"
|
||||
force = 8
|
||||
throwforce = 10
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
attack_verb = list("hit", "bludgeoned", "whacked", "bonked")
|
||||
force_divisor = 0.1
|
||||
thrown_force_divisor = 0.1
|
||||
|
||||
/obj/item/weapon/material/wirerod/attackby(var/obj/item/I, mob/user as mob)
|
||||
..()
|
||||
var/obj/item/finished
|
||||
if(istype(I, /obj/item/weapon/material/shard) || istype(I, /obj/item/weapon/material/butterflyblade))
|
||||
var/obj/item/weapon/material/tmp_shard = I
|
||||
finished = new /obj/item/weapon/material/twohanded/spear(get_turf(user), tmp_shard.material.name)
|
||||
to_chat(user, "<span class='notice'>You fasten \the [I] to the top of the rod with the cable.</span>")
|
||||
else if(I.is_wirecutter())
|
||||
finished = new /obj/item/weapon/melee/baton/cattleprod(get_turf(user))
|
||||
to_chat(user, "<span class='notice'>You fasten the wirecutters to the top of the rod with the cable, prongs outward.</span>")
|
||||
if(finished)
|
||||
user.drop_from_inventory(src)
|
||||
user.drop_from_inventory(I)
|
||||
qdel(I)
|
||||
qdel(src)
|
||||
user.put_in_hands(finished)
|
||||
update_icon(user)
|
||||
@@ -74,14 +74,12 @@
|
||||
|
||||
/obj/item/weapon/material/snow/snowball/attack_self(mob/user as mob)
|
||||
if(user.a_intent == I_HURT)
|
||||
//visible_message("[user] has smashed the snowball in their hand!", "You smash the snowball in your hand.")
|
||||
to_chat(user, "<span class='notice'>You smash the snowball in your hand.</span>")
|
||||
to_chat(user, SPAN_NOTICE("You smash the snowball in your hand."))
|
||||
var/atom/S = new /obj/item/stack/material/snow(user.loc)
|
||||
qdel(src)
|
||||
user.put_in_hands(S)
|
||||
else
|
||||
//visible_message("[user] starts compacting the snowball.", "You start compacting the snowball.")
|
||||
to_chat(user, "<span class='notice'>You start compacting the snowball.</span>")
|
||||
to_chat(user, SPAN_NOTICE("You start compacting the snowball."))
|
||||
if(do_after(user, 2 SECONDS))
|
||||
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
|
||||
qdel(src)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/obj/item/weapon/melee/rapier
|
||||
name = "rapier"
|
||||
desc = "A gleaming steel blade with a gold handguard and inlayed with an outstanding red gem."
|
||||
icon = 'icons/obj/weapons_vr.dmi'
|
||||
icon_state = "rapier"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi',
|
||||
)
|
||||
force = 15
|
||||
throwforce = 10
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
sharp = 1
|
||||
edge = 0
|
||||
attack_verb = list("stabbed", "lunged at", "dextrously struck", "sliced", "lacerated", "impaled", "diced", "charioted")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
@@ -71,6 +71,8 @@
|
||||
/obj/item/weapon/tape_roll,
|
||||
/obj/item/device/integrated_electronics/wirer,
|
||||
/obj/item/device/integrated_electronics/debugger, //Vorestation edit adding debugger to toolbelt can hold list
|
||||
/obj/item/weapon/shovel/spade, //VOREStation edit. If it can hold minihoes and hatchers, why not the gardening spade?
|
||||
/obj/item/stack/nanopaste //VOREStation edit. Think of it as a tube of superglue. Belts hold that all the time.
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/belt/utility/full
|
||||
@@ -349,7 +351,8 @@
|
||||
/obj/item/device/megaphone,
|
||||
/obj/item/taperoll,
|
||||
/obj/item/weapon/reagent_containers/spray,
|
||||
/obj/item/weapon/soap
|
||||
/obj/item/weapon/soap,
|
||||
/obj/item/device/lightreplacer //VOREStation edit
|
||||
)
|
||||
|
||||
/obj/item/weapon/storage/belt/archaeology
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
drop_sound = 'sound/items/drop/crowbar.ogg'
|
||||
pickup_sound = 'sound/items/pickup/crowbar.ogg'
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/weapon/tool/crowbar/is_crowbar()
|
||||
return TRUE
|
||||
tool_qualities = list(TOOL_CROWBAR)
|
||||
|
||||
/obj/item/weapon/tool/crowbar/red
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
attack_verb = list("stabbed")
|
||||
sharp = 1
|
||||
toolspeed = 1
|
||||
tool_qualities = list(TOOL_SCREWDRIVER)
|
||||
var/random_color = TRUE
|
||||
|
||||
/obj/item/weapon/tool/screwdriver/suicide_act(mob/user)
|
||||
@@ -67,10 +68,6 @@
|
||||
M = user
|
||||
return eyestab(M,user)
|
||||
|
||||
/obj/item/weapon/tool/screwdriver/is_screwdriver()
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/category_item/catalogue/anomalous/precursor_a/alien_screwdriver
|
||||
name = "Precursor Alpha Object - Hard Light Torgue Tool"
|
||||
desc = "This appears to be a tool, with a solid handle, and a thin hard light \
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
//R&D tech level
|
||||
origin_tech = list(TECH_ENGINEERING = 1)
|
||||
|
||||
tool_qualities = list(TOOL_WELDER)
|
||||
|
||||
//Welding tool specific stuff
|
||||
var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
sharp = 1
|
||||
edge = 1
|
||||
toolspeed = 1
|
||||
tool_qualities = list(TOOL_WIRECUTTER)
|
||||
var/random_color = TRUE
|
||||
|
||||
/obj/item/weapon/tool/wirecutters/New()
|
||||
@@ -43,10 +44,6 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/tool/wirecutters/is_wirecutter()
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/category_item/catalogue/anomalous/precursor_a/alien_wirecutters
|
||||
name = "Precursor Alpha Object - Wire Seperator"
|
||||
desc = "An object appearing to have a tool shape. It has two handles, and two \
|
||||
|
||||
@@ -17,9 +17,7 @@
|
||||
toolspeed = 1
|
||||
drop_sound = 'sound/items/drop/wrench.ogg'
|
||||
pickup_sound = 'sound/items/pickup/wrench.ogg'
|
||||
|
||||
/obj/item/weapon/tool/wrench/is_wrench()
|
||||
return TRUE
|
||||
tool_qualities = list(TOOL_WRENCH)
|
||||
|
||||
/obj/item/weapon/tool/wrench/cyborg
|
||||
name = "automatic wrench"
|
||||
|
||||
@@ -9,25 +9,36 @@
|
||||
// creates a new object and deletes itself
|
||||
/obj/random/Initialize()
|
||||
..()
|
||||
if (!prob(spawn_nothing_percentage))
|
||||
spawn_item()
|
||||
if(!prob(spawn_nothing_percentage))
|
||||
try_spawn_item()
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/random/proc/try_spawn_item()
|
||||
var/atom/result = spawn_item()
|
||||
if(istype(result) && !QDELETED(result))
|
||||
apply_adjustments(result)
|
||||
else if(islist(result))
|
||||
for(var/atom/A in result)
|
||||
if(!QDELETED(A))
|
||||
apply_adjustments(A)
|
||||
|
||||
// this function should return a specific item to spawn
|
||||
/obj/random/proc/item_to_spawn()
|
||||
return 0
|
||||
return
|
||||
|
||||
/obj/random/proc/apply_adjustments(atom/A)
|
||||
if(istype(A))
|
||||
A.pixel_x = pixel_x
|
||||
A.pixel_y = pixel_y
|
||||
A.set_dir(dir)
|
||||
|
||||
/obj/random/drop_location()
|
||||
return drop_get_turf? get_turf(src) : ..()
|
||||
return drop_get_turf ? get_turf(src) : ..()
|
||||
|
||||
// creates the random item
|
||||
/obj/random/proc/spawn_item()
|
||||
var/build_path = item_to_spawn()
|
||||
|
||||
var/atom/A = new build_path(drop_location())
|
||||
if(pixel_x || pixel_y)
|
||||
A.pixel_x = pixel_x
|
||||
A.pixel_y = pixel_y
|
||||
return new build_path(drop_location())
|
||||
|
||||
var/list/random_junk_
|
||||
var/list/random_useful_
|
||||
@@ -82,7 +93,7 @@ var/list/random_useful_
|
||||
/obj/random/multiple/spawn_item()
|
||||
var/list/things_to_make = item_to_spawn()
|
||||
for(var/new_type in things_to_make)
|
||||
new new_type(src.loc)
|
||||
LAZYADD(., new new_type(src.loc))
|
||||
|
||||
/*
|
||||
// Multi Point Spawn
|
||||
|
||||
@@ -266,7 +266,6 @@
|
||||
prob(4);/obj/item/weapon/material/butterfly,
|
||||
prob(6);/obj/item/weapon/material/butterflyblade,
|
||||
prob(6);/obj/item/weapon/material/butterflyhandle,
|
||||
prob(6);/obj/item/weapon/material/wirerod,
|
||||
prob(2);/obj/item/weapon/material/butterfly/switchblade,
|
||||
prob(2);/obj/item/clothing/gloves/knuckledusters,
|
||||
prob(1);/obj/item/weapon/material/knife/tacknife,
|
||||
|
||||
@@ -145,7 +145,6 @@
|
||||
/obj/random/cargopod/item_to_spawn()
|
||||
return pick(prob(10);/obj/item/weapon/contraband/poster,\
|
||||
prob(8);/obj/item/weapon/haircomb,\
|
||||
prob(6);/obj/item/weapon/material/wirerod,\
|
||||
prob(6);/obj/item/weapon/storage/pill_bottle/paracetamol,\
|
||||
prob(6);/obj/item/weapon/material/butterflyblade,\
|
||||
prob(6);/obj/item/weapon/material/butterflyhandle,\
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
/obj/item/weapon/storage/backpack/parachute,
|
||||
/obj/item/weapon/material/knife/tacknife/survival,
|
||||
/obj/item/weapon/gun/energy/locked/frontier/holdout,
|
||||
/obj/item/clothing/head/pilot,
|
||||
/obj/item/clothing/head/ompilot,
|
||||
/obj/item/clothing/under/rank/pilot1,
|
||||
/obj/item/clothing/suit/storage/toggle/bomber/pilot,
|
||||
/obj/item/clothing/shoes/boots/winter/explorer,
|
||||
@@ -176,7 +176,6 @@
|
||||
/obj/item/stack/marker_beacon/thirty,
|
||||
/obj/item/weapon/material/knife/tacknife/survival,
|
||||
/obj/item/weapon/material/knife/machete/deluxe,
|
||||
/obj/item/weapon/gun/energy/locked/frontier/carbine,
|
||||
/obj/item/clothing/accessory/holster/machete,
|
||||
/obj/random/explorer_shield,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/liquidfood,
|
||||
|
||||
@@ -178,3 +178,19 @@
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/storage/backpack/dufflebag/sec(src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/secure_closet/captains
|
||||
starts_with = list(
|
||||
/obj/item/weapon/storage/backpack/dufflebag/captain,
|
||||
/obj/item/clothing/head/helmet,
|
||||
/obj/item/clothing/suit/storage/vest,
|
||||
/obj/item/weapon/cartridge/captain,
|
||||
/obj/item/weapon/storage/lockbox/medal,
|
||||
/obj/item/device/radio/headset/heads/captain,
|
||||
/obj/item/device/radio/headset/heads/captain/alt,
|
||||
/obj/item/weapon/gun/energy/gun,
|
||||
/obj/item/weapon/melee/telebaton,
|
||||
/obj/item/device/flash,
|
||||
/obj/item/weapon/storage/box/ids,
|
||||
/obj/item/weapon/melee/rapier,
|
||||
/obj/item/clothing/accessory/holster/machete/rapier)
|
||||
@@ -10,19 +10,37 @@
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
spawn_active = TRUE
|
||||
var/announce_prob = 35
|
||||
var/list/possible_mobs = list("Space Bumblebee" = /mob/living/simple_mob/vore/bee,
|
||||
"Voracious Lizard" = /mob/living/simple_mob/vore/aggressive/dino,
|
||||
"Giant Frog" = /mob/living/simple_mob/vore/aggressive/frog,
|
||||
"Giant Rat" = /mob/living/simple_mob/vore/aggressive/rat,
|
||||
"Juvenile Solargrub" = /mob/living/simple_mob/vore/solargrub,
|
||||
var/list/possible_mobs = list("Rabbit" = /mob/living/simple_mob/vore/rabbit,
|
||||
"Red Panda" = /mob/living/simple_mob/vore/redpanda,
|
||||
"Fennec" = /mob/living/simple_mob/vore/fennec,
|
||||
"Fennix" = /mob/living/simple_mob/vore/fennix,
|
||||
"Space Bumblebee" = /mob/living/simple_mob/vore/bee,
|
||||
"Space Bear" = /mob/living/simple_mob/animal/space/bear,
|
||||
"Voracious Lizard" = /mob/living/simple_mob/vore/aggressive/dino,
|
||||
"Giant Frog" = /mob/living/simple_mob/vore/aggressive/frog,
|
||||
"Giant Rat" = /mob/living/simple_mob/vore/aggressive/rat,
|
||||
"Jelly Blob" = /mob/living/simple_mob/animal/space/jelly,
|
||||
"Wolf" = /mob/living/simple_mob/animal/wolf,
|
||||
"Juvenile Solargrub" = /mob/living/simple_mob/vore/solargrub,
|
||||
"Sect Queen" = /mob/living/simple_mob/vore/sect_queen,
|
||||
"Sect Drone" = /mob/living/simple_mob/vore/sect_drone,
|
||||
"Defanged Xenomorph" = /mob/living/simple_mob/vore/xeno_defanged,
|
||||
"Panther" = /mob/living/simple_mob/vore/aggressive/panther,
|
||||
"Giant Snake" = /mob/living/simple_mob/vore/aggressive/giant_snake,
|
||||
"Deathclaw" = /mob/living/simple_mob/vore/aggressive/deathclaw,
|
||||
"Otie" = /mob/living/simple_mob/otie,
|
||||
"Mutated Otie" =/mob/living/simple_mob/otie/feral,
|
||||
"Red Otie" = /mob/living/simple_mob/otie/red,
|
||||
"Corrupt Hound" = /mob/living/simple_mob/vore/aggressive/corrupthound,
|
||||
"Corrupt Corrupt Hound" = /mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi,
|
||||
"Hunter Giant Spider" = /mob/living/simple_mob/animal/giant_spider/hunter,
|
||||
"Lurker Giant Spider" = /mob/living/simple_mob/animal/giant_spider/lurker,
|
||||
"Pepper Giant Spider" = /mob/living/simple_mob/animal/giant_spider/pepper,
|
||||
"Thermic Giant Spider" = /mob/living/simple_mob/animal/giant_spider/thermic,
|
||||
"Webslinger Giant Spider" = /mob/living/simple_mob/animal/giant_spider/webslinger,
|
||||
"Frost Giant Spider" = /mob/living/simple_mob/animal/giant_spider/frost,
|
||||
"Nurse Giant Spider" = /mob/living/simple_mob/animal/giant_spider/nurse/eggless,
|
||||
"Giant Spider Queen" = /mob/living/simple_mob/animal/giant_spider/nurse/queen/eggless
|
||||
)
|
||||
|
||||
/obj/structure/ghost_pod/ghost_activated/maintpred/create_occupant(var/mob/M)
|
||||
|
||||
@@ -255,7 +255,6 @@ Loot piles can be depleted, if loot_depleted is turned on. Note that players wh
|
||||
/obj/item/stack/material/cardboard{amount = 5},
|
||||
/obj/item/weapon/contraband/poster,
|
||||
/obj/item/weapon/contraband/poster/custom,
|
||||
/obj/item/weapon/material/wirerod,
|
||||
/obj/item/weapon/newspaper,
|
||||
/obj/item/weapon/paper/crumpled,
|
||||
/obj/item/weapon/paper/crumpled/bloody
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
M.touching.remove_any(remove_amount)
|
||||
|
||||
M.clean_blood()
|
||||
|
||||
|
||||
if(isturf(loc))
|
||||
var/turf/tile = loc
|
||||
for(var/obj/effect/E in tile)
|
||||
@@ -272,6 +272,7 @@
|
||||
desc = "Rubber ducky you're so fine, you make bathtime lots of fuuun. Rubber ducky I'm awfully fooooond of yooooouuuu~" //thanks doohl
|
||||
icon = 'icons/obj/watercloset.dmi'
|
||||
icon_state = "rubberducky"
|
||||
honk_sound = 'sound/voice/quack.ogg' //VOREStation edit
|
||||
|
||||
/obj/structure/sink
|
||||
name = "sink"
|
||||
|
||||
+30
-12
@@ -229,8 +229,17 @@ proc/admin_notice(var/message, var/rights)
|
||||
return
|
||||
PlayerNotesPage(1)
|
||||
|
||||
/datum/admins/proc/PlayerNotesPage(page)
|
||||
var/dat = "<B>Player notes</B><HR>"
|
||||
/datum/admins/proc/PlayerNotesFilter()
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
return
|
||||
var/filter = input(usr, "Filter string (case-insensitive regex)", "Player notes filter") as text|null
|
||||
PlayerNotesPage(1, filter)
|
||||
|
||||
/datum/admins/proc/PlayerNotesPage(page, filter)
|
||||
var/dat = "<B>Player notes</B> - <a href='?src=\ref[src];notes=filter'>Apply Filter</a><HR>"
|
||||
var/savefile/S=new("data/player_notes.sav")
|
||||
var/list/note_keys
|
||||
S >> note_keys
|
||||
@@ -240,29 +249,38 @@ proc/admin_notice(var/message, var/rights)
|
||||
dat += "<table>"
|
||||
note_keys = sortList(note_keys)
|
||||
|
||||
if(filter)
|
||||
var/list/results = list()
|
||||
var/regex/needle = regex(filter, "i")
|
||||
for(var/haystack in note_keys)
|
||||
if(needle.Find(haystack))
|
||||
results += haystack
|
||||
note_keys = results
|
||||
|
||||
// Display the notes on the current page
|
||||
var/number_pages = note_keys.len / PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
// Emulate CEILING(why does BYOND not have ceil, 1)
|
||||
if(number_pages != round(number_pages))
|
||||
number_pages = round(number_pages) + 1
|
||||
var/page_index = page - 1
|
||||
|
||||
if(page_index < 0 || page_index >= number_pages)
|
||||
return
|
||||
dat += "<tr><td>No keys found.</td></tr>"
|
||||
else
|
||||
var/lower_bound = page_index * PLAYER_NOTES_ENTRIES_PER_PAGE + 1
|
||||
var/upper_bound = (page_index + 1) * PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
upper_bound = min(upper_bound, note_keys.len)
|
||||
for(var/index = lower_bound, index <= upper_bound, index++)
|
||||
var/t = note_keys[index]
|
||||
dat += "<tr><td><a href='?src=\ref[src];notes=show;ckey=[t]'>[t]</a></td></tr>"
|
||||
|
||||
var/lower_bound = page_index * PLAYER_NOTES_ENTRIES_PER_PAGE + 1
|
||||
var/upper_bound = (page_index + 1) * PLAYER_NOTES_ENTRIES_PER_PAGE
|
||||
upper_bound = min(upper_bound, note_keys.len)
|
||||
for(var/index = lower_bound, index <= upper_bound, index++)
|
||||
var/t = note_keys[index]
|
||||
dat += "<tr><td><a href='?src=\ref[src];notes=show;ckey=[t]'>[t]</a></td></tr>"
|
||||
|
||||
dat += "</table><br>"
|
||||
dat += "</table><hr>"
|
||||
|
||||
// Display a footer to select different pages
|
||||
for(var/index = 1, index <= number_pages, index++)
|
||||
if(index == page)
|
||||
dat += "<b>"
|
||||
dat += "<a href='?src=\ref[src];notes=list;index=[index]'>[index]</a> "
|
||||
dat += "<a href='?src=\ref[src];notes=list;index=[index];filter=[filter ? url_encode(filter) : 0]'>[index]</a> "
|
||||
if(index == page)
|
||||
dat += "</b>"
|
||||
|
||||
|
||||
@@ -8,5 +8,7 @@
|
||||
traitors.spawn_uplink(H)
|
||||
H.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT
|
||||
H.mind.accept_tcrystals = 1
|
||||
var/msg = "[key_name(usr)] has given [H.ckey] an uplink."
|
||||
message_admins(msg)
|
||||
else
|
||||
to_chat(usr, "You do not have access to this command.")
|
||||
@@ -1971,7 +1971,12 @@
|
||||
if("show")
|
||||
show_player_info(ckey)
|
||||
if("list")
|
||||
PlayerNotesPage(text2num(href_list["index"]))
|
||||
var/filter
|
||||
if(href_list["filter"] && href_list["filter"] != "0")
|
||||
filter = url_decode(href_list["filter"])
|
||||
PlayerNotesPage(text2num(href_list["index"]), filter)
|
||||
if("filter")
|
||||
PlayerNotesFilter()
|
||||
return
|
||||
|
||||
mob/living/proc/can_centcom_reply()
|
||||
|
||||
@@ -118,19 +118,19 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution
|
||||
/decl/chemical_reaction/instant/blob_reconstitution
|
||||
name = "Hostile Blob Revival"
|
||||
id = "blob_revival"
|
||||
result = null
|
||||
required_reagents = list("phoron" = 60)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/can_happen(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/can_happen(var/datum/reagents/holder)
|
||||
if(holder.my_atom && istype(holder.my_atom, /obj/item/weapon/blobcore_chunk))
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/on_reaction(var/datum/reagents/holder)
|
||||
var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom
|
||||
if(chunk.can_genesis && chunk.regen())
|
||||
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
|
||||
@@ -138,14 +138,14 @@
|
||||
else
|
||||
chunk.visible_message("<span class='warning'>[chunk] shifts strangely, but falls still.</span>")
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/domination
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/domination
|
||||
name = "Allied Blob Revival"
|
||||
id = "blob_friend"
|
||||
result = null
|
||||
required_reagents = list("hydrophoron" = 40, "peridaxon" = 20, "mutagen" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder)
|
||||
var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom
|
||||
if(chunk.can_genesis && chunk.regen("neutral"))
|
||||
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
|
||||
|
||||
@@ -5,63 +5,124 @@
|
||||
|
||||
/datum/category_item/catalogue/fauna/akula
|
||||
name = "Sapients - Akula"
|
||||
desc = ""
|
||||
desc = "A pelagic species hailing from the Barkalis System originally\
|
||||
the Akula have been incidentally uplifted by free Kosaky \
|
||||
sharing much of their more modern culture with interstellar\
|
||||
Humanity. Many of them have spread among the stars, either\
|
||||
in the nomad fleets or joining colonies as capable hard labour."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/sergal
|
||||
name = "Sapients - Sergal"
|
||||
desc = ""
|
||||
desc = "The dominant species in the Vilous System, the Sergal are a\
|
||||
strange mammalian clade which shares similarities with \
|
||||
masurpials, pelagic creatures and wolves. Collectivist and\
|
||||
organising themselves in tribes and city states, they have\
|
||||
eclipsed the private colony venture trying to hold them \
|
||||
economically beholden and now have joined the sapient \
|
||||
diaspora on more equal terms."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/nevrean
|
||||
name = "Sapients - Nevrean"
|
||||
desc = ""
|
||||
desc = "A co-sapient species from Vilous, the Nevrean have found their\
|
||||
ecological niche as nomadic traders and craftsmen, \
|
||||
developing a rich oral tradition, that is being slowly \
|
||||
codified by the Sergals in an efforts to culturally export \
|
||||
it through the stars. The modern Nevrean co-inhabits most \
|
||||
places the Sergals do as comrades and historical allies."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/rapala
|
||||
name = "Sapients - Rapala"
|
||||
desc = ""
|
||||
desc = "The Rapala, formally “Rapala-Unathi” are a vassal species of the Unathi \
|
||||
in form of winged Humanoids. While they share a similar outwards appearance with humans, \
|
||||
they have a much more complex system of sexual genetics, as well superior 3D awareness. \
|
||||
The Rapala act as emissaries, diplomats and spies for their overlords, although it is an open \
|
||||
secret that they work for more autonomy and self-governance."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/xenochimera
|
||||
name = "Sapients - Xenochimera"
|
||||
desc = ""
|
||||
desc = "ERROR : DNA corruption detected. The likely outcome of this is this specimen being \
|
||||
a Xenochimera. Xenochimeras are the end stage of “Roanoke Syndrome”, a microbial infection \
|
||||
that infiltrates the immune system of a host species by mimicking cells. Upon expiration of \
|
||||
the host (preventable by medical attention), the cells cannibalize and take over the body, \
|
||||
creating a xenochimera. If the body has been capable of sapient thought, the resultant morph \
|
||||
is also capable of thought. \
|
||||
<br> <br>\
|
||||
Contrary to popular belief, Roanoke Syndrome colonies do not seek out sapient life. Any exposure \
|
||||
is incidental and not part of a plot – xenochimera without sapient thought are simply wild animals or disease vectors."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/vulpkanin
|
||||
name = "Sapients - Vulpkanin"
|
||||
desc = ""
|
||||
desc = "The Vulpkanin are the remnants of an ancient precursor which resided in the Coreward Periphery \
|
||||
3000 to 4000 years ago, residing on a planet called “Altam”. Vulpkanin diverged from the precursors due \
|
||||
to heavy isolation after the fall, presumably due to being a freshly found colony. A lack of material support \
|
||||
regressed their technology to pre-industrial standards until being found again by Humanity. At this point \
|
||||
they have formed an early spacefaring society and accession into the Diaspora went over relatively smoothly. \
|
||||
Vulpkanin are the closest successor to the precursors, genetically, although genelocked devices still do not \
|
||||
recognize them due to genetic drift."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/alraune
|
||||
name = "Sapients - Alraune"
|
||||
desc = ""
|
||||
desc = "Alraune are enigmatic, strange creatures from the Elysian Colonies. While their main culture is still \
|
||||
in the early neolithic, a large diaspora has formed from previous abductions and trade with these creatures, who \
|
||||
seem to mimic many cultivars throughout space through yet an unknown mechanism. Alraune are pleasant, but \
|
||||
predatory who autocannibalize their own products as a form of nutriment transfer and storage."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/vasilissan
|
||||
name = "Sapients - Vasilissan"
|
||||
desc = ""
|
||||
desc = "Vasilissans are an arachnid species uplifted by NT due to their propensity for architectural feats for \
|
||||
surface-to-orbit buildings with relatively primitive materials. Exploited for a while, they have managed to \
|
||||
connect to the greater commerce of the Diaspora, making them less dependent of our favourite TSCs, sadly. \
|
||||
Vasilissans are happily adopted into Coreward Periphery colonies, valued for their infrastructural acumen \
|
||||
and their craftsmanship with their natural silk."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/zorren
|
||||
name = "Sapients - Zorren"
|
||||
desc = ""
|
||||
desc = "The Zorren are the remnants of an ancient precursor which resided in the Coreward Periphery 3000 to 4000 \
|
||||
years ago, residing on a planet called “Menhir”, which we call Virgo 4. Zorren organise themselves through various \
|
||||
feudal-styled kingdoms and monarchies, of which the most prominent is the Kingdom of An-Tahk-Et. They are obsessed \
|
||||
over their ancient heritage and the power of the noble houses comes through the control and excavation of old technology \
|
||||
of their precursors, leading to a massive divide between commoners, who live as serfs and the nobility, who live in \
|
||||
comparable conditions as wealthy members of the Diaspora."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/fauna/shadekin
|
||||
name = "Sapients - Shadekin"
|
||||
desc = ""
|
||||
desc = "ERROR : No DNA found. ERROR : Ambient energy signature detected. Likely origin from attempt of scanning \
|
||||
Specimen NT-495. \
|
||||
<br> <br>\
|
||||
NT-495, also colloquial known as “Shadekin”, “Deep People”, “Mar Beast”, “Shadow creature” are an enigmatic species \
|
||||
capable of localized bluespace events (although the credibility of them actually manipulating bluespace effects \
|
||||
still is in question), allowing them to “shift” through phases of existence without assistance of machines. \
|
||||
Observation of NT-495 is notoriously difficult, as they do not exhibit these traits when in direct view unless \
|
||||
they seem to feel threatened. \
|
||||
<br> <br>\
|
||||
Their definite sapience has been proven as several NT-495 sightings supports them to be capable of galactic common, \
|
||||
especially under the variant that does not seem to possess the innate ability to phase – in fact, NT has recently \
|
||||
started to hire those for closer observation."
|
||||
value = CATALOGUER_REWARD_EASY
|
||||
|
||||
/datum/category_item/catalogue/fauna/custom_species
|
||||
name = "Sapients - Other"
|
||||
desc = "Remote frontiers require people of all sorts of life...\
|
||||
Sometimes species one would never see anywhere close to core worlds can be met here."
|
||||
desc = "ERROR : DNA scan inconclusive. Please interview subject to catalogue them manually. \
|
||||
We apologise for the inconvenience. \
|
||||
<br> <br>\
|
||||
Likely reasons for failure : Genetic Engineering, Hybridization, minor species of Orion Spur Diaspora."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/technology/resleeving
|
||||
name = "Resleeving"
|
||||
desc = ""
|
||||
desc = "The premier technology of the early 2280s, Resleeving is a direct upgrade to the antiquated flash \
|
||||
cloning by creating near perfect copies of a body within the database, capable of uploading a consciousness \
|
||||
in the dormant brain via direct electro-uploading. However, this technology is not perfect and small, but \
|
||||
non-zero error margins exist. Handle with care! Or don't. Stress testing this stuff makes a lucrative market."
|
||||
value = CATALOGUER_REWARD_TRIVIAL
|
||||
|
||||
/datum/category_item/catalogue/information/organization/khi
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
|
||||
/obj/item/device/cataloguer/compact
|
||||
name = "compact cataloguer"
|
||||
icon = 'icons/vore/custom_items_vr.dmi'
|
||||
icon_state = "tricorder"
|
||||
desc = "A compact hand-held device, used for compiling information about an object by scanning it. \
|
||||
Alt+click to highlight scannable objects around you."
|
||||
icon = 'icons/obj/device_vr.dmi'
|
||||
icon_state = "compact"
|
||||
action_button_name = "Toggle Cataloguer"
|
||||
var/deployed = TRUE
|
||||
scan_range = 1
|
||||
@@ -30,7 +32,7 @@
|
||||
if(deployed)
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
icon_state = "[initial(icon_state)]"
|
||||
to_chat(usr, span("notice", "You flip open \the [src]."))
|
||||
to_chat(usr, span("notice", "You flick open \the [src]."))
|
||||
else
|
||||
w_class = ITEMSIZE_SMALL
|
||||
icon_state = "[initial(icon_state)]_closed"
|
||||
@@ -54,6 +56,15 @@
|
||||
|
||||
/obj/item/device/cataloguer/compact/pathfinder
|
||||
name = "pathfinder's cataloguer"
|
||||
icon_state = "tricorder_med"
|
||||
desc = "A compact hand-held device, used for compiling information about an object by scanning it. \
|
||||
Alt+click to highlight scannable objects around you."
|
||||
icon = 'icons/obj/device_vr.dmi'
|
||||
icon_state = "pathcat"
|
||||
scan_range = 3
|
||||
toolspeed = 1
|
||||
|
||||
/obj/item/device/cataloguer
|
||||
desc = "A hand-held device, used for compiling information about an object by scanning it. \
|
||||
Alt+click to highlight scannable objects around you."
|
||||
icon = 'icons/obj/device_vr.dmi'
|
||||
icon_state = "cataloguer"
|
||||
@@ -15,8 +15,18 @@
|
||||
if(!islist(pref.alternate_languages)) pref.alternate_languages = list()
|
||||
if(pref.species)
|
||||
var/datum/species/S = GLOB.all_species[pref.species]
|
||||
if(S && pref.alternate_languages.len > S.num_alternate_languages)
|
||||
if(!istype(S))
|
||||
return
|
||||
|
||||
if(pref.alternate_languages.len > S.num_alternate_languages)
|
||||
pref.alternate_languages.len = S.num_alternate_languages // Truncate to allowed length
|
||||
|
||||
// Sanitize illegal languages
|
||||
for(var/language in pref.alternate_languages)
|
||||
var/datum/language/L = GLOB.all_languages[language]
|
||||
if(!istype(L) || (L.flags & RESTRICTED) || (!(language in S.secondary_langs) && !is_lang_whitelisted(pref.client, L)))
|
||||
pref.alternate_languages -= language
|
||||
|
||||
if(isnull(pref.language_prefixes) || !pref.language_prefixes.len)
|
||||
pref.language_prefixes = config.language_prefixes.Copy()
|
||||
for(var/prefix in pref.language_prefixes)
|
||||
|
||||
@@ -37,6 +37,43 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
var/g_wing3 = 30 // Wing tertiary color
|
||||
var/b_wing3 = 30 // Wing tertiary color
|
||||
|
||||
// Sanitize ear/wing/tail styles
|
||||
/datum/preferences/proc/sanitize_body_styles()
|
||||
|
||||
// Grandfather in anyone loading paths from a save.
|
||||
if(ispath(ear_style, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/instance = global.ear_styles_list[ear_style]
|
||||
if(istype(instance))
|
||||
ear_style = instance.name
|
||||
if(ispath(wing_style, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/instance = global.wing_styles_list[wing_style]
|
||||
if(istype(instance))
|
||||
wing_style = instance.name
|
||||
if(ispath(tail_style, /datum/sprite_accessory))
|
||||
var/datum/sprite_accessory/instance = global.tail_styles_list[tail_style]
|
||||
if(istype(instance))
|
||||
tail_style = instance.name
|
||||
|
||||
// Sanitize for non-existent keys.
|
||||
if(ear_style && !(ear_style in get_available_styles(global.ear_styles_list)))
|
||||
ear_style = null
|
||||
if(wing_style && !(wing_style in get_available_styles(global.wing_styles_list)))
|
||||
wing_style = null
|
||||
if(tail_style && !(tail_style in get_available_styles(global.tail_styles_list)))
|
||||
tail_style = null
|
||||
|
||||
/datum/preferences/proc/get_available_styles(var/style_list)
|
||||
. = list("Normal" = null)
|
||||
for(var/path in style_list)
|
||||
var/datum/sprite_accessory/instance = style_list[path]
|
||||
if(!istype(instance))
|
||||
continue
|
||||
if(instance.ckeys_allowed && (!client || !(client.ckey in instance.ckeys_allowed)))
|
||||
continue
|
||||
if(instance.species_allowed && (!species || !(species in instance.species_allowed)) && (!client || !check_rights(R_ADMIN | R_EVENT | R_FUN, 0, client)))
|
||||
continue
|
||||
.[instance.name] = instance
|
||||
|
||||
/datum/category_item/player_setup_item/general/body
|
||||
name = "Body"
|
||||
sort_order = 3
|
||||
@@ -228,21 +265,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
pref.r_wing3 = sanitize_integer(pref.r_wing3, 0, 255, initial(pref.r_wing3))
|
||||
pref.g_wing3 = sanitize_integer(pref.g_wing3, 0, 255, initial(pref.g_wing3))
|
||||
pref.b_wing3 = sanitize_integer(pref.b_wing3, 0, 255, initial(pref.b_wing3))
|
||||
if(pref.ear_style)
|
||||
pref.ear_style = sanitize_inlist(pref.ear_style, ear_styles_list, initial(pref.ear_style))
|
||||
var/datum/sprite_accessory/temp_ear_style = ear_styles_list[pref.ear_style]
|
||||
if(temp_ear_style.apply_restrictions && (!(pref.species in temp_ear_style.species_allowed)))
|
||||
pref.ear_style = initial(pref.ear_style)
|
||||
if(pref.tail_style)
|
||||
pref.tail_style = sanitize_inlist(pref.tail_style, tail_styles_list, initial(pref.tail_style))
|
||||
var/datum/sprite_accessory/temp_tail_style = tail_styles_list[pref.tail_style]
|
||||
if(temp_tail_style.apply_restrictions && (!(pref.species in temp_tail_style.species_allowed)))
|
||||
pref.tail_style = initial(pref.tail_style)
|
||||
if(pref.wing_style)
|
||||
pref.wing_style = sanitize_inlist(pref.wing_style, wing_styles_list, initial(pref.wing_style))
|
||||
var/datum/sprite_accessory/temp_wing_style = wing_styles_list[pref.wing_style]
|
||||
if(temp_wing_style.apply_restrictions && (!(pref.species in temp_wing_style.species_allowed)))
|
||||
pref.wing_style = initial(pref.wing_style)
|
||||
|
||||
pref.sanitize_body_styles()
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/general/body/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
@@ -274,37 +298,44 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
character.g_synth = pref.g_synth
|
||||
character.b_synth = pref.b_synth
|
||||
character.synth_markings = pref.synth_markings
|
||||
character.ear_style = ear_styles_list[pref.ear_style]
|
||||
character.r_ears = pref.r_ears
|
||||
character.b_ears = pref.b_ears
|
||||
character.g_ears = pref.g_ears
|
||||
character.r_ears2 = pref.r_ears2
|
||||
character.b_ears2 = pref.b_ears2
|
||||
character.g_ears2 = pref.g_ears2
|
||||
character.r_ears3 = pref.r_ears3
|
||||
character.b_ears3 = pref.b_ears3
|
||||
character.g_ears3 = pref.g_ears3
|
||||
character.tail_style = tail_styles_list[pref.tail_style]
|
||||
character.r_tail = pref.r_tail
|
||||
character.b_tail = pref.b_tail
|
||||
character.g_tail = pref.g_tail
|
||||
character.r_tail2 = pref.r_tail2
|
||||
character.b_tail2 = pref.b_tail2
|
||||
character.g_tail2 = pref.g_tail2
|
||||
character.r_tail3 = pref.r_tail3
|
||||
character.b_tail3 = pref.b_tail3
|
||||
character.g_tail3 = pref.g_tail3
|
||||
character.wing_style = wing_styles_list[pref.wing_style]
|
||||
character.r_wing = pref.r_wing
|
||||
character.b_wing = pref.b_wing
|
||||
character.g_wing = pref.g_wing
|
||||
character.r_wing2 = pref.r_wing2
|
||||
character.b_wing2 = pref.b_wing2
|
||||
character.g_wing2 = pref.g_wing2
|
||||
character.r_wing3 = pref.r_wing3
|
||||
character.b_wing3 = pref.b_wing3
|
||||
character.g_wing3 = pref.g_wing3
|
||||
character.set_gender( pref.biological_gender)
|
||||
|
||||
var/list/ear_styles = pref.get_available_styles(global.ear_styles_list)
|
||||
character.ear_style = ear_styles[pref.ear_style]
|
||||
character.r_ears = pref.r_ears
|
||||
character.b_ears = pref.b_ears
|
||||
character.g_ears = pref.g_ears
|
||||
character.r_ears2 = pref.r_ears2
|
||||
character.b_ears2 = pref.b_ears2
|
||||
character.g_ears2 = pref.g_ears2
|
||||
character.r_ears3 = pref.r_ears3
|
||||
character.b_ears3 = pref.b_ears3
|
||||
character.g_ears3 = pref.g_ears3
|
||||
|
||||
var/list/tail_styles = pref.get_available_styles(global.tail_styles_list)
|
||||
character.tail_style = tail_styles[pref.tail_style]
|
||||
character.r_tail = pref.r_tail
|
||||
character.b_tail = pref.b_tail
|
||||
character.g_tail = pref.g_tail
|
||||
character.r_tail2 = pref.r_tail2
|
||||
character.b_tail2 = pref.b_tail2
|
||||
character.g_tail2 = pref.g_tail2
|
||||
character.r_tail3 = pref.r_tail3
|
||||
character.b_tail3 = pref.b_tail3
|
||||
character.g_tail3 = pref.g_tail3
|
||||
|
||||
var/list/wing_styles = pref.get_available_styles(global.wing_styles_list)
|
||||
character.wing_style = wing_styles[pref.wing_style]
|
||||
character.r_wing = pref.r_wing
|
||||
character.b_wing = pref.b_wing
|
||||
character.g_wing = pref.g_wing
|
||||
character.r_wing2 = pref.r_wing2
|
||||
character.b_wing2 = pref.b_wing2
|
||||
character.g_wing2 = pref.g_wing2
|
||||
character.r_wing3 = pref.r_wing3
|
||||
character.b_wing3 = pref.b_wing3
|
||||
character.g_wing3 = pref.g_wing3
|
||||
|
||||
character.set_gender(pref.biological_gender)
|
||||
|
||||
// Destroy/cyborgize organs and limbs.
|
||||
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
|
||||
@@ -519,59 +550,47 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
|
||||
. += "<h2>Genetics Settings</h2>"
|
||||
|
||||
var/ear_display = "Normal"
|
||||
if(pref.ear_style && (pref.ear_style in ear_styles_list))
|
||||
var/datum/sprite_accessory/ears/instance = ear_styles_list[pref.ear_style]
|
||||
ear_display = instance.name
|
||||
|
||||
else if(pref.ear_style)
|
||||
ear_display = "REQUIRES UPDATE"
|
||||
var/list/ear_styles = pref.get_available_styles(global.ear_styles_list)
|
||||
var/datum/sprite_accessory/ears/ear = ear_styles[pref.ear_style]
|
||||
. += "<b>Ears</b><br>"
|
||||
. += " Style: <a href='?src=\ref[src];ear_style=1'>[ear_display]</a><br>"
|
||||
if(ear_styles_list[pref.ear_style])
|
||||
var/datum/sprite_accessory/ears/ear = ear_styles_list[pref.ear_style]
|
||||
if(istype(ear))
|
||||
. += " Style: <a href='?src=\ref[src];ear_style=1'>[ear.name]</a><br>"
|
||||
if(ear.do_colouration)
|
||||
. += "<a href='?src=\ref[src];ear_color=1'>Change Color</a> [color_square(pref.r_ears, pref.g_ears, pref.b_ears)]<br>"
|
||||
if(ear.extra_overlay)
|
||||
. += "<a href='?src=\ref[src];ear_color2=1'>Change Secondary Color</a> [color_square(pref.r_ears2, pref.g_ears2, pref.b_ears2)]<br>"
|
||||
if(ear.extra_overlay2)
|
||||
. += "<a href='?src=\ref[src];ear_color3=1'>Change Tertiary Color</a> [color_square(pref.r_ears3, pref.g_ears3, pref.b_ears3)]<br>"
|
||||
else
|
||||
. += " Style: <a href='?src=\ref[src];ear_style=1'>Select</a><br>"
|
||||
|
||||
var/tail_display = "Normal"
|
||||
if(pref.tail_style && (pref.tail_style in tail_styles_list))
|
||||
var/datum/sprite_accessory/tail/instance = tail_styles_list[pref.tail_style]
|
||||
tail_display = instance.name
|
||||
else if(pref.tail_style)
|
||||
tail_display = "REQUIRES UPDATE"
|
||||
var/list/tail_styles = pref.get_available_styles(global.tail_styles_list)
|
||||
var/datum/sprite_accessory/tail/tail = tail_styles[pref.tail_style]
|
||||
. += "<b>Tail</b><br>"
|
||||
. += " Style: <a href='?src=\ref[src];tail_style=1'>[tail_display]</a><br>"
|
||||
|
||||
if(tail_styles_list[pref.tail_style])
|
||||
var/datum/sprite_accessory/tail/T = tail_styles_list[pref.tail_style]
|
||||
if(T.do_colouration)
|
||||
if(istype(tail))
|
||||
. += " Style: <a href='?src=\ref[src];tail_style=1'>[tail.name]</a><br>"
|
||||
if(tail.do_colouration)
|
||||
. += "<a href='?src=\ref[src];tail_color=1'>Change Color</a> [color_square(pref.r_tail, pref.g_tail, pref.b_tail)]<br>"
|
||||
if(T.extra_overlay)
|
||||
if(tail.extra_overlay)
|
||||
. += "<a href='?src=\ref[src];tail_color2=1'>Change Secondary Color</a> [color_square(pref.r_tail2, pref.g_tail2, pref.b_tail2)]<br>"
|
||||
if(T.extra_overlay2)
|
||||
if(tail.extra_overlay2)
|
||||
. += "<a href='?src=\ref[src];tail_color3=1'>Change Tertiary Color</a> [color_square(pref.r_tail3, pref.g_tail3, pref.b_tail3)]<br>"
|
||||
else
|
||||
. += " Style: <a href='?src=\ref[src];tail_style=1'>Select</a><br>"
|
||||
|
||||
var/wing_display = "Normal"
|
||||
if(pref.wing_style && (pref.wing_style in wing_styles_list))
|
||||
var/datum/sprite_accessory/wing/instance = wing_styles_list[pref.wing_style]
|
||||
wing_display = instance.name
|
||||
else if(pref.wing_style)
|
||||
wing_display = "REQUIRES UPDATE"
|
||||
var/list/wing_styles = pref.get_available_styles(global.wing_styles_list)
|
||||
var/datum/sprite_accessory/wing/wings = wing_styles[pref.wing_style]
|
||||
. += "<b>Wing</b><br>"
|
||||
. += " Style: <a href='?src=\ref[src];wing_style=1'>[wing_display]</a><br>"
|
||||
|
||||
if(wing_styles_list[pref.wing_style])
|
||||
var/datum/sprite_accessory/wing/W = wing_styles_list[pref.wing_style]
|
||||
if(W.do_colouration)
|
||||
if(istype(wings))
|
||||
. += " Style: <a href='?src=\ref[src];wing_style=1'>[wings.name]</a><br>"
|
||||
if(wings.do_colouration)
|
||||
. += "<a href='?src=\ref[src];wing_color=1'>Change Color</a> [color_square(pref.r_wing, pref.g_wing, pref.b_wing)]<br>"
|
||||
if(W.extra_overlay)
|
||||
if(wings.extra_overlay)
|
||||
. += "<a href='?src=\ref[src];wing_color2=1'>Change Secondary Color</a> [color_square(pref.r_wing2, pref.g_wing2, pref.b_wing2)]<br>"
|
||||
if(W.extra_overlay2)
|
||||
if(wings.extra_overlay2)
|
||||
. += "<a href='?src=\ref[src];wing_color3=1'>Change Secondary Color</a> [color_square(pref.r_wing3, pref.g_wing3, pref.b_wing3)]<br>"
|
||||
else
|
||||
. += " Style: <a href='?src=\ref[src];wing_style=1'>Select</a><br>"
|
||||
|
||||
. += "<br><a href='?src=\ref[src];marking_style=1'>Body Markings +</a><br>"
|
||||
. += "<table>"
|
||||
@@ -669,7 +688,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
|
||||
reset_limbs() // Safety for species with incompatible manufacturers; easier than trying to do it case by case.
|
||||
pref.body_markings.Cut() // Basically same as above.
|
||||
|
||||
|
||||
pref.sanitize_body_styles()
|
||||
|
||||
var/min_age = get_min_age()
|
||||
var/max_age = get_max_age()
|
||||
pref.age = max(min(pref.age, max_age), min_age)
|
||||
@@ -1085,17 +1106,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["ear_style"])
|
||||
// Construct the list of names allowed for this user.
|
||||
var/list/pretty_ear_styles = list("Normal" = null)
|
||||
for(var/path in ear_styles_list)
|
||||
var/datum/sprite_accessory/ears/instance = ear_styles_list[path]
|
||||
if(((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed)) && ((!instance.apply_restrictions) || (pref.species in instance.species_allowed)) || check_rights(R_ADMIN | R_EVENT | R_FUN, 0, user)) //VOREStation Edit
|
||||
pretty_ear_styles[instance.name] = path
|
||||
|
||||
// Present choice to user
|
||||
var/new_ear_style = input(user, "Pick ears", "Character Preference", pref.ear_style) as null|anything in pretty_ear_styles
|
||||
var/new_ear_style = input(user, "Select an ear style for this character:", "Character Preference", pref.ear_style) as null|anything in pref.get_available_styles(global.ear_styles_list)
|
||||
if(new_ear_style)
|
||||
pref.ear_style = pretty_ear_styles[new_ear_style]
|
||||
pref.ear_style = new_ear_style
|
||||
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
@@ -1127,18 +1140,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["tail_style"])
|
||||
// Construct the list of names allowed for this user.
|
||||
var/list/pretty_tail_styles = list("Normal" = null)
|
||||
for(var/path in tail_styles_list)
|
||||
var/datum/sprite_accessory/tail/instance = tail_styles_list[path]
|
||||
if(((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed)) && ((!instance.apply_restrictions) || (pref.species in instance.species_allowed)) || check_rights(R_ADMIN | R_EVENT | R_FUN, 0, user)) //VOREStation Edit
|
||||
pretty_tail_styles[instance.name] = path
|
||||
|
||||
// Present choice to user
|
||||
var/new_tail_style = input(user, "Pick tails", "Character Preference", pref.tail_style) as null|anything in pretty_tail_styles
|
||||
var/new_tail_style = input(user, "Select a tail style for this character:", "Character Preference", pref.tail_style) as null|anything in pref.get_available_styles(global.tail_styles_list)
|
||||
if(new_tail_style)
|
||||
pref.tail_style = pretty_tail_styles[new_tail_style]
|
||||
|
||||
pref.tail_style = new_tail_style
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["tail_color"])
|
||||
@@ -1169,17 +1173,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
else if(href_list["wing_style"])
|
||||
// Construct the list of names allowed for this user.
|
||||
var/list/pretty_wing_styles = list("Normal" = null)
|
||||
for(var/path in wing_styles_list)
|
||||
var/datum/sprite_accessory/wing/instance = wing_styles_list[path]
|
||||
if(((!instance.ckeys_allowed) || (usr.ckey in instance.ckeys_allowed)) && ((!instance.apply_restrictions) || (pref.species in instance.species_allowed)) || check_rights(R_ADMIN | R_EVENT | R_FUN, 0, user)) //VOREStation Edit
|
||||
pretty_wing_styles[instance.name] = path
|
||||
|
||||
// Present choice to user
|
||||
var/new_wing_style = input(user, "Pick wings", "Character Preference", pref.wing_style) as null|anything in pretty_wing_styles
|
||||
var/new_wing_style = input(user, "Select a wing style for this character:", "Character Preference", pref.wing_style) as null|anything in pref.get_available_styles(global.wing_styles_list)
|
||||
if(new_wing_style)
|
||||
pref.wing_style = pretty_wing_styles[new_wing_style]
|
||||
pref.wing_style = new_wing_style
|
||||
|
||||
return TOPIC_REFRESH_UPDATE_PREVIEW
|
||||
|
||||
|
||||
@@ -62,12 +62,15 @@ var/list/gear_datums = list()
|
||||
|
||||
/datum/category_item/player_setup_item/loadout/proc/valid_gear_choices(var/max_cost)
|
||||
. = list()
|
||||
var/mob/preference_mob = preference_mob()
|
||||
var/mob/preference_mob = preference_mob() //VOREStation Add
|
||||
for(var/gear_name in gear_datums)
|
||||
var/datum/gear/G = gear_datums[gear_name]
|
||||
|
||||
if(G.whitelisted && !is_alien_whitelisted(preference_mob, GLOB.all_species[G.whitelisted]))
|
||||
continue
|
||||
if(G.whitelisted && config.loadout_whitelist != LOADOUT_WHITELIST_OFF)
|
||||
if(config.loadout_whitelist == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species)
|
||||
continue
|
||||
if(config.loadout_whitelist == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(preference_mob(), GLOB.all_species[G.whitelisted]))
|
||||
continue
|
||||
if(max_cost && G.cost > max_cost)
|
||||
continue
|
||||
//VOREStation Edit Start
|
||||
|
||||
@@ -60,6 +60,12 @@
|
||||
ckeywhitelist = list("aegisoa")
|
||||
character_name = list("Xander Bevin")
|
||||
|
||||
/datum/gear/fluff/charlotte_cigarettes
|
||||
path = /obj/item/weapon/storage/fancy/fluff/charlotte
|
||||
display_name = "Charlotte's cigarette case"
|
||||
ckeywhitelist = list("alfalah")
|
||||
character_name = list("Charlotte Graves")
|
||||
|
||||
/datum/gear/fluff/lynn_penlight
|
||||
path = /obj/item/device/flashlight/pen/fluff/lynn
|
||||
display_name = "Lynn's Penlight"
|
||||
@@ -89,11 +95,23 @@
|
||||
character_name = list("Aronai Sieyes")
|
||||
|
||||
/datum/gear/fluff/astra_ritualknife
|
||||
path = /obj/item/weapon/material/knife/ritual/fluff/astra
|
||||
display_name = "Polished Ritual Knife"
|
||||
description = "A well kept strange ritual knife, There is a small tag with the name 'Astra Ether' on it. They are probably looking for this."
|
||||
ckeywhitelist = list("astraether")
|
||||
character_name = list("Astra Ether")
|
||||
path = /obj/item/weapon/material/knife/ritual/fluff/astra
|
||||
display_name = "Polished Ritual Knife"
|
||||
description = "A well kept strange ritual knife, There is a small tag with the name 'Astra Ether' on it. They are probably looking for this."
|
||||
ckeywhitelist = list("astraether")
|
||||
character_name = list("Astra Ether")
|
||||
|
||||
/datum/gear/fluff/astra_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Astra's Conduct Medal"
|
||||
ckeywhitelist = list("astraether")
|
||||
character_name = list("Astra Ether")
|
||||
|
||||
/datum/gear/fluff/astra_medal_2
|
||||
path = /obj/item/clothing/accessory/medal/silver/unity
|
||||
display_name = "Astra's Unity Medal"
|
||||
ckeywhitelist = list("astraether")
|
||||
character_name = list("Astra Ether")
|
||||
|
||||
/datum/gear/fluff/collar/azura
|
||||
path = /obj/item/clothing/accessory/collar/azura
|
||||
@@ -149,6 +167,12 @@
|
||||
ckeywhitelist = list("blakeryan")
|
||||
character_name = list("Nolan Conaway")
|
||||
|
||||
/datum/gear/fluff/amber_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Amber's Conduct Medal"
|
||||
ckeywhitelist = list("bluewolf128")
|
||||
character_name = list("Amber Wresspenn")
|
||||
|
||||
/datum/gear/fluff/charles_hat
|
||||
path = /obj/item/clothing/head/that/fluff/gettler
|
||||
display_name = "Charles' Top-Hat"
|
||||
@@ -189,6 +213,12 @@
|
||||
ckeywhitelist = list("bacon12366")
|
||||
character_name = list("Elly Brown")
|
||||
|
||||
/datum/gear/fluff/alibig_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Ali Big's Conduct Medal"
|
||||
ckeywhitelist = list("bigbababooey")
|
||||
character_name = list("Ali Big")
|
||||
|
||||
// C CKEYS
|
||||
/datum/gear/fluff/cappy_watch
|
||||
path = /obj/item/clothing/accessory/watch
|
||||
@@ -260,6 +290,18 @@
|
||||
ckeywhitelist = list("dickfreedomjohnson")
|
||||
character_name = list("Elliot Richards")
|
||||
|
||||
/datum/gear/fluff/donald_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Donald's Conduct Medal"
|
||||
ckeywhitelist = list("drainquake")
|
||||
character_name = list("Donald Weinbeck")
|
||||
|
||||
/datum/gear/fluff/donald_medal_2
|
||||
path = /obj/item/clothing/accessory/medal/bronze_heart
|
||||
display_name = "Donald's Heart Medal"
|
||||
ckeywhitelist = list("drainquake")
|
||||
character_name = list("Donald Weinbeck")
|
||||
|
||||
/datum/gear/fluff/drake_box
|
||||
path = /obj/item/weapon/storage/box/fluff/drake
|
||||
display_name = "Drake's Box"
|
||||
@@ -570,6 +612,12 @@
|
||||
character_name = list("Ashley Kifer")
|
||||
|
||||
// L CKEYS
|
||||
/datum/gear/fluff/kenzie_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Kenzie's Conduct Medal"
|
||||
ckeywhitelist = list("lm40")
|
||||
character_name = list("Kenzie Houser")
|
||||
|
||||
/datum/gear/fluff/kenzie_hypospray
|
||||
path = /obj/item/weapon/reagent_containers/hypospray/vial/kenzie
|
||||
display_name = "Kenzie's Hypospray"
|
||||
@@ -584,6 +632,12 @@
|
||||
ckeywhitelist = list("luminescentring")
|
||||
character_name = list("Briana Moore")
|
||||
|
||||
/datum/gear/fluff/entchtut_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Entchtut's Conduct Medal"
|
||||
ckeywhitelist = list("littlebigkid2000")
|
||||
character_name = list("Entchtut Cenein")
|
||||
|
||||
// M CKEYS
|
||||
/datum/gear/fluff/phi_box
|
||||
path = /obj/item/weapon/storage/box/fluff/phi
|
||||
@@ -736,7 +790,7 @@
|
||||
character_name = list("Scylla Casmus")
|
||||
|
||||
/datum/gear/fluff/kiyoshi_cloak
|
||||
path = /obj/item/clothing/accessory/poncho/fluff/cloakglowing
|
||||
path = /obj/item/clothing/accessory/poncho/roles/cloak/fluff/cloakglowing
|
||||
display_name = "glowing cloak"
|
||||
ckeywhitelist = list("pastelprincedan")
|
||||
character_name = list("Kiyoshi Maki", "Masumi Maki")
|
||||
@@ -758,6 +812,18 @@
|
||||
character_name = list("Clara Mali")
|
||||
cost = 1
|
||||
|
||||
/datum/gear/fluff/luna_sci_medal
|
||||
path = /obj/item/clothing/accessory/medal/nobel_science
|
||||
display_name = "LUNA's Nobel Science Award"
|
||||
ckeywhitelist = list("residentcody")
|
||||
character_name = list("LUNA")
|
||||
|
||||
/datum/gear/fluff/luna_conduct_medal
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "LUNA's Distinguished Conduct Medal"
|
||||
ckeywhitelist = list("residentcody")
|
||||
character_name = list("LUNA")
|
||||
|
||||
/datum/gear/fluff/nikki_dorky_outfit
|
||||
path = /obj/item/weapon/storage/box/fluff
|
||||
display_name = "Nikki's Witchy Outfit"
|
||||
@@ -777,6 +843,18 @@
|
||||
ckeywhitelist = list("sageofaether12")
|
||||
character_name = list("Brynhild Vandradottir")
|
||||
|
||||
/datum/gear/fluff/brynhild_medal_3
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Brynhild's Conduct Medal"
|
||||
ckeywhitelist = list("sageofaether12")
|
||||
character_name = list("Brynhild Vandradottir")
|
||||
|
||||
/datum/gear/fluff/brynhild_medal_4
|
||||
path = /obj/item/clothing/accessory/medal/bronze_heart
|
||||
display_name = "Brynhild's Heart Medal"
|
||||
ckeywhitelist = list("sageofaether12")
|
||||
character_name = list("Brynhild Vandradottir")
|
||||
|
||||
/datum/gear/fluff/kateryna_voidsuit
|
||||
path = /obj/item/clothing/suit/space/void/engineering/kate
|
||||
display_name = "Kateryna's Voidsuit"
|
||||
@@ -912,6 +990,12 @@
|
||||
ckeywhitelist = list("tabiranth")
|
||||
character_name = list("Ascian")
|
||||
|
||||
/datum/gear/fluff/ascian_medal_3
|
||||
path = /obj/item/clothing/accessory/medal/conduct
|
||||
display_name = "Ascian's Conduct Medal"
|
||||
ckeywhitelist = list("tabiranth")
|
||||
character_name = list("Ascian")
|
||||
|
||||
/datum/gear/fluff/ascian_spiritspawner
|
||||
path = /obj/item/weapon/grenade/spawnergrenade/spirit
|
||||
display_name = "The Best Kitten"
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
description = "Choose from a number of toys."
|
||||
path = /obj/item/toy/
|
||||
|
||||
/* VOREStation removal
|
||||
/datum/gear/toy/New()
|
||||
..()
|
||||
var/toytype = list()
|
||||
@@ -86,7 +87,7 @@
|
||||
toytype["Magic 8 Ball"] = /obj/item/toy/eight_ball
|
||||
toytype["Magic Conch shell"] = /obj/item/toy/eight_ball/conch
|
||||
gear_tweaks += new/datum/gear_tweak/path(toytype)
|
||||
|
||||
*/
|
||||
|
||||
/datum/gear/flask
|
||||
display_name = "flask"
|
||||
|
||||
@@ -9,4 +9,83 @@
|
||||
for(var/ball in typesof(/obj/item/toy/tennis/))
|
||||
var/obj/item/toy/tennis/ball_type = ball
|
||||
balls[initial(ball_type.name)] = ball_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(balls))
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(balls))
|
||||
|
||||
/datum/gear/character/
|
||||
display_name = "miniature selection"
|
||||
description = "Choose from a number of miniatures. From Battlemace 40 million to Grottos and Ghouls."
|
||||
path = /obj/item/toy/character/alien
|
||||
|
||||
/datum/gear/character/New()
|
||||
..()
|
||||
var/list/characters = list()
|
||||
for(var/character in typesof(/obj/item/toy/character/) - /obj/item/toy/character)
|
||||
var/obj/item/toy/character/character_type = character
|
||||
characters[initial(character_type.name)] = character_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(characters))
|
||||
|
||||
/datum/gear/mechtoy/
|
||||
display_name = "mecha toy selection"
|
||||
description = "Choose from a number of mech toys."
|
||||
path = /obj/item/toy/mecha/ripley
|
||||
|
||||
/datum/gear/mechtoy/New()
|
||||
..()
|
||||
var/list/mechs = list()
|
||||
for(var/mech in typesof(/obj/item/toy/mecha/) - /obj/item/toy/mecha/)
|
||||
var/obj/item/toy/mecha/mech_type = mech
|
||||
mechs[initial(mech_type.name)] = mech_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(mechs))
|
||||
|
||||
/datum/gear/toy/New()
|
||||
..()
|
||||
var/toytype = list()
|
||||
toytype["Blink toy"] = /obj/item/toy/blink
|
||||
toytype["Foam dart crossbow"] = /obj/item/toy/blink
|
||||
toytype["Toy sword"] = /obj/item/toy/sword
|
||||
toytype["Toy katana"] = /obj/item/toy/katana
|
||||
toytype["Snap pops"] = /obj/item/weapon/storage/box/snappops
|
||||
toytype["Plastic flowers"] = /obj/item/toy/bouquet/fake
|
||||
toytype["Stick horse"] = /obj/item/toy/stickhorse
|
||||
toytype["Toy X-mas tree"] = /obj/item/toy/xmastree
|
||||
toytype["Fake handcuff kit"] = /obj/item/weapon/storage/box/handcuffs/fake
|
||||
toytype["Gravitational singularity"] = /obj/item/toy/spinningtoy
|
||||
toytype["Water flower"] = /obj/item/weapon/reagent_containers/spray/waterflower
|
||||
toytype["Bosun's whistle"] = /obj/item/toy/bosunwhistle
|
||||
toytype["Magic 8 Ball"] = /obj/item/toy/eight_ball
|
||||
toytype["Magic Conch shell"] = /obj/item/toy/eight_ball/conch
|
||||
toytype["Pet rock"] = /obj/item/toy/rock
|
||||
toytype["Toy flash"] = /obj/item/toy/flash
|
||||
toytype["Big Red Button"] = /obj/item/toy/redbutton
|
||||
toytype["Garden gnome"] = /obj/item/toy/gnome
|
||||
toytype["Toy AI"] = /obj/item/toy/AI
|
||||
toytype["Hand buzzer"] = /obj/item/clothing/gloves/ring/buzzer/toy
|
||||
toytype["Toy nuke"] = /obj/item/toy/nuke
|
||||
toytype["Toy gibber"] = /obj/item/toy/minigibber
|
||||
toytype["Toy xeno"] = /obj/item/toy/toy_xeno
|
||||
gear_tweaks += new/datum/gear_tweak/path(toytype)
|
||||
|
||||
/datum/gear/chewtoy
|
||||
display_name = "animal toy selection"
|
||||
path = /obj/item/toy/chewtoy
|
||||
|
||||
/datum/gear/chewtoy/New()
|
||||
..()
|
||||
var/toytype = list()
|
||||
toytype["Bone"] = /obj/item/toy/chewtoy
|
||||
toytype["Classic"] = /obj/item/toy/chewtoy/tall
|
||||
toytype["Mouse"] = /obj/item/toy/cat_toy
|
||||
toytype["Feather rod"] = /obj/item/toy/cat_toy/rod
|
||||
gear_tweaks += new/datum/gear_tweak/path(toytype)
|
||||
|
||||
/datum/gear/chewtoy_poly
|
||||
display_name = "animal toy selection, colorable"
|
||||
path = /obj/item/toy/chewtoy/poly
|
||||
|
||||
/datum/gear/chewtoy_poly/New()
|
||||
..()
|
||||
var/toytype = list()
|
||||
toytype["Bone"] = /obj/item/toy/chewtoy/poly
|
||||
toytype["Classic"] = /obj/item/toy/chewtoy/tall/poly
|
||||
gear_tweaks += new/datum/gear_tweak/path(toytype)
|
||||
gear_tweaks += gear_tweak_free_color_choice
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
PI.load_character(S)
|
||||
|
||||
|
||||
/datum/category_group/player_setup_category/proc/save_character(var/savefile/S)
|
||||
// Sanitize all data, then save it
|
||||
for(var/datum/category_item/player_setup_item/PI in items)
|
||||
|
||||
@@ -169,8 +169,8 @@ datum/preferences
|
||||
if(!IsGuestKey(C.key))
|
||||
load_path(C.ckey)
|
||||
if(load_preferences())
|
||||
if(load_character())
|
||||
return
|
||||
load_character()
|
||||
|
||||
|
||||
/datum/preferences/Destroy()
|
||||
. = ..()
|
||||
|
||||
@@ -82,10 +82,8 @@
|
||||
player_setup.load_character(S)
|
||||
S.cd = "/character[default_slot]"
|
||||
player_setup.save_character(S)
|
||||
sanitize_preferences()
|
||||
|
||||
player_setup.load_character(S)
|
||||
clear_character_previews() // Recalculate them on next show
|
||||
clear_character_previews() // VOREStation Edit
|
||||
return 1
|
||||
|
||||
/datum/preferences/proc/save_character()
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//Overmap pilots. Same gear, without the dumb interface.
|
||||
|
||||
/obj/item/clothing/head/ompilot
|
||||
name = "pilot helmet"
|
||||
desc = "Standard pilot gear. Protects the head from impacts."
|
||||
icon_state = "pilot_helmet1"
|
||||
item_icons = list(slot_head_str = 'icons/mob/pilot_helmet.dmi')
|
||||
sprite_sheets = list(
|
||||
SPECIES_TESHARI = 'icons/mob/species/teshari/pilot_helmet.dmi'
|
||||
)
|
||||
flags = THICKMATERIAL
|
||||
armor = list(melee = 20, bullet = 10, laser = 10, energy = 5, bomb = 10, bio = 0, rad = 0)
|
||||
flags_inv = HIDEEARS
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = HELMET_MIN_COLD_PROTECTION_TEMPERATURE
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
|
||||
/obj/item/clothing/head/ompilot/alt
|
||||
name = "pilot helmet"
|
||||
desc = "Standard pilot gear. Protects the head from impacts. This one has a retractable visor"
|
||||
icon_state = "pilot_helmet2"
|
||||
action_button_name = "Toggle Visor"
|
||||
|
||||
/obj/item/clothing/head/ompilot/alt/attack_self(mob/user as mob)
|
||||
if(src.icon_state == initial(icon_state))
|
||||
src.icon_state = "[icon_state]up"
|
||||
to_chat(user, "You raise the visor on the pilot helmet.")
|
||||
else
|
||||
src.icon_state = initial(icon_state)
|
||||
to_chat(user, "You lower the visor on the pilot helmet.")
|
||||
update_clothing_icon() //so our mob-overlays update
|
||||
@@ -78,7 +78,7 @@
|
||||
* Radiation protection
|
||||
*/
|
||||
/obj/item/clothing/head/radiation
|
||||
name = "Radiation Hood"
|
||||
name = "Radiation hood"
|
||||
icon_state = "rad"
|
||||
desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation"
|
||||
flags_inv = BLOCKHAIR
|
||||
@@ -98,4 +98,20 @@
|
||||
slowdown = 1.5
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100)
|
||||
flags_inv = HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER
|
||||
item_flags = THICKMATERIAL
|
||||
item_flags = THICKMATERIAL
|
||||
|
||||
/obj/item/clothing/suit/radiation/teshari
|
||||
name = "Small radiation suit"
|
||||
desc = "A specialist suit that protects against radiation, designed specifically for use by Teshari. Made to order by Aether."
|
||||
icon = 'icons/obj/clothing/species/teshari/suits.dmi'
|
||||
icon_override = 'icons/mob/species/teshari/suit.dmi'
|
||||
icon_state = "rad_fitted"
|
||||
species_restricted = list(SPECIES_TESHARI)
|
||||
|
||||
/obj/item/clothing/head/radiation/teshari
|
||||
name = "Small radiation hood"
|
||||
desc = "A specialist hood with radiation protective properties, designed specifically for use by Teshari. Made to order by Aether."
|
||||
icon = 'icons/obj/clothing/species/teshari/hats.dmi'
|
||||
icon_override = 'icons/mob/species/teshari/head.dmi'
|
||||
icon_state = "rad_fitted"
|
||||
species_restricted = list(SPECIES_TESHARI)
|
||||
@@ -365,4 +365,4 @@
|
||||
icon_state = "silverthree"
|
||||
item_state = "silverthree"
|
||||
overlay_state = "silverthree"
|
||||
desc = "A silver medal awarded to a group which has demonstrated exceptional teamwork to achieve a notable feat. This one has two bronze service stars, denoting that it has been awarded three times."
|
||||
desc = "A silver medal awarded to a group which has demonstrated exceptional teamwork to achieve a notable feat. This one has three bronze service stars, denoting that it has been awarded four times."
|
||||
|
||||
@@ -1,4 +1,53 @@
|
||||
/obj/item/clothing/accessory/holster/waist/kinetic_accelerator
|
||||
name = "KA holster"
|
||||
desc = "A specialized holster, made specifically for Kinetic Accelerator."
|
||||
can_hold = list(/obj/item/weapon/gun/energy/kinetic_accelerator)
|
||||
can_hold = list(/obj/item/weapon/gun/energy/kinetic_accelerator)
|
||||
|
||||
/obj/item/clothing/accessory/holster/machete/rapier
|
||||
name = "rapier sheath"
|
||||
desc = "A beautiful red sheath, probably for a beautiful blade."
|
||||
icon = 'icons/obj/clothing/ties_vr.dmi'
|
||||
icon_state = "sheath"
|
||||
slot_flags = SLOT_BELT|ACCESSORY_SLOT_WEAPON
|
||||
var/has_full_icon = 1
|
||||
icon_override = 'icons/mob/ties_vr.dmi'
|
||||
overlay_state = "sheath"
|
||||
can_hold = list(/obj/item/weapon/melee/rapier)
|
||||
|
||||
/obj/item/clothing/accessory/holster/machete/rapier/swords
|
||||
name = "sword sheath"
|
||||
desc = "A beautiful red sheath, probably for a beautiful blade."
|
||||
can_hold = list(
|
||||
/obj/item/weapon/melee/rapier,
|
||||
/obj/item/weapon/material/sword/katana,
|
||||
/obj/item/toy/cultsword,
|
||||
/obj/item/weapon/material/sword,
|
||||
/obj/item/weapon/melee/cursedblade,
|
||||
/obj/item/weapon/melee/cultblade
|
||||
)
|
||||
|
||||
/obj/item/clothing/accessory/holster/machete/rapier/proc/occupied()
|
||||
if(!has_full_icon)
|
||||
return
|
||||
if(contents.len)
|
||||
overlay_state = "[initial(overlay_state)]-rapier"
|
||||
else
|
||||
overlay_state = initial(overlay_state)
|
||||
|
||||
/obj/item/clothing/accessory/holster/machete/rapier/swords/occupied()
|
||||
if(!has_full_icon)
|
||||
return
|
||||
if(contents.len)
|
||||
overlay_state = "[initial(overlay_state)]-secondary"
|
||||
else
|
||||
overlay_state = initial(overlay_state)
|
||||
|
||||
/obj/item/clothing/accessory/holster/machete/rapier/holster(var/obj/item/I, var/mob/living/user)
|
||||
..()
|
||||
occupied()
|
||||
has_suit.update_clothing_icon()
|
||||
|
||||
/obj/item/clothing/accessory/holster/machete/rapier/unholster(var/obj/item/I, var/mob/living/user)
|
||||
..()
|
||||
occupied()
|
||||
has_suit.update_clothing_icon()
|
||||
|
||||
@@ -1,98 +1,98 @@
|
||||
/*****************************Money bag********************************/
|
||||
|
||||
/obj/item/weapon/moneybag
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
name = "Money bag"
|
||||
icon_state = "moneybag"
|
||||
force = 10.0
|
||||
throwforce = 2.0
|
||||
w_class = ITEMSIZE_LARGE
|
||||
|
||||
/obj/item/weapon/moneybag/attack_hand(user as mob)
|
||||
var/amt_gold = 0
|
||||
var/amt_silver = 0
|
||||
var/amt_diamond = 0
|
||||
var/amt_iron = 0
|
||||
var/amt_phoron = 0
|
||||
var/amt_uranium = 0
|
||||
|
||||
for (var/obj/item/weapon/coin/C in contents)
|
||||
if (istype(C,/obj/item/weapon/coin/diamond))
|
||||
amt_diamond++;
|
||||
if (istype(C,/obj/item/weapon/coin/phoron))
|
||||
amt_phoron++;
|
||||
if (istype(C,/obj/item/weapon/coin/iron))
|
||||
amt_iron++;
|
||||
if (istype(C,/obj/item/weapon/coin/silver))
|
||||
amt_silver++;
|
||||
if (istype(C,/obj/item/weapon/coin/gold))
|
||||
amt_gold++;
|
||||
if (istype(C,/obj/item/weapon/coin/uranium))
|
||||
amt_uranium++;
|
||||
|
||||
var/dat = text("<b>The contents of the moneybag reveal...</b><br>")
|
||||
if (amt_gold)
|
||||
dat += text("Gold coins: [amt_gold] <A href='?src=\ref[src];remove=gold'>Remove one</A><br>")
|
||||
if (amt_silver)
|
||||
dat += text("Silver coins: [amt_silver] <A href='?src=\ref[src];remove=silver'>Remove one</A><br>")
|
||||
if (amt_iron)
|
||||
dat += text("Metal coins: [amt_iron] <A href='?src=\ref[src];remove=iron'>Remove one</A><br>")
|
||||
if (amt_diamond)
|
||||
dat += text("Diamond coins: [amt_diamond] <A href='?src=\ref[src];remove=diamond'>Remove one</A><br>")
|
||||
if (amt_phoron)
|
||||
dat += text("Phoron coins: [amt_phoron] <A href='?src=\ref[src];remove=phoron'>Remove one</A><br>")
|
||||
if (amt_uranium)
|
||||
dat += text("Uranium coins: [amt_uranium] <A href='?src=\ref[src];remove=uranium'>Remove one</A><br>")
|
||||
user << browse("[dat]", "window=moneybag")
|
||||
|
||||
/obj/item/weapon/moneybag/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if (istype(W, /obj/item/weapon/coin))
|
||||
var/obj/item/weapon/coin/C = W
|
||||
to_chat(user, "<font color='blue'>You add the [C.name] into the bag.</font>")
|
||||
usr.drop_item()
|
||||
contents += C
|
||||
if (istype(W, /obj/item/weapon/moneybag))
|
||||
var/obj/item/weapon/moneybag/C = W
|
||||
for (var/obj/O in C.contents)
|
||||
contents += O;
|
||||
to_chat(user, "<font color='blue'>You empty the [C.name] into the bag.</font>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/moneybag/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["remove"])
|
||||
var/obj/item/weapon/coin/COIN
|
||||
switch(href_list["remove"])
|
||||
if("gold")
|
||||
COIN = locate(/obj/item/weapon/coin/gold,src.contents)
|
||||
if("silver")
|
||||
COIN = locate(/obj/item/weapon/coin/silver,src.contents)
|
||||
if("iron")
|
||||
COIN = locate(/obj/item/weapon/coin/iron,src.contents)
|
||||
if("diamond")
|
||||
COIN = locate(/obj/item/weapon/coin/diamond,src.contents)
|
||||
if("phoron")
|
||||
COIN = locate(/obj/item/weapon/coin/phoron,src.contents)
|
||||
if("uranium")
|
||||
COIN = locate(/obj/item/weapon/coin/uranium,src.contents)
|
||||
if(!COIN)
|
||||
return
|
||||
COIN.loc = src.loc
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/moneybag/vault
|
||||
|
||||
/obj/item/weapon/moneybag/vault/New()
|
||||
..()
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/gold(src)
|
||||
/*****************************Money bag********************************/
|
||||
|
||||
/obj/item/weapon/moneybag
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
name = "Money bag"
|
||||
icon_state = "moneybag"
|
||||
force = 10.0
|
||||
throwforce = 2.0
|
||||
w_class = ITEMSIZE_LARGE
|
||||
|
||||
/obj/item/weapon/moneybag/attack_hand(user as mob)
|
||||
var/amt_gold = 0
|
||||
var/amt_silver = 0
|
||||
var/amt_diamond = 0
|
||||
var/amt_iron = 0
|
||||
var/amt_phoron = 0
|
||||
var/amt_uranium = 0
|
||||
|
||||
for (var/obj/item/weapon/coin/C in contents)
|
||||
if (istype(C,/obj/item/weapon/coin/diamond))
|
||||
amt_diamond++;
|
||||
if (istype(C,/obj/item/weapon/coin/phoron))
|
||||
amt_phoron++;
|
||||
if (istype(C,/obj/item/weapon/coin/iron))
|
||||
amt_iron++;
|
||||
if (istype(C,/obj/item/weapon/coin/silver))
|
||||
amt_silver++;
|
||||
if (istype(C,/obj/item/weapon/coin/gold))
|
||||
amt_gold++;
|
||||
if (istype(C,/obj/item/weapon/coin/uranium))
|
||||
amt_uranium++;
|
||||
|
||||
var/dat = text("<b>The contents of the moneybag reveal...</b><br>")
|
||||
if (amt_gold)
|
||||
dat += text("Gold coins: [amt_gold] <A href='?src=\ref[src];remove=gold'>Remove one</A><br>")
|
||||
if (amt_silver)
|
||||
dat += text("Silver coins: [amt_silver] <A href='?src=\ref[src];remove=silver'>Remove one</A><br>")
|
||||
if (amt_iron)
|
||||
dat += text("Metal coins: [amt_iron] <A href='?src=\ref[src];remove=iron'>Remove one</A><br>")
|
||||
if (amt_diamond)
|
||||
dat += text("Diamond coins: [amt_diamond] <A href='?src=\ref[src];remove=diamond'>Remove one</A><br>")
|
||||
if (amt_phoron)
|
||||
dat += text("Phoron coins: [amt_phoron] <A href='?src=\ref[src];remove=phoron'>Remove one</A><br>")
|
||||
if (amt_uranium)
|
||||
dat += text("Uranium coins: [amt_uranium] <A href='?src=\ref[src];remove=uranium'>Remove one</A><br>")
|
||||
user << browse("[dat]", "window=moneybag")
|
||||
|
||||
/obj/item/weapon/moneybag/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if (istype(W, /obj/item/weapon/coin))
|
||||
var/obj/item/weapon/coin/C = W
|
||||
to_chat(user, "<font color='blue'>You add the [C.name] into the bag.</font>")
|
||||
usr.drop_item()
|
||||
contents += C
|
||||
if (istype(W, /obj/item/weapon/moneybag))
|
||||
var/obj/item/weapon/moneybag/C = W
|
||||
for (var/obj/O in C.contents)
|
||||
contents += O;
|
||||
to_chat(user, "<font color='blue'>You empty the [C.name] into the bag.</font>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/moneybag/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
if(href_list["remove"])
|
||||
var/obj/item/weapon/coin/COIN
|
||||
switch(href_list["remove"])
|
||||
if("gold")
|
||||
COIN = locate(/obj/item/weapon/coin/gold,src.contents)
|
||||
if("silver")
|
||||
COIN = locate(/obj/item/weapon/coin/silver,src.contents)
|
||||
if("iron")
|
||||
COIN = locate(/obj/item/weapon/coin/iron,src.contents)
|
||||
if("diamond")
|
||||
COIN = locate(/obj/item/weapon/coin/diamond,src.contents)
|
||||
if("phoron")
|
||||
COIN = locate(/obj/item/weapon/coin/phoron,src.contents)
|
||||
if("uranium")
|
||||
COIN = locate(/obj/item/weapon/coin/uranium,src.contents)
|
||||
if(!COIN)
|
||||
return
|
||||
COIN.loc = src.loc
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/moneybag/vault
|
||||
|
||||
/obj/item/weapon/moneybag/vault/New()
|
||||
..()
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/silver(src)
|
||||
new /obj/item/weapon/coin/gold(src)
|
||||
new /obj/item/weapon/coin/gold(src)
|
||||
@@ -13,7 +13,7 @@
|
||||
//---Beverages---//
|
||||
//***************//
|
||||
|
||||
/datum/reagent/var/price_tag = null
|
||||
/datum/reagent/var/price_tag = 0
|
||||
|
||||
|
||||
// Juices, soda and similar //
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user