Merge pull request #10 from CHOMPStation2/master

aa
This commit is contained in:
cadyn
2020-10-27 12:27:06 -07:00
committed by GitHub
173 changed files with 29250 additions and 4401 deletions
+10 -4
View File
@@ -1,5 +1,6 @@
#pretending we're C because otherwise ruby will initialize, even with "language: dm".
language: c
language: generic
os: linux
dist: bionic
env:
global:
@@ -12,10 +13,14 @@ cache:
addons:
apt:
packages:
- libc6-i386
- libc6:i386
- libgcc1:i386
- libstdc++6:i386
- libssl-dev:i386
- libssl1.1:i386
- g++-7
- g++-7-multilib
- gcc-multilib
- zlib1g:i386
before_install:
- chmod -R +x ./tools/travis
@@ -27,6 +32,7 @@ before_script:
- shopt -s globstar
script:
- ldd librust_g.so
- ./tools/travis/compile_and_run.sh
# Build-specific settings
+1 -1
View File
@@ -4,7 +4,7 @@ export SPACEMANDMM_TAG=suite-1.4
# For NanoUI + TGUI
export NODE_VERSION=12
# For the scripts in tools
export PHP_VERSION=5.6
export PHP_VERSION=7.2
# Byond Major
export BYOND_MAJOR=513
# Byond Minor
-4
View File
@@ -7,10 +7,6 @@
2 for preloading absolutely everything;
*/
#define RUST_G "rust_g" // If uncommented, we will use the rust-g (https://github.com/tgstation/rust-g) native library for fast
// logging. This requires you to have the rust_g.dll or rust_g (renamed from librust_g.so) installed in the root folder or BYOND/bin
// The define's value should be the name of library file.
// ZAS Compile Options
//#define ZASDBG // Uncomment to turn on super detailed ZAS debugging that probably won't even compile.
#define MULTIZAS // Uncomment to turn on Multi-Z ZAS Support!
+1 -1
View File
@@ -20,7 +20,7 @@
//For custom species
#define STARTING_SPECIES_POINTS 1
#define MAX_SPECIES_TRAITS 5
#define MAX_SPECIES_TRAITS 8 //CHOMPEdit
// Xenochimera thing mostly
#define REVIVING_NOW -1
+103
View File
@@ -0,0 +1,103 @@
// rust_g.dm - DM API for rust_g extension library
//
// To configure, create a `rust_g.config.dm` and set what you care about from
// the following options:
//
// #define RUST_G "path/to/rust_g"
// Override the .dll/.so detection logic with a fixed path or with detection
// logic of your own.
//
// #define RUSTG_OVERRIDE_BUILTINS
// Enable replacement rust-g functions for certain builtins. Off by default.
#ifndef RUST_G
// Default automatic RUST_G detection.
// On Windows, looks in the standard places for `rust_g.dll`.
// On Linux, looks in `.`, `$LD_LIBRARY_PATH`, and `~/.byond/bin` for either of
// `librust_g.so` (preferred) or `rust_g` (old).
/* This comment bypasses grep checks */ /var/__rust_g
/proc/__detect_rust_g()
if (world.system_type == UNIX)
if (fexists("./librust_g.so"))
// No need for LD_LIBRARY_PATH badness.
return __rust_g = "./librust_g.so"
else if (fexists("./rust_g"))
// Old dumb filename.
return __rust_g = "./rust_g"
else if (fexists("[world.GetConfig("env", "HOME")]/.byond/bin/rust_g"))
// Old dumb filename in `~/.byond/bin`.
return __rust_g = "rust_g"
else
// It's not in the current directory, so try others
return __rust_g = "librust_g.so"
else
return __rust_g = "rust_g"
#define RUST_G (__rust_g || __detect_rust_g())
#endif
#define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET"
#define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB"
#define RUSTG_JOB_ERROR "JOB PANICKED"
#define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname)
#define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data)
#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y)
#define rustg_file_read(fname) call(RUST_G, "file_read")(fname)
#define rustg_file_exists(fname) call(RUST_G, "file_exists")(fname)
#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname)
#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname)
#ifdef RUSTG_OVERRIDE_BUILTINS
#define file2text(fname) rustg_file_read("[fname]")
#define text2file(text, fname) rustg_file_append(text, "[fname]")
#endif
#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev)
#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev)
#define rustg_hash_string(algorithm, text) call(RUST_G, "hash_string")(algorithm, text)
#define rustg_hash_file(algorithm, fname) call(RUST_G, "hash_file")(algorithm, fname)
#define RUSTG_HASH_MD5 "md5"
#define RUSTG_HASH_SHA1 "sha1"
#define RUSTG_HASH_SHA256 "sha256"
#define RUSTG_HASH_SHA512 "sha512"
#ifdef RUSTG_OVERRIDE_BUILTINS
#define md5(thing) (isfile(thing) ? rustg_hash_file(RUSTG_HASH_MD5, "[thing]") : rustg_hash_string(RUSTG_HASH_MD5, thing))
#endif
#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true")
#define rustg_log_write(fname, text, format) call(RUST_G, "log_write")(fname, text, format)
/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")()
#define rustg_url_encode(text) call(RUST_G, "url_encode")(text)
#define rustg_url_decode(text) call(RUST_G, "url_decode")(text)
#ifdef RUSTG_OVERRIDE_BUILTINS
#define url_encode(text) rustg_url_encode(text)
#define url_decode(text) rustg_url_decode(text)
#endif
#define RUSTG_HTTP_METHOD_GET "get"
#define RUSTG_HTTP_METHOD_PUT "put"
#define RUSTG_HTTP_METHOD_DELETE "delete"
#define RUSTG_HTTP_METHOD_PATCH "patch"
#define RUSTG_HTTP_METHOD_HEAD "head"
#define RUSTG_HTTP_METHOD_POST "post"
#define rustg_http_request_blocking(method, url, body, headers) call(RUST_G, "http_request_blocking")(method, url, body, headers)
#define rustg_http_request_async(method, url, body, headers) call(RUST_G, "http_request_async")(method, url, body, headers)
#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id)
#define rustg_sql_connect_pool(options) call(RUST_G, "sql_connect_pool")(options)
#define rustg_sql_query_async(handle, query, params) call(RUST_G, "sql_query_async")(handle, query, params)
#define rustg_sql_query_blocking(handle, query, params) call(RUST_G, "sql_query_blocking")(handle, query, params)
#define rustg_sql_connected(handle) call(RUST_G, "sql_connected")(handle)
#define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle)
#define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]")
+1
View File
@@ -9,6 +9,7 @@
#define LANGUAGE_DAEMON "Daemon"
#define LANGUAGE_ENOCHIAN "Enochian"
#define LANGUAGE_VESPINAE "Vespinae"
#define LANGUAGE_SPACER "Spacer"
#define LANGUAGE_CHIMPANZEE "Chimpanzee"
#define LANGUAGE_NEAERA "Neaera"
+4 -12
View File
@@ -1,25 +1,17 @@
//print an error message to world.log
// Fall back to using old format if we are not using rust-g
#ifdef RUST_G
#define WRITE_LOG(log, text) call(RUST_G, "log_write")(log, text)
#else
#define WRITE_LOG(log, text) log << "\[[time_stamp()]][text]"
#endif
//This is an external call, "true" and "false" are how rust parses out booleans
#define WRITE_LOG(log, text) rustg_log_write(log, text, "true")
#define WRITE_LOG_NO_FORMAT(log, text) rustg_log_write(log, text, "false")
/* For logging round startup. */
/proc/start_log(log)
#ifndef RUST_G
log = file(log)
#endif
WRITE_LOG(log, "START: Starting up [log_path].")
return log
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
/proc/shutdown_logging()
#ifdef RUST_G
call(RUST_G, "log_close_all")()
#endif
rustg_log_close_all()
/proc/error(msg)
to_world_log("## ERROR: [msg]")
+7
View File
@@ -151,6 +151,13 @@
containername = "Singularity Generator crate"
access = access_ce
/datum/supply_pack/eng/engine/tesla_gen
name = "Tesla Generator crate"
contains = list(/obj/machinery/the_singularitygen/tesla)
containertype = /obj/structure/closet/crate/secure/einstein
containername = "Tesla Generator crate"
access = access_ce
/datum/supply_pack/eng/engine/collector
name = "Collector crate"
contains = list(/obj/machinery/power/rad_collector = 3)
+1 -2
View File
@@ -29,8 +29,7 @@
desc = "Used to control various station atmospheric systems. The light indicates the current air status of the area."
icon = 'icons/obj/monitors_vr.dmi' //CHOMPEdit: Continues using new air alarm sprite, contrary to YW
icon_state = "alarm0"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
anchored = 1
use_power = USE_POWER_IDLE
idle_power_usage = 80
+1 -2
View File
@@ -2,8 +2,7 @@
name = "button"
icon = 'icons/obj/objects.dmi'
icon_state = "launcherbtt"
// plane = TURF_PLANE //Can't have them under tables, oh well.
// layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
desc = "A remote control switch for something."
var/id = null
var/active = 0
+1 -2
View File
@@ -59,8 +59,7 @@
name = "Telescreen"
desc = "Used for watching an empty arena."
icon_state = "wallframe"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
icon_keyboard = null
icon_screen = null
light_range_on = 0
+1 -2
View File
@@ -79,8 +79,7 @@
name = "guest pass terminal"
desc = "Used to print temporary passes for people. Handy!"
icon_state = "guest"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
icon_keyboard = null
icon_screen = "pass"
density = 0
@@ -148,6 +148,7 @@ obj/machinery/door/airlock/Destroy()
obj/machinery/airlock_sensor
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "airlock_sensor_off"
layer = ABOVE_WINDOW_LAYER
name = "airlock sensor"
desc = "Sends atmospheric readings to a nearby controller."
@@ -233,6 +234,7 @@ obj/machinery/airlock_sensor/airlock_exterior/shuttle/return_air()
obj/machinery/access_button
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "access_button_standby"
layer = ABOVE_WINDOW_LAYER
name = "access button"
anchored = 1
+1
View File
@@ -22,6 +22,7 @@
name = "Door Timer"
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
layer = ABOVE_WINDOW_LAYER
desc = "A remote control for a door."
req_access = list(access_brig)
anchored = 1.0 // can't pick it up
@@ -15,6 +15,7 @@
var/list/dummy_terminals = list()
var/cycle_to_external_air = 0
valid_actions = list("cycle_ext", "cycle_int", "force_ext", "force_int", "abort", "purge", "secure")
layer = ABOVE_WINDOW_LAYER
/obj/machinery/embedded_controller/radio/airlock/Destroy()
// TODO - Leshana - Implement dummy terminals
+1 -2
View File
@@ -6,8 +6,7 @@ FIRE ALARM
desc = "<i>\"Pull this in case of emergency\"</i>. Thus, keep pulling it forever."
icon = 'icons/obj/monitors.dmi'
icon_state = "fire0"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
var/detecting = 1.0
var/working = 1.0
var/time = 10.0
+1
View File
@@ -4,6 +4,7 @@
desc = "A wall-mounted flashbulb device."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "mflash1"
layer = ABOVE_WINDOW_LAYER
var/id = null
var/range = 2 //this is roughly the size of brig cell
var/disable = 0
+1
View File
@@ -48,6 +48,7 @@
desc = "A wall-mounted ignition device."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "migniter"
layer = ABOVE_WINDOW_LAYER
var/id = null
var/disable = 0
var/last_spark = 0
+1
View File
@@ -6,6 +6,7 @@
desc = "It turns lights on and off. What are you, simple?"
icon = 'icons/obj/power_vr.dmi' // VOREStation Edit
icon_state = "light1"
layer = ABOVE_WINDOW_LAYER
anchored = 1.0
use_power = USE_POWER_IDLE
idle_power_usage = 10
+1
View File
@@ -4,6 +4,7 @@
desc = "Small wall-mounted electronic sign"
icon = 'icons/obj/neonsigns.dmi'
icon_state = "sign_off"
layer = ABOVE_WINDOW_LAYER
plane = MOB_PLANE
use_power = USE_POWER_IDLE
idle_power_usage = 2
+1 -2
View File
@@ -126,8 +126,7 @@ GLOBAL_LIST_BOILERPLATE(allCasters, /obj/machinery/newscaster)
desc = "A standard newsfeed handler for use on commercial space stations. All the news you absolutely have no use for, in one place!"
icon = 'icons/obj/terminals_vr.dmi' //VOREStation Edit
icon_state = "newscaster_normal"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
var/isbroken = 0 //1 if someone banged it with something heavy
var/ispowered = 1 //starts powered, changes with power_change()
//var/list/datum/feed_channel/channel_list = list() //This list will contain the names of the feed channels. Each name will refer to a data region where the messages of the feed channels are stored.
+1 -2
View File
@@ -28,8 +28,7 @@ var/list/obj/machinery/requests_console/allConsoles = list()
anchored = 1
icon = 'icons/obj/terminals_vr.dmi' //VOREStation Edit
icon_state = "req_comp0"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
circuit = /obj/item/weapon/circuitboard/request
var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department
var/list/message_log = list() //List of all messages
+2 -2
View File
@@ -13,7 +13,7 @@
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
name = "status display"
anchored = 1
density = 0
@@ -267,4 +267,4 @@
#undef FOND_SIZE
#undef FONT_COLOR
#undef FONT_STYLE
#undef SCROLL_SPEED
#undef SCROLL_SPEED
+1
View File
@@ -59,6 +59,7 @@ var/list/ai_status_emotions = list(
/obj/machinery/ai_status_display
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
layer = ABOVE_WINDOW_LAYER
name = "AI display"
anchored = 1
density = 0
+2
View File
@@ -396,6 +396,7 @@
description_fluff = "NanoMed is NanoTrasen's medical science division, and provides almost all of the modern medbay essentials in-house at no extra charge. By using this vending machine, employees accept liability for products that may or may not be temporarily replaced by placebos or experimental treatments."
product_ads = "Go save some lives!;The best stuff for your medbay.;Only the finest tools.;Natural chemicals!;This stuff saves lives.;Don't you want some?"
icon_state = "wallmed"
layer = ABOVE_WINDOW_LAYER
density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude
products = list(/obj/item/stack/medical/bruise_pack = 2,
/obj/item/stack/medical/ointment = 2,
@@ -413,6 +414,7 @@
desc = "A wall-mounted version of the NanoMed, containing only vital first aid equipment."
description_fluff = "NanoMed is NanoTrasen's medical science division, and provides almost all of the modern medbay essentials in-house at no extra charge. By using this vending machine, employees accept liability for products that may or may not be temporarily replaced by placebos or experimental treatments."
icon_state = "wallmed"
layer = ABOVE_WINDOW_LAYER
density = 0 //It is wall-mounted, and thus, not dense. --Superxpdude
products = list(/obj/item/weapon/reagent_containers/hypospray/autoinjector = 5,
/obj/item/weapon/reagent_containers/syringe/antitoxin = 3,
+7 -7
View File
@@ -41,14 +41,14 @@
materials = list(DEFAULT_WALL_MATERIAL = 12500)
/datum/design/item/mecha/drill/micro
name = "Miniature Drill"
name = "Micro Drill" //CHOMPedit
id = "micro_drill"
build_path = /obj/item/mecha_parts/mecha_equipment/tool/drill/micro
time = 5
materials = list(DEFAULT_WALL_MATERIAL = 2500)
/datum/design/item/mecha/hydraulic_clamp/micro
name = "Mounted ore box"
name = "Mounted micro ore box" //CHOMPedit
id = "ore_scoop"
build_path = /obj/item/mecha_parts/mecha_equipment/tool/micro/orescoop
time = 5
@@ -103,31 +103,31 @@
materials = list(DEFAULT_WALL_MATERIAL = 12500, "plastic" = 7500)
/datum/design/item/mecha/taser/micro
name = "\improper TS-12 \"Suppressor\" integrated taser"
name = "\improper TS-12 \"Suppressor\" integrated micro taser" //CHOMPedit
id = "micro_taser"
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/microtaser
/datum/design/item/mecha/weapon/laser/micro
name = "\improper WS-19 \"Torch\" laser carbine"
name = "\improper WS-19 \"Torch\" micro laser carbine" //CHOMPedit
id = "micro_laser"
// req_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 3)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/microlaser
/datum/design/item/mecha/weapon/laser_heavy/micro
name = "\improper PC-20 \"Lance\" light laser cannon"
name = "\improper PC-20 \"Lance\" micro laser cannon" //CHOMPedit
id = "micro_laser_heavy"
req_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 1000, "diamond" = 2000)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/microheavy
/datum/design/item/mecha/weapon/grenade_launcher/micro
name = "\improper FP-20 mounted grenade launcher"
name = "\improper FP-20 mounted micro flashbang launcher" //CHOMPedit
id = "micro_flashbang_launcher"
// req_tech = list(TECH_COMBAT = 3)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/microflashbang
/datum/design/item/mecha/weapon/scattershot/micro
name = "\improper Remington C-12 \"Boomstick\""
name = "\improper Remington C-12 \"Micro-Boomstick\"" //CHOMPedit
desc = "A mounted combat shotgun with integrated ammo-lathe."
id = "micro_scattershot"
// req_tech = list(TECH_COMBAT = 4)
+14 -14
View File
@@ -6,9 +6,9 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/microlaser
w_class = ITEMSIZE_LARGE
desc = "A mounted laser-carbine for light exosuits."
desc = "A mounted micro laser-carbine for micro mechs." //CHOMPedit
equip_cooldown = 10 // same as the laser carbine
name = "\improper WS-19 \"Torch\" laser carbine"
name = "\improper WS-19 \"Torch\" micro laser carbine" //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "micromech_laser"
energy_drain = 50
@@ -19,9 +19,9 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/microheavy
w_class = ITEMSIZE_LARGE
desc = "A mounted laser cannon for light exosuits."
desc = "A mounted micro laser cannon for micro mechs." //CHOMPedit
equip_cooldown = 30 // same as portable
name = "\improper PC-20 \"Lance\" light laser cannon"
name = "\improper PC-20 \"Lance\" micro light laser cannon" //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "micromech_lasercannon"
energy_drain = 120
@@ -32,8 +32,8 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/microtaser
w_class = ITEMSIZE_LARGE
desc = "A mounted taser for light exosuits."
name = "\improper TS-12 \"Suppressor\" integrated taser"
desc = "A mounted micro taser for micro mechs." //CHOMPedit
name = "\improper TS-12 \"Suppressor\" integrated micro taser" //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "micromech_taser"
energy_drain = 40
@@ -45,8 +45,8 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/microshotgun
w_class = ITEMSIZE_LARGE
desc = "A mounted combat shotgun with integrated ammo-lathe."
name = "\improper Remington C-12 \"Boomstick\""
desc = "A mounted micro combat shotgun with integrated ammo-lathe." //CHOMPedit
name = "\improper Remington C-12 \"Micro-Boomstick\"" //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "micromech_shotgun"
equip_cooldown = 15
@@ -84,8 +84,8 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/microflashbang
w_class = ITEMSIZE_LARGE
desc = "A mounted grenade launcher for smaller mechs."
name = "\improper FP-20 mounted grenade launcher"
desc = "A mounted micro flashbang launcher for micro mechs." //CHOMPedit
name = "\improper FP-20 mounted micro flashbang launcher" //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "micromech_launcher"
projectiles = 1
@@ -103,8 +103,8 @@
/obj/item/mecha_parts/mecha_equipment/tool/drill/micro
w_class = ITEMSIZE_LARGE
name = "drill"
desc = "This is the drill that'll sorta poke holes in the heavens!"
name = "Micro Drill" //CHOMPedit
desc = "This is the micro drill that'll sorta poke holes in the heavens!" //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "microdrill"
equip_cooldown = 30
@@ -155,8 +155,8 @@
/obj/item/mecha_parts/mecha_equipment/tool/micro/orescoop
w_class = ITEMSIZE_LARGE
name = "Mounted ore box"
desc = "A mounted ore scoop and hopper, for gathering ores."
name = "Mounted micro ore box" //CHOMPedit
desc = "A small mounted ore scoop and hopper, for gathering ores in a micro mech." //CHOMPedit
icon = 'icons/mecha/mecha_equipment_vr.dmi'
icon_state = "microscoop"
equip_cooldown = 5
@@ -3,8 +3,7 @@
desc = "Talk through this."
icon = 'icons/obj/radio_vr.dmi' //VOREStation Edit - New Icon
icon_state = "intercom"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
anchored = 1
w_class = ITEMSIZE_LARGE
canhear_range = 7 //VOREStation Edit
@@ -4,6 +4,10 @@
name = "stack of grass"
type_to_spawn = /obj/item/stack/tile/grass
/obj/fiftyspawner/grass/sif
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif
/obj/fiftyspawner/wood
name = "stack of wood"
type_to_spawn = /obj/item/stack/tile/wood
@@ -46,6 +46,12 @@
no_variants = FALSE
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
/obj/item/stack/tile/grass/sif
name = "sivian grass tile"
singular_name = "sivian grass floor tile"
desc = "A patch of grass like those that decorate the plains of Sif."
/*
* Wood
*/
+45 -1
View File
@@ -114,6 +114,18 @@
w_class = ITEMSIZE_LARGE
drop_sound = 'sound/items/drop/rubber.ogg'
/obj/item/toy/colorballoon /// To color it, VV the 'color' var with a hex color code with the # included.
name = "balloon"
desc = "It's a plain little balloon. Comes in many colors!"
throwforce = 0
throw_speed = 4
throw_range = 20
force = 0
icon = 'icons/obj/weapons.dmi'
icon_state = "colorballoon"
w_class = ITEMSIZE_LARGE
drop_sound = 'sound/items/drop/rubber.ogg'
/*
* Fake telebeacon
*/
@@ -1438,4 +1450,36 @@
name = "purple king"
desc = "A large king piece for playing chess. It's made of a purple-colored glass."
description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose."
icon_state = "b-king"
icon_state = "b-king"
/// Balloon structures
/obj/structure/balloon
name = "generic balloon"
desc = "A generic balloon. How boring."
icon = 'icons/obj/toy.dmi'
icon_state = "ghostballoon"
anchored = 0
density = 0
/obj/structure/balloon/attack_hand(mob/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(user.a_intent == I_HELP)
user.visible_message("<span class='notice'><b>\The [user]</b> pokes [src]!</span>","<span class='notice'>You poke [src]!</span>")
else if (user.a_intent == I_HURT)
user.visible_message("<span class='warning'><b>\The [user]</b> punches [src]!</span>","<span class='warning'>You punch [src]!</span>")
else if (user.a_intent == I_GRAB)
user.visible_message("<span class='warning'><b>\The [user]</b> attempts to pop [src]!</span>","<span class='warning'>You attempt to pop [src]!</span>")
else
user.visible_message("<span class='notice'><b>\The [user]</b> lightly bats the [src].</span>","<span class='notice'>You lightly bat the [src].</span>")
/obj/structure/balloon/bat
name = "giant bat balloon"
desc = "A large balloon in the shape of a spooky bat with orange eyes."
icon_state = "batballoon"
/obj/structure/balloon/ghost
name = "giant ghost balloon"
desc = "Oh no, it's a ghost! Oh wait, it's just a balloon. Phew!"
icon_state = "ghostballoon"
@@ -178,6 +178,7 @@
desc = "It doesn't seem all that secure. Oh well, it'll do."
icon = 'icons/obj/storage.dmi'
icon_state = "safe"
layer = ABOVE_WINDOW_LAYER
icon_opened = "safe0"
icon_locking = "safeb"
icon_sparking = "safespark"
@@ -0,0 +1,6 @@
/obj/item/weapon/surgical/bioregen
name="bioregenerator"
desc="A special tool used in surgeries which can pull toxins from and restore oxygen to organic tissue as well as recreate missing biological structures to allow otherwise irreperable flesh to be mended."
icon='icons/obj/surgery_ch.dmi'
icon_state="bioregen"
drop_sound = 'sound/items/drop/scrap.ogg'
+1 -2
View File
@@ -3,8 +3,7 @@
desc = "A small wall mounted cabinet designed to hold a fire extinguisher."
icon = 'icons/obj/closet.dmi'
icon_state = "extinguisher_closed"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
layer = ABOVE_WINDOW_LAYER
anchored = 1
density = 0
var/obj/item/weapon/extinguisher/has_extinguisher
+1
View File
@@ -5,6 +5,7 @@
var/obj/item/weapon/material/twohanded/fireaxe/fireaxe
icon = 'icons/obj/closet.dmi' //Not bothering to move icons out for now. But its dumb still.
icon_state = "fireaxe1000"
layer = ABOVE_WINDOW_LAYER
anchored = 1
density = 0
var/open = 0
+21 -19
View File
@@ -41,59 +41,61 @@
/obj/structure/flora/log1
name = "waterlogged trunk"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A part of a felled tree. Moss is growing across it."
icon_state = "log1"
/obj/structure/flora/log2
name = "waterlogged trunk"
name = "driftwood"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "Driftwood carelessly lost in the water."
icon_state = "log2"
/obj/structure/flora/lily1
name = "waterlogged trunk"
name = "red flowered lilypads"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A bunch of lilypads. A beautiful red flower grows in the middle of them."
icon_state = "lilypad1"
/obj/structure/flora/lily2
name = "waterlogged trunk"
name = "yellow flowered lilypads"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A few lilypads. A sunny yellow flower stems from the water and from between the lilypads."
icon_state = "lilypad2"
/obj/structure/flora/lily3
name = "waterlogged trunk"
name = "lilypads"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A group of flowerless lilypads."
icon_state = "lilypad3"
/obj/structure/flora/smallbould
name = "waterlogged trunk"
name = "small boulder"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A small boulder, with its top smothered with moss."
icon_state = "smallerboulder"
/obj/structure/flora/bboulder1
name = "waterlogged trunk"
name = "large boulder"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "Small stones sit beside this large boulder. Moss grows on the top of each of them."
icon_state = "bigboulder1"
density = 1
/obj/structure/flora/bboulder2
name = "waterlogged trunk"
name = "jagged large boulder"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "This boulder has had plates broken off it. Moss grows in the cracks and across the top."
icon_state = "bigboulder2"
density = 1
/obj/structure/flora/rocks1
name = "waterlogged trunk"
name = "rocks"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A bunch of mossy rocks."
icon_state = "rocks1"
/obj/structure/flora/rocks2
name = "waterlogged trunk"
name = "rocks"
icon = 'icons/obj/flora/amayastuff.dmi'
desc = "A part of a felled tree. It is soaking up the water it is bouyant on."
desc = "A bunch of mossy rocks."
icon_state = "rocks2"
+1
View File
@@ -4,6 +4,7 @@
desc = "A SalonPro Nano-Mirror(TM) brand mirror! The leading technology in hair salon products, utilizing nano-machinery to style your hair just right."
icon = 'icons/obj/watercloset.dmi'
icon_state = "mirror"
layer = ABOVE_WINDOW_LAYER
density = 0
anchored = 1
var/shattered = 0
+1
View File
@@ -146,6 +146,7 @@ var/list/flooring_types
flags = TURF_REMOVE_SHOVEL
icon = 'icons/turf/outdoors.dmi'
icon_base = "grass_sif"
build_type = /obj/item/stack/tile/grass/sif
has_base_range = 1
/decl/flooring/water
+11 -2
View File
@@ -82,6 +82,7 @@
return
if (istype(A,/mob/living))
var/dirtslip = FALSE //CHOMPEdit
var/mob/living/M = A
if(M.lying || M.flying) //VOREStation Edit
return ..()
@@ -92,6 +93,7 @@
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
dirtslip = H.species.dirtslip //CHOMPEdit
// Tracking blood
var/list/bloodDNA = null
var/bloodcolor=""
@@ -117,7 +119,7 @@
bloodDNA = null
if(src.wet)
if(src.wet || (dirtslip && (dirt > 50 || outdoors))) //CHOMPEdit
if(M.buckled || (src.wet == 1 && M.m_intent == "walk"))
return
@@ -125,7 +127,14 @@
var/slip_dist = 1
var/slip_stun = 6
var/floor_type = "wet"
//CHOMPEdit Begin
if(dirtslip)
slip_stun = 10
if(dirt > 50)
floor_type = "dirty"
else if(outdoors)
floor_type = "uneven"
//CHOMPEdit End
switch(src.wet)
if(2) // Lube
floor_type = "slippery"
+1 -5
View File
@@ -119,18 +119,14 @@ GLOBAL_LIST_EMPTY(asset_datums)
if (size[SPRSZ_STRIPPED])
continue
#ifdef RUST_G
// save flattened version
var/fname = "data/spritesheets/[name]_[size_id].png"
fcopy(size[SPRSZ_ICON], fname)
var/error = call(RUST_G, "dmi_strip_metadata")(fname)
var/error = rustg_dmi_strip_metadata(fname)
if(length(error))
stack_trace("Failed to strip [name]_[size_id].png: [error]")
size[SPRSZ_STRIPPED] = icon(fname)
fdel(fname)
#else
#warn It looks like you don't have RUST_G enabled. Without RUST_G, the RPD icons will not function, so it strongly recommended you reenable it.
#endif
/datum/asset/spritesheet/proc/generate_css()
var/list/out = list()
@@ -6,6 +6,14 @@
/datum/category_item/player_setup_item/general/language/load_character(var/savefile/S)
S["language"] >> pref.alternate_languages
S["language_prefixes"] >> pref.language_prefixes
//CHOMPEdit Begin
S["pos_traits"] >> pref.pos_traits
var/morelang = 0
for(var/trait in pref.pos_traits)
if(trait==/datum/trait/linguist)
morelang = 1
pref.num_languages = morelang * 12
//CHOMPEdit End
/datum/category_item/player_setup_item/general/language/save_character(var/savefile/S)
S["language"] << pref.alternate_languages
@@ -15,8 +23,8 @@
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)
pref.alternate_languages.len = S.num_alternate_languages // Truncate to allowed length
if(S && pref.alternate_languages.len > pref.numlanguage()) //CHOMPEdit
pref.alternate_languages.len = pref.numlanguage() // Truncate to allowed length CHOMPEdit
if(isnull(pref.language_prefixes) || !pref.language_prefixes.len)
pref.language_prefixes = config.language_prefixes.Copy()
for(var/prefix in pref.language_prefixes)
@@ -30,14 +38,14 @@
. += "- [S.language]<br>"
if(S.default_language && S.default_language != S.language)
. += "- [S.default_language]<br>"
if(S.num_alternate_languages)
if(pref.numlanguage()) //CHOMPEdit
if(pref.alternate_languages.len)
for(var/i = 1 to pref.alternate_languages.len)
var/lang = pref.alternate_languages[i]
. += "- [lang] - <a href='?src=\ref[src];remove_language=[i]'>remove</a><br>"
if(pref.alternate_languages.len < S.num_alternate_languages)
. += "- <a href='?src=\ref[src];add_language=1'>add</a> ([S.num_alternate_languages - pref.alternate_languages.len] remaining)<br>"
if(pref.alternate_languages.len < pref.numlanguage()) //CHOMPEdit
. += "- <a href='?src=\ref[src];add_language=1'>add</a> ([pref.numlanguage() - pref.alternate_languages.len] remaining)<br>" //CHOMPEdit
else
. += "- [pref.species] cannot choose secondary languages.<br>"
@@ -51,7 +59,7 @@
return TOPIC_REFRESH
else if(href_list["add_language"])
var/datum/species/S = GLOB.all_species[pref.species]
if(pref.alternate_languages.len >= S.num_alternate_languages)
if(pref.alternate_languages.len >= pref.numlanguage()) //CHOMPEdit
alert(user, "You have already selected the maximum number of alternate languages for this species!")
else
var/list/available_languages = S.secondary_langs.Copy()
@@ -69,7 +77,7 @@
alert(user, "There are no additional languages available to select.")
else
var/new_lang = input(user, "Select an additional language", "Character Generation", null) as null|anything in available_languages
if(new_lang && pref.alternate_languages.len < S.num_alternate_languages)
if(new_lang && pref.alternate_languages.len < pref.numlanguage()) //CHOMPEdit
pref.alternate_languages |= new_lang
return TOPIC_REFRESH
@@ -264,7 +264,7 @@
if(pref.dirty_synth && instance.not_for_synths)//if you are a synth you can't take this trait.
alert("You cannot take this trait as a SYNTH.\
Please remove that trait, or pick another trait to add.","Error")
pref.dirty_synth = 0 //Just to be sure
//pref.dirty_synth = 0 //Just to be sure // Commented out because it allow for someone to take a synth-blacklisted trait CHOMP Edit
return TOPIC_REFRESH
+6 -2
View File
@@ -30,6 +30,7 @@ datum/preferences
var/tgui_lock = FALSE
//character preferences
var/num_languages = 0 //CHOMPEdit
var/real_name //our character's name
var/be_random_name = 0 //whether we are a random name every round
var/nickname //our character's nickname
@@ -154,8 +155,11 @@ datum/preferences
var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off
var/list/volume_channels = list()
//CHOMPEdit Begin
/datum/preferences/proc/numlanguage()
var/datum/species/S = GLOB.all_species[species]
return num_languages ? num_languages : S.num_alternate_languages
//CHOMPEdit End
/datum/preferences/New(client/C)
player_setup = new(src)
set_biological_gender(pick(MALE, FEMALE))
@@ -123,6 +123,31 @@
glass_center_of_mass = list("x"=16, "y"=9)
glass_icon_file = 'icons/obj/drinks_vr.dmi'
/datum/reagent/ethanol/originalsin
glass_icon_state = "originalsinglass"
glass_center_of_mass = list("x"=16, "y"=9)
glass_icon_file = 'icons/obj/drinks_vr.dmi'
/datum/reagent/ethanol/whiskeysour
glass_icon_state = "whiskeysourglass"
glass_center_of_mass = list("x"=16, "y"=9)
glass_icon_file = 'icons/obj/drinks_vr.dmi'
/datum/reagent/ethanol/newyorksour
glass_icon_state = "newyorksourglass"
glass_center_of_mass = list("x"=16, "y"=9)
glass_icon_file = 'icons/obj/drinks_vr.dmi'
/datum/reagent/ethanol/mudslide
glass_icon_state = "mudslideglass"
glass_center_of_mass = list("x"=16, "y"=9)
glass_icon_file = 'icons/obj/drinks_vr.dmi'
/datum/reagent/ethanol/windgarita
glass_icon_state = "windgaritaglass"
glass_center_of_mass = list("x"=16, "y"=9)
glass_icon_file = 'icons/obj/drinks_vr.dmi'
/datum/reagent/drink/soda/kiraspecial
glass_icon_file = 'icons/obj/drinks_vr.dmi'
+1 -1
View File
@@ -208,7 +208,7 @@
var/obj/item/I = locate(i) in container
if (I && I.reagents)
I.reagents.trans_to_holder(buffer,I.reagents.total_volume)
qdel(I)
qdel(I)
//Find fruits
if (fruit && fruit.len)
+60 -1
View File
@@ -12,7 +12,8 @@
var/datum/chemical_reaction/drinks/CR = new path()
drink_recipes[path] = list("Result" = CR.name,
"ResAmt" = CR.result_amount,
"Reagents" = CR.required_reagents)
"Reagents" = CR.required_reagents,
"Catalysts" = CR.catalysts)
qdel(CR)
//////////////////////// FOOD
@@ -30,8 +31,10 @@
"Result" = "[res.name]",
"ResAmt" = "1",
"Reagents" = R.reagents,
"Catalysts" = list(),
"Fruit" = R.fruit,
"Ingredients" = R.items,
"Coating" = R.coating,
"Appliance" = R.appliance,
"Image" = result_icon
)
@@ -45,6 +48,7 @@
food_recipes[path] = list("Result" = CR.name,
"ResAmt" = CR.result_amount,
"Reagents" = CR.required_reagents,
"Catalysts" = CR.catalysts,
"Fruit" = list(),
"Ingredients" = list(),
"Image" = null)
@@ -54,8 +58,11 @@
//Items needs further processing into human-readability.
for(var/Rp in food_recipes)
var/working_ing_list = list()
food_recipes[Rp]["has_coatable_items"] = FALSE
for(var/I in food_recipes[Rp]["Ingredients"])
var/atom/ing = new I()
if(istype(ing, /obj/item/weapon/reagent_containers/food/snacks)) // only subtypes of this have a coating variable and are checked for it (fruit are a subtype of this, so there's a check for them too later)
food_recipes[Rp]["has_coatable_items"] = TRUE
//So now we add something like "Bread" = 3
if(ing.name in working_ing_list)
@@ -64,6 +71,8 @@
else
working_ing_list[ing.name] = 1
if(LAZYLEN(food_recipes[Rp]["Fruit"]))
food_recipes[Rp]["has_coatable_items"] = TRUE
food_recipes[Rp]["Ingredients"] = working_ing_list
//Reagents can be resolved to nicer names as well
@@ -77,6 +86,15 @@
var/amt = food_recipes[Rp]["Reagents"][rid]
food_recipes[Rp]["Reagents"] -= rid
food_recipes[Rp]["Reagents"][R_name] = amt
for(var/rid in food_recipes[Rp]["Catalysts"])
var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid]
if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran.
log_runtime(EXCEPTION("Food \"[Rp]\" had an invalid RID: \"[rid]\"! Check your reagents list for a missing or mistyped reagent!"))
continue // This allows the dump to still continue, and it will skip the invalid recipes.
var/R_name = Rd.name
var/amt = food_recipes[Rp]["Catalysts"][rid]
food_recipes[Rp]["Catalysts"] -= rid
food_recipes[Rp]["Catalysts"][R_name] = amt
for(var/Rp in drink_recipes)
for(var/rid in drink_recipes[Rp]["Reagents"])
var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid]
@@ -87,6 +105,15 @@
var/amt = drink_recipes[Rp]["Reagents"][rid]
drink_recipes[Rp]["Reagents"] -= rid
drink_recipes[Rp]["Reagents"][R_name] = amt
for(var/rid in drink_recipes[Rp]["Catalysts"])
var/datum/reagent/Rd = SSchemistry.chemical_reagents[rid]
if(!Rd) // Leaving this here in the event that if rd is ever invalid or there's a recipe issue, it'll be skipped and recipe dumps can still be ran.
log_runtime(EXCEPTION("Food \"[Rp]\" had an invalid RID: \"[rid]\"! Check your reagents list for a missing or mistyped reagent!"))
continue // This allows the dump to still continue, and it will skip the invalid recipes.
var/R_name = Rd.name
var/amt = drink_recipes[Rp]["Catalysts"][rid]
drink_recipes[Rp]["Catalysts"] -= rid
drink_recipes[Rp]["Catalysts"][R_name] = amt
//We can also change the appliance to its proper name.
for(var/Rp in food_recipes)
@@ -174,6 +201,20 @@
if(pretty_ing != "")
html += "<li><b>Ingredients:</b> [pretty_ing]</li>"
//Coating
if(!food_recipes[Rp]["has_coatable_items"])
html += "<span class = \"coating coating_not_applicable\"><li><b>Coating:</b> N/A, no coatable items</li></span>"
// css can be used to style or hide these depending on the class. This has two classes
// coating and coating_not_applicable, which can each have styles applied.
else if(food_recipes[Rp]["Coating"] == -1)
html += "<span class = \"coating coating_any_coating\"><li><b>Coating:</b> Optionally, any coating</li></span>"
else if(isnull(food_recipes[Rp]["Coating"]))
html += "<span class = \"coating coating_uncoated\"><li><b>Coating:</b> Must be uncoated</li></span>"
else
var/coatingtype = food_recipes[Rp]["Coating"]
var/datum/reagent/coating = new coatingtype()
html += "<span class = \"coating coating_specific_coating\"><li><b>Coating:</b> [coating.name]</li></span>"
//For each fruit
var/pretty_fru = ""
count = 0
@@ -192,6 +233,15 @@
if(pretty_rea != "")
html += "<li><b>Mix in:</b> [pretty_rea]</li>"
//For each catalyst
var/pretty_cat = ""
count = 0
for(var/cat in food_recipes[Rp]["Catalysts"])
pretty_cat += "[count == 0 ? "" : ", "][food_recipes[Rp]["Catalysts"][cat]]u [cat]"
count++
if(pretty_cat != "")
html += "<li><b>Catalysts:</b> [pretty_cat]</li>"
//Close ingredients
html += "</ul></td>"
//Close this row
@@ -230,6 +280,15 @@
if(pretty_rea != "")
html += "<li><b>Mix together:</b> [pretty_rea]</li>"
//For each catalyst
var/pretty_cat = ""
count = 0
for(var/cat in drink_recipes[Rp]["Catalysts"])
pretty_cat += "[count == 0 ? "" : ", "][drink_recipes[Rp]["Catalysts"][cat]]u [cat]"
count++
if(pretty_cat != "")
html += "<li><b>Catalysts:</b> [pretty_cat]</li>"
html += "<li>Makes [drink_recipes[Rp]["ResAmt"]]u</li>"
//Close reagents
+1
View File
@@ -406,6 +406,7 @@ datum/unarmed_attack/holopugilism/unarmed_override(var/mob/living/carbon/human/u
desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!"
icon = 'icons/obj/monitors.dmi'
icon_state = "auth_off"
layer = ABOVE_WINDOW_LAYER
var/ready = 0
var/area/currentarea = null
var/eventstarted = 0
+1 -3
View File
@@ -6,6 +6,7 @@
desc = "A virtual map of the surrounding station."
icon = 'icons/obj/machines/stationmap.dmi'
icon_state = "station_map"
layer = ABOVE_WINDOW_LAYER
anchored = 1
density = 0
use_power = USE_POWER_IDLE
@@ -19,9 +20,6 @@
var/light_range_on = 2
light_color = "#64C864"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
var/mob/watching_mob = null
var/image/small_station_map = null
var/image/floor_markings = null
+30 -1
View File
@@ -1,3 +1,7 @@
//Variables to make certain things work. Consider sending upstream.
/datum/seed
var/ai_mob_product = 0 //This variable determines whether or not a mob product is meant to be ai-controlled. If set to 0, mob products die without a player to control them.
//////CHOMP PLANTS//////
/datum/seed/soybean/sapbean
@@ -150,13 +154,38 @@
set_trait(TRAIT_WATER_CONSUMPTION, 6)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25)
/datum/seed/pitcher_plant //Pitcher plant
name = "pitcher plant"
seed_name = "pitcher plant"
seed_noun = "pits"
display_name = "pitcher shoots"
can_self_harvest = 1
apply_color_to_mob = FALSE
has_mob_product = /mob/living/simple_mob/vore/pitcher_plant
ai_mob_product = 1
/datum/seed/pitcher_plant/New() //No custom icons yet. No spread trait yet even though pitcher fruit can be planted outside of a tray as I've not tied that to hydroponics code.
..()
set_trait(TRAIT_IMMUTABLE,1)
set_trait(TRAIT_CARNIVOROUS,1)
set_trait(TRAIT_MATURATION,8)
set_trait(TRAIT_PRODUCTION,6)
set_trait(TRAIT_WATER_CONSUMPTION,6)
set_trait(TRAIT_YIELD,1)
set_trait(TRAIT_POTENCY,10)
set_trait(TRAIT_PRODUCT_ICON,"corn")
set_trait(TRAIT_PRODUCT_COLOUR,"#a839a2")
set_trait(TRAIT_PLANT_COLOUR,"#5b6f43")
set_trait(TRAIT_PLANT_ICON,"ambrosia")
/datum/seed/hardlightseed //WIP: havent ported the mob and such yet, best someone more keen on these mobs does it - Jack
name = "Type NULL Hardlight Generator"
seed_name = "Biomechanical Hardlight generator seed"
display_name = "Biomechanical Hardlight stem"
mutants = null
can_self_harvest = 1
has_mob_product = null
has_mob_product = /mob/living/simple_mob/animal/synx/ai/pet/holo
ai_mob_product = 1
/datum/seed/hardlightseed/New()
..()
+1 -1
View File
@@ -1,7 +1,7 @@
// The following procs are used to grab players for mobs produced by a seed (mostly for dionaea).
/datum/seed/proc/handle_living_product(var/mob/living/host)
if(!host || !istype(host)) return
if(!host || !istype(host) || ai_mob_product) return //CHOMPedit: ai_mob_product var to allow ai mobs to spawn from plants.
if(apply_color_to_mob)
host.color = traits[TRAIT_PRODUCT_COLOUR]
+4 -1
View File
@@ -1,3 +1,6 @@
/obj/item/seeds/teaseed
seed_type = "tea"
seed_type = "tea"
/obj/item/seeds/pitcherseed
seed_type = "pitcher plant"
+3 -1
View File
@@ -49,6 +49,7 @@
/obj/item/seeds/shrinkshroom = 3,
/obj/item/seeds/megashroom = 3)
//CHOMPedit: adds pitcherseed
/obj/machinery/seed_storage/xenobotany
name = "Xenobotany seed storage"
scanner = list("stats", "produce", "soil", "temperature", "light")
@@ -106,4 +107,5 @@
/obj/item/seeds/whitebeetseed = 3,
/obj/item/seeds/shrinkshroom = 3,
/obj/item/seeds/megashroom = 3,
/obj/item/seeds/lustflower = 2)
/obj/item/seeds/lustflower = 2,
/obj/item/seeds/pitcherseed = 3)
@@ -127,6 +127,15 @@
child.anchored = 1
child.update_icon()
//CHOMPedit start: Pitcher plant spawning
if((seed.get_trait(TRAIT_POTENCY)) >= 70) //Random event spacevines have 70 potency minimum. Should guarantee this always triggers on spacevines.
var/mob/living/pitcher
if(!seed.get_trait(TRAIT_CARNIVOROUS) && prob(2)) //Check for canivorous or this could call if prob(10) above fails.
pitcher = new /mob/living/simple_mob/vore/pitcher_plant(src.loc)
pitcher.nutrition = 0 //With 0 nutrition, vine-spawned pitchers should die after ~10 minutes
pitcher.adjustToxLoss(170) //Reduce health, 200 is excessive when a lot of these are spawning.
//CHOMPedit end
//see if anything is there
for(var/thing in child.loc)
if(thing != child && istype(thing, /obj/effect/plant))
+20
View File
@@ -1,3 +1,5 @@
#define AGE_MOD_MAX 10 //CHOMPedit: Define for age_mod sanity check as a define to allow for easy tweaking.
/obj/machinery/portable_atmospherics/hydroponics
name = "hydroponics tray"
desc = "A tray usually full of fluid for growing plants."
@@ -29,6 +31,7 @@
var/toxins = 0 // Toxicity in the tray?
var/mutation_level = 0 // When it hits 100, the plant mutates.
var/tray_light = 1 // Supplied lighting.
var/age_mod = 0 //CHOMPedit: Variable for chems which speed up plant growth. On average, every 3 age mod reduces growing time by 2.5 minutes.
// Mechanical concerns.
var/health = 0 // Plant health.
@@ -132,6 +135,12 @@
"mutagen" = 15
)
//CHOMPedit: Reagents which double plant growth speed.
var/static/list/age_reagents = list(
"pitcher_nectar" = 1
)
//CHOMPedit end
/obj/machinery/portable_atmospherics/hydroponics/AltClick(var/mob/living/user)
if(!istype(user))
return
@@ -286,6 +295,11 @@
else if(toxic_reagents[R.id])
toxins += toxic_reagents[R.id] * reagent_total
//CHOMPedit: Agents which speed up plant growth
if(age_reagents[R.id])
age_mod += age_reagents[R.id] * reagent_total
//CHOMPedit end
//Handle some general level adjustments. These values are independent of plants existing.
if(weedkiller_reagents[R.id])
weedlevel -= weedkiller_reagents[R.id] * reagent_total
@@ -337,6 +351,7 @@
age = 0
sampled = 0
mutation_mod = 0
age_mod = 0 //CHOMPedit
check_health()
return
@@ -355,6 +370,7 @@
age = 0
yield_mod = 0
mutation_mod = 0
age_mod = 0 //CHOMPedit
to_chat(user, "You remove the dead plant.")
lastproduce = 0
@@ -371,6 +387,7 @@
dead = 0
age = 0
age_mod = 0 //CHOMPedit
health = seed.get_trait(TRAIT_ENDURANCE)
lastcycle = world.time
harvest = 0
@@ -447,6 +464,7 @@
pestlevel = max(0,min(pestlevel,10))
weedlevel = max(0,min(weedlevel,10))
toxins = max(0,min(toxins,10))
age_mod = max(0,min(age_mod,AGE_MOD_MAX)) //CHOMPedit: age_mod sanity check
/obj/machinery/portable_atmospherics/hydroponics/proc/mutate_species()
@@ -682,3 +700,5 @@
closed_system = !closed_system
to_chat(user, "You [closed_system ? "close" : "open"] the tray's lid.")
update_icon()
#undef AGE_MOD_MAX //CHOMPedit
@@ -38,7 +38,11 @@
return
// Advance plant age.
if(prob(30)) age += 1 * HYDRO_SPEED_MULTIPLIER
if(prob(30)) //CHOMPedit start: I have to push the age increase down for a line for this to work with the compiler.
age += 1 * HYDRO_SPEED_MULTIPLIER
if(age_mod >= 1) //Age reagents double the speed of plant growth in sufficient quantities
age += 1 * HYDRO_SPEED_MULTIPLIER
age_mod -= 1 //CHOMPedit end
//Highly mutable plants have a chance of mutating every tick.
if(seed.get_trait(TRAIT_IMMUTABLE) == -1)
@@ -8,6 +8,7 @@
name = "production machine console"
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "console"
layer = ABOVE_WINDOW_LAYER
density = TRUE
anchored = TRUE
+1
View File
@@ -4,6 +4,7 @@
name = "stacking machine console"
icon = 'icons/obj/machines/mining_machines_vr.dmi' // VOREStation Edit
icon_state = "console"
layer = ABOVE_WINDOW_LAYER
density = 1
anchored = 1
var/obj/machinery/mineral/stacking_machine/machine = null
+10
View File
@@ -134,6 +134,16 @@
"roar", "hyaa", "ma", "ha", "ya", "shi", "yo", "go"
)
/datum/language/spacer
name = LANGUAGE_SPACER
desc = "A rough pidgin-language comprised of Tradeband, Gutter, and Sol Common used by various space-born communities unique to Humanity."
key = "J"
syllables = list(
"ada", "zir", "bian", "ach", "usk", "ado", "ich", "cuan", "iga", "qing", "le", "que", "ki", "qaf", "dei", "eta"
)
colour = "spacer"
machine_understands = TRUE
/datum/language/unathi
flags = 0
/datum/language/tajaran
@@ -21,6 +21,7 @@
xeno_harm_strength = 9
req_one_access = list(access_research, access_robotics)
botcard_access = list(access_research, access_robotics, access_xenobiology, access_xenoarch, access_tox, access_tox_storage, access_maint_tunnels)
retaliates = FALSE
var/xeno_stun_strength = 6
/mob/living/bot/secbot/ed209/slime/update_icons()
+3 -1
View File
@@ -24,6 +24,7 @@
var/declare_arrests = FALSE // If true, announces arrests over sechuds.
var/threat = 0 // How much of a threat something is. Set upon acquiring a target.
var/attacked = FALSE // If true, gives the bot enough threat assessment to attack immediately.
var/retaliates = TRUE //If this type of secbot should retaliate at all - so that slime securitrons don't go ballistic the second they get glomped.
var/is_ranged = FALSE
var/awaiting_surrender = 0
@@ -64,6 +65,7 @@
desc = "A little security robot, with a slime baton subsituted for the regular one."
default_icon_state = "slimesecbot"
stun_strength = 10 // Slimebatons aren't meant for humans.
retaliates = FALSE // No, you're not allowed to beat the slimes to death just because they scratched you.
xeno_harm_strength = 9 // Weaker than regular slimesky but they can stun.
baton_glow = "#33CCFF"
@@ -194,7 +196,7 @@
..()
/mob/living/bot/secbot/proc/react_to_attack(mob/attacker)
if(!on) // We don't want it to react if it's off
if(!on || !retaliates) // We don't want it to react if it's off or doesn't care
return
if(!target)
@@ -694,13 +694,11 @@
if(!muzzled)
message = "[species.scream_verb]!"
m_type = 2
//CHOMPStation Edit Start. Uncommented block. Why was it commented in the first place?
//The offending content was commented out as well anyway.
if(get_gender() == FEMALE)
playsound(src, "[species.female_scream_sound]", 80, 1)
if(get_gender() == FEMALE) //CHOMPedit start : fixed scream sounds by giving them the ability to grab from a list, and a way to turn them off in preferences
playsound(src, pick(species.female_scream_sound), 80, preference = /datum/client_preference/emote_noises)
else
playsound(src, "[species.male_scream_sound]", 80, 1) //default to male screams if no gender is present.
//CHOMPStation Edit End.
playsound(src, pick(species.male_scream_sound), 80, preference = /datum/client_preference/emote_noises) //default to male screams if no gender is present.
//CHOMPedit end
else
message = "makes a very loud noise."
m_type = 2
@@ -269,3 +269,17 @@
set desc = "Switch tail layer on top."
tail_alt = !tail_alt
update_tail_showing()
/mob/living/carbon/human/verb/hide_wings_vr()
set name = "Show/Hide wings"
set category = "IC"
set desc = "Hide your wings, or show them if you already hid them."
wings_hidden = !wings_hidden
update_wing_showing()
var/message = ""
if(!wings_hidden)
message = "reveals their wings!"
else
message = "hides their wings."
visible_message("[src] [message]")
@@ -1,2 +1,4 @@
/mob/living/carbon/human
var/gender_change_cooldown = 0 // A cooldown for gender and gender indentify changing procs to make it easy to avoid spam of gender change
var/gender_change_cooldown = 0 // A cooldown for gender and gender indentify changing procs to make it easy to avoid spam of gender change
var/loneliness_stage = 0
var/next_loneliness_time = 0
@@ -9,6 +9,7 @@
var/impersonate_bodytype //For impersonating a bodytype
var/ability_flags = 0 //Shadekin abilities/potentially other species-based?
var/sensorpref = 5 //Suit sensor loadout pref
var/wings_hidden = FALSE
/mob/living/carbon/human/proc/shadekin_get_energy()
var/datum/species/shadekin/SK = species
@@ -48,4 +49,4 @@
if(!istype(SK))
return 0
SK.set_energy(src, SK.get_energy(src) + amount)
SK.set_energy(src, SK.get_energy(src) + amount)
+13 -1
View File
@@ -950,7 +950,14 @@
take_overall_damage(1,1)
else //heal in the dark
heal_overall_damage(1,1)
//CHOMPEdit Begin
if(species.photosynthesizing && nutrition < 1000)
var/light_amount = 0
if(isturf(loc))
var/turf/T = loc
light_amount = T.get_lumcount() / 10
adjust_nutrition(light_amount)
//CHOMPEdit End
// nutrition decrease
if (nutrition > 0 && stat != DEAD)
var/nutrition_reduction = species.hunger_factor
@@ -958,6 +965,11 @@
for(var/datum/modifier/mod in modifiers)
if(!isnull(mod.metabolism_percent))
nutrition_reduction *= mod.metabolism_percent
//CHOMPEdit Begin
if(nutrition > 1000 && species.grows && size_multiplier < RESIZE_HUGE)
nutrition_reduction *= 5
resize(min(size_multiplier+0.004,RESIZE_HUGE))
//CHOMPEdit End
adjust_nutrition(-nutrition_reduction)
if(noisy == TRUE && nutrition < 250 && prob(10)) //VOREStation edit for hunger noises.
@@ -12,6 +12,9 @@
has_organ = list()
siemens_coefficient = 0
male_scream_sound = null //CHOMPedit It has no mouth yet it must scream
female_scream_sound = null //CHOMPedit
blood_color = "#CCCCCC"
flesh_color = "#AAAAAA"
@@ -15,6 +15,9 @@
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = null
male_scream_sound = null //CHOMPedit Screaming skeletons would be funny, but needs better sounds
female_scream_sound = null //CHOMPedit
show_ssd = null
blood_volume = null
@@ -22,6 +22,9 @@
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/shadekin, /datum/unarmed_attack/bite/sharp/shadekin)
rarity_value = 15 //INTERDIMENSIONAL FLUFFERS
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
siemens_coefficient = 0
darksight = 10
@@ -75,8 +75,8 @@
//Soundy emotey things.
var/scream_verb = "screams"
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
var/female_scream_sound //= 'sound/goonstation/voice/female_scream.ogg' Removed due to licensing, replace!
var/male_scream_sound = list('sound/effects/mob_effects/m_scream_1.ogg','sound/effects/mob_effects/m_scream_2.ogg','sound/effects/mob_effects/m_scream_3.ogg','sound/effects/mob_effects/m_scream_4.ogg') //CHOMpedit start : Added tgstation screams
var/female_scream_sound = list('sound/effects/mob_effects/f_scream_1.ogg','sound/effects/mob_effects/f_scream_2.ogg','sound/effects/mob_effects/f_scream_3.ogg','sound/effects/mob_effects/f_scream_4.ogg') //CHOMPedit end
var/male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
var/female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg')
var/male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'
@@ -0,0 +1,10 @@
/datum/species
var/list/env_traits = list()
var/dirtslip = FALSE
var/photosynthesizing = FALSE
var/grows = FALSE
/datum/species/handle_environment_special(var/mob/living/carbon/human/H)
for(var/datum/trait/env_trait in env_traits)
env_trait.handle_environment_special(H)
return
@@ -16,6 +16,9 @@
base_species = SPECIES_ALRAUNE
selects_bodytype = TRUE
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
body_temperature = T20C
breath_type = "oxygen"
poison_type = "phoron"
@@ -22,6 +22,9 @@
you select and set this species as your species. Please look at the VORE tab if you select this species."
catalogue_data = list(/datum/category_item/catalogue/fauna/custom_species)
male_scream_sound = null //CHOMPedit These are going to be a hassle for custom species if not null
female_scream_sound = null //CHOMPedit
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 18
max_age = 200
@@ -11,6 +11,9 @@
spawn_flags = SPECIES_IS_RESTRICTED
siemens_coefficient = 0
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
assisted_langs = list()
breath_type = null
@@ -27,7 +27,8 @@
darksight = 5
reagent_tag = IS_GREY
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
min_age = 18
max_age = 130
@@ -22,6 +22,9 @@
tail = "chimptail"
fire_icon_state = "monkey"
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws)
inherent_verbs = list(/mob/living/proc/ventcrawl)
hud_type = /datum/hud_data/monkey
@@ -6,6 +6,8 @@
tail = null //The tail is part of its body due to tail using the "icons/effects/species.dmi" file. It must be null, or they'll have a chimp tail.
greater_form = "Akula"
default_language = "Skrellian" //Closest we have.
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
/datum/species/monkey/sergal
name = SPECIES_MONKEY_SERGAL
@@ -14,6 +16,8 @@
deform = 'icons/mob/human_races/monkeys/r_sergaling_vr.dmi'
tail = null
default_language = LANGUAGE_SAGARU
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
/datum/species/monkey/sparra
name = SPECIES_MONKEY_NEVREAN
@@ -23,6 +27,8 @@
icobase = 'icons/mob/human_races/monkeys/r_sparra_vr.dmi'
deform = 'icons/mob/human_races/monkeys/r_sparra_vr.dmi'
default_language = LANGUAGE_BIRDSONG
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
/* Example from Polaris code
@@ -52,6 +58,8 @@
flesh_color = "#966464"
base_color = "#000000"
tail = null
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
//INSERT CODE HERE SO MONKEYS CAN BE SPAWNED.
//Also, M was added to the end of the spawn names to signify that it's a monkey, since some names were conflicting.
@@ -49,6 +49,9 @@ var/datum/species/shapeshifter/promethean/prometheans
economic_modifier = 3
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
gluttonous = 1
virus_immune = 1
blood_volume = 560
@@ -26,6 +26,9 @@
breath_type = null
poison_type = null
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
virus_immune = 1
blood_volume = 0
min_age = 18
@@ -80,6 +80,8 @@
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN
body_temperature = 270
cold_level_1 = 180 //Default 260
cold_level_2 = 130 //Default 200
cold_level_3 = 70 //Default 120
@@ -76,6 +76,9 @@
max_age = 260
economic_modifier = 10
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "A heavily reptillian species, Unathi hail from the \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, inhospitable \
@@ -191,6 +194,9 @@
economic_modifier = 10
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "The Tajaran are a mammalian species resembling roughly felines, hailing from Meralar in the Rarkajar system. \
While reaching to the stars independently from outside influences, the humans engaged them in peaceful trade contact \
and have accelerated the fledgling culture into the interstellar age. Their history is full of war and highly fractious \
@@ -198,7 +204,7 @@
home worlds and speak a variety of languages, especially Siik and Akhani."
catalogue_data = list(/datum/category_item/catalogue/fauna/tajaran)
body_temperature = 320.15 //Even more cold resistant, even more flammable
body_temperature = 280.15 //Even more cold resistant, even more flammable
cold_level_1 = 200 //Default 260
cold_level_2 = 140 //Default 200
@@ -235,7 +241,7 @@
"Your overheated skin itches."
)
cold_discomfort_level = 275
cold_discomfort_level = 215
has_organ = list( //No appendix.
O_HEART = /obj/item/organ/internal/heart,
@@ -280,6 +286,9 @@
economic_modifier = 10
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
darksight = 4
flash_mod = 1.2
chemOD_mod = 0.9
@@ -358,6 +367,9 @@
min_age = 16
max_age = 90
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "The Zaddat are an Unathi client race only recently introduced to SolGov space. Having evolved on \
the high-pressure and post-apocalyptic world of Xohok, Zaddat require an environmental suit called a Shroud \
to survive in usual planetary and station atmospheres. Despite these restrictions, worsening conditions on \
@@ -470,6 +482,9 @@
economic_modifier = 10
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \
there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \
@@ -38,6 +38,9 @@
min_age = 18
max_age = 80
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Some amalgamation of different species from across the universe,with extremely unstable DNA, making them unfit for regular cloners. \
Widely known for their voracious nature and violent tendencies when stressed or left unfed for long periods of time. \
Most, if not all chimeras possess the ability to undergo some type of regeneration process, at the cost of energy."
@@ -381,6 +384,9 @@
min_age = 18
max_age = 80
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Vasilissans are a tall, lanky, spider like people. \
Each having four eyes, an extra four, large legs sprouting from their back, and a chitinous plating on their body, and the ability to spit webs \
from their mandible lined mouths. They are a recent discovery by Nanotrasen, only being discovered roughly seven years ago. \
@@ -451,6 +457,9 @@
min_age = 18
max_age = 200
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Big buff werewolves. These are a limited functionality event species that are not balanced for regular gameplay. Adminspawn only."
wikilink="N/A"
@@ -19,6 +19,9 @@
min_age = 18
max_age = 110
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "There are two subspecies of Sergal; Southern and Northern. Northern sergals are a highly aggressive race \
that lives in the plains and tundra of their homeworld. They are characterized by long, fluffy fur bodies with cold colors; \
usually with white abdomens, somewhat short ears, and thick faces. Southern sergals are much more docile and live in the \
@@ -85,6 +88,9 @@
min_age = 18
max_age = 110
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "The Akula are a species of amphibious humanoids like the Skrell, but have an appearance very similar to that of a shark. \
They were first discovered as a primitive race of underwater dwelling tribal creatures by the Skrell. At first they were not believed \
to be noteworthy, but the Akula proved to be such swift and clever learners that the Skrell reclassified them as sentients. Allegedly, \
@@ -132,6 +138,9 @@
min_age = 18
max_age = 110
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Nevreans are a race of avian and dinosaur-like creatures living on Tal. They belong to a group of races that hails from Eltus, \
in the Vilous system. Unlike sergals whom they share a star system with, their species is a very peaceful one. They possess remarkable \
intelligence and very skillful hands that are put use for constructing precision instruments, but tire-out fast when repeatedly working \
@@ -174,6 +183,9 @@
min_age = 18
max_age = 110
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "The fox-like Zorren are native to Virgo-Prime, however there are two distinct varieties of Zorren one with large ears and shorter fur, \
and the other with longer fur that is a bit more vibrant. The long-eared, short-furred Zorren have come to be known as Flatland Zorren as that \
is where most of their settlements are located. The Flatland Zorren are somewhat tribal and shamanistic as they have only recently started to be \
@@ -221,6 +233,9 @@
color_mult = 1
inherent_verbs = list(/mob/living/proc/shred_limb, /mob/living/carbon/human/proc/lick_wounds)
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \
dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \
culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, and utilitarianism dominates their lifestyles \
@@ -386,6 +401,9 @@ datum/species/harpy
base_color = "#EECEB3"
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "An Avian species, coming from a distant planet, the Rapalas are the very proud race.\
Sol researchers have commented on them having a very close resemblance to the mythical race called 'Harpies',\
who are known for having massive winged arms and talons as feet. They've been clocked at speeds of over 35 miler per hour chasing the planet's many fish-like fauna.\
@@ -413,6 +431,8 @@ datum/species/harpy
deform = 'icons/mob/human_races/r_shadekin_vr.dmi'
tail = "tail"
icobase_tail = 1
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Very little is known about these creatures. They appear to be largely mammalian in appearance. \
Seemingly very rare to encounter, there have been widespread myths of these creatures the galaxy over, \
but next to no verifiable evidence to their existence. However, they have recently been more verifiably \
@@ -537,6 +557,9 @@ datum/species/harpy
min_age = 18
max_age = 80
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
//primitive_form = "" //We don't have fennec-monkey sprites.
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
@@ -568,6 +591,9 @@ datum/species/harpy
min_age = 18
max_age = 80
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
blurb = "Xenomorphs hybrids are a mixture of xenomorph DNA and some other humanoid species. \
Xenomorph hyrids mostly have had had their natural aggression removed due to the gene modification process \
although there are some exceptions, such as when they are harmed. Most xenomorph hybrids are female, due to their natural xenomorph genes, \
@@ -0,0 +1,123 @@
/datum/trait/hollow
excludes = list(/datum/trait/densebones)
/datum/trait/slipperydirt
name = "Dirt Vulnerability"
desc = "Even the tiniest particles of dirt give you uneasy footing, even through several layers of footwear."
cost = -5
var_changes = list("dirtslip" = TRUE)
/datum/trait/lonely
name = "Minor loneliness vulnerability"
desc = "You're very prone to loneliness! Being alone for extended periods of time causes adverse effects. Most mobs will cure this loneliness as long as they aren't hostile."
var/warning_cap = 400
var/only_people = FALSE
var/hallucination_cap = 25
var/escalation_speed = 0.8
cost = -2
special_env = TRUE
excludes = list(/datum/trait/lonely/major)
/datum/trait/lonely/major
name = "Major loneliness vulnerability"
desc = "You're extremely prone to loneliness! Being alone for extended periods of time causes adverse effects. Most mobs won't be enough to cure this loneliness, you need other social beings."
warning_cap = 300
hallucination_cap = 50
escalation_speed = 1.3
only_people = TRUE
cost = -5
special_env = TRUE
excludes = list(/datum/trait/lonely)
/datum/trait/lonely/proc/check_mob_company(var/mob/living/carbon/human/H,var/mob/living/M)
if(only_people && !istype(M, /mob/living/carbon) && !istype(M, /mob/living/silicon/robot))
return 0
if(M == H || M.stat == DEAD || M.invisibility > H.see_invisible)
return 0
if(only_people && !M.ckey)
return 0
if(M.faction == "neutral" || M.faction == H.faction)
if(H.loneliness_stage > 0)
H.loneliness_stage -= 4
if(H.loneliness_stage < 0)
H.loneliness_stage = 0
if(world.time >= H.next_loneliness_time)
to_chat(H, "The nearby company calms you down...")
H.next_loneliness_time = world.time+500
return 1
else
if(M.vore_organs)
for(var/obj/belly/B in M.vore_organs)
for(var/mob/living/content in B.contents)
if(istype(content))
check_mob_company(H,content)
return 0
/datum/trait/lonely/handle_environment_special(var/mob/living/carbon/human/H)
spawn(0)
// If they're dead or unconcious they're a bit beyond this kind of thing.
if(H.stat)
return
// No point processing if we're already stressing the hell out.
if(H.hallucination >= hallucination_cap && H.loneliness_stage >= warning_cap)
return
// Vored? Not gonna get frightened.
if(isbelly(H.loc))
if(H.loneliness_stage > 0)
H.loneliness_stage -= 4
return
if(istype(H.loc, /obj/item/weapon/holder))
if(H.loneliness_stage > 0)
H.loneliness_stage -= 4
return
// Check for company.
for(var/mob/living/M in viewers(H))
if(check_mob_company(H,M))
return
if(H.vore_organs)
for(var/obj/belly/B in H.vore_organs)
for(var/mob/living/content in B.contents)
if(istype(content))
if(check_mob_company(H,content))
return
for(var/obj/item/weapon/holder/micro/M in range(1, H))
if(H.loneliness_stage > 0)
H.loneliness_stage -= 4
if(H.loneliness_stage < 0)
H.loneliness_stage = 0
if(world.time >= H.next_loneliness_time)
to_chat(H, "[M] calms you down...")
H.next_loneliness_time = world.time+500
for(var/obj/effect/overlay/aiholo/A in range(5, H))
if(H.loneliness_stage > 0)
H.loneliness_stage -= 4
if(H.loneliness_stage < 0)
H.loneliness_stage = 0
if(world.time >= H.next_loneliness_time)
to_chat(H, "[A] calms you down...")
H.next_loneliness_time = world.time+500
// No company? Suffer :(
if(H.loneliness_stage < warning_cap)
H.loneliness_stage = min(warning_cap,H.loneliness_stage+escalation_speed)
handle_loneliness(H)
if(H.loneliness_stage >= warning_cap && H.hallucination < hallucination_cap)
H.hallucination = min(hallucination_cap,H.hallucination+2.5*escalation_speed)
/datum/trait/lonely/proc/handle_loneliness(var/mob/living/carbon/human/H)
var/ms = ""
if(H.loneliness_stage == escalation_speed)
ms = "Well.. No one is around you anymore..."
if(H.loneliness_stage >= 50)
ms = "You begin to feel alone..."
if(H.loneliness_stage >= 250)
ms = "[pick("You don't think you can last much longer without some visible company!", "You should go find someone!")]"
if(H.stuttering < hallucination_cap)
H.stuttering += 5
if(H.loneliness_stage >= warning_cap)
ms = "<span class='danger'><b>[pick("Where are the others?", "Please, there has to be someone nearby!", "I don't want to be alone!")]</b></span>"
if(world.time < H.next_loneliness_time)
return
if(ms != "")
to_chat(H, ms)
H.next_loneliness_time = world.time+500
@@ -14,4 +14,10 @@
/datum/trait/succubus_bite/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
H.verbs |= /mob/living/proc/succubus_bite
H.verbs |= /mob/living/proc/succubus_bite
/datum/trait/nutritiongrow
name = "Growing"
desc = "After you consume enough nutrition, you start to slowly grow while metabolizing nutrition faster."
cost = 0
var_changes = list("grows" = TRUE)
@@ -100,6 +100,12 @@
cost = 2
var_changes = list("unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp, /datum/unarmed_attack/bite/sharp/numbing))
/datum/trait/fangs
name = "Numbing Fangs"
desc = "Provides fangs that makes the person bit unable to feel their body or pain."
cost = 1
var_changes = list("unarmed_types" = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite/sharp/numbing))
/datum/trait/minor_brute_resist
name = "Minor Brute Resist"
desc = "Adds 10% resistance to brute damage sources."
@@ -159,13 +165,13 @@
desc = "You've drunk so much that most booze doesn't even faze you. It takes something like a Pan-Galactic or a pint of Deathbell for you to even get slightly buzzed. You may wish to note this down in your medical records."
cost = 2
var_changes = list("alcohol_mod" = 0.25)
/datum/trait/pain_tolerance_basic
name = "Pain Tolerant"
desc = "You're a little more resistant to pain than most, and experience 10% less pain from from all sources."
cost = 1
var_changes = list("pain_mod" = 0.9)
/datum/trait/pain_tolerance_advanced
name = "High Pain Tolerance"
desc = "You are noticeably more resistant to pain than most, and experience 20% less pain from all sources."
@@ -247,13 +253,15 @@
cost = 2
var_changes = list("cold_level_1" = 200, "cold_level_2" = 150, "cold_level_3" = 90, "breath_cold_level_1" = 180, "breath_cold_level_2" = 100, "breath_cold_level_3" = 60, "cold_discomfort_level" = 210, "heat_level_1" = 305, "heat_level_2" = 360, "heat_level_3" = 700, "breath_heat_level_1" = 345, "breath_heat_level_2" = 380, "breath_heat_level_3" = 780, "heat_discomfort_level" = 295)
excludes = list(/datum/trait/hotadapt)
not_for_synths = 1 // CHOMP edit
/datum/trait/hotadapt
name = "Heat-Adapted"
desc = "You are able to withstand much hotter temperatures than other species, and can even be comfortable in extremely hot environments. You are also more vulnerable to cold environments as a consequence of these adaptations."
cost = 2
var_changes = list("heat_level_1" = 420, "heat_level_2" = 460, "heat_level_3" = 1100, "breath_heat_level_1" = 440, "breath_heat_level_2" = 510, "breath_heat_level_3" = 1500, "heat_discomfort_level" = 390, "cold_level_1" = 280, "cold_level_2" = 220, "cold_level_3" = 140, "breath_cold_level_1" = 260, "breath_cold_level_2" = 240, "breath_cold_level_3" = 120, "cold_discomfort_level" = 280)
excludes = list(/datum/trait/coldadapt)
not_for_synths = 1 // CHOMP edit
// YW Addition end
/datum/trait/snowwalker
@@ -0,0 +1,37 @@
/datum/trait/linguist
name = "Master Linguist"
desc = "You are a master of languages! For whatever reason you might have, you are able to learn many more languages than others."
cost = 2
var_changes = list("num_alternate_languages" = 12)
/datum/trait/densebones
name = "Dense bones"
desc = "Your bones (or robotic limbs) are more dense or stronger then what is considered normal. It is much harder to fracture your bones, yet pain from fractures is much more intense."
cost = 2
excludes = list(/datum/trait/hollow)
/datum/trait/densebones/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
for(var/obj/item/organ/external/organ in H.organs)
if(istype(organ))
organ.min_broken_damage *= 1.5
organ.brokenpain *= 2
/datum/trait/lowpressureres
name = "Low Pressure Resistance"
desc = "Your body is more resistant to low pressures. Pretty simple."
cost = 3
var_changes = list("hazard_low_pressure" = HAZARD_LOW_PRESSURE*0.66, "warning_low_pressure" = WARNING_LOW_PRESSURE*0.66, "minimum_breath_pressure" = 16*0.66)
/datum/trait/highpressureres
name = "High Pressure Resistance"
desc = "Your body is more resistant to high pressures. Pretty simple."
cost = 3
var_changes = list("hazard_high_pressure" = HAZARD_HIGH_PRESSURE*1.5, "warning_high_pressure" = WARNING_HIGH_PRESSURE*1.5)
/datum/trait/photosynth
name = "Photosynthesis"
desc = "Your body is able to produce nutrition from being in light."
cost = 3
var_changes = list("photosynthesizing" = TRUE)
not_for_synths = 1 //Synths don't use nutrition.
@@ -0,0 +1,19 @@
/datum/trait
var/special_env = FALSE
/datum/trait/proc/handle_environment_special(var/mob/living/carbon/human/H)
return
/datum/trait/apply(var/datum/species/S,var/mob/living/carbon/human/H)
ASSERT(S)
if(var_changes)
for(var/V in var_changes)
S.vars[V] = var_changes[V]
if(special_env)
S.env_traits += src
return
/datum/trait/remove(var/datum/species/S)
ASSERT(S)
if(special_env)
S.env_traits -= src
return
@@ -10,6 +10,9 @@
hud_type = /datum/hud_data/alien
rarity_value = 3
male_scream_sound = null //CHOMPedit Note, add xenomorph screams later, shouldn't be hard
female_scream_sound = null //CHOMPedit
darksight = 10 //CHOMPedit. Added darksight
vision_flags = SEE_SELF|SEE_MOBS|SEE_TURFS //CHOMPedit trying to make xenos see properly
@@ -151,7 +151,10 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone.
M.Turn(90)
M.Scale(desired_scale_x, desired_scale_y)
M.Translate(1,-6)
if(species.icon_height == 64)//VOREStation Edit
M.Translate(13,-22)
else
M.Translate(1,-6)
layer = MOB_LAYER -0.01 // Fix for a byond bug where turf entry order no longer matters
else
M.Scale(desired_scale_x, desired_scale_y)
@@ -3,13 +3,13 @@
return
//If you are FBP with wing style and didn't set a custom one
if(synthetic && synthetic.includes_wing && !wing_style)
if((synthetic && synthetic.includes_wing && !wing_style) && !wings_hidden)
var/icon/wing_s = new/icon("icon" = synthetic.icon, "icon_state" = "wing") //I dunno. If synths have some custom wing?
wing_s.Blend(rgb(src.r_skin, src.g_skin, src.b_skin), species.color_mult ? ICON_MULTIPLY : ICON_ADD)
return image(wing_s)
//If you have custom wings selected
if(wing_style && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
if((wing_style && !(wear_suit && wear_suit.flags_inv & HIDETAIL)) && !wings_hidden)
var/icon/wing_s = new/icon("icon" = wing_style.icon, "icon_state" = flapping && wing_style.ani_state ? wing_style.ani_state : wing_style.icon_state)
if(wing_style.do_colouration)
wing_s.Blend(rgb(src.r_wing, src.g_wing, src.b_wing), wing_style.color_blend_mode)
@@ -252,7 +252,7 @@
to_chat(user, "<span class='notice'>You finish off \the [target.name], and gain some charge!</span>")
var/mob/living/silicon/robot/R = user
var/obj/item/weapon/cell/C = target
R.cell.charge += C.maxcharge / 3
R.cell.charge += C.charge / 3
water.use_charge(5)
qdel(target)
return
@@ -219,7 +219,8 @@
/obj/item/mecha_parts/part,
/obj/item/mecha_parts/micro/part, //VOREStation Edit: Allow construction of micromechs,
/obj/item/mecha_parts/mecha_equipment,
/obj/item/mecha_parts/mecha_tracking
/obj/item/mecha_parts/mecha_tracking,
/obj/item/mecha_parts/component
)
/obj/item/weapon/gripper/no_use //Used when you want to hold and put items in other things, but not able to 'use' the item
@@ -2,7 +2,7 @@
#define SYNX_UPPER_DAMAGE 6
/mob/living/simple_mob/retaliate/synx //Player controlled variant
/mob/living/simple_mob/animal/synx //Player controlled variant
//on inteligence https://synx.fandom.com/wiki/Behavior/Intelligence //keeping this here for player controlled synxes.
name = "Synx"
desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. Plain, white, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration."
@@ -13,6 +13,7 @@
icon_state = "synx_living"
icon_living = "synx_living"
icon_dead = "synx_dead"
mob_bump_flag = SIMPLE_ANIMAL //This not existing was breaking vore bump for some reason.
var/list/speak = list()
var/speak_chance = 1 //MAy have forgotten to readd that.
@@ -100,12 +101,12 @@
max_n2 = 0 //Maybe add a max
// TODO: Set a max temperature of about 20-30 above room temperatures. Synx don't like the heat.
/mob/living/simple_mob/retaliate/synx/ai //AI controlled variant
/mob/living/simple_mob/animal/synx/ai //AI controlled variant
ai_holder_type = /datum/ai_holder/simple_mob/retaliate
/mob/living/simple_mob/retaliate/synx/init_vore()
/mob/living/simple_mob/animal/synx/init_vore()
..()
var/obj/belly/B = vore_selected
//B.human_prey_swallow_time = 6 SECONDS //doesnt work
@@ -134,7 +135,7 @@
)
B.mode_flags = DM_FLAG_NUMBING //Prey are more docile when it doesn't hurt.
/mob/living/simple_mob/retaliate/synx/ai/pet/asteri/init_vore()
/mob/living/simple_mob/animal/synx/ai/pet/asteri/init_vore()
..()
var/obj/belly/B = vore_selected
B.desc = "The synx eagerly swallows you, taking you from its gullet into its long, serpentine stomach. The internals around you greedily press into your from all sides, keeping you coated in a slick coat of numbing fluids..."
@@ -158,16 +159,16 @@
"The synx's body gleefully takes what's left of your life, Asteri's usually-repressed sadism overwhelmed with a sinister satisfaction in snuffing you out as your liquefied remains gush into a bit more heft on the parasite's emaciated frame.",
)
/mob/living/simple_mob/retaliate/synx/New() //this is really cool. Should be able to ventcrawl canonicaly, contort, and make random speech.
/mob/living/simple_mob/animal/synx/New() //this is really cool. Should be able to ventcrawl canonicaly, contort, and make random speech.
//some things should be here that arent tho.
..()
verbs |= /mob/living/proc/ventcrawl
verbs |= /mob/living/simple_mob/retaliate/synx/proc/distend_stomach //to do later: sprites of stomach outside the body.
verbs |= /mob/living/simple_mob/animal/synx/proc/distend_stomach //to do later: sprites of stomach outside the body.
verbs |= /mob/living/simple_mob/proc/contort
verbs |= /mob/living/simple_mob/retaliate/synx/proc/sonar_ping
verbs |= /mob/living/simple_mob/animal/synx/proc/sonar_ping
verbs |= /mob/living/proc/shred_limb
verbs |= /mob/living/simple_mob/retaliate/synx/proc/disguise
verbs |= /mob/living/simple_mob/retaliate/synx/proc/randomspeech
verbs |= /mob/living/simple_mob/animal/synx/proc/disguise
verbs |= /mob/living/simple_mob/animal/synx/proc/randomspeech
realname = name
voices += "Garbled voice"
voices += "Unidentifiable Voice"
@@ -177,6 +178,7 @@
//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// SPECIAL ITEMS/REAGENTS !!!! ////////////////////////////
////////////////////////////////////////////////////////////////////////////////////// //keeping most of these the same except the stuff that apply to the standard synx. -lo
/*
/datum/seed/hardlightseed/
name = "Type NULL Hardlight Generator"
seed_name = "Biomechanical Hardlight generator seed"
@@ -204,7 +206,8 @@
name = "hardlightseedsx"
seed_name = "hardlightseedsx"
display_name = "Biomechanical Hardlight Generator SX"//PLant that is part mechanical part biological
has_mob_product = /mob/living/simple_mob/retaliate/synx/ai/pet/holo
has_mob_product = /mob/living/simple_mob/animal/synx/ai/pet/holo
*/ //This is defined in seed_datums_ch
/obj/item/seeds/hardlightseed/typesx
seed_type = "hardlightseedsx"
@@ -310,7 +313,7 @@
//////////////////////////////////////////////////////////////////////////////////////
// nevermind. I added any roleplay flavor weird fur mechanics to happen when you touch or attack the synx.
/mob/living/simple_mob/retaliate/synx/apply_melee_effects(var/atom/A) //Re-adding this for AI synx
/mob/living/simple_mob/animal/synx/apply_melee_effects(var/atom/A) //Re-adding this for AI synx
if(stomach_distended) //Hacky burn damage code
if(isliving(A)) //Only affect living mobs, should include silicons. This could be expanded to deal special effects to acid-vulnerable objects.
var/mob/living/L = A
@@ -345,7 +348,7 @@
/mob/living/simple_mob/retaliate/synx/hear_say(message,verb,language,fakename,isItalics,var/mob/living/speaker)
/mob/living/simple_mob/animal/synx/hear_say(message,verb,language,fakename,isItalics,var/mob/living/speaker)
. = ..()
if(!message) return
if (speaker == src) return
@@ -361,7 +364,7 @@
if(message=="Honk!")
bikehorn()
/mob/living/simple_mob/retaliate/synx/ai/pet/clown/Life()
/mob/living/simple_mob/animal/synx/ai/pet/clown/Life()
..()
if(vore_fullness)
size_multiplier = 1+(0.5*vore_fullness)
@@ -369,13 +372,13 @@
if(!vore_fullness && size_multiplier != 1)
size_multiplier = 1
update_icons()
/mob/living/simple_mob/retaliate/synx/Life()
/mob/living/simple_mob/animal/synx/Life()
..()
//mob/living/simple_mob/retaliate/synx/ai/handle_idle_speaking() //Only ai-controlled synx will randomly speak
//mob/living/simple_mob/animal/synx/ai/handle_idle_speaking() //Only ai-controlled synx will randomly speak
if(voices && prob(speak_chance/2))
randomspeech()
/mob/living/simple_mob/retaliate/synx/perform_the_nom() //Synx can only eat people if their organs are on the inside.
/mob/living/simple_mob/animal/synx/perform_the_nom() //Synx can only eat people if their organs are on the inside.
if(stomach_distended)
to_chat(src,"<span class='notice'>You can't eat people without your stomach inside of you!</span>")
return
@@ -406,7 +409,7 @@
to_chat(src,"<span class='notice'>You are now hiding.</span>")
movement_cooldown = 6
/mob/living/simple_mob/retaliate/synx/proc/disguise()
/mob/living/simple_mob/animal/synx/proc/disguise()
set name = "Toggle Form"
set desc = "Switch between amorphous and humanoid forms."
set category = "Abilities"
@@ -429,7 +432,7 @@
transformed = !transformed
update_icons()
/mob/living/simple_mob/retaliate/synx/proc/randomspeech()
/mob/living/simple_mob/animal/synx/proc/randomspeech()
set name = "speak"
set desc = "Takes a sentence you heard and says it"
set category = "Abilities"
@@ -438,7 +441,7 @@
else
usr << "<span class='warning'>YOU NEED TO HEAR THINGS FIRST, try using Ventcrawl to eevesdrop on nerds</span>"
/mob/living/simple_mob/retaliate/synx/proc/handle_mimic()
/mob/living/simple_mob/animal/synx/proc/handle_mimic()
name = pick(voices)
spawn(2)
src.say(pick(speak))
@@ -447,10 +450,10 @@
//lo- procs adjusted to mobs.
/mob/living/simple_mob/retaliate/synx
/mob/living/simple_mob/animal/synx
var/next_sonar_ping = 0
/mob/living/simple_mob/retaliate/synx/proc/sonar_ping()
/mob/living/simple_mob/animal/synx/proc/sonar_ping()
set name = "Listen In"
set desc = "Allows you to listen in to movement and noises around you."
set category = "Abilities"
@@ -499,7 +502,7 @@
/mob/living/simple_mob/retaliate/synx/proc/distend_stomach()
/mob/living/simple_mob/animal/synx/proc/distend_stomach()
set name = "Distend Stomach"
set desc = "Allows you to throw up your stomach, giving your attacks burn damage at the cost of your stomach contents going everywhere. Yuck."
set category = "Abilities"
@@ -537,7 +540,7 @@
////////////////////////////////////////
////////////////PET VERSION/////////////
////////////////////////////////////////
/mob/living/simple_mob/retaliate/synx/ai/pet
/mob/living/simple_mob/animal/synx/ai/pet
faction = "Cargonia" //Should not share a faction with those pesky non station synxes.//This is so newspaper has a failchance
name = "Bob"
desc = "A very regular pet."
@@ -546,25 +549,25 @@
glow_toggle = 1
player_msg = "You aren't supposed to be in this. Wrong mob."
/mob/living/simple_mob/retaliate/synx/ai/pet/init_vore()
/mob/living/simple_mob/animal/synx/ai/pet/init_vore()
..()
var/obj/belly/B = vore_selected
B.vore_verb = "swallow"
B.digest_burn = 1
B.digest_brute = 0
/mob/living/simple_mob/retaliate/synx/ai/pet/holo/init_vore()
/mob/living/simple_mob/animal/synx/ai/pet/holo/init_vore()
..()
var/obj/belly/B = vore_selected
B.vore_verb = "swallow"
B.digest_burn = 5
B.digest_brute = 5
/mob/living/simple_mob/retaliate/synx/ai/pet
/mob/living/simple_mob/animal/synx/ai/pet
speak_chance = 2.0666
//HONKMOTHER Code.
/*/mob/living/simple_mob/retaliate/synx/proc/honk()
/*/mob/living/simple_mob/animal/synx/proc/honk()
set name = "HONK"
set desc = "TAAA RAINBOW"
set category = "Abilities"
@@ -572,18 +575,18 @@
icon_living = "synx_pet_rainbow"
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
*/
/mob/living/simple_mob/retaliate/synx/proc/bikehorn()
/mob/living/simple_mob/animal/synx/proc/bikehorn()
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
//HOLOSEEDSPAWNCODE
/mob/living/simple_mob/retaliate/synx/ai/pet/holo/death()
/mob/living/simple_mob/animal/synx/ai/pet/holo/death()
..()
visible_message("<span class='notice'>\The [src] fades away!</span>")
var/location = get_turf(src)
new /obj/item/seeds/hardlightseed/typesx(location)
qdel(src)
/mob/living/simple_mob/retaliate/synx/ai/pet/holo/gib()
/mob/living/simple_mob/animal/synx/ai/pet/holo/gib()
visible_message("<span class='notice'>\The [src] fades away!</span>")
var/location = get_turf(src)
new /obj/item/seeds/hardlightseed/typesx(location)
@@ -592,7 +595,7 @@
////////////////////////////////////////
////////////////SYNX VARIATIONS/////////
////////////////////////////////////////
/mob/living/simple_mob/retaliate/synx/ai/pet/holo
/mob/living/simple_mob/animal/synx/ai/pet/holo
poison_chance = 100
poison_type = "fakesynxchem" //unlike synxchem this one heals!
name = "Hardlight synx"
@@ -617,7 +620,7 @@
vore_escape_chance = 30 //Much higher escape chance.. it's a hologram.
swallowTime = 10 SECONDS //Much more time to run
/mob/living/simple_mob/retaliate/synx/ai/pet/greed
/mob/living/simple_mob/animal/synx/ai/pet/greed
name = "Greed"
desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. black, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration.. This one has the name Greed burnt into its back, the burnt in name seems to be luminescent making it harder for it to blend into the dark."
//icon= //icon= would just set what DMI we are using, we already have our special one set.
@@ -635,7 +638,7 @@
vore_bump_chance = 2 //lowered bump chance
vore_escape_chance = 5 //Multivore allows for people to shove eachother out so lower normal escape chance.
/mob/living/simple_mob/retaliate/synx/ai/pet/greed/synth
/mob/living/simple_mob/animal/synx/ai/pet/greed/synth
/*
▓███▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓███▓
▓▓ ▓▓▓█ ▓▓ ▓▓█ ▓▓ ▓▓█ ▓▓ ▓▓█ ▓▓ ▓▓█ ▓▓ ▓▓▓█
@@ -691,11 +694,11 @@
..()
name = "SYN-KinC-([rand(100,999)])"
/mob/living/simple_mob/retaliate/synx/ai/pet/greed/synth/goodboy
/mob/living/simple_mob/animal/synx/ai/pet/greed/synth/goodboy
//hostile = 0
faction = "neutral"
/mob/living/simple_mob/retaliate/synx/ai/pet/diablo
/mob/living/simple_mob/animal/synx/ai/pet/diablo
//var/diablo_LIVING = "synx_diablo_living"
//var/diablo_DEAD = "synx_diablo_dead"
name = "diablo"
@@ -707,7 +710,7 @@
//Vore Section
vore_capacity = 2
/mob/living/simple_mob/retaliate/synx/ai/pet/asteri
/mob/living/simple_mob/animal/synx/ai/pet/asteri
name = "Asteri"
desc = "A cold blooded, genderless, parasitic eel from the more distant and stranger areas of the cosmos. Bleak white, perpetually grinning and possessing a hunger as enthusiastic and endless as humanity's sense of exploration.. This one has distinctive markings over its face forming the shape of a star, and its back holds a sizeable scar leading up to a small implanted device just above its waist, the name 'Asteri' scribed across the metal."
//icon= //icon= would just set what DMI we are using, we already have our special one set.
@@ -726,7 +729,7 @@
vore_bump_chance = 2
vore_escape_chance = 5
/mob/living/simple_mob/retaliate/synx/ai/pet/clown
/mob/living/simple_mob/animal/synx/ai/pet/clown
//hostile = 1
poison_chance = 100
poison_type = "clownsynxchem" //unlike synxchem this one HONKS
@@ -752,32 +755,32 @@
////////////////////////////////////////
////////////////SYNX DEBUG//////////////
////////////////////////////////////////
/mob/living/simple_mob/retaliate/synx/ai/pet/debug
/mob/living/simple_mob/animal/synx/ai/pet/debug
name = "Syntox"
desc = "ERROR Connection to translation server could not be established!"
/mob/living/simple_mob/retaliate/synx/ai/pet/debug/proc/rename()
/mob/living/simple_mob/animal/synx/ai/pet/debug/proc/rename()
set name = "rename"
set desc = "Renames the synx"
set category = "DEBUG"
name = input(usr, "What would you like to change name to?", "Renaming", null)
/mob/living/simple_mob/retaliate/synx/ai/pet/debug/proc/redesc()
/mob/living/simple_mob/animal/synx/ai/pet/debug/proc/redesc()
set name = "redesc"
set desc = "Redescribes the synx"
set category = "DEBUG"
desc = input(usr, "What would you like to change desc to?", "Redescribing", null)
/mob/living/simple_mob/retaliate/synx/ai/pet/debug/proc/resprite()
/mob/living/simple_mob/animal/synx/ai/pet/debug/proc/resprite()
set name = "resprite"
set desc = "Resprite the synx"
set category = "DEBUG"
icon_state = input(usr, "What would you like to change icon_state to?", "Respriting", null)
/mob/living/simple_mob/retaliate/synx/ai/pet/debug/New()
verbs |= /mob/living/simple_mob/retaliate/synx/ai/pet/debug/proc/rename
verbs |= /mob/living/simple_mob/retaliate/synx/ai/pet/debug/proc/resprite
verbs |= /mob/living/simple_mob/retaliate/synx/ai/pet/debug/proc/redesc
/mob/living/simple_mob/animal/synx/ai/pet/debug/New()
verbs |= /mob/living/simple_mob/animal/synx/ai/pet/debug/proc/rename
verbs |= /mob/living/simple_mob/animal/synx/ai/pet/debug/proc/resprite
verbs |= /mob/living/simple_mob/animal/synx/ai/pet/debug/proc/redesc
////////////////////////////////////////
////////////////SYNX SPAWNER////////////
@@ -786,10 +789,10 @@
name = "This is synxes"
/obj/random/mob/synx/item_to_spawn()
return pick(prob(66);/mob/living/simple_mob/retaliate/synx/ai/pet/greed,
//prob(50);/mob/living/simple_mob/retaliate/synx/pet/asteri,//He's crew so let's remove this
prob(33);/mob/living/simple_mob/retaliate/synx/ai/pet/holo,
prob(50);/mob/living/simple_mob/retaliate/synx/ai,) //normal eel boyo.
return pick(prob(66);/mob/living/simple_mob/animal/synx/ai/pet/greed,
//prob(50);/mob/living/simple_mob/animal/synx/pet/asteri,//He's crew so let's remove this
prob(33);/mob/living/simple_mob/animal/synx/ai/pet/holo,
prob(50);/mob/living/simple_mob/animal/synx/ai,) //normal eel boyo.
////////////////////////////////////////////////////////////////////////////
//////////////////////////NOT A SYNX///////but looks kinda like one/////////
@@ -820,7 +823,7 @@ This includes the sprites of the below Mob which are based upon SCP 939 and spri
use_astar = TRUE //Clever boy!
threaten = TRUE
/mob/living/simple_mob/retaliate/synx/scp
/mob/living/simple_mob/animal/synx/scp
name = "Unknown"
desc = "It's a red canine looking creature."
tt_desc = "Unknown Alien Lifeform"
@@ -0,0 +1,304 @@
/mob/living/simple_mob/vore/lamia
name = "purple lamia"
desc = "Combination snake-human. This one is purple."
icon = 'icons/mob/vore_lamia.dmi'
icon_state = "ffta"
icon_living = "ffta"
icon_rest = "ffta_rest"
icon_dead = "ffta_dead"
harm_intent_damage = 5
melee_damage_lower = 0
melee_damage_upper = 0
response_help = "pets"
response_disarm = "gently baps"
response_harm = "hits"
health = 60
maxHealth = 60
old_x = -16
old_y = 0
default_pixel_x = -16
pixel_x = -16
pixel_y = 0
// Vore tags
vore_active = 1
vore_capacity = 1
vore_bump_emote = "coils their tail around"
vore_icons = 0
// Default stomach
vore_stomach_name = "upper stomach"
vore_stomach_flavor = "You've ended up inside of the lamia's human stomach. It's pretty much identical to any human stomach, but the valve leading deeper is much bigger."
// Meaningful stats
vore_default_mode = DM_HOLD
vore_digest_chance = 0
vore_pounce_chance = 65
vore_bump_chance = 50
vore_standing_too = TRUE
vore_escape_chance = 25
// Special lamia vore tags
var/vore_upper_transfer_chance = 50
var/vore_tail_digest_chance = 25
var/vore_tail_absorb_chance = 0
var/vore_tail_transfer_chance = 50
say_list_type = /datum/say_list/lamia
ai_holder_type = /datum/ai_holder/simple_mob/passive
/mob/living/simple_mob/vore/lamia/update_fullness()
var/new_fullness = 0
// We only want to count our upper_stomach towards capacity
for(var/belly in vore_organs)
var/obj/belly/B = belly
if(B.name == "upper stomach")
for(var/mob/living/M in B)
new_fullness += M.size_multiplier
new_fullness /= size_multiplier
new_fullness = round(new_fullness, 1)
vore_fullness = min(vore_capacity, new_fullness)
/mob/living/simple_mob/vore/lamia/update_icon()
. = ..()
if(vore_active)
// Icon_state for fullness is as such if they are CONSCIOUS:
// [icon_living]_vore_[upper_shows]_[tail_shows]
// So copper_vore_1_1 is a full upper stomach *and* tail stomach
// And copper_vore_1_0 is full upper stomach, but empty tail stomach
// For unconscious: [icon_rest]_vore_[upper]_[tail]
// For dead, it doesn't show.
var/upper_shows = FALSE
var/tail_shows = FALSE
for(var/belly in vore_organs)
var/obj/belly/B = belly
if(!(B.name in list("upper stomach", "tail stomach")))
continue
var/belly_fullness = 0
for(var/mob/living/M in B)
belly_fullness += M.size_multiplier
belly_fullness /= size_multiplier
belly_fullness = round(belly_fullness, 1)
if(belly_fullness)
if(B.name == "upper stomach")
upper_shows = TRUE
else if(B.name == "tail stomach")
tail_shows = TRUE
if(upper_shows || tail_shows)
if((stat == CONSCIOUS) && (!icon_rest || !resting || !incapacitated(INCAPACITATION_DISABLED)))
icon_state = "[icon_living]_vore_[upper_shows]_[tail_shows]"
else if(stat >= DEAD)
icon_state = icon_dead
else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest)
icon_state = "[icon_rest]_vore_[upper_shows]_[tail_shows]"
/mob/living/simple_mob/vore/lamia/init_vore()
. = ..()
var/obj/belly/B = vore_selected
B.transferchance = vore_upper_transfer_chance
B.transferlocation = "tail stomach"
var/obj/belly/tail = new /obj/belly(src)
tail.immutable = TRUE
tail.name = "tail stomach"
tail.desc = "You slide out into the narrow, constricting tube of flesh that is the lamia's snake half, heated walls and strong muscles all around clinging to your form with every slither."
tail.digest_mode = vore_default_mode
tail.mode_flags = vore_default_flags
tail.item_digest_mode = vore_default_item_mode
tail.contaminates = vore_default_contaminates
tail.contamination_flavor = vore_default_contamination_flavor
tail.contamination_color = vore_default_contamination_color
tail.escapable = TRUE // needed for transferchance
tail.escapechance = 0 // No directly escaping a tail, gotta squirm back out.
tail.digestchance = vore_tail_digest_chance
tail.absorbchance = vore_tail_absorb_chance
tail.transferchance = vore_tail_transfer_chance
tail.transferlocation = "upper stomach"
tail.human_prey_swallow_time = swallowTime
tail.nonhuman_prey_swallow_time = swallowTime
tail.vore_verb = "stuff"
tail.emote_lists[DM_HOLD] = B.emote_lists[DM_HOLD].Copy()
tail.emote_lists[DM_DIGEST] = B.emote_lists[DM_DIGEST].Copy()
// FFTA Bra
/mob/living/simple_mob/vore/lamia/bra
desc = "Combination snake-human. This one is purple. They're wearing a bra."
icon_state = "ffta_bra"
icon_living = "ffta_bra"
icon_rest = "ffta_bra_rest"
icon_dead = "ffta_bra_dead"
// Albino
/mob/living/simple_mob/vore/lamia/albino
name = "albino lamia"
desc = "Combination snake-human. This one is albino."
icon_state = "albino"
icon_living = "albino"
icon_rest = "albino_rest"
icon_dead = "albino_dead"
/mob/living/simple_mob/vore/lamia/albino/bra
desc = "Combination snake-human. This one is albino. They're wearing a bra."
icon_state = "albino_bra"
icon_living = "albino_bra"
icon_rest = "albino_bra_rest"
icon_dead = "albino_bra_dead"
/mob/living/simple_mob/vore/lamia/albino/shirt
desc = "Combination snake-human. This one is albino. They're wearing a shirt."
icon_state = "albino_shirt"
icon_living = "albino_shirt"
icon_rest = "albino_shirt_rest"
icon_dead = "albino_shirt_dead"
// Cobra
/mob/living/simple_mob/vore/lamia/cobra
name = "cobra lamia"
desc = "Combination snake-human. This one looks like a cobra."
icon_state = "cobra"
icon_living = "cobra"
icon_rest = "cobra_rest"
icon_dead = "cobra_dead"
/mob/living/simple_mob/vore/lamia/cobra/bra
desc = "Combination snake-human. This one looks like a cobra. They're wearing a bra."
icon_state = "cobra_bra"
icon_living = "cobra_bra"
icon_rest = "cobra_bra_rest"
icon_dead = "cobra_bra_dead"
/mob/living/simple_mob/vore/lamia/cobra/shirt
desc = "Combination snake-human. This one looks like a cobra. They're wearing a shirt."
icon_state = "cobra_shirt"
icon_living = "cobra_shirt"
icon_rest = "cobra_shirt_rest"
icon_dead = "cobra_shirt_dead"
// Copper
/mob/living/simple_mob/vore/lamia/copper
name = "copper lamia"
desc = "Combination snake-human. This one is copper."
icon_state = "copper"
icon_living = "copper"
icon_rest = "copper_rest"
icon_dead = "copper_dead"
/mob/living/simple_mob/vore/lamia/copper/bra
desc = "Combination snake-human. This one is copper. They're wearing a bra."
icon_state = "copper_bra"
icon_living = "copper_bra"
icon_rest = "copper_bra_rest"
icon_dead = "copper_bra_dead"
/mob/living/simple_mob/vore/lamia/copper/shirt
desc = "Combination snake-human. This one is copper. They're wearing a shirt."
icon_state = "copper_shirt"
icon_living = "copper_shirt"
icon_rest = "copper_shirt_rest"
icon_dead = "copper_shirt_dead"
// Green
/mob/living/simple_mob/vore/lamia/green
name = "green lamia"
desc = "Combination snake-human. This one is green."
icon_state = "green"
icon_living = "green"
icon_rest = "green_rest"
icon_dead = "green_dead"
/mob/living/simple_mob/vore/lamia/green/bra
desc = "Combination snake-human. This one is green. They're wearing a bra."
icon_state = "green_bra"
icon_living = "green_bra"
icon_rest = "green_bra_rest"
icon_dead = "green_bra_dead"
/mob/living/simple_mob/vore/lamia/green/shirt
desc = "Combination snake-human. This one is green. They're wearing a shirt."
icon_state = "green_shirt"
icon_living = "green_shirt"
icon_rest = "green_shirt_rest"
icon_dead = "green_shirt_dead"
// Zebra
/mob/living/simple_mob/vore/lamia/zebra
name = "zebra lamia"
desc = "Combination snake-human. This one has a zebra pattern."
icon_state = "zebra"
icon_living = "zebra"
icon_rest = "zebra_rest"
icon_dead = "zebra_dead"
/mob/living/simple_mob/vore/lamia/zebra/bra
desc = "Combination snake-human. This one has a zebra pattern. They're wearing a bra."
icon_state = "zebra_bra"
icon_living = "zebra_bra"
icon_rest = "zebra_bra_rest"
icon_dead = "zebra_bra_dead"
/mob/living/simple_mob/vore/lamia/zebra/shirt
desc = "Combination snake-human. This one has a zebra pattern. They're wearing a shirt."
icon_state = "zebra_shirt"
icon_living = "zebra_shirt"
icon_rest = "zebra_shirt_rest"
icon_dead = "zebra_shirt_dead"
GLOBAL_LIST_INIT(valid_random_lamias, list(
/mob/living/simple_mob/vore/lamia,
/mob/living/simple_mob/vore/lamia/bra,
/mob/living/simple_mob/vore/lamia/albino,
/mob/living/simple_mob/vore/lamia/albino/bra,
/mob/living/simple_mob/vore/lamia/albino/shirt,
/mob/living/simple_mob/vore/lamia/cobra,
/mob/living/simple_mob/vore/lamia/cobra/bra,
/mob/living/simple_mob/vore/lamia/cobra/shirt,
/mob/living/simple_mob/vore/lamia/copper,
/mob/living/simple_mob/vore/lamia/copper/bra,
/mob/living/simple_mob/vore/lamia/copper/shirt,
/mob/living/simple_mob/vore/lamia/green,
/mob/living/simple_mob/vore/lamia/green/bra,
/mob/living/simple_mob/vore/lamia/green/shirt,
/mob/living/simple_mob/vore/lamia/zebra,
/mob/living/simple_mob/vore/lamia/zebra/bra,
/mob/living/simple_mob/vore/lamia/zebra/shirt,
))
/mob/living/simple_mob/vore/lamia/random
/mob/living/simple_mob/vore/lamia/random/New()
var/mob/living/simple_mob/vore/lamia/new_attrs = pick(GLOB.valid_random_lamias)
name = initial(new_attrs.name)
desc = initial(new_attrs.desc)
icon_state = initial(new_attrs.icon_state)
icon_living = initial(new_attrs.icon_living)
icon_rest = initial(new_attrs.icon_rest)
icon_dead = initial(new_attrs.icon_dead)
vore_default_mode = initial(new_attrs.vore_default_mode)
vore_digest_chance = initial(new_attrs.vore_digest_chance)
vore_pounce_chance = initial(new_attrs.vore_pounce_chance)
vore_bump_chance = initial(new_attrs.vore_bump_chance)
vore_standing_too = initial(new_attrs.vore_standing_too)
vore_escape_chance = initial(new_attrs.vore_escape_chance)
vore_upper_transfer_chance = initial(new_attrs.vore_upper_transfer_chance)
vore_tail_digest_chance = initial(new_attrs.vore_tail_digest_chance)
vore_tail_absorb_chance = initial(new_attrs.vore_tail_absorb_chance)
vore_tail_transfer_chance = initial(new_attrs.vore_tail_transfer_chance)
. = ..()
/datum/say_list/lamia
speak = list("Sss...","Sss!","Hiss!","HSSSSS")
emote_hear = list("hisses","slithers")
emote_see = list("shakes her head","coils","stretches","slithers")
@@ -0,0 +1,325 @@
#define NUTRITION_FRUIT 250 //The amount of nutrition needed to produce a fruit
#define NUTRITION_PITCHER 3 * NUTRITION_FRUIT //The amount of nutrition needed to produce a new pitcher
#define NUTRITION_MEAT 50 //The amount of nutrition provided by slabs of meat
#define PITCHER_SATED 250 //The amount of nutrition needed before the pitcher will attempt to grow fruit.
#define PITCHER_HUNGRY 150 //The nutrition cap under which the pitcher actively attempts to lure prey.
GLOBAL_LIST_INIT(pitcher_plant_lure_messages, list(
"The pitcher plant smells lovely, beckoning you closer.",
"The sweet scent wafting from the pitcher plant makes your mouth water.",
"You feel an urge to investigate the pitcher plant closely.",
"You find yourself staring at the pitcher plant without really thinking about it.",
"Doesn't the pitcher plant smell amazing?")) //Messages sent to nearby players if the pitcher is trying to lure prey. This is global to prevent a new list every time a new pitcher plant spawns.
//Pitcher plants, a passive carnivorous plant mob for xenobio and space vine spawning.
//Consider making immune to space vine entangling. Check entangle_immunity in the old CHOMPstation github for an example.
/mob/living/simple_mob/vore/pitcher_plant
name = "pitcher plant"
desc = "A carnivorous pitcher plant, bigger than a man."
tt_desc = "Sarraceniaceae gigantus"
icon_state = "pitcher_plant"
icon_living = "pitcher_plant"
icon_dead = "pitcher_plant_dead"
icon = 'icons/mob/vore_ch.dmi'
anchored = 1 //Rooted plant. Only killing it will let you move it.
maxHealth = 200
health = 200
a_intent = I_HELP //White this is help by default I'm leaving this here as a reminder thatdisarm will prevent playersfrom swapping places with the pitcher (but interfere with vore bump).
faction = "plants" //Makes plantbgone deadly.
ai_holder_type = /datum/ai_holder/simple_mob/passive/pitcher //It's a passive carnivorous plant, it can't detect or interact with people.
min_oxy = 0 //Immune to atmos because so are space vines. This is arbitrary and can be tweaked if desired.
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
melee_damage_upper = 0 //This shouldn't attack people but if it does (admemes) no damage can be dealt.
melee_damage_lower = 0
armor = list(
"melee" = 0,
"bullet" = 0,
"laser" = -50,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 100)
var/fruit = FALSE //Has the pitcher produced a fruit?
var/meat = 0 //How many units of meat is the plant digesting? Separate from actual vore mechanics.
var/meatspeed = 5 //How many units of meat is converted to nutrition each tick?
var/pitcher_metabolism = 0.1 //How much nutriment does the pitcher lose every 2 seconds? 0.1 should be around 30 every 10 minutes.
var/scent_strength = 5 //How much can a hungry pitcher confuse nearby people?
var/last_lifechecks = 0 //Timing variable to limit vore/hungry proc calls
var/list/pitcher_plant_lure_messages = null
/mob/living/simple_mob/vore/pitcher_plant //Putting vore variables separately because apparently that's tradition.
vore_bump_chance = 100
vore_bump_emote = "slurps up" //Not really a good way to make the grammar work with a passive vore plant.
vore_active = 1
vore_icons = 1
vore_capacity = 1
vore_pounce_chance = 0 //Plants only eat people who stumble into them.
swallowTime = 3 //3 deciseconds. This is intended to be nearly instant, e.g. victim trips and falls in.
vore_ignores_undigestable = 0
vore_default_mode = DM_DIGEST
/mob/living/simple_mob/vore/pitcher_plant/init_vore()
..()
var/obj/belly/B = vore_selected
B.desc = "You leaned a little too close to the pitcher plant, stumbling over the lip and splashing into a puddle of liquid filling the bottom of the cramped pitcher. You squirm madly, righting yourself and scrabbling at the walls in vain as the slick surface offers no purchase. The dim light grows dark as the pitcher's cap lowers, silently sealing the exit. With a sinking feeling you realize you won't be able to push the exit open even if you could somehow climb that high, leaving you helplessly trapped in the slick, tingling fluid. ((You can't escape this mob without help but you may use OOC Escape if you wish.))"
B.digest_burn = 0.5
B.digest_brute = 0
B.vore_verb = "trip"
B.name = "pitcher"
B.mode_flags = DM_FLAG_THICKBELLY
B.wet_loop = 0 //As nice as the fancy internal sounds are this is a plant.
B.digestchance = 0
B.escapechance = 0
B.fancy_vore = 1
B.vore_sound = "Squish2"
B.release_sound = "Pred Escape"
B.contamination_color = "purple"
B.contamination_flavor = "Wet"
//Why is it we have all these customizeable belly options which nobody ever alters for mobs?
B.emote_lists[DM_HOLD] = list(
"Slick fluid trickles over you, carrying threads of sweetness.",
"Everything is still, dark, and quiet. Your breaths echo quietly.",
"The surrounding air feels thick and humid.")
B.emote_lists[DM_DIGEST] = list(
"The slimy puddle stings faintly. It seems the plant has no need to quickly break down victims.",
"The humid air settles in your lungs, keeping each breath more labored than the last.",
"Fluid drips onto you, burning faintly as your body heat warms it."
)
B.emote_lists[DM_DRAIN] = list(
"Each bead of slick fluid running down your body leaves you feeling weaker.",
"It's cramped and dark, the air thick and heavy. Your limbs feel like lead.",
"Strength drains from your frame. The cramped chamber feels easier to settle into with each passing moment.")
/mob/living/simple_mob/vore/pitcher_plant/Life()
. = ..()
if(!.)
return
var/lastmeat = meat //If Life procs every 2 seconds that means it takes 20 seconds to digest a steak
meat = max(0,meat - meatspeed) //Clamp it to zero
adjust_nutrition(lastmeat - meat) //If there's no meat, this will just be zero.
if(nutrition >= PITCHER_SATED + NUTRITION_FRUIT)
if(prob(10)) //Should be about once every 20 seconds.
grow_fruit()
var/lastnutrition = nutrition
adjust_nutrition(-pitcher_metabolism)
adjustBruteLoss(nutrition - lastnutrition)
adjustToxLoss((nutrition - lastnutrition) * 3)
if(nutrition < pitcher_metabolism)
adjustToxLoss(pitcher_metabolism)
if(world.time > last_lifechecks + 30 SECONDS)
last_lifechecks = world.time
vore_checks()
handle_hungry()
/mob/living/simple_mob/vore/pitcher_plant/New()
..()
pitcher_plant_lure_messages = GLOB.pitcher_plant_lure_messages
/mob/living/simple_mob/vore/pitcher_plant/Initialize()
..()
pitcher_plant_lure_messages = GLOB.pitcher_plant_lure_messages
/mob/living/simple_mob/vore/pitcher_plant/death()
..()
anchored = 0
if(fruit)
new /obj/item/weapon/reagent_containers/food/snacks/pitcher_fruit(get_turf(src))
fruit = FALSE
/mob/living/simple_mob/vore/pitcher_plant/proc/grow_fruit() //This proc handles the pitcher turning nutrition into fruit (and new pitchers).
if(!fruit)
if(nutrition >= PITCHER_SATED + NUTRITION_FRUIT)
fruit = TRUE
adjust_nutrition(-NUTRITION_FRUIT)
return
else
return
if(fruit)
if(nutrition >= PITCHER_SATED + NUTRITION_PITCHER)
var/turf/T = safepick(circleviewturfs(src, 2)) //Try this if the above doesn't work, add src.loc == T check to density check
if(T.density) //No spawning in walls
return
else if(src.loc ==T)
return
else
new /mob/living/simple_mob/vore/pitcher_plant(get_turf(T))
fruit = FALSE //No admeming this to spawn endless pitchers.
adjust_nutrition(-NUTRITION_PITCHER)
/mob/living/simple_mob/vore/pitcher_plant/attack_hand(mob/living/user)
if(user.a_intent == I_HELP)
if(fruit)
to_chat(user, "You pick a fruit from \the [src].")
var/obj/F = new /obj/item/weapon/reagent_containers/food/snacks/pitcher_fruit(get_turf(user)) //Drops at the user's feet if put_in_hands fails
fruit = FALSE
user.put_in_hands(F)
else
to_chat(user, "The [src] hasn't grown any fruit yet!")
else
..()
/mob/living/simple_mob/vore/pitcher_plant/examine(mob/user)
. = ..()
if(fruit)
. += "A plump fruit glistens beneath \the [src]'s cap."
/mob/living/simple_mob/vore/pitcher_plant/attackby(obj/item/O, mob/user)
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/meat))
if(meat > NUTRITION_FRUIT - NUTRITION_MEAT) //Can't exceed 250
to_chat(user, "The [src] is full!")
return
else
meat += NUTRITION_MEAT
qdel(O)
return
if(istype(O, /obj/item/stack/cable_coil)) //How to free people without killing the pitcher. I guess cable is ss13 rope.
var/mob/living/carbon/human/H
var/N = 0
for(H in vore_selected.contents) //Only works for carbons, RIP mice. Should pick the first human the code finds.
user.visible_message("[user] tries to fish somebody out of \the [src].", "You try to snag somebody trapped in \the [src]...")
if(do_after(user, rand(3 SECONDS, 7 SECONDS))) //You can just spam click to stack attempts if you feel like abusing it.
if(prob(15))
user.visible_message("[user] tugs a sticky [H] free from \the [src].", "You heft [H] free from \the [src].")
prey_excludes += H
vore_selected.release_specific_contents(H)
N = 1
//addtimer(CALLBACK(src, .proc/removeMobFromPreyExcludes, weakref(H)), 1 MINUTES) //At the time of this PR, removeMobFromPreyExcludes breaks prey_excludes by deleting the list which causes problems with the Crossed() vore override before. This can be commented back in if that gets fixed.
break
else
to_chat(user, "The victim slips from your grasp!")
N = 1
break //We need to terminate the loop after each outcome or this could loop through multiple bellies. Of course, there should only be one belly.
if(!N)
to_chat(user, "The pitcher is empty.")
if(istype(O, /obj/item/weapon/newspaper))
return //Can't newspaper people to freedom.
..()
/mob/living/simple_mob/vore/pitcher_plant/proc/vore_checks()
if(ckey) //This isn't intended to be a playable mob but skip all of this if it's player-controlled.
return
if(vore_selected && vore_selected.contents.len) //Looping through all (potential) vore bellies would be more thorough but probably not worth the processing power if this check happens every 30 seconds.
var/mob/living/L
var/N = 0
var/hasdigestable = 0
var/hasindigestable = 0
for(L in vore_selected.contents)
if(istype(L, /mob/living/carbon/human/monkey))
L.nutrition = 0 //No stuffing monkeys with protein shakes for massive nutrition.
if(!L.digestable)
vore_selected.digest_mode = DM_DRAIN
N = 1
hasindigestable = 1
continue
else
vore_selected.digest_mode = DM_DIGEST
N = 1
hasdigestable = 1
continue
if(hasdigestable && hasindigestable)
vore_selected.digest_mode = DM_DIGEST //Let's digest until we digest all the digestable prey, then move onto draining indigestable prey.
if(!N)
vore_selected.release_all_contents() //If there's no prey, spit out everything.
/mob/living/simple_mob/vore/pitcher_plant/proc/handle_hungry() //Let's run this check every 30 seconds. This is how a hungry pitcher tries to lure prey.
if(nutrition <= PITCHER_HUNGRY) //Is sanity check another way to say redundancy?
var/turf/T = get_turf(src)
var/cardinal_turfs = T.CardinalTurfs()
for(var/mob/living/carbon/human/H in oview(2, src))
if(!istype(H) || !isliving(H) || H.stat == DEAD) //Living mobs only
continue
if(isSynthetic(H) || !H.species.breath_type || H.internal) //Exclude species which don't breathe or have internals.
continue
if(src.Adjacent(H)) //If they can breathe and are next to the pitcher, confuse them.
to_chat(H,"<font color='red'>The sweet, overwhelming scent from \the [src] makes your senses reel!</font>")
H.Confuse(scent_strength)
continue
else
to_chat(H, "<font color='red'>[pick(pitcher_plant_lure_messages)]</font>")
for(var/turf/simulated/TR in cardinal_turfs)
TR.wet_floor(1) //Same effect as water. Slip into plant, get ate.
else
return
/mob/living/simple_mob/vore/pitcher_plant/Crossed(atom/movable/AM as mob|obj) //Yay slipnoms
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living) && will_eat(AM) && !istype(AM, type) && prob(vore_bump_chance) && !ckey)
animal_nom(AM)
..()
/datum/ai_holder/simple_mob/passive/pitcher
wander = 0
/obj/item/weapon/reagent_containers/food/snacks/pitcher_fruit //As much as I want to tie hydroponics harvest code to the mob, this is simpler (albeit kinda hacky).
name = "squishy fruit"
desc = "A tender, fleshy fruit with a thin skin."
icon = 'icons/obj/hydroponics_products.dmi'
icon_state = "treefruit-product"
color = "#a839a2"
trash = /obj/item/seeds/pitcherseed
nutriment_amt = 1
nutriment_desc = list("pineapple" = 1)
w_class = ITEMSIZE_SMALL
var/datum/seed/seed = null
var/obj/item/seeds/pit = null
/obj/item/weapon/reagent_containers/food/snacks/pitcher_fruit/Initialize()
. = ..()
reagents.add_reagent("pitcher_nectar", 5)
bitesize = 4
pit = new /obj/item/seeds/pitcherseed(src.contents)
seed = pit.seed
/obj/item/weapon/reagent_containers/food/snacks/pitcher_fruit/afterattack(obj/O as obj, mob/user as mob, proximity)
if(istype(O,/obj/machinery/microwave))
return ..()
if(istype (O, /obj/machinery/seed_extractor))
pit.loc = O.loc //1 seed, perhaps balanced because you can get the reagents and the seed. Can be increased if desirable.
qdel(src)
if(!(proximity && O.is_open_container()))
return
to_chat(user, "<span class='notice'>You squeeze \the [src], juicing it into \the [O].</span>")
reagents.trans_to(O, reagents.total_volume)
user.drop_from_inventory(src)
pit.loc = user.loc
qdel(src)
/obj/item/weapon/reagent_containers/food/snacks/pitcher_fruit/attack_self(mob/user)
to_chat(user, "<span class='notice'>You plant the fruit.</span>")
new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(get_turf(user),src.seed)
GLOB.seed_planted_shift_roundstat++
qdel(src)
return
#undef NUTRITION_FRUIT
#undef NUTRITION_PITCHER
#undef NUTRITION_MEAT
#undef PITCHER_SATED
#undef PITCHER_HUNGRY
+15 -7
View File
@@ -222,16 +222,24 @@
if(istype(A, /obj/effect/decal/point))
return 0
var/tile = get_turf(A)
var/turf/tile = get_turf(A)
if (!tile)
return 0
var/obj/P = new /obj/effect/decal/point(tile)
P.invisibility = invisibility
P.plane = plane
spawn (20)
if(P)
qdel(P) // qdel
var/turf/our_tile = get_turf(src)
var/obj/visual = new /obj/effect/decal/point(our_tile)
visual.invisibility = invisibility
visual.plane = plane
animate(visual,
pixel_x = (tile.x - our_tile.x) * world.icon_size + A.pixel_x,
pixel_y = (tile.y - our_tile.y) * world.icon_size + A.pixel_y,
time = 1.7,
easing = EASE_OUT)
spawn(20)
if(visual)
qdel(visual) // qdel
face_atom(A)
return 1
@@ -697,6 +697,11 @@
icon_state = "eyes_sergal"
body_parts = list(BP_HEAD)
closedeyes
name = "Closed Eyes"
icon_state = "eyes_closed"
body_parts = list(BP_HEAD)
brows
name = "Eyebrows"
icon_state = "brows"
+1 -1
View File
@@ -14,7 +14,7 @@
set_typing_indicator(FALSE)
usr.say(message)
/mob/verb/me_verb(message as text)
/mob/verb/me_verb(message as message)
set name = "Me"
set category = "IC"
@@ -3,6 +3,7 @@
desc = "A wall-mounted touchscreen computer."
icon = 'icons/obj/modular_telescreen.dmi'
icon_state = "telescreen"
layer = ABOVE_WINDOW_LAYER
icon_state_unpowered = "telescreen"
icon_state_menu = "menu"
icon_state_screensaver = "standby"
+1 -1
View File
@@ -127,7 +127,7 @@
/datum/nifsoft/sizechange/activate()
if((. = ..()))
var/new_size = input("Put the desired size (25-200%)", "Set Size", 200) as num
var/new_size = input("Put the desired size (25-200%)", "Set Size", 200) as num|null
if (!ISINRANGE(new_size,25,200))
to_chat(nif.human,"<span class='notice'>The safety features of the NIF Program prevent you from choosing this size.</span>")

Some files were not shown because too many files have changed in this diff Show More