mirror of
https://github.com/Yawn-Wider/YWPolarisVore.git
synced 2026-08-26 06:26:41 +01:00
Merge branch 'master' into upstream-merge-8341
This commit is contained in:
@@ -23,7 +23,7 @@ These are just guidelines, not rules, use your best judgment and feel free to pr
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
|
||||
This project adheres to the Contributor Covenant [code of conduct](code_of_conduct.md).
|
||||
By participating, you are expected to uphold this code.
|
||||
|
||||
## How Can I Contribute?
|
||||
@@ -38,7 +38,7 @@ Any code submissions that do not meet our coding standards are likely to be reje
|
||||
|
||||
* If it is something like a bugfix that Polaris would want (the codebase we use), you may want to consider coding it there as well. They may want any general gameplay bugfixes, and things that are obviously intended to work one way, but do not. They do not have any of our fluff species (vulp, akula, fenn, etc) so do not make PRs related to that, or any vore content to them.
|
||||
* Change whitespace as little as possible. Do not randomly add/remove whitespace.
|
||||
* Map changes must be in tgm format. See the [Mapmerge2 Readme] for details.
|
||||
* Map changes must be in tgm format. See the [Mapmerge2 Readme] for details, or use [StrongDMM] which can automatically save maps as tgm.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
@@ -60,4 +60,5 @@ Commits with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00
|
||||
|
||||
All commits whose authorship dates are not prior to `1420675200 +0000` are assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files.
|
||||
|
||||
[Mapmerge2 Readme]: ../tools/mapmerge2/readme.md
|
||||
[Mapmerge2 Readme]: ../tools/mapmerge2/mapmerge tool readme.md
|
||||
[StrongDMM]: ../tools/StrongDMM/README.md
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update || true
|
||||
sudo apt install zlib1g-dev:i386 libssl-dev:i386 pkg-config:i386
|
||||
sudo apt install zlib1g-dev:i386 libssl-dev:i386
|
||||
ldd librust_g.so
|
||||
- name: Unit Tests
|
||||
run: |
|
||||
|
||||
@@ -6,6 +6,6 @@ export NODE_VERSION=12
|
||||
# Byond Major
|
||||
export BYOND_MAJOR=514
|
||||
# Byond Minor
|
||||
export BYOND_MINOR=1557
|
||||
export BYOND_MINOR=1569
|
||||
# Macro Count
|
||||
export MACRO_COUNT=4
|
||||
@@ -329,9 +329,6 @@
|
||||
/obj/machinery/atmospherics/tvalve/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
if (!W.is_wrench())
|
||||
return ..()
|
||||
if (istype(src, /obj/machinery/atmospherics/tvalve/digital))
|
||||
to_chat(user, "<span class='warning'>You cannot unwrench \the [src], it's too complicated.</span>")
|
||||
return 1
|
||||
if(!can_unwrench())
|
||||
to_chat(user, "<span class='warnng'>You cannot unwrench \the [src], it too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Normal digestion modes
|
||||
#define DM_HOLD "Hold"
|
||||
#define DM_HOLD_ABSORBED "Hold Absorbed" // Not a real bellymode, used for handling different idle messages for absorbed prey.
|
||||
#define DM_DIGEST "Digest"
|
||||
#define DM_ABSORB "Absorb"
|
||||
#define DM_UNABSORB "Unabsorb"
|
||||
@@ -10,10 +11,6 @@
|
||||
#define DM_HEAL "Heal"
|
||||
#define DM_EGG "Encase In Egg"
|
||||
|
||||
//#define DM_ITEMWEAK "Digest (Item Friendly)"
|
||||
//#define DM_STRIPDIGEST "Strip Digest (Items Only)"
|
||||
//#define DM_DIGEST_NUMB "Digest (Numbing)"
|
||||
|
||||
//Addon mode flags
|
||||
#define DM_FLAG_NUMBING 0x1
|
||||
#define DM_FLAG_STRIPPING 0x2
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE "atom_init_success"
|
||||
///from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby"
|
||||
///Return this in response if you don't want afterattack to be called
|
||||
#define COMPONENT_NO_AFTERATTACK (1<<0)
|
||||
///Return this in response if you don't want later item attack procs to be called.
|
||||
#define COMPONENT_CANCEL_ATTACK_CHAIN (1<<0)
|
||||
///from base of atom/attack_hulk(): (/mob/living/carbon/human)
|
||||
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack"
|
||||
///from base of atom/animal_attack(): (/mob/user)
|
||||
@@ -94,6 +94,7 @@
|
||||
#define COMSIG_ATOM_BUMPED "atom_bumped"
|
||||
///from base of atom/ex_act(): (severity, target)
|
||||
#define COMSIG_ATOM_EX_ACT "atom_ex_act"
|
||||
#define COMPONENT_IGNORE_EXPLOSION (1<<0)
|
||||
///from base of atom/emp_act(): (severity)
|
||||
#define COMSIG_ATOM_EMP_ACT "atom_emp_act"
|
||||
///from base of atom/fire_act(): (exposed_temperature, exposed_volume)
|
||||
@@ -225,7 +226,7 @@
|
||||
|
||||
// /atom/movable signals
|
||||
|
||||
///from base of atom/movable/Moved(): (/atom)
|
||||
///from base of atom/movable/Move(): (atom/newloc, dir, movetime)
|
||||
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move"
|
||||
#define COMPONENT_MOVABLE_BLOCK_PRE_MOVE (1<<0)
|
||||
///from base of atom/movable/Moved(): (/atom, dir)
|
||||
@@ -778,3 +779,5 @@
|
||||
#define COMSIG_CONFLICT_ELEMENT_CHECK "conflict_element_check"
|
||||
/// A conflict was found
|
||||
#define ELEMENT_CONFLICT_FOUND (1<<0)
|
||||
//From reagents touch_x.
|
||||
#define COMSIG_REAGENTS_TOUCH "reagent_touch"
|
||||
|
||||
@@ -38,9 +38,11 @@
|
||||
#define BE_LOYALIST 0x4000
|
||||
#define BE_PAI 0x8000
|
||||
//VOREStation Add
|
||||
#define BE_LOSTDRONE 0x10000
|
||||
#define BE_MAINTPRED 0x20000
|
||||
#define BE_MORPH 0x40000
|
||||
#define BE_LOSTDRONE 0x10000
|
||||
#define BE_MAINTPRED 0x20000
|
||||
#define BE_MORPH 0x40000
|
||||
#define BE_CORGI 0x80000
|
||||
#define BE_CURSEDSWORD 0x100000
|
||||
//VOREStation Add End
|
||||
|
||||
var/list/be_special_flags = list(
|
||||
@@ -64,6 +66,8 @@ var/list/be_special_flags = list(
|
||||
"Lost Drone" = BE_LOSTDRONE,
|
||||
"Maint Pred" = BE_MAINTPRED,
|
||||
"Morph" = BE_MORPH,
|
||||
"Corgi" = BE_CORGI,
|
||||
"Cursed Sword" = BE_CURSEDSWORD,
|
||||
//VOREStation Add End
|
||||
)
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#define isstorage(A) istype(A, /obj/item/weapon/storage)
|
||||
|
||||
#define ismecha(A) istype(A, /obj/mecha)
|
||||
|
||||
//---------------
|
||||
//#define isarea(D) istype(D, /area) //Built in
|
||||
|
||||
@@ -60,3 +62,4 @@
|
||||
#define ismineralturf(A) istype(A, /turf/simulated/mineral)
|
||||
|
||||
#define istaurtail(A) istype(A, /datum/sprite_accessory/tail/taur)
|
||||
#define islongtail(A) istype(A, /datum/sprite_accessory/tail/longtail)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define MAP_LEVEL_XENOARCH_EXEMPT 0x080 // Z-levels exempt from xenoarch digsite generation.
|
||||
#define MAP_LEVEL_PERSIST 0x100 // Z-levels where SSpersistence should persist between rounds
|
||||
#define MAP_LEVEL_MAPPABLE 0x200 // Z-levels where mapping units will work fully
|
||||
#define MAP_LEVEL_BELOW_BLOCKED 0x400 // Z-levels in multiz with level below not meant to be 'normally' accessible
|
||||
|
||||
// Misc map defines.
|
||||
#define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#define AG_WEAKEN 0x10 // too weak to move, oof
|
||||
#define AG_BLURRY 0x20 // blurred vision!
|
||||
#define AG_SLEEPY 0x40 // fatigue/exhaustion
|
||||
#define AG_CONFUSE 0x80 // disorientation - VOREStation addition
|
||||
|
||||
// Species spawn flags
|
||||
#define SPECIES_IS_WHITELISTED 0x1 // Must be whitelisted to play.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define LANGUAGE_VESPINAE "Vespinae"
|
||||
#define LANGUAGE_SPACER "Spacer"
|
||||
#define LANGUAGE_CLOWNISH "Coulrian"
|
||||
#define LANGUAGE_TAVAN "Tavan"
|
||||
|
||||
#define LANGUAGE_CHIMPANZEE "Chimpanzee"
|
||||
#define LANGUAGE_NEAERA "Neaera"
|
||||
|
||||
@@ -7,6 +7,6 @@ GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the
|
||||
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
|
||||
GLOBAL_LIST_EMPTY(tagger_locations)
|
||||
|
||||
GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Prey", "Switch", "Non-Vore", "Unset"))
|
||||
GLOBAL_LIST_INIT(char_directory_tags, list("Pred", "Pred-Pref", "Prey", "Prey-Pref", "Switch", "Non-Vore", "Unset"))
|
||||
GLOBAL_LIST_INIT(char_directory_erptags, list("Top", "Bottom", "Switch", "No ERP", "Unset"))
|
||||
GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes
|
||||
|
||||
@@ -249,13 +249,13 @@
|
||||
/mob/living/silicon/robot/can_hear_radio(var/list/hearturfs)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/device/radio/borg/R = hearturfs[T] // this should be an assoc list of turf-to-radio
|
||||
|
||||
|
||||
// We heard it on our own radio? We use power for that.
|
||||
if(istype(R) && R.myborg == src)
|
||||
var/datum/robot_component/CO = get_component("radio")
|
||||
if(!CO || !is_component_functioning("radio") || !cell_use_power(CO.active_usage))
|
||||
return FALSE // Sorry, couldn't hear
|
||||
|
||||
|
||||
return R // radio, true, false, what's the difference
|
||||
|
||||
/mob/observer/dead/can_hear_radio(var/list/hearturfs)
|
||||
@@ -272,14 +272,17 @@
|
||||
|
||||
var/list/hear = dview(range,T,INVISIBILITY_MAXIMUM)
|
||||
var/list/hearturfs = list()
|
||||
|
||||
|
||||
// Openspace visibility handling
|
||||
// Below turfs we can see
|
||||
for(var/turf/simulated/open/O in hear)
|
||||
var/turf/U = GetBelow(O)
|
||||
while(istype(U))
|
||||
hearturfs |= U
|
||||
U = GetBelow(U)
|
||||
if(isopenspace(U))
|
||||
U = GetBelow(U)
|
||||
else
|
||||
U = null
|
||||
|
||||
// Above us
|
||||
var/above_range = range
|
||||
|
||||
@@ -42,6 +42,7 @@ var/global/list/facial_hair_styles_male_list = list()
|
||||
var/global/list/facial_hair_styles_female_list = list()
|
||||
var/global/list/skin_styles_female_list = list() //unused
|
||||
var/global/list/body_marking_styles_list = list() //stores /datum/sprite_accessory/marking indexed by name
|
||||
var/global/list/body_marking_nopersist_list = list() // Body marking styles, minus non-genetic markings and augments
|
||||
var/global/list/ear_styles_list = list() // Stores /datum/sprite_accessory/ears indexed by type
|
||||
var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail indexed by type
|
||||
var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
|
||||
@@ -149,6 +150,8 @@ GLOBAL_LIST_EMPTY(mannequins)
|
||||
for(var/path in paths)
|
||||
var/datum/sprite_accessory/marking/M = new path()
|
||||
body_marking_styles_list[M.name] = M
|
||||
if(!M.genetic)
|
||||
body_marking_nopersist_list[M.name] = M
|
||||
|
||||
//Surgery Steps - Initialize all /datum/surgery_step into a list
|
||||
paths = subtypesof(/datum/surgery_step)
|
||||
|
||||
@@ -229,7 +229,8 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
|
||||
/obj/item/weapon/storage/fancy/egg_box,
|
||||
/obj/item/weapon/storage/wallet,
|
||||
/obj/item/weapon/storage/vore_egg,
|
||||
/obj/item/weapon/bikehorn/tinytether
|
||||
/obj/item/weapon/bikehorn/tinytether,
|
||||
/obj/item/capture_crystal
|
||||
)
|
||||
|
||||
var/global/list/contamination_flavors = list(
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
/atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3)
|
||||
if(!segments)
|
||||
return
|
||||
//VOREStation Addition Start
|
||||
if(speed == 0)
|
||||
loops = 0
|
||||
if(speed < 0)
|
||||
speed = speed * -1
|
||||
clockwise = 0
|
||||
//VOREStation Addition End
|
||||
var/segment = 360/segments
|
||||
if(!clockwise)
|
||||
segment = -segment
|
||||
|
||||
@@ -95,3 +95,6 @@
|
||||
///Species have sort_hint they self-generate to hint themselves into groups. After that, alphabetical.
|
||||
/proc/cmp_species(datum/species/A, datum/species/B)
|
||||
return A.sort_hint == B.sort_hint ? sorttext("[B.name]","[A.name]") : A.sort_hint - B.sort_hint
|
||||
|
||||
/proc/cmp_stored_item_name(datum/stored_item/A, datum/stored_item/B)
|
||||
return sorttext(B.item_name, A.item_name)
|
||||
@@ -50,13 +50,17 @@ var/station_date = ""
|
||||
var/next_station_date_change = 1 DAY
|
||||
|
||||
#define duration2stationtime(time) time2text(station_time_in_ds + time, "hh:mm")
|
||||
#define worldtime2stationtime(time) time2text(GLOB.roundstart_hour HOURS + time, "hh:mm")
|
||||
#define roundstart_delay_time (world.time - round_duration_in_ds)
|
||||
#define world_time_in_ds(time) (GLOB.roundstart_hour HOURS + time - roundstart_delay_time)
|
||||
#define round_duration_in_ds (GLOB.round_start_time ? REALTIMEOFDAY - GLOB.round_start_time : 0)
|
||||
#define station_time_in_ds (GLOB.roundstart_hour HOURS + round_duration_in_ds)
|
||||
|
||||
/proc/stationtime2text()
|
||||
return time2text(station_time_in_ds + GLOB.timezoneOffset, "hh:mm")
|
||||
|
||||
/proc/worldtime2stationtime(time)
|
||||
return time2text(world_time_in_ds(time) + GLOB.timezoneOffset, "hh:mm")
|
||||
|
||||
/proc/stationdate2text()
|
||||
var/update_time = FALSE
|
||||
if(station_time_in_ds > next_station_date_change)
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
var/old_icon1 = T.icon
|
||||
var/old_decals = T.decals ? T.decals.Copy() : null
|
||||
|
||||
B.Destroy()
|
||||
X = B.ChangeTurf(T.type)
|
||||
X.set_dir(old_dir1)
|
||||
X.icon_state = old_icon_state1
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#define isbelly(A) istype(A, /obj/belly)
|
||||
#define iscapturecrystal(A) istype(A, /obj/item/capture_crystal)
|
||||
|
||||
@@ -191,6 +191,11 @@ The box in your backpack has an oxygen tank and gas mask in it."
|
||||
desc = "Your battery is about to die! Charge it ASAP!"
|
||||
icon_state = "c_starving"
|
||||
|
||||
/obj/screen/alert/warm
|
||||
name = "Too Warm"
|
||||
desc = "You're uncomfortably warm. Take off some clothes or tweak the thermostat a few degrees cooler."
|
||||
icon_state = "mildhot"
|
||||
|
||||
/obj/screen/alert/hot
|
||||
name = "Too Hot"
|
||||
desc = "You're flaming hot! Get somewhere cooler and take off any insulating clothing like a fire suit."
|
||||
@@ -199,6 +204,11 @@ The box in your backpack has an oxygen tank and gas mask in it."
|
||||
/obj/screen/alert/hot/robot
|
||||
desc = "The air around you is too hot for a humanoid. Be careful to avoid exposing them to this enviroment."
|
||||
|
||||
/obj/screen/alert/chilly
|
||||
name = "Too Chilly"
|
||||
desc = "You're uncomfortably cold. Rug up or tweak the thermostat a few degrees higher."
|
||||
icon_state = "mildcold"
|
||||
|
||||
/obj/screen/alert/cold
|
||||
name = "Too Cold"
|
||||
desc = "You're freezing cold! Get somewhere warmer and take off any insulating clothing like a space suit."
|
||||
|
||||
@@ -25,28 +25,48 @@ avoid code duplication. This includes items that may sometimes act as a standard
|
||||
return
|
||||
return
|
||||
|
||||
// Called at the start of resolve_attackby(), before the actual attack.
|
||||
/obj/item/proc/pre_attack(atom/a, mob/user)
|
||||
return
|
||||
/**
|
||||
* Called at the start of resolve_attackby(), before the actual attack.
|
||||
*
|
||||
* Arguments:
|
||||
* * atom/A - The atom about to be hit
|
||||
* * mob/living/user - The mob doing the htting
|
||||
* * params - click params such as alt/shift etc
|
||||
*
|
||||
* See: [/obj/item/proc/melee_attack_chain]
|
||||
*/
|
||||
|
||||
/obj/item/proc/pre_attack(atom/A, mob/user, params) //do stuff before attackby!
|
||||
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return TRUE
|
||||
return FALSE //return TRUE to avoid calling attackby after this proc does stuff
|
||||
|
||||
//I would prefer to rename this to attack(), but that would involve touching hundreds of files.
|
||||
/obj/item/proc/resolve_attackby(atom/A, mob/user, var/attack_modifier = 1, var/click_parameters)
|
||||
pre_attack(A, user)
|
||||
add_fingerprint(user)
|
||||
. = pre_attack(A, user, click_parameters)
|
||||
if(.) // We're returning the value of pre_attack, important if it has a special return.
|
||||
return
|
||||
return A.attackby(src, user, attack_modifier, click_parameters)
|
||||
|
||||
// No comment
|
||||
/atom/proc/attackby(obj/item/W, mob/user, var/attack_modifier, var/click_parameters)
|
||||
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, click_parameters) & COMPONENT_NO_AFTERATTACK)
|
||||
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, click_parameters) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/attackby(obj/item/I, mob/user, var/attack_modifier, var/click_parameters)
|
||||
if(!ismob(user))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, I, user, click_parameters) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return FALSE
|
||||
|
||||
if(can_operate(src, user) && I.do_surgery(src,user))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(attempt_vr(src,"vore_attackby",args)) return //VOREStation Add - The vore, of course.
|
||||
|
||||
return I.attack(src, user, user.zone_sel.selecting, attack_modifier)
|
||||
|
||||
// Used to get how fast a mob should attack, and influences click delay.
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
A.attack_hand(src)
|
||||
|
||||
/atom/proc/attack_hand(mob/user as mob)
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
|
||||
return
|
||||
|
||||
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(ai)
|
||||
var/list/currentrun = list()
|
||||
|
||||
var/slept_mobs = 0
|
||||
var/list/process_z = list()
|
||||
var/list/process_z = list()
|
||||
|
||||
/datum/controller/subsystem/ai/stat_entry(msg_prefix)
|
||||
..("P: [processing.len] | S: [slept_mobs]")
|
||||
@@ -32,10 +32,14 @@ SUBSYSTEM_DEF(ai)
|
||||
while(currentrun.len)
|
||||
var/datum/ai_holder/A = currentrun[currentrun.len]
|
||||
--currentrun.len
|
||||
if(!A || QDELETED(A) || !A.holder?.loc || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
|
||||
if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
|
||||
continue
|
||||
|
||||
if(process_z[get_z(A.holder)])
|
||||
|
||||
var/mob/living/L = A.holder //VOREStation Edit Start
|
||||
if(!L?.loc)
|
||||
continue
|
||||
|
||||
if(process_z[get_z(L)] || !L.low_priority) //VOREStation Edit End
|
||||
A.handle_strategicals()
|
||||
else
|
||||
slept_mobs++
|
||||
|
||||
@@ -76,7 +76,9 @@ SUBSYSTEM_DEF(mapping)
|
||||
// VOREStation Edit Start: Enable This
|
||||
/datum/controller/subsystem/mapping/proc/loadLateMaps()
|
||||
var/list/deffo_load = using_map.lateload_z_levels
|
||||
var/list/maybe_load = using_map.lateload_single_pick
|
||||
var/list/maybe_load = using_map.lateload_gateway
|
||||
var/list/also_load = using_map.lateload_overmap
|
||||
|
||||
|
||||
for(var/list/maplist in deffo_load)
|
||||
if(!islist(maplist))
|
||||
@@ -110,6 +112,28 @@ SUBSYSTEM_DEF(mapping)
|
||||
error("Randompick Z level \"[map]\" is not a valid map!")
|
||||
else
|
||||
MT.load_new_z(centered = FALSE)
|
||||
|
||||
if(LAZYLEN(also_load)) //Just copied from gateway picking, this is so we can have a kind of OM map version of the same concept.
|
||||
var/picklist = pick(also_load)
|
||||
|
||||
if(!picklist) //No lateload maps at all
|
||||
return
|
||||
|
||||
if(!islist(picklist)) //So you can have a 'chain' of z-levels that make up one away mission
|
||||
error("Randompick Z level [picklist] is not a list! Must be in a list!")
|
||||
return
|
||||
|
||||
for(var/map in picklist)
|
||||
if(islist(map))
|
||||
// TRIPLE NEST. In this situation we pick one at random from the choices in the list.
|
||||
//This allows a sort of a1,a2,a3,b1,b2,b3,c1,c2,c3 setup where it picks one 'a', one 'b', one 'c'
|
||||
map = pick(map)
|
||||
var/datum/map_template/MT = map_templates[map]
|
||||
if(!istype(MT))
|
||||
error("Randompick Z level \"[map]\" is not a valid map!")
|
||||
else
|
||||
MT.load_new_z(centered = FALSE)
|
||||
|
||||
|
||||
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
|
||||
for(var/datum/map_template/shelter/shelter_type as anything in subtypesof(/datum/map_template/shelter))
|
||||
|
||||
@@ -25,6 +25,7 @@ SUBSYSTEM_DEF(persist)
|
||||
return
|
||||
if(!resumed)
|
||||
src.currentrun = human_mob_list.Copy()
|
||||
src.currentrun += silicon_mob_list.Copy()
|
||||
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
@@ -41,9 +42,7 @@ SUBSYSTEM_DEF(persist)
|
||||
return
|
||||
continue
|
||||
|
||||
// Do not collect useless PTO
|
||||
var/department_earning = J.pto_type
|
||||
clear_unused_pto(M)
|
||||
|
||||
// Determine special PTO types and convert properly
|
||||
if(department_earning == PTO_CYBORG)
|
||||
@@ -103,12 +102,4 @@ SUBSYSTEM_DEF(persist)
|
||||
// They have a custom title, aren't crew, or someone deleted their record, so we need a fallback method.
|
||||
// Let's check the mind.
|
||||
if(M.mind && M.mind.assigned_role)
|
||||
. = job_master.GetJob(M.mind.assigned_role)
|
||||
|
||||
// This proc tries makes sure old Command PTO doesn't linger
|
||||
/datum/controller/subsystem/persist/proc/clear_unused_pto(var/mob/M)
|
||||
var/client/C = M.client
|
||||
LAZYINITLIST(C.department_hours)
|
||||
if(C.department_hours[DEPARTMENT_COMMAND])
|
||||
C.department_hours[DEPARTMENT_COMMAND] = null
|
||||
C.department_hours.Remove(DEPARTMENT_COMMAND)
|
||||
. = job_master.GetJob(M.mind.assigned_role)
|
||||
@@ -4,7 +4,7 @@ SUBSYSTEM_DEF(persistence)
|
||||
flags = SS_NO_FIRE
|
||||
var/list/tracking_values = list()
|
||||
var/list/persistence_datums = list()
|
||||
|
||||
|
||||
/// Places our subsystem can spawn paintings (helps with art spawning differently across maps)
|
||||
var/list/obj/structure/sign/painting/painting_frames = list()
|
||||
var/list/all_paintings = list()
|
||||
@@ -36,10 +36,6 @@ SUBSYSTEM_DEF(persistence)
|
||||
if(!A || (A.flags & AREA_FLAG_IS_NOT_PERSISTENT))
|
||||
return
|
||||
|
||||
// if((!T.z in GLOB.using_map.station_levels) || !initialized)
|
||||
if(!(T.z in using_map.station_levels))
|
||||
return
|
||||
|
||||
if(!(T.z in using_map.persist_levels))
|
||||
return
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ SUBSYSTEM_DEF(supply)
|
||||
return 1
|
||||
if(istype(A,/obj/item/device/perfect_tele_beacon)) //VOREStation Addition: Translocator beacons
|
||||
return 1 //VOREStation Addition: Translocator beacons
|
||||
if(istype(A,/obj/machinery/power/quantumpad)) // //VOREStation Add: Quantum pads
|
||||
return 1 //VOREStation Add: Quantum pads
|
||||
|
||||
for(var/atom/B in A.contents)
|
||||
if(.(B))
|
||||
|
||||
@@ -67,7 +67,7 @@ SUBSYSTEM_DEF(throwing)
|
||||
src.speed = speed
|
||||
src.thrower = thrower
|
||||
src.callback = callback
|
||||
if(!QDELETED(thrower))
|
||||
if(!QDELETED(thrower) && ismob(thrower))
|
||||
src.target_zone = thrower.zone_sel ? thrower.zone_sel.selecting : null
|
||||
|
||||
dist_x = abs(target.x - thrownthing.x)
|
||||
@@ -204,4 +204,4 @@ SUBSYSTEM_DEF(throwing)
|
||||
|
||||
if(hit_thing)
|
||||
finalize(hit=TRUE, t_target=hit_thing)
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/datum/category_item/autolathe/medical/autoinjector
|
||||
name = "empty autoinjector"
|
||||
path =/obj/item/weapon/reagent_containers/hypospray/autoinjector/empty
|
||||
resources = list(MAT_PLASTIC = 10) //for recycling purposes mostly
|
||||
|
||||
/datum/category_item/autolathe/medical/autoinjector/biginjector
|
||||
name = "empty large autoinjector"
|
||||
path =/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/empty
|
||||
resources = list(MAT_PLASTIC = 2000)
|
||||
resources = list(MAT_PLASTIC = 500)
|
||||
@@ -48,3 +48,11 @@
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/primitive_shield
|
||||
name = "Primitive Shield"
|
||||
result = /obj/item/weapon/shield/primitive
|
||||
reqs = list(list(/obj/item/stack/material/wood = 2), list(/obj/item/weapon/reagent_containers/glass/bucket/wood =1), list(/obj/item/stack/material/cloth = 5))
|
||||
time = 120
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
if(!(mat_container_flags & MATCONTAINER_SILENT))
|
||||
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
|
||||
return
|
||||
. = COMPONENT_NO_AFTERATTACK
|
||||
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
||||
var/datum/callback/pc = precondition
|
||||
if(pc && !pc.Invoke(user))
|
||||
return
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
// It shouldn't be possible to add more matter than our max
|
||||
ASSERT((total_amount + (matter_per_sheet * sheets_to_use)) <= max_amount)
|
||||
|
||||
|
||||
// Use the amount of sheets from the stack
|
||||
if(!S.use(sheets_to_use))
|
||||
to_chat(user, "<span class='warning'>Something went wrong with your stack. Split it manually and try again.</span>")
|
||||
@@ -358,7 +358,7 @@
|
||||
if(materials[M] < (sheet_amt * SHEET_MATERIAL_AMOUNT))
|
||||
sheet_amt = round(materials[M] / SHEET_MATERIAL_AMOUNT)
|
||||
|
||||
var/obj/item/stack/S = M.stack_type
|
||||
var/obj/item/stack/S = M.stack_type
|
||||
var/max_stack_size = initial(S.max_amount)
|
||||
|
||||
var/count = 0
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
for(var/ban in check_bans)
|
||||
if(jobban_isbanned(candidate, ban))
|
||||
return FALSE // They're banned from this role.
|
||||
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Send async alerts and ask for responses. Expects you to have tested D for client and type already
|
||||
@@ -59,10 +59,10 @@
|
||||
|
||||
var/client/C = D.client
|
||||
window_flash(C)
|
||||
|
||||
|
||||
if(query_sound)
|
||||
SEND_SOUND(C, sound(query_sound))
|
||||
|
||||
|
||||
tgui_alert_async(D, question, "[role_name] request", list("Yes", "No", "Never for this round"), CALLBACK(src, .proc/get_reply), wait_time SECONDS)
|
||||
|
||||
/// Process an async alert response
|
||||
@@ -70,9 +70,9 @@
|
||||
var/mob/observer/dead/D = usr
|
||||
if(!D?.client)
|
||||
return
|
||||
|
||||
|
||||
// Unhandled are "No" and "Nevermind" responses, which should just do nothing
|
||||
|
||||
|
||||
// This response is always fine, doesn't warrant retesting
|
||||
switch(response)
|
||||
if("Never for this round")
|
||||
@@ -189,10 +189,12 @@
|
||||
role_name = "Dark Creature"
|
||||
question = "A curious explorer has touched a mysterious rune. \
|
||||
Would you like to play as the creature it summons?"
|
||||
be_special_flag = BE_CORGI
|
||||
cutoff_number = 1
|
||||
|
||||
/datum/ghost_query/cursedblade
|
||||
role_name = "Cursed Sword"
|
||||
question = "A cursed blade has been discovered by a curious explorer. \
|
||||
Would you like to play as the soul imprisoned within?"
|
||||
be_special_flag = BE_CURSEDSWORD
|
||||
cutoff_number = 1
|
||||
|
||||
@@ -75,17 +75,24 @@
|
||||
mid_sounds = list(
|
||||
'sound/effects/weather/acidrain_mid.ogg' = 1
|
||||
)
|
||||
mid_length = 15 SECONDS // The lengths for the files vary, but the longest is ten seconds, so this will make it sound like intermittent wind.
|
||||
mid_length = 15 SECONDS
|
||||
start_sound = 'sound/effects/weather/acidrain_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/acidrain_end.ogg'
|
||||
volume = 20
|
||||
|
||||
/datum/looping_sound/weather/rain/indoors
|
||||
volume = 10
|
||||
|
||||
/datum/looping_sound/weather/rain/heavy
|
||||
volume = 40
|
||||
|
||||
/datum/looping_sound/weather/rain/heavy/indoors
|
||||
volume = 20
|
||||
/datum/looping_sound/weather/rain/indoors
|
||||
mid_sounds = list(
|
||||
'sound/effects/weather/indoorrain_mid.ogg' = 1
|
||||
)
|
||||
mid_length = 15 SECONDS
|
||||
start_sound = 'sound/effects/weather/indoorrain_start.ogg'
|
||||
start_length = 13 SECONDS
|
||||
end_sound = 'sound/effects/weather/indoorrain_end.ogg'
|
||||
volume = 20 //Sound is already quieter in file
|
||||
|
||||
/datum/looping_sound/weather/rain/indoors/heavy
|
||||
volume = 40
|
||||
@@ -25,8 +25,8 @@
|
||||
var/obj/item/weapon/storage/briefcase/new_briefcase = new(H)
|
||||
for(var/obj/item/briefcase_item in new_briefcase)
|
||||
qdel(briefcase_item)
|
||||
new_briefcase.contents += new /obj/item/toy/crossbow
|
||||
new_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/capgun
|
||||
new_briefcase.contents += new /obj/item/weapon/gun/projectile/pistol/toy
|
||||
new_briefcase.contents += new /obj/item/ammo_magazine/mfoam_dart/pistol
|
||||
new_briefcase.contents += new /obj/item/clothing/mask/gas/clown_hat
|
||||
H.equip_to_slot_or_del(new_briefcase, slot_l_hand)
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
suit = /obj/item/clothing/suit/storage/toggle/brown_jacket/sleeveless
|
||||
shoes = /obj/item/clothing/shoes/boots/jackboots
|
||||
gloves = /obj/item/clothing/gloves/fingerless
|
||||
l_pocket = /obj/item/toy/crossbow
|
||||
l_pocket = /obj/item/weapon/gun/projectile/revolver/toy/crossbow/halloween
|
||||
r_pocket = /obj/item/device/flashlight/color/red
|
||||
|
||||
/decl/hierarchy/outfit/costume/pirate
|
||||
@@ -119,4 +119,12 @@
|
||||
shoes = /obj/item/clothing/shoes/white
|
||||
suit = /obj/item/clothing/suit/storage/hooded/chaplain_hoodie/whiteout
|
||||
gloves = /obj/item/clothing/gloves/white
|
||||
mask = /obj/item/clothing/mask/surgical
|
||||
mask = /obj/item/clothing/mask/surgical
|
||||
|
||||
/decl/hierarchy/outfit/costume/marine
|
||||
name = OUTFIT_COSTUME("Ruin Marine")
|
||||
uniform = /obj/item/clothing/under/color/grey
|
||||
shoes = /obj/item/clothing/shoes/brown
|
||||
head = /obj/item/clothing/head/marine
|
||||
suit = /obj/item/clothing/suit/marine
|
||||
r_hand = /obj/item/weapon/gun/projectile/revolver/toy/sawnoff
|
||||
@@ -8,6 +8,7 @@
|
||||
var/key_name = "the keys" // What the 'keys' for the thing being rided on would be called.
|
||||
var/atom/movable/ridden = null // The thing that the datum is attached to.
|
||||
var/only_one_driver = FALSE // If true, only the person in 'front' (first on list of riding mobs) can drive.
|
||||
var/rider_size = 1 // VOREStation Edit to figure out offsets for rider.
|
||||
|
||||
/datum/riding/New(atom/movable/_ridden)
|
||||
ridden = _ridden
|
||||
|
||||
@@ -394,4 +394,22 @@
|
||||
)
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Knights Gear Crate"
|
||||
containername = "Knights Gear Crate"
|
||||
|
||||
/datum/supply_pack/costumes/christmas
|
||||
name = "Christmas costume pack"
|
||||
contains = list(
|
||||
/obj/item/clothing/head/santa,
|
||||
/obj/item/clothing/head/santa/green,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/christmasred,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/christmasgreen,
|
||||
/obj/item/clothing/under/christmas/red,
|
||||
/obj/item/clothing/under/christmas/green,
|
||||
/obj/item/clothing/under/christmas/croptop/red,
|
||||
/obj/item/clothing/under/christmas/croptop/green,
|
||||
/obj/item/clothing/shoes/boots/winter/christmasred,
|
||||
/obj/item/clothing/shoes/boots/winter/christmasgreen
|
||||
)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "Christmas costume pack"
|
||||
@@ -49,6 +49,13 @@
|
||||
containertype = /obj/structure/largecrate/animal/cat
|
||||
containername = "Cat Crate"
|
||||
|
||||
/datum/supply_pack/hydro/catslug
|
||||
name = "Catslug Crate"
|
||||
contains = list()
|
||||
cost = 200
|
||||
containertype = /obj/structure/largecrate/animal/catslug
|
||||
containername = "Catslug Crate"
|
||||
|
||||
/datum/supply_pack/hydro/hydroponics
|
||||
name = "Hydroponics Supply Crate"
|
||||
contains = list(
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
)
|
||||
cost = 250
|
||||
containertype = /obj/structure/closet/crate/secure/gear
|
||||
containername = "Commonwealth medical hardsuit crate"
|
||||
access = access_medical
|
||||
containername = "Commonwealth engineering hardsuit crate"
|
||||
access = access_engine
|
||||
|
||||
/datum/supply_pack/misc/zero_rig
|
||||
name = "null hardsuit (jets)"
|
||||
@@ -157,5 +157,4 @@
|
||||
)
|
||||
cost = 300
|
||||
containertype = /obj/structure/closet/crate
|
||||
containername = "cordless jukebox speakers crate"
|
||||
|
||||
containername = "cordless jukebox speakers crate"
|
||||
@@ -187,6 +187,14 @@
|
||||
containername = "Magnetic ammunition crate"
|
||||
access = access_security
|
||||
|
||||
/datum/supply_pack/munitions/claymore
|
||||
name = "Weapons - Melee - Claymores"
|
||||
contains = list(/obj/item/weapon/material/sword = 2)
|
||||
cost = 150
|
||||
containertype = /obj/structure/closet/crate/secure/weapon
|
||||
containername = "Claymore crate"
|
||||
access = access_armory //two swords that are a one-hit 40 brute + IB chance should be armory-locked
|
||||
|
||||
/datum/supply_pack/munitions/shotgunammo
|
||||
name = "Ammunition - Shotgun shells"
|
||||
contains = list(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Here is where any supply packs
|
||||
* related to recreation live.
|
||||
*/
|
||||
* Here is where any supply packs
|
||||
* related to recreation live.
|
||||
*/
|
||||
|
||||
|
||||
/datum/supply_pack/recreation
|
||||
@@ -23,6 +23,25 @@
|
||||
containertype = /obj/structure/closet/crate/allico
|
||||
containername = "foam weapon crate"
|
||||
|
||||
/datum/supply_pack/recreation/donksoftweapons
|
||||
name = "Donk-Soft Weapon Crate"
|
||||
contains = list(
|
||||
/obj/item/ammo_magazine/ammo_box/foam = 2,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/toy = 2,
|
||||
/obj/item/weapon/gun/projectile/pistol/toy = 2,
|
||||
/obj/item/ammo_magazine/mfoam_dart/pistol = 2
|
||||
)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/allico
|
||||
containername = "foam weapon crate"
|
||||
|
||||
/datum/supply_pack/recreation/donksoftvend
|
||||
name = "Donk-Soft Vendor Crate"
|
||||
contains = list()
|
||||
cost = 75
|
||||
containertype = /obj/structure/largecrate/donksoftvendor
|
||||
containername = "\improper Donk-Soft vendor crate"
|
||||
|
||||
/datum/supply_pack/recreation/lasertag
|
||||
name = "Lasertag equipment"
|
||||
contains = list(
|
||||
|
||||
@@ -23,6 +23,7 @@ var/list/all_supply_groups = list("Atmospherics",
|
||||
"Science",
|
||||
"Security",
|
||||
"Supplies",
|
||||
"Vendor Refills",
|
||||
"Voidsuits")
|
||||
|
||||
/datum/supply_pack
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/datum/supply_pack/vending_refills
|
||||
group = "Vendor Refills"
|
||||
containertype = /obj/structure/closet/crate/plastic
|
||||
containername = "vendor refill cartridge crate"
|
||||
|
||||
/datum/supply_pack/randomised/vending_refills
|
||||
group = "Vendor Refills"
|
||||
containertype = /obj/structure/closet/crate/plastic
|
||||
containername = "vendor refill cartridge crate"
|
||||
|
||||
/datum/supply_pack/vending_refills/snack
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snack)
|
||||
name = "Getmore Chocolate Corp Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/fitness
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/fitness)
|
||||
name = "SweatMAX Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/hotfood
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/hotfood)
|
||||
name = "Hot Foods Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/weeb
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/weeb)
|
||||
name = "Nippon-tan Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/sol
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/sol)
|
||||
name = "Sol-Snacks Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/snix
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snix)
|
||||
name = "Snix Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/snlvend
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snlvend)
|
||||
name = "Shop-n-Large Snacks Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/sovietvend
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/sovietvend)
|
||||
name = "Ration Station Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/coffee
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/drink/coffee)
|
||||
name = "Hot Drinks Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/cola
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/drink/cola)
|
||||
name = "Robust Softdrinks Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/cola_soft
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/drink/cola_soft)
|
||||
name = "Soft Robustdrinks Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/sovietsoda
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/drink/sovietsoda)
|
||||
name = "BODA Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/bepis
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/drink/bepis)
|
||||
name = "Bepis Softdrinks Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/cigarette
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/cigarette)
|
||||
name = "Cigarette Vendor Refill Cartridge"
|
||||
cost = 15
|
||||
|
||||
/datum/supply_pack/vending_refills/wardrobe
|
||||
contains = list(/obj/item/weapon/refill_cartridge/multitype/wardrobe)
|
||||
name = "Wardrobe Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/giftvendor
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/giftvendor)
|
||||
name = "AlliCo Baubles and Confectionaries Vendor Refill Cartridge"
|
||||
cost = 20
|
||||
|
||||
/datum/supply_pack/vending_refills/general_food
|
||||
contains = list(/obj/item/weapon/refill_cartridge/multitype/food = 5)
|
||||
name = "5-Pack Food Vendor Refill Cartridges"
|
||||
cost = 75
|
||||
|
||||
/datum/supply_pack/vending_refills/general_drink
|
||||
contains = list(/obj/item/weapon/refill_cartridge/multitype/drink = 5)
|
||||
name = "5-Pack Drink Vendor Refill Cartridges"
|
||||
cost = 75
|
||||
|
||||
/datum/supply_pack/vending_refills/general_clothing
|
||||
contains = list(/obj/item/weapon/refill_cartridge/multitype/clothing = 5)
|
||||
name = "5-Pack Clothing Vendor Refill Cartridges"
|
||||
cost = 75
|
||||
|
||||
/datum/supply_pack/vending_refills/general_technical
|
||||
contains = list(/obj/item/weapon/refill_cartridge/multitype/technical = 5)
|
||||
name = "5-Pack Technical Vendor Refill Cartridges"
|
||||
cost = 75
|
||||
|
||||
/datum/supply_pack/vending_refills/general_specialty
|
||||
contains = list(/obj/item/weapon/refill_cartridge/multitype/specialty = 5)
|
||||
name = "5-Pack Specialty Vendor Refill Cartridges"
|
||||
cost = 150
|
||||
|
||||
/datum/supply_pack/randomised/vending_refills/value_pack // 5 random vendor-specific cartridges at lower average price. But why?
|
||||
num_contained = 5
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snack,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/fitness,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/hotfood,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/weeb,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/sol,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/snix,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/snlvend,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/sovietvend,
|
||||
/obj/item/weapon/refill_cartridge/autoname/drink/coffee,
|
||||
/obj/item/weapon/refill_cartridge/autoname/drink/cola,
|
||||
/obj/item/weapon/refill_cartridge/autoname/drink/cola_soft,
|
||||
/obj/item/weapon/refill_cartridge/autoname/drink/sovietsoda,
|
||||
/obj/item/weapon/refill_cartridge/autoname/drink/bepis,
|
||||
/obj/item/weapon/refill_cartridge/autoname/cigarette,
|
||||
/obj/item/weapon/refill_cartridge/multitype/wardrobe,
|
||||
/obj/item/weapon/refill_cartridge/autoname/technical/assist,
|
||||
/obj/item/weapon/refill_cartridge/autoname/technical/tool,
|
||||
/obj/item/weapon/refill_cartridge/autoname/giftvendor)
|
||||
name = "5-pack Extra-Cheap Vendor Refill Cartridges"
|
||||
cost = 35
|
||||
@@ -73,6 +73,11 @@
|
||||
item_cost = 15
|
||||
path = /obj/fiftyspawner/glass
|
||||
|
||||
/datum/uplink_item/item/tools/holdingpouch
|
||||
name = "Pouch of Holding"
|
||||
item_cost = 20
|
||||
path = /obj/item/weapon/storage/pouch/holding
|
||||
|
||||
/datum/uplink_item/item/tools/elitelaptop
|
||||
name = "Laptop (Advanced)"
|
||||
item_cost = 20
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
var/atom/movable/product = instances[instances.len] // Remove the last added product
|
||||
instances -= product
|
||||
product.forceMove(product_location)
|
||||
//VOREStation Addition Start
|
||||
if(istype(product, /obj))
|
||||
var/obj/item = product
|
||||
item.persist_storable = FALSE
|
||||
//VOREStation Addition End
|
||||
return product
|
||||
|
||||
/datum/stored_item/proc/add_product(var/atom/movable/product)
|
||||
@@ -60,7 +65,12 @@
|
||||
var/new_product = new item_path(stored)
|
||||
instances += new_product
|
||||
|
||||
|
||||
/datum/stored_item/proc/refill_products(var/refill_amount)
|
||||
if(!instances)
|
||||
init_products()
|
||||
for(var/i = 1 to refill_amount)
|
||||
var/new_product = new item_path(stored)
|
||||
instances += new_product
|
||||
|
||||
/datum/stored_item/stack/get_amount()
|
||||
return amount
|
||||
@@ -75,15 +85,15 @@
|
||||
/datum/stored_item/stack/get_product(var/product_location, var/count)
|
||||
if(!LAZYLEN(instances))
|
||||
return null // Shouldn't happen, but will loudly complain if it breaks
|
||||
|
||||
|
||||
var/obj/item/stack/S = instances[1]
|
||||
count = min(count, S.get_max_amount())
|
||||
src.amount -= count // We won't vend more than one full stack per call
|
||||
|
||||
|
||||
// Case 1: Draw the full amount from the first instance
|
||||
if(count < S.get_amount())
|
||||
S = S.split(count)
|
||||
|
||||
|
||||
// Case 2: Amount at least one stack, or have to accumulate
|
||||
else if(count >= S.get_amount())
|
||||
count -= S.get_amount()
|
||||
@@ -91,6 +101,8 @@
|
||||
for(var/obj/item/stack/T as anything in instances)
|
||||
if(count <= 0)
|
||||
break
|
||||
if(T.get_amount() <= count)
|
||||
instances -=T
|
||||
count -= T.transfer_to(S, count)
|
||||
|
||||
S.forceMove(product_location)
|
||||
|
||||
@@ -376,7 +376,7 @@
|
||||
icon_state = unique_reskin[pick]
|
||||
item_state = unique_reskin[pick]
|
||||
reskin_ran = TRUE
|
||||
to_chat(M, "[src] is now '[pick].'")
|
||||
to_chat(M, "[src] is now '[pick]'.")
|
||||
|
||||
/obj/item/weapon/storage/part_replacer/drop_contents() // hacky-feeling tier-based drop system
|
||||
hide_from(usr)
|
||||
|
||||
@@ -9,3 +9,28 @@
|
||||
icon_state = "centcom_dock"
|
||||
ambience = AMBIENCE_ARRIVALS
|
||||
base_turf = /turf/simulated/floor/reinforced
|
||||
|
||||
//////// Abductor Areas ////////
|
||||
/area/unknown
|
||||
requires_power = 0
|
||||
flags = RAD_SHIELDED
|
||||
icon_state = "red2"
|
||||
limit_mob_size = FALSE
|
||||
|
||||
/area/unknown/dorm1
|
||||
name = "Unknown Dorm 1"
|
||||
|
||||
/area/unknown/dorm2
|
||||
name = "Unknown Dorm 2"
|
||||
|
||||
/area/unknown/dorm3
|
||||
name = "Unknown Dorm 3"
|
||||
|
||||
/area/unknown/dorm4
|
||||
name = "Unknown Dorm 4"
|
||||
|
||||
/area/unknown/dorm5
|
||||
name = "Unknown Dorm 5"
|
||||
|
||||
/area/unknown/dorm6
|
||||
name = "Unknown Dorm 6"
|
||||
|
||||
+7
-2
@@ -125,6 +125,8 @@
|
||||
/atom/proc/Bumped(AM as mob|obj)
|
||||
set waitfor = FALSE
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_BUMPED, AM)
|
||||
|
||||
// Convenience proc to see if a container is open for chemistry handling
|
||||
// returns true if open
|
||||
// false if closed
|
||||
@@ -166,6 +168,9 @@
|
||||
return
|
||||
|
||||
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
|
||||
if(SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
||||
return
|
||||
|
||||
P.on_hit(src, 0, def_zone)
|
||||
. = 0
|
||||
|
||||
@@ -260,8 +265,8 @@
|
||||
invisibility = new_invisibility
|
||||
return TRUE
|
||||
|
||||
/atom/proc/ex_act()
|
||||
return
|
||||
/atom/proc/ex_act(var/strength = 3)
|
||||
return (SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, strength, src) & COMPONENT_IGNORE_EXPLOSION)
|
||||
|
||||
/atom/proc/emag_act(var/remaining_charges, var/mob/user, var/emag_source)
|
||||
return -1
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
if(!loc || !newloc)
|
||||
return FALSE
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, newloc, direct, movetime) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
|
||||
return FALSE
|
||||
|
||||
// Store this early before we might move, it's used several places
|
||||
var/atom/oldloc = loc
|
||||
|
||||
@@ -232,6 +235,9 @@
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
for (var/datum/light_source/light as anything in light_sources) // Cycle through the light sources on this atom and tell them to update.
|
||||
light.source_atom.update_light()
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, old_loc, direction)
|
||||
|
||||
return TRUE
|
||||
|
||||
/atom/movable/set_dir(newdir)
|
||||
@@ -265,6 +271,9 @@
|
||||
throwing = 0
|
||||
if(QDELETED(A))
|
||||
return
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
|
||||
|
||||
A.Bumped(src)
|
||||
A.last_bumped = world.time
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ var/global/list/datum/dna/gene/dna_genes[0]
|
||||
// New stuff
|
||||
var/species = SPECIES_HUMAN
|
||||
var/list/body_markings = list()
|
||||
var/list/body_markings_genetic = list()
|
||||
var/list/body_descriptors = null
|
||||
var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance.
|
||||
|
||||
@@ -143,6 +144,8 @@ var/global/list/datum/dna/gene/dna_genes[0]
|
||||
new_dna.custom_ask=custom_ask //VOREStaton Edit
|
||||
new_dna.custom_whisper=custom_whisper //VOREStaton Edit
|
||||
new_dna.custom_exclaim=custom_exclaim //VOREStaton Edit
|
||||
var/list/body_markings_genetic = (body_markings - body_marking_nopersist_list)
|
||||
new_dna.body_markings=body_markings_genetic.Copy()
|
||||
for(var/b=1;b<=DNA_SE_LENGTH;b++)
|
||||
new_dna.SE[b]=SE[b]
|
||||
if(b<=DNA_UI_LENGTH)
|
||||
|
||||
@@ -632,7 +632,7 @@ var/global/list/all_objectives = list()
|
||||
return
|
||||
|
||||
/datum/objective/heist/kidnap/choose_target()
|
||||
var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Station Engineer")
|
||||
var/list/roles = list("Chief Engineer","Research Director","Roboticist","Chemist","Engineer")
|
||||
var/list/possible_targets = list()
|
||||
var/list/priority_targets = list()
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ var/const/access_pilot = 67
|
||||
/datum/access/pilot
|
||||
id = access_pilot
|
||||
desc = "Pilot"
|
||||
region = ACCESS_REGION_SUPPLY
|
||||
region = ACCESS_REGION_GENERAL
|
||||
|
||||
/var/const/access_talon = 301
|
||||
/datum/access/talon
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
disallow_jobhop = TRUE
|
||||
pto_type = PTO_CIVILIAN
|
||||
dept_time_required = 80 //Pending something more complicated
|
||||
alt_titles = list("Overseer"= /datum/alt_title/overseer, "Facility Director" = /datum/alt_title/facility_director, "Chief Supervisor" = /datum/alt_title/chief_supervisor, "Captain" = /datum/alt_title/captain)
|
||||
alt_titles = list("Overseer"= /datum/alt_title/overseer, "Facility Director" = /datum/alt_title/facility_director, "Chief Supervisor" = /datum/alt_title/chief_supervisor,
|
||||
"Captain" = /datum/alt_title/captain)
|
||||
|
||||
/datum/alt_title/facility_director
|
||||
title = "Facility Director"
|
||||
@@ -13,7 +14,6 @@
|
||||
/datum/alt_title/captain
|
||||
title = "Captain"
|
||||
|
||||
|
||||
/datum/job/hop
|
||||
disallow_jobhop = TRUE
|
||||
pto_type = PTO_CIVILIAN
|
||||
|
||||
@@ -196,6 +196,38 @@
|
||||
title = "Monk"
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Pilot
|
||||
//////////////////////////////////
|
||||
|
||||
/datum/job/pilot
|
||||
title = "Pilot"
|
||||
flag = PILOT
|
||||
departments = list(DEPARTMENT_CIVILIAN)
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 5
|
||||
spawn_positions = 5
|
||||
supervisors = "the Head of Personnel"
|
||||
selection_color = "#515151"
|
||||
economic_modifier = 5
|
||||
minimal_player_age = 3
|
||||
pto_type = PTO_CIVILIAN
|
||||
access = list(access_pilot)
|
||||
minimal_access = list(access_pilot)
|
||||
outfit_type = /decl/hierarchy/outfit/job/pilot
|
||||
job_description = "A Pilot flies the various shuttles in the Virgo-Erigone System."
|
||||
alt_titles = list("Co-Pilot" = /datum/alt_title/co_pilot, "Navigator" = /datum/alt_title/navigator, "Helmsman" = /datum/alt_title/helmsman)
|
||||
|
||||
/datum/alt_title/co_pilot
|
||||
title = "Co-Pilot"
|
||||
title_blurb = "A Co-Pilot is there primarily to assist main pilot as well as learn from them"
|
||||
|
||||
/datum/alt_title/navigator
|
||||
title = "Navigator"
|
||||
|
||||
/datum/alt_title/helmsman
|
||||
title = "Helmsman"
|
||||
|
||||
//////////////////////////////////
|
||||
// Entertainer
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
// Engineer
|
||||
//////////////////////////////////
|
||||
/datum/job/engineer
|
||||
title = "Station Engineer"
|
||||
title = "Engineer"
|
||||
flag = ENGINEER
|
||||
departments = list(DEPARTMENT_ENGINEERING)
|
||||
department_flag = ENGSEC
|
||||
|
||||
@@ -55,37 +55,6 @@
|
||||
/datum/alt_title/exploration_manager
|
||||
title = "Exploration Manager"
|
||||
|
||||
|
||||
/datum/job/pilot
|
||||
title = "Pilot"
|
||||
flag = PILOT
|
||||
departments = list(DEPARTMENT_CIVILIAN)
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 5
|
||||
spawn_positions = 5
|
||||
supervisors = "the Head of Personnel"
|
||||
selection_color = "#515151"
|
||||
economic_modifier = 5
|
||||
minimal_player_age = 3
|
||||
pto_type = PTO_EXPLORATION
|
||||
access = list(access_pilot)
|
||||
minimal_access = list(access_pilot)
|
||||
outfit_type = /decl/hierarchy/outfit/job/pilot
|
||||
job_description = "A Pilot flies the various shuttles in the Virgo-Erigone System."
|
||||
alt_titles = list("Co-Pilot" = /datum/alt_title/co_pilot, "Navigator" = /datum/alt_title/navigator, "Helmsman" = /datum/alt_title/helmsman)
|
||||
|
||||
/datum/alt_title/co_pilot
|
||||
title = "Co-Pilot"
|
||||
title_blurb = "A Co-Pilot is there primarily to assist main pilot as well as learn from them"
|
||||
|
||||
/datum/alt_title/navigator
|
||||
title = "Navigator"
|
||||
|
||||
/datum/alt_title/helmsman
|
||||
title = "Helmsman"
|
||||
|
||||
|
||||
/datum/job/explorer
|
||||
title = "Explorer"
|
||||
flag = EXPLORER
|
||||
|
||||
@@ -59,6 +59,7 @@ var/const/TALPIL =(1<<1)
|
||||
var/const/TALDOC =(1<<2)
|
||||
var/const/TALSEC =(1<<3)
|
||||
var/const/TALENG =(1<<4)
|
||||
var/const/TALMIN =(1<<5)
|
||||
//VOREStation Add End
|
||||
|
||||
/proc/guest_jobbans(var/job)
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
if(H.reagents.reagent_list.len >= 1)
|
||||
for(var/datum/reagent/R in H.reagents.reagent_list)
|
||||
reagentData[++reagentData.len] = list(
|
||||
"name" = R.name,
|
||||
"name" = R.name,
|
||||
"amount" = R.volume,
|
||||
"overdose" = (R.overdose && R.volume > R.overdose) ? TRUE : FALSE,
|
||||
)
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured())
|
||||
organData["lungRuptured"] = 1
|
||||
|
||||
|
||||
for(var/datum/wound/W in E.wounds)
|
||||
if(W.internal)
|
||||
organData["internalBleeding"] = 1
|
||||
@@ -349,10 +349,10 @@
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(target))
|
||||
var/name = occupant ? occupant.name : "Unknown"
|
||||
P.info = "<CENTER><B>Body Scan - [name]</B></CENTER><BR>"
|
||||
P.info += "<b>Time of scan:</b> [worldtime2stationtime(world.time)]<br><br>"
|
||||
P.info += "<b>Time of scan:</b> [stationtime2text()]<br><br>"
|
||||
P.info += "[generate_printing_text()]"
|
||||
P.info += "<br><br><b>Notes:</b><br>"
|
||||
P.name = "Body Scan - [name] ([worldtime2stationtime(world.time)]"
|
||||
P.name = "Body Scan - [name] ([stationtime2text()]"
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -479,7 +479,7 @@
|
||||
var/obj/item/device/nif/N = I //VOREStation Add: NIFs
|
||||
if(istype(I) && I.known_implant)
|
||||
imp += "[I] implanted:"
|
||||
if(istype(N) && N.known_implant) //VOREStation Add: NIFs
|
||||
else if(istype(N) && N.known_implant) //VOREStation Add: NIFs
|
||||
imp += "[N] implanted:"
|
||||
else
|
||||
unknown_body++
|
||||
|
||||
@@ -230,4 +230,11 @@
|
||||
desc = "A shimmering forcefield that keeps the good air inside and the bad air outside. It seems fairly solid, almost like it's made out of some kind of hardened light.<br><br>Note: prolonged immersion in active atmospheric retention fields may have negative long-term health consequences."
|
||||
icon = 'icons/obj/atm_fieldgen.dmi'
|
||||
icon_state = "arfg_field"
|
||||
density = TRUE
|
||||
density = TRUE
|
||||
|
||||
/obj/machinery/atmospheric_field_generator/perma/underdoors
|
||||
field_type = /obj/structure/atmospheric_retention_field/underdoors
|
||||
|
||||
/obj/structure/atmospheric_retention_field/underdoors
|
||||
plane = OBJ_PLANE
|
||||
layer = UNDER_JUNK_LAYER
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
|
||||
/obj/machinery/portable_atmospherics/New()
|
||||
..()
|
||||
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
//VOREStation Edit - Fix runtime
|
||||
if(air_contents)
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
//VOREStation Edit End
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"Eyes" = list(/obj/item/organ/internal/eyes, 20),
|
||||
"Liver" = list(/obj/item/organ/internal/liver, 20),
|
||||
"Spleen" = list(/obj/item/organ/internal/spleen, 20),
|
||||
"Stomach" = list(/obj/item/organ/internal/stomach, 20),
|
||||
"Arm, Left" = list(/obj/item/organ/external/arm, 40),
|
||||
"Arm, Right" = list(/obj/item/organ/external/arm/right, 40),
|
||||
"Leg, Left" = list(/obj/item/organ/external/leg, 40),
|
||||
@@ -80,7 +81,7 @@
|
||||
/obj/machinery/organ_printer/Initialize()
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
|
||||
/obj/machinery/organ_printer/examine(var/mob/user)
|
||||
. = ..()
|
||||
var/biomass = get_biomass_volume()
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
/obj/item/toy/blink = 2,
|
||||
/obj/item/clothing/under/syndicate/tacticool = 2,
|
||||
/obj/item/toy/sword = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/capgun = 2,
|
||||
/obj/item/toy/crossbow = 2,
|
||||
/obj/item/weapon/storage/box/capguntoy = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/toy/crossbow = 2,
|
||||
/obj/item/clothing/suit/syndicatefake = 2,
|
||||
/obj/item/weapon/storage/fancy/crayons = 2,
|
||||
/obj/item/toy/spinningtoy = 2,
|
||||
@@ -1083,7 +1083,7 @@
|
||||
/obj/machinery/computer/arcade/clawmachine
|
||||
name = "AlliCo Grab-a-Gift"
|
||||
desc = "Show off your arcade skills for that special someone!"
|
||||
icon_state = "clawmachine"
|
||||
icon_state = "clawmachine_new"
|
||||
icon_keyboard = null
|
||||
icon_screen = null
|
||||
circuit = /obj/item/weapon/circuitboard/arcade/clawmachine
|
||||
@@ -1244,10 +1244,10 @@
|
||||
|
||||
/// TGUI Stuff
|
||||
|
||||
/obj/machinery/computer/arcade/clawmachine/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/arcade/clawmachine/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ClawMachine", name, 300, 400, master_ui, state)
|
||||
ui = new(user, src, "ClawMachine", name, ui_x = 300, ui_y = 400)
|
||||
ui.autoupdate = TRUE
|
||||
ui.open()
|
||||
|
||||
@@ -1270,7 +1270,7 @@
|
||||
|
||||
if(action == "newgame" && gamepaid == 1)
|
||||
gameStatus = "CLAWMACHINE_ON"
|
||||
icon_state = "clawmachine_move"
|
||||
icon_state = "clawmachine_new_move"
|
||||
instructions = "Guide the claw to the prize you want!"
|
||||
wintick = 0
|
||||
|
||||
@@ -1307,7 +1307,7 @@
|
||||
winscreen = "Aw, shucks. Try again!"
|
||||
wintick = 0
|
||||
gamepaid = 0
|
||||
icon_state = "clawmachine"
|
||||
icon_state = "clawmachine_new"
|
||||
gameStatus = "CLAWMACHINE_END"
|
||||
|
||||
/obj/machinery/computer/arcade/clawmachine/emag_act(mob/user)
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
/obj/item/toy/blink = 2,
|
||||
/obj/item/clothing/under/syndicate/tacticool = 2,
|
||||
/obj/item/toy/sword = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/capgun = 2,
|
||||
/obj/item/toy/crossbow = 2,
|
||||
/obj/item/weapon/storage/box/capguntoy = 2,
|
||||
/obj/item/weapon/gun/projectile/revolver/toy/crossbow = 2,
|
||||
/obj/item/clothing/suit/syndicatefake = 2,
|
||||
/obj/item/weapon/storage/fancy/crayons = 2,
|
||||
/obj/item/toy/spinningtoy = 2,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
name = "guest pass"
|
||||
desc = "Allows temporary access to station areas."
|
||||
icon_state = "guest"
|
||||
initial_sprite_stack = list()
|
||||
light_color = "#0099ff"
|
||||
|
||||
var/temp_access = list() //to prevent agent cards stealing access as permanent
|
||||
@@ -12,6 +13,9 @@
|
||||
var/expired = 0
|
||||
var/reason = "NOT SPECIFIED"
|
||||
|
||||
/obj/item/weapon/card/id/guest/update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/card/id/guest/GetAccess()
|
||||
if(world.time > expiration_time)
|
||||
return access
|
||||
|
||||
@@ -50,6 +50,11 @@
|
||||
if(istype(P, /obj/item/weapon/circuitboard))
|
||||
var/obj/item/weapon/circuitboard/B = P
|
||||
if(B.board_type == "machine")
|
||||
//VOREStation Addition End
|
||||
if(istype(B, /obj/item/weapon/circuitboard/quantumpad) && istype(get_area(src), /area/shuttle))
|
||||
to_chat(user, "<span class='warning'>This is too unstable a platform for a quantum pad to operate on!</span>")
|
||||
return
|
||||
//VOREStation Addition End
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You add the circuit board to the frame.</span>")
|
||||
circuit = P
|
||||
|
||||
@@ -979,6 +979,7 @@ About the new airlock wires panel:
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/AltClick(mob/user as mob)
|
||||
. = ..()
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if(!Adjacent(user))
|
||||
return
|
||||
@@ -988,13 +989,13 @@ About the new airlock wires panel:
|
||||
if(icon_state == "door_closed" && arePowerSystemsOn())
|
||||
flick("door_deny", src)
|
||||
playsound(src, knock_hammer_sound, 50, 0, 3)
|
||||
else if(arePowerSystemsOn())
|
||||
else if(arePowerSystemsOn() && user.a_intent == I_HELP)
|
||||
src.visible_message("[user] presses the door bell on \the [src].", "\The [src]'s bell rings.")
|
||||
src.add_fingerprint(user)
|
||||
if(icon_state == "door_closed")
|
||||
flick("door_deny", src)
|
||||
playsound(src, knock_sound, 50, 0, 3)
|
||||
else
|
||||
else if(user.a_intent == I_HELP)
|
||||
src.visible_message("[user] knocks on \the [src].", "Someone knocks on \the [src].")
|
||||
src.add_fingerprint(user)
|
||||
playsound(src, knock_unpowered_sound, 50, 0, 3)
|
||||
|
||||
@@ -319,6 +319,23 @@
|
||||
density = FALSE
|
||||
opacity = 0
|
||||
|
||||
|
||||
// SUBTYPE: Shuttle
|
||||
// Slightly weaker, intergrated shutters - open state is hidden from view. Found on fancy_shuttles
|
||||
/obj/machinery/door/blast/shuttle
|
||||
name = "shuttle blast doors"
|
||||
icon_state_open = "spdoor0"
|
||||
icon_state_opening = "spdoorc0"
|
||||
icon_state_closed = "spdoor1"
|
||||
icon_state_closing = "spdoorc1"
|
||||
icon_state = "spdoor1"
|
||||
maxhealth = 400
|
||||
|
||||
/obj/machinery/door/blast/shuttle/open
|
||||
icon_state = "spdoor0"
|
||||
density = FALSE
|
||||
opacity = 0
|
||||
|
||||
// SUBTYPE: Shutters
|
||||
// Nicer looking, and also weaker, shutters. Found in kitchen and similar areas.
|
||||
/obj/machinery/door/blast/shutters
|
||||
|
||||
@@ -101,7 +101,19 @@
|
||||
/obj/machinery/door/blast/regular/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return // blast doors are immune to fire completely.
|
||||
|
||||
/obj/machinery/door/blast/regular/
|
||||
/obj/machinery/door/blast/regular
|
||||
heat_proof = 1 //just so repairing them doesn't try to fireproof something that never takes fire damage
|
||||
|
||||
/obj/machinery/door/blast/angled/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return // blast doors are immune to fire completely.
|
||||
|
||||
/obj/machinery/door/blast/angled
|
||||
heat_proof = 1 //just so repairing them doesn't try to fireproof something that never takes fire damage
|
||||
|
||||
/obj/machinery/door/blast/puzzle/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return // blast doors are immune to fire completely.
|
||||
|
||||
/obj/machinery/door/blast/puzzle
|
||||
heat_proof = 1 //just so repairing them doesn't try to fireproof something that never takes fire damage
|
||||
|
||||
/obj/machinery/door/proc/toggle()
|
||||
|
||||
@@ -16,3 +16,8 @@
|
||||
name = "\improper Emergency Shutter System"
|
||||
desc = "Emergency air-tight shutter, capable of sealing off breached areas. This model fits flush with the walls, and has a panel in the floor for maintenance."
|
||||
icon = 'icons/obj/doors/DoorHazardHidden_steel.dmi'
|
||||
|
||||
/obj/machinery/door/firedoor/glass/hidden/shuttle
|
||||
name = "\improper Emergency Shuttle Shutters"
|
||||
desc = "Emergency air-tight shutter, capable of sealing off breached areas. This model fits flush with shuttle walls."
|
||||
icon = 'icons/obj/doors/DoorHazardHidden_shuttle.dmi'
|
||||
@@ -134,7 +134,7 @@ GLOBAL_LIST_INIT(disposal_pipe_recipes, list(
|
||||
dirtype = initial(construction_type.dispenser_class)
|
||||
if (dirtype == PIPE_TRIN_M)
|
||||
icon_state_m = "[icon_state]m"
|
||||
paintable = ispath(path, /obj/machinery/atmospherics/pipe) && !(ispath(path, /obj/machinery/atmospherics/pipe/vent)) // VOREStation Add
|
||||
paintable = !ispath(path, /obj/machinery/atmospherics/pipe/simple/heat_exchanging) && ispath(path, /obj/machinery/atmospherics/pipe) && !(ispath(path, /obj/machinery/atmospherics/pipe/vent)) // VOREStation Add
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
|
||||
/obj/machinery/pump
|
||||
name = "fluid pump"
|
||||
desc = "A fluid pumping machine."
|
||||
|
||||
description_info = "A machine that can pump fluid from certain turfs.<br>\
|
||||
Water can be pumped from any body of water. Certain locations or environmental\
|
||||
conditions can cause different byproducts to be produced.<br>\
|
||||
Magma or Lava can be pumped to produce mineralized fluid."
|
||||
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
|
||||
icon = 'icons/obj/machines/reagent.dmi'
|
||||
icon_state = "pump"
|
||||
|
||||
circuit = /obj/item/weapon/circuitboard/fluidpump
|
||||
|
||||
var/on = 0
|
||||
var/obj/item/weapon/cell/cell = null
|
||||
var/use = 200
|
||||
var/efficiency = 1
|
||||
var/reagents_per_cycle = 40
|
||||
var/unlocked = 0
|
||||
var/open = 0
|
||||
|
||||
var/obj/item/hose_connector/output/Output
|
||||
|
||||
// Overlay cache vars.
|
||||
var/icon/liquid
|
||||
var/icon/tank
|
||||
var/icon/powerlow
|
||||
var/icon/glass
|
||||
var/icon/open_overlay
|
||||
var/icon/cell_overlay
|
||||
|
||||
/obj/machinery/pump/Initialize()
|
||||
create_reagents(200)
|
||||
. = ..()
|
||||
default_apply_parts()
|
||||
|
||||
if(ispath(cell))
|
||||
cell = new cell(src)
|
||||
|
||||
Output = new(src)
|
||||
|
||||
RefreshParts()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/pump/update_icon()
|
||||
..()
|
||||
if(!tank)
|
||||
tank = new/icon(icon, "[icon_state]-volume")
|
||||
|
||||
if(!powerlow)
|
||||
powerlow = new/icon(icon, "[icon_state]-lowpower")
|
||||
|
||||
if(!liquid)
|
||||
var/icon/cutter = new/icon(icon, "[icon_state]-volume")
|
||||
|
||||
cutter.Blend(rgb(0, 0, 0,), ICON_MULTIPLY)
|
||||
|
||||
liquid = new/icon(icon, "[icon_state]-cutting")
|
||||
|
||||
liquid.Blend(cutter,ICON_AND)
|
||||
|
||||
if(!glass)
|
||||
glass = new/icon(icon, "[icon_state]-glass")
|
||||
|
||||
glass.Blend(rgb(1,1,1,0.5), ICON_MULTIPLY)
|
||||
|
||||
if(!open_overlay)
|
||||
open_overlay = new/icon(icon, "[icon_state]-open")
|
||||
|
||||
if(!cell_overlay)
|
||||
cell_overlay = new/icon(icon, "[icon_state]-cell")
|
||||
|
||||
cut_overlays()
|
||||
add_overlay(tank)
|
||||
|
||||
if(cell && cell.charge < (use * CELLRATE / efficiency))
|
||||
add_overlay(powerlow)
|
||||
|
||||
if(reagents.total_volume >= 1)
|
||||
var/list/hextorgb = hex2rgb(reagents.get_color())
|
||||
liquid.GrayScale()
|
||||
|
||||
liquid.Blend(rgb(hextorgb[1],hextorgb[2],hextorgb[3]),ICON_MULTIPLY)
|
||||
|
||||
add_overlay(liquid)
|
||||
|
||||
add_overlay(glass)
|
||||
|
||||
if(open)
|
||||
add_overlay(open_overlay)
|
||||
|
||||
if(cell)
|
||||
add_overlay(cell_overlay)
|
||||
|
||||
if(on)
|
||||
icon_state = "[initial(icon_state)]-running"
|
||||
|
||||
else
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/machinery/pump/process()
|
||||
if(Output.get_pairing())
|
||||
reagents.trans_to_holder(Output.reagents, Output.reagents.maximum_volume)
|
||||
if(prob(5))
|
||||
visible_message("<b>\The [src]</b> gurgles as it exports fluid.")
|
||||
|
||||
if(!on)
|
||||
return
|
||||
|
||||
if(!cell || (cell.charge < (use * CELLRATE / efficiency)))
|
||||
turn_off(TRUE)
|
||||
return
|
||||
|
||||
handle_pumping()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/pump/RefreshParts()
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/SM in component_parts)
|
||||
efficiency = SM.rating
|
||||
|
||||
var/total_bin_rating = 0
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/SB in component_parts)
|
||||
total_bin_rating += SB.rating
|
||||
|
||||
reagents.maximum_volume = round(initial(reagents.maximum_volume) + 100 * total_bin_rating)
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/pump/power_change()
|
||||
if(!cell || cell.charge < (use * CELLRATE) || !anchored)
|
||||
return turn_off(TRUE)
|
||||
|
||||
return FALSE
|
||||
|
||||
|
||||
// Returns 0 on failure and 1 on success
|
||||
/obj/machinery/pump/proc/turn_on(var/loud = 0)
|
||||
if(!cell)
|
||||
return 0
|
||||
if(cell.charge < (use * CELLRATE))
|
||||
return 0
|
||||
|
||||
on = 1
|
||||
update_icon()
|
||||
if(loud)
|
||||
visible_message("<b>\The [src]</b> turns on.")
|
||||
return 1
|
||||
|
||||
/obj/machinery/pump/proc/turn_off(var/loud = 0)
|
||||
on = 0
|
||||
set_light(0, 0)
|
||||
update_icon()
|
||||
if(loud)
|
||||
visible_message("<b>\The [src]</b> shuts down.")
|
||||
|
||||
if(!on)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/pump/attack_ai(mob/user as mob)
|
||||
if(istype(user, /mob/living/silicon/robot) && Adjacent(user))
|
||||
return attack_hand(user)
|
||||
|
||||
if(on)
|
||||
turn_off(TRUE)
|
||||
else
|
||||
if(!turn_on(1))
|
||||
to_chat(user, "<span class='notice'>You try to turn on \the [src] but it does not work.</span>")
|
||||
|
||||
/obj/machinery/pump/attack_hand(mob/user as mob)
|
||||
if(open && cell)
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(cell)
|
||||
cell.loc = user.loc
|
||||
else
|
||||
cell.loc = src.loc
|
||||
|
||||
cell.add_fingerprint(user)
|
||||
cell.update_icon()
|
||||
|
||||
cell = null
|
||||
on = 0
|
||||
set_light(0)
|
||||
to_chat(user, "<span class='notice'>You remove the power cell.</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(on)
|
||||
turn_off(TRUE)
|
||||
else if(anchored)
|
||||
if(!turn_on(1))
|
||||
to_chat(user, "<span class='notice'>You try to turn on \the [src] but it does not work.</span>")
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/pump/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(W.is_screwdriver())
|
||||
if(!open)
|
||||
if(unlocked)
|
||||
unlocked = 0
|
||||
to_chat(user, "<span class='notice'>You screw the battery panel in place.</span>")
|
||||
else
|
||||
unlocked = 1
|
||||
to_chat(user, "<span class='notice'>You unscrew the battery panel.</span>")
|
||||
|
||||
else if(W.is_crowbar())
|
||||
if(unlocked)
|
||||
if(open)
|
||||
open = 0
|
||||
overlays = null
|
||||
to_chat(user, "<span class='notice'>You crowbar the battery panel in place.</span>")
|
||||
else
|
||||
if(unlocked)
|
||||
open = 1
|
||||
to_chat(user, "<span class='notice'>You remove the battery panel.</span>")
|
||||
|
||||
else if(W.is_wrench())
|
||||
if(on)
|
||||
to_chat(user, "<span class='notice'>\The [src] is active. Turn it off before trying to move it!</span>")
|
||||
return
|
||||
default_unfasten_wrench(user, W, 2 SECONDS)
|
||||
|
||||
else if(istype(W, /obj/item/weapon/cell))
|
||||
if(open)
|
||||
if(cell)
|
||||
to_chat(user, "<span class='notice'>There is a power cell already installed.</span>")
|
||||
else
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
cell = W
|
||||
to_chat(user, "<span class='notice'>You insert the power cell.</span>")
|
||||
else
|
||||
..()
|
||||
RefreshParts()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/pump/proc/handle_pumping()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(istype(T, /turf/simulated/floor/water))
|
||||
cell.use(use * CELLRATE / efficiency)
|
||||
reagents.add_reagent("water", reagents_per_cycle)
|
||||
|
||||
if(T.temperature <= T0C)
|
||||
reagents.add_reagent("ice", round(reagents_per_cycle / 2, 0.1))
|
||||
|
||||
if((istype(T,/turf/simulated/floor/water/pool) || istype(T,/turf/simulated/floor/water/deep/pool)))
|
||||
reagents.add_reagent("chlorine", round(reagents_per_cycle / 10 * efficiency, 0.1))
|
||||
|
||||
else if(istype(T,/turf/simulated/floor/water/contaminated))
|
||||
reagents.add_reagent("vatstabilizer", round(reagents_per_cycle / 2))
|
||||
|
||||
if(T.loc.name == "Sea") // Saltwater.
|
||||
reagents.add_reagent("sodiumchloride", round(reagents_per_cycle / 10 * efficiency, 0.1))
|
||||
|
||||
for(var/turf/simulated/mineral/MT in range(5))
|
||||
if(MT.mineral)
|
||||
var/obj/effect/mineral/OR = MT.mineral
|
||||
reagents.add_reagent(OR.ore_reagent, round(reagents_per_cycle / 20 * efficiency, 0.1))
|
||||
|
||||
else if(istype(T, /turf/simulated/floor/lava))
|
||||
cell.use(use * CELLRATE / efficiency * 4)
|
||||
reagents.add_reagent("mineralizedfluid", round(reagents_per_cycle * efficiency / 2, 0.1))
|
||||
@@ -10,7 +10,7 @@
|
||||
name = ""
|
||||
department = ""
|
||||
departmentType = ""
|
||||
announcementConsole = 0
|
||||
announcementConsole = TRUE
|
||||
|
||||
// Departments
|
||||
/obj/machinery/requests_console/preset/cargo
|
||||
|
||||
@@ -286,6 +286,10 @@ GLOBAL_LIST_EMPTY(suit_cycler_emagged)
|
||||
name = "Talon Pilot (Closed Helm)"
|
||||
helmet_becomes = /obj/item/clothing/head/helmet/space/void/refurb/pilot/alt/talon
|
||||
suit_becomes = /obj/item/clothing/suit/space/void/refurb/pilot/talon
|
||||
/datum/suit_cycler_choice/department/talon/miner
|
||||
name = "Talon Miner"
|
||||
helmet_becomes = /obj/item/clothing/head/helmet/space/void/refurb/mining/talon
|
||||
suit_becomes = /obj/item/clothing/suit/space/void/refurb/mining/talon
|
||||
/datum/suit_cycler_choice/department/talon/res
|
||||
name = "Talon Research (Bubble Helm)"
|
||||
helmet_becomes = /obj/item/clothing/head/helmet/space/void/refurb/research/alt/talon
|
||||
|
||||
@@ -52,4 +52,10 @@
|
||||
name = "Talon captain suit cycler"
|
||||
model_text = "Talon captain"
|
||||
req_access = list(access_talon)
|
||||
departments = list(/datum/suit_cycler_choice/department/talon/officer)
|
||||
departments = list(/datum/suit_cycler_choice/department/talon/officer)
|
||||
|
||||
/obj/machinery/suit_cycler/vintage/tminer
|
||||
name = "Talon miner suit cycler"
|
||||
model_text = "Talon miner"
|
||||
req_access = list(access_talon)
|
||||
departments = list(/datum/suit_cycler_choice/department/talon/miner)
|
||||
@@ -185,7 +185,8 @@
|
||||
if(!forced && avatar && tgui_alert(avatar, "Someone wants to remove you from virtual reality. Do you want to leave?", "Leave VR?", list("Yes", "No")) == "No")
|
||||
return
|
||||
|
||||
avatar.exit_vr()
|
||||
if(avatar)
|
||||
avatar.exit_vr()
|
||||
avatar = null
|
||||
|
||||
if(occupant.client)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "frame_bitem"
|
||||
var/build_machine_type
|
||||
var/build_wall_only = FALSE
|
||||
var/refund_amt = 5
|
||||
var/refund_type = /obj/item/stack/material/steel
|
||||
var/reverse = 0 //if resulting object faces opposite its dir (like light fixtures)
|
||||
@@ -27,7 +28,7 @@
|
||||
..()
|
||||
update_type_list()
|
||||
var/datum/frame/frame_types/frame_type
|
||||
if(!build_machine_type)
|
||||
if(!build_machine_type && !build_wall_only)
|
||||
var/datum/frame/frame_types/response = tgui_input_list(user, "What kind of frame would you like to make?", "Frame type request", frame_types_floor)
|
||||
if(!response)
|
||||
return
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
desc = "You're not so sure about this, anymore..."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "syndbeacon"
|
||||
use_power = USE_POWER_OFF
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/charges = 1
|
||||
var/insisting = 0
|
||||
|
||||
/obj/machinery/wish_granter/attack_hand(var/mob/user as mob)
|
||||
anchored = 1
|
||||
density = 1
|
||||
use_power = USE_POWER_OFF
|
||||
|
||||
var/chargesa = 1
|
||||
var/insistinga = 0
|
||||
|
||||
/obj/machinery/wish_granter/attack_hand(var/mob/living/carbon/human/user as mob)
|
||||
usr.set_machine(src)
|
||||
|
||||
if(charges <= 0)
|
||||
if(chargesa <= 0)
|
||||
to_chat(user, "The Wish Granter lies silent.")
|
||||
return
|
||||
|
||||
@@ -23,47 +25,45 @@
|
||||
else if(is_special_character(user))
|
||||
to_chat(user, "Even to a heart as dark as yours, you know nothing good will come of this. Something instinctual makes you pull away.")
|
||||
|
||||
else if(!insisting)
|
||||
else if (!insistinga)
|
||||
to_chat(user, "Your first touch makes the Wish Granter stir, listening to you. Are you really sure you want to do this?")
|
||||
insisting++
|
||||
insistinga++
|
||||
|
||||
else
|
||||
var/message = "You speak. [pick("I want the station to disappear","Humanity is corrupt, mankind must be destroyed","I want to be rich", "I want to rule the world","I want immortality.")]. The Wish Granter answers."
|
||||
to_chat(user, message)
|
||||
to_chat(user, "Your head pounds for a moment, before your vision clears. You are the avatar of the Wish Granter, and your power is LIMITLESS! And it's all yours. You need to make sure no one can take it from you. No one can know, first.")
|
||||
|
||||
charges--
|
||||
insisting = 0
|
||||
|
||||
if(!(HULK in user.mutations))
|
||||
user.mutations.Add(HULK)
|
||||
|
||||
if(!(LASER in user.mutations))
|
||||
user.mutations.Add(LASER)
|
||||
|
||||
if(!(XRAY in user.mutations))
|
||||
user.mutations.Add(XRAY)
|
||||
user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
|
||||
user.see_in_dark = 8
|
||||
user.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
|
||||
if(!(COLD_RESISTANCE in user.mutations))
|
||||
user.mutations.Add(COLD_RESISTANCE)
|
||||
|
||||
if(!(TK in user.mutations))
|
||||
user.mutations.Add(TK)
|
||||
|
||||
if(!(HEAL in user.mutations))
|
||||
user.mutations.Add(HEAL)
|
||||
|
||||
user.update_mutations()
|
||||
user.mind.special_role = "Avatar of the Wish Granter"
|
||||
|
||||
var/datum/objective/silence/silence = new
|
||||
silence.owner = user.mind
|
||||
user.mind.objectives += silence
|
||||
|
||||
show_objectives(user.mind)
|
||||
to_chat(user, "You have a very bad feeling about this.")
|
||||
|
||||
return
|
||||
chargesa--
|
||||
insistinga = 0
|
||||
var/wish = tgui_input_list(usr, "You want...","Wish", list("Power","Wealth","Immortality","To Kill","Peace"))
|
||||
switch(wish)
|
||||
if("Power")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul.")
|
||||
if (!(LASER in user.mutations))
|
||||
user.mutations.Add(LASER)
|
||||
to_chat(user, "<span class='notice'>You feel pressure building behind your eyes.</span>")
|
||||
if (!(COLD_RESISTANCE in user.mutations))
|
||||
user.mutations.Add(COLD_RESISTANCE)
|
||||
to_chat(user, "<span class='notice'>Your body feels warm.</span>")
|
||||
if (!(XRAY in user.mutations))
|
||||
user.mutations.Add(XRAY)
|
||||
user.sight |= (SEE_MOBS|SEE_OBJS|SEE_TURFS)
|
||||
user.see_in_dark = 8
|
||||
user.see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
to_chat(user, "<span class='notice'>The walls suddenly disappear.</span>")
|
||||
if("Wealth")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul.")
|
||||
new /obj/structure/closet/syndicate/resources/everything(loc)
|
||||
if("To Kill")
|
||||
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
|
||||
to_chat(user, "The Wish Granter is outraged at your excessive wickedness, yet grants you your wish regardless. Someone will be killed soon.")
|
||||
spawn(100)
|
||||
if(user)
|
||||
to_chat(user, "Suddenly, you feel as though you are being torn to countless shreds! Your wish is coming true!")
|
||||
user.gib()
|
||||
if("Peace")
|
||||
to_chat(user, "<B>Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence.</B>")
|
||||
to_chat(user, "You feel as if you just narrowly avoided a terrible fate...")
|
||||
for(var/mob/living/simple_mob/faithless/F in living_mob_list)
|
||||
F.health = -10
|
||||
F.set_stat(DEAD)
|
||||
F.icon_state = "faithless_dead"
|
||||
@@ -48,6 +48,43 @@
|
||||
if(!action_checks())
|
||||
return chassis.dyndomove(direction)
|
||||
var/move_result = 0
|
||||
if(direction == UP || direction == DOWN)
|
||||
if(!chassis.can_ztravel())
|
||||
chassis.occupant_message("<span class='warning'>Your vehicle lacks the capacity to move in that direction!</span>")
|
||||
return FALSE
|
||||
|
||||
//We're using locs because some mecha are 2x2 turfs. So thicc!
|
||||
var/result = TRUE
|
||||
|
||||
for(var/turf/T in chassis.locs)
|
||||
if(!T.CanZPass(chassis,direction))
|
||||
chassis.occupant_message("<span class='warning'>You can't move that direction from here!</span>")
|
||||
result = FALSE
|
||||
break
|
||||
var/turf/dest = (direction == UP) ? GetAbove(chassis) : GetBelow(chassis)
|
||||
if(!dest)
|
||||
chassis.occupant_message("<span class='notice'>There is nothing of interest in this direction.</span>")
|
||||
result = FALSE
|
||||
break
|
||||
if(!dest.CanZPass(chassis,direction))
|
||||
chassis.occupant_message("<span class='warning'>There's something blocking your movement in that direction!</span>")
|
||||
result = FALSE
|
||||
break
|
||||
if(result)
|
||||
move_result = chassis.mechstep(direction)
|
||||
|
||||
if(move_result)
|
||||
chassis.can_move = 0
|
||||
chassis.use_power(chassis.step_energy_drain)
|
||||
if(istype(chassis.loc, /turf/space))
|
||||
if(!chassis.check_for_support())
|
||||
chassis.float_direction = direction
|
||||
chassis.start_process(MECHA_PROC_MOVEMENT)
|
||||
chassis.log_message("<span class='warning'>Movement control lost. Inertial movement started.</span>")
|
||||
if(chassis.do_after(get_step_delay()))
|
||||
chassis.can_move = 1
|
||||
return 1
|
||||
return 0
|
||||
if(chassis.hasInternalDamage(MECHA_INT_CONTROL_LOST))
|
||||
move_result = step_rand(chassis)
|
||||
else if(chassis.dir!=direction)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/storage
|
||||
name = "auxillary exosuit storage bay"
|
||||
desc = "An auxillary storage compartment, for attaching to exosuits."
|
||||
icon_state = "mecha_tiler"
|
||||
icon = 'icons/mecha/mecha_equipment_vr.dmi'
|
||||
origin_tech = list(TECH_MATERIAL = 3)
|
||||
range = 0
|
||||
var/storage_added = 5
|
||||
equip_type = EQUIP_SPECIAL
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/storage/attach(obj/mecha/M)
|
||||
. = ..()
|
||||
M.cargo_capacity += storage_added
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/storage/detach()
|
||||
chassis.cargo_capacity -= storage_added
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/storage/bluespace
|
||||
name = "auxillary exosuit storage wormhole"
|
||||
desc = "An auxillary storage wormhole, utilizing a localized rip in bluespace for storage. Interestingly enough, teleport-stable, \
|
||||
despite its blatant disregard for the fabric of reality or reality-adjacency."
|
||||
icon_state = "mecha_phase_array"
|
||||
storage_added = 15
|
||||
origin_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 4, TECH_MAGNET = 4, TECH_POWER = 5, TECH_BLUESPACE = 3)
|
||||
@@ -101,7 +101,7 @@
|
||||
var/list/equipment = new //This lists holds what stuff you bolted onto your baby ride
|
||||
var/obj/item/mecha_parts/mecha_equipment/selected
|
||||
var/max_equip = 2
|
||||
|
||||
|
||||
// What direction to float in, if inertial movement is active.
|
||||
var/float_direction = 0
|
||||
// Process() iterator count.
|
||||
@@ -833,7 +833,7 @@
|
||||
if(hasInternalDamage(MECHA_INT_CONTROL_LOST))
|
||||
move_result = mechsteprand()
|
||||
//Up/down zmove
|
||||
else if(direction & UP || direction & DOWN)
|
||||
else if(direction == UP || direction == DOWN)
|
||||
if(!can_ztravel())
|
||||
occupant_message("<span class='warning'>Your vehicle lacks the capacity to move in that direction!</span>")
|
||||
return FALSE
|
||||
@@ -846,7 +846,7 @@
|
||||
occupant_message("<span class='warning'>You can't move that direction from here!</span>")
|
||||
result = FALSE
|
||||
break
|
||||
var/turf/dest = direction & UP ? GetAbove(T) : GetBelow(T)
|
||||
var/turf/dest = (direction == UP) ? GetAbove(src) : GetBelow(src)
|
||||
if(!dest)
|
||||
occupant_message("<span class='notice'>There is nothing of interest in this direction.</span>")
|
||||
result = FALSE
|
||||
@@ -2483,8 +2483,8 @@
|
||||
var/obj/item/mecha_parts/mecha_equipment/equip = top_filter.getObj("select_equip")
|
||||
if(equip)
|
||||
src.selected = equip
|
||||
src.occupant_message("You switch to [equip]")
|
||||
src.visible_message("[src] raises [equip]")
|
||||
src.occupant_message("You switch to [equip].")
|
||||
src.visible_message("[src] raises [equip].")
|
||||
send_byjax(src.occupant,"exosuit.browser","eq_list",src.get_equipment_list())
|
||||
return
|
||||
if(href_list["eject"])
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
name = "Virgo Orbital Research Establishment"
|
||||
desc = "It features the logo of the local branch of Nanotrasen; Virgo Orbital Research Establishment."
|
||||
/decl/poster/vore_95
|
||||
icon_state = "3btetherposter"
|
||||
icon_state = "tetherposter"
|
||||
name = "The Frontier Awaits"
|
||||
desc = "A stunning depiction of Virgo 3b in front of a field of stars, a purple nebula laces in from behind, while the shining tower of NSB Adephagia gleams in the starlight. 'The Frontier Awaits' is printed in silver lettering. It looks like a recruitment ad."
|
||||
/decl/poster/vore_96
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/obj/effect/landmark/start/atmostech
|
||||
name = "Atmospheric Technician"
|
||||
/obj/effect/landmark/start/engineer
|
||||
name = "Station Engineer"
|
||||
name = "Engineer"
|
||||
/obj/effect/landmark/start/cmo
|
||||
name = "Chief Medical Officer"
|
||||
/obj/effect/landmark/start/chemist
|
||||
@@ -90,3 +90,5 @@
|
||||
name = "Talon Guard"
|
||||
/obj/effect/landmark/start/talonpilot
|
||||
name = "Talon Pilot"
|
||||
/obj/effect/landmark/start/talonminer
|
||||
name = "Talon Miner"
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
return
|
||||
if("JoinLateGateway")
|
||||
latejoin_gateway += loc
|
||||
latejoin += src //VOREStation Addition
|
||||
delete_me = 1
|
||||
return
|
||||
if("JoinLateElevator")
|
||||
@@ -77,6 +78,12 @@
|
||||
endgame_exits += loc
|
||||
delete_me = 1
|
||||
return
|
||||
//VOREStation Add Start
|
||||
if("vinestart")
|
||||
vinestart += loc
|
||||
delete_me = 1
|
||||
return
|
||||
//VORE Station Add End
|
||||
|
||||
landmarks_list += src
|
||||
return 1
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
/obj/effect/landmark
|
||||
var/abductor = 0
|
||||
|
||||
/obj/effect/landmark/vines
|
||||
name = "vinestart"
|
||||
|
||||
/obj/effect/landmark/vermin
|
||||
name = "verminstart"
|
||||
|
||||
/obj/effect/landmark/late_antag
|
||||
name = "Antag Latespawn"
|
||||
var/antag_id
|
||||
@@ -39,4 +45,4 @@
|
||||
|
||||
/obj/effect/landmark/late_antag/raider
|
||||
name = "Raider - Lateload"
|
||||
antag_id = MODE_RAIDER
|
||||
antag_id = MODE_RAIDER
|
||||
|
||||
@@ -51,11 +51,16 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
list(/mob/living/simple_mob/animal/passive/opossum),
|
||||
list(/mob/living/simple_mob/animal/passive/pillbug),
|
||||
list(/mob/living/simple_mob/animal/passive/snake),
|
||||
list(/mob/living/simple_mob/animal/passive/snake/red),
|
||||
list(/mob/living/simple_mob/animal/passive/snake/python),
|
||||
list(/mob/living/simple_mob/animal/passive/tindalos),
|
||||
list(/mob/living/simple_mob/animal/passive/yithian),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf = 10,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 1
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 5,
|
||||
/mob/living/simple_mob/vore/greatwolf = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/black = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/grey = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/rabbit),
|
||||
list(/mob/living/simple_mob/vore/redpanda),
|
||||
@@ -109,12 +114,8 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
/mob/living/simple_mob/animal/giant_spider/phorogenic = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/thermic = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/tunneler = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/webslinger = 5
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf = 10,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 1
|
||||
),
|
||||
/mob/living/simple_mob/animal/giant_spider/webslinger = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/broodmother = 1),
|
||||
list(/mob/living/simple_mob/creature/strong),
|
||||
list(/mob/living/simple_mob/faithless/strong),
|
||||
list(/mob/living/simple_mob/animal/goat),
|
||||
@@ -244,7 +245,6 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
list(/mob/living/simple_mob/mechanical/wahlem),
|
||||
list(/mob/living/simple_mob/animal/passive/fox/syndicate),
|
||||
list(/mob/living/simple_mob/animal/passive/fox),
|
||||
list(/mob/living/simple_mob/animal/wolf/direwolf),
|
||||
list(/mob/living/simple_mob/animal/space/jelly),
|
||||
list(
|
||||
/mob/living/simple_mob/otie/feral,
|
||||
@@ -253,12 +253,12 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
/mob/living/simple_mob/otie/red/chubby
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/shadekin/blue/ai = 100,
|
||||
/mob/living/simple_mob/shadekin/green/ai = 50,
|
||||
/mob/living/simple_mob/shadekin/orange/ai = 20,
|
||||
/mob/living/simple_mob/shadekin/purple/ai = 60,
|
||||
/mob/living/simple_mob/shadekin/red/ai = 40,
|
||||
/mob/living/simple_mob/shadekin/yellow/ai = 1
|
||||
/mob/living/simple_mob/shadekin/blue = 100,
|
||||
/mob/living/simple_mob/shadekin/green = 50,
|
||||
/mob/living/simple_mob/shadekin/orange = 20,
|
||||
/mob/living/simple_mob/shadekin/purple = 60,
|
||||
/mob/living/simple_mob/shadekin/red = 40,
|
||||
/mob/living/simple_mob/shadekin/yellow = 1
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/aggressive/corrupthound,
|
||||
@@ -292,7 +292,21 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/solargrub),
|
||||
list(/mob/living/simple_mob/vore/woof),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi)
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_ghost),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/catslug),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/startreader),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/bigdragon,
|
||||
/mob/living/simple_mob/vore/bigdragon/friendly),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/leopardmander = 50,
|
||||
/mob/living/simple_mob/vore/leopardmander/blue = 10,
|
||||
/mob/living/simple_mob/vore/leopardmander/exotic = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/sheep),
|
||||
list(/mob/living/simple_mob/vore/weretiger)
|
||||
)
|
||||
|
||||
/obj/random/mob/semirandom_mob_spawner/item_to_spawn()
|
||||
@@ -359,11 +373,16 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
list(/mob/living/simple_mob/animal/passive/opossum) = 10,
|
||||
list(/mob/living/simple_mob/animal/passive/pillbug) = 10,
|
||||
list(/mob/living/simple_mob/animal/passive/snake) = 10,
|
||||
list(/mob/living/simple_mob/animal/passive/snake/red) = 10,
|
||||
list(/mob/living/simple_mob/animal/passive/snake/python) = 10,
|
||||
list(/mob/living/simple_mob/animal/passive/tindalos) = 10,
|
||||
list(/mob/living/simple_mob/animal/passive/yithian) = 10,
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf = 10,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 1
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 5,
|
||||
/mob/living/simple_mob/vore/greatwolf = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/black = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/grey = 1
|
||||
) = 10,
|
||||
list(/mob/living/simple_mob/vore/rabbit) = 10,
|
||||
list(/mob/living/simple_mob/vore/redpanda) = 10,
|
||||
@@ -407,7 +426,18 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
) = 5,
|
||||
list(/mob/living/simple_mob/animal/sif/siffet) = 5,
|
||||
list(/mob/living/simple_mob/animal/sif/tymisian) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 10
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 10,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/dustjumper) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_ghost) = 5,
|
||||
list(
|
||||
/mob/living/simple_mob/vore/leopardmander = 50,
|
||||
/mob/living/simple_mob/vore/leopardmander/blue = 10,
|
||||
/mob/living/simple_mob/vore/leopardmander/exotic = 1
|
||||
) = 5,
|
||||
list(/mob/living/simple_mob/vore/sheep) = 5,
|
||||
list(/mob/living/simple_mob/vore/weretiger) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/skeleton) = 5
|
||||
)
|
||||
|
||||
/obj/random/mob/semirandom_mob_spawner/monster
|
||||
@@ -433,14 +463,17 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
/mob/living/simple_mob/animal/giant_spider/webslinger = 5
|
||||
) = 100,
|
||||
list(
|
||||
/mob/living/simple_mob/shadekin/red/ai = 5,
|
||||
/mob/living/simple_mob/shadekin/orange/ai = 1,
|
||||
/mob/living/simple_mob/shadekin/purple/ai = 10
|
||||
/mob/living/simple_mob/shadekin/red = 5,
|
||||
/mob/living/simple_mob/shadekin/orange = 1,
|
||||
/mob/living/simple_mob/shadekin/purple = 10
|
||||
) = 1,
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf = 10,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 1,
|
||||
) = 80,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 5,
|
||||
/mob/living/simple_mob/vore/greatwolf = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/black = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/grey = 1
|
||||
) = 40,
|
||||
list(/mob/living/simple_mob/creature/strong) = 40,
|
||||
list(/mob/living/simple_mob/faithless/strong) = 20,
|
||||
list(/mob/living/simple_mob/animal/goat) = 1,
|
||||
@@ -501,7 +534,18 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
/mob/living/simple_mob/vore/oregrub = 5,
|
||||
/mob/living/simple_mob/vore/oregrub/lava = 1
|
||||
) = 15,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 15
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 15,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_ghost) = 5,
|
||||
list(
|
||||
/mob/living/simple_mob/vore/leopardmander = 50,
|
||||
/mob/living/simple_mob/vore/leopardmander/blue = 10,
|
||||
/mob/living/simple_mob/vore/leopardmander/exotic = 1
|
||||
) = 5,
|
||||
list(/mob/living/simple_mob/vore/sheep) = 5,
|
||||
list(/mob/living/simple_mob/vore/weretiger) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/skeleton) = 5,
|
||||
list(/mob/living/simple_mob/vore/alienanimals/catslug) = 5
|
||||
)
|
||||
|
||||
/obj/random/mob/semirandom_mob_spawner/humanoid
|
||||
@@ -512,9 +556,9 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
|
||||
possible_mob_types = list(
|
||||
list(
|
||||
/mob/living/simple_mob/shadekin/blue/ai = 25,
|
||||
/mob/living/simple_mob/shadekin/green/ai = 10,
|
||||
/mob/living/simple_mob/shadekin/purple/ai = 1,
|
||||
/mob/living/simple_mob/shadekin/blue = 25,
|
||||
/mob/living/simple_mob/shadekin/green = 10,
|
||||
/mob/living/simple_mob/shadekin/purple = 1,
|
||||
) = 1,
|
||||
list(/mob/living/simple_mob/vore/catgirl) = 100,
|
||||
list(/mob/living/simple_mob/vore/wolfgirl) = 100,
|
||||
@@ -537,7 +581,7 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
/mob/living/simple_mob/vore/lamia/zebra/bra,
|
||||
/mob/living/simple_mob/vore/lamia/zebra/shirt
|
||||
) = 100,
|
||||
// LOOK OKAY MERCS ARE HUMANOIDS SO THEY ARE HERE, but they are also kind of bullshit so they probably shouldn't be able to spawn in the same place as catgirls.
|
||||
// LOOK OKAY MERCS ARE HUMANOIDS SO THEY ARE HERE, but they are also kind of bullshit so they probably shouldn't be able to spawn in the same place as catgirls.
|
||||
// I want some better potentially hostile humanoids that aren't stupid to fight. If they become a big issue I'll comment them out.
|
||||
// For now they are just rare, and the ranged ones are way more rare than the melee ones, which I think will help balance them out.
|
||||
list(
|
||||
@@ -675,7 +719,12 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
mob_faction = "vore"
|
||||
|
||||
possible_mob_types = list(
|
||||
list(/mob/living/simple_mob/animal/wolf/direwolf) = 100,
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 5,
|
||||
/mob/living/simple_mob/vore/greatwolf = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/black = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/grey = 1
|
||||
) = 100,
|
||||
list(/mob/living/simple_mob/animal/space/jelly) = 70,
|
||||
list(
|
||||
/mob/living/simple_mob/otie/feral,
|
||||
@@ -684,12 +733,12 @@ var/global/list/semirandom_mob_spawner_decisions = list()
|
||||
/mob/living/simple_mob/otie/red/chubby
|
||||
) = 50,
|
||||
list(
|
||||
/mob/living/simple_mob/shadekin/blue/ai = 100,
|
||||
/mob/living/simple_mob/shadekin/green/ai = 50,
|
||||
/mob/living/simple_mob/shadekin/orange/ai = 20,
|
||||
/mob/living/simple_mob/shadekin/purple/ai = 60,
|
||||
/mob/living/simple_mob/shadekin/red/ai = 40,
|
||||
/mob/living/simple_mob/shadekin/yellow/ai = 1
|
||||
/mob/living/simple_mob/shadekin/blue = 100,
|
||||
/mob/living/simple_mob/shadekin/green = 50,
|
||||
/mob/living/simple_mob/shadekin/orange = 20,
|
||||
/mob/living/simple_mob/shadekin/purple = 60,
|
||||
/mob/living/simple_mob/shadekin/red = 40,
|
||||
/mob/living/simple_mob/shadekin/yellow = 1
|
||||
) = 1,
|
||||
list(
|
||||
/mob/living/simple_mob/vore/aggressive/corrupthound,
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
// Works similarly to worn sprite_sheets, except the alternate sprites are used when the clothing/refit_for_species() proc is called.
|
||||
var/list/sprite_sheets_obj
|
||||
|
||||
var/toolspeed = 1.0 // This is a multipler on how 'fast' a tool works. e.g. setting this to 0.5 will make the tool work twice as fast.
|
||||
var/toolspeed = 1 // This is a multipler on how 'fast' a tool works. e.g. setting this to 0.5 will make the tool work twice as fast.
|
||||
var/attackspeed = DEFAULT_ATTACK_COOLDOWN // How long click delay will be when using this, in 1/10ths of a second. Checked in the user's get_attack_speed().
|
||||
var/reach = 1 // Length of tiles it can reach, 1 is adjacent.
|
||||
var/addblends // Icon overlay for ADD highlights when applicable.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon = 'icons/obj/apc_repair.dmi'
|
||||
icon_state = "apc_frame"
|
||||
refund_amt = 2
|
||||
build_wall_only = TRUE
|
||||
matter = list(MAT_STEEL = 100, MAT_GLASS = 30)
|
||||
|
||||
/obj/item/frame/apc/try_build(turf/on_wall, mob/user as mob)
|
||||
|
||||
@@ -76,6 +76,10 @@
|
||||
// Clean up the simplemob
|
||||
ghostjoin = FALSE
|
||||
ghostjoin_icon()
|
||||
if(capture_caught)
|
||||
to_chat(src, "<span class='notice'>You are bound to [revivedby], follow their commands within reason and to the best of your abilities, and avoid betraying or abandoning them.</span><span class= warning> You are allied with [revivedby]. Do not attack anyone for no reason. Of course, you may do scenes as you like, but you must still respect preferences.</span>")
|
||||
visible_message("[src]'s eyes flicker with a curious intelligence.", runemessage = "looks around")
|
||||
return
|
||||
if(revivedby != "no one")
|
||||
to_chat(src, "<span class='notice'>Where once your life had been rough and scary, you have been assisted by [revivedby]. They seem to be the reason you are on your feet again... so perhaps you should help them out.</span> <span class= warning> Being as you were revived, you are allied with the station. Do not attack anyone unless they are threatening the one who revived you. And try to listen to the one who revived you within reason. Of course, you may do scenes as you like, but you must still respect preferences.</span>")
|
||||
visible_message("[src]'s eyes flicker with a curious intelligence.", runemessage = "looks around")
|
||||
@@ -95,6 +99,10 @@
|
||||
to_chat(D, "<span class='notice'>Sorry, someone else has already inhabited [src].</span>")
|
||||
return FALSE
|
||||
|
||||
if(capture_caught && !D.client.prefs.capture_crystal)
|
||||
to_chat(D, "<span class='notice'>Sorry, [src] is participating in capture mechanics, and your preferences do not allow for that.</span>")
|
||||
return FALSE
|
||||
|
||||
// Insert whatever ban checks you want here if we ever add simplemob bans
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -409,7 +409,7 @@ GLOBAL_LIST_BOILERPLATE(premade_tele_beacons, /obj/item/device/perfect_tele_beac
|
||||
if(confirm == "Eat it!")
|
||||
var/obj/belly/bellychoice = tgui_input_list(usr, "Which belly?","Select A Belly", L.vore_organs)
|
||||
if(bellychoice)
|
||||
user.visible_message("<span class='warning'>[user] is trying to stuff \the [src] into [user.gender == MALE ? "his" : user.gender == FEMALE ? "her" : "their"] [bellychoice]!</span>","<span class='notice'>You begin putting \the [src] into your [bellychoice]!</span>")
|
||||
user.visible_message("<span class='warning'>[user] is trying to stuff \the [src] into [user.gender == MALE ? "his" : user.gender == FEMALE ? "her" : "their"] [bellychoice.name]!</span>","<span class='notice'>You begin putting \the [src] into your [bellychoice.name]!</span>")
|
||||
if(do_after(user,5 SECONDS,src))
|
||||
user.unEquip(src)
|
||||
forceMove(bellychoice)
|
||||
|
||||
@@ -259,6 +259,17 @@
|
||||
new_desc = "A very retro APLU unit; didn't they retire these back in 2543?"
|
||||
new_icon = "ripley-old"
|
||||
allowed_types = list("ripley")
|
||||
var/showpilot = TRUE
|
||||
var/showpilot_lift = 5
|
||||
|
||||
/obj/item/device/kit/paint/ripley/customize(obj/mecha/M, mob/user)
|
||||
if(showpilot)
|
||||
M.show_pilot = TRUE
|
||||
M.pilot_lift = 5
|
||||
else
|
||||
M.show_pilot = FALSE
|
||||
M.pilot_lift = 0
|
||||
. = ..()
|
||||
|
||||
/obj/item/device/kit/paint/ripley/death
|
||||
name = "\"Reaper\" APLU customisation kit"
|
||||
@@ -266,18 +277,21 @@
|
||||
new_desc = "A terrifying, grim power loader. Why do those clamps have spikes?"
|
||||
new_icon = "deathripley"
|
||||
allowed_types = list("ripley","firefighter")
|
||||
showpilot = FALSE
|
||||
|
||||
/obj/item/device/kit/paint/ripley/flames_red
|
||||
name = "\"Firestarter\" APLU customisation kit"
|
||||
new_name = "APLU \"Firestarter\""
|
||||
new_desc = "A standard APLU exosuit with stylish orange flame decals."
|
||||
new_icon = "ripley_flames_red"
|
||||
showpilot = FALSE
|
||||
|
||||
/obj/item/device/kit/paint/ripley/flames_blue
|
||||
name = "\"Burning Chrome\" APLU customisation kit"
|
||||
new_name = "APLU \"Burning Chrome\""
|
||||
new_desc = "A standard APLU exosuit with stylish blue flame decals."
|
||||
new_icon = "ripley_flames_blue"
|
||||
showpilot = FALSE
|
||||
|
||||
// Durand kits.
|
||||
/obj/item/device/kit/paint/durand
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
R.add_language(LANGUAGE_ENOCHIAN, 1)
|
||||
R.add_language(LANGUAGE_SLAVIC, 1)
|
||||
R.add_language(LANGUAGE_DRUDAKAR, 1)
|
||||
R.add_language(LANGUAGE_TAVAN, 1)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Mech toys (previously labeled prizes, but that's unintuitive)
|
||||
* Mech toy combat
|
||||
*/
|
||||
|
||||
|
||||
// Mech battle special attack types.
|
||||
#define SPECIAL_ATTACK_HEAL 1
|
||||
#define SPECIAL_ATTACK_DAMAGE 2
|
||||
@@ -17,7 +17,7 @@
|
||||
icon_state = "ripleytoy"
|
||||
drop_sound = 'sound/mecha/mechstep.ogg'
|
||||
reach = 2 // So you can battle across the table!
|
||||
|
||||
|
||||
// Mech Battle Vars
|
||||
var/timer = 0 // Timer when it'll be off cooldown
|
||||
var/cooldown = 1.5 SECONDS // Cooldown between play sessions (and interactions)
|
||||
@@ -34,7 +34,7 @@
|
||||
var/special_attack_cooldown = 0 // Current cooldown of their special attack
|
||||
var/wins = 0 // This mech's win count in combat
|
||||
var/losses = 0 // ...And their loss count in combat
|
||||
|
||||
|
||||
/obj/item/toy/mecha/Initialize()
|
||||
. = ..()
|
||||
desc = "Mini-Mecha action figure! Collect them all! Attack your friends or another mech with one to initiate epic mech combat! [desc]."
|
||||
@@ -58,7 +58,7 @@
|
||||
return 0 //not in range and not telekinetic
|
||||
|
||||
/**
|
||||
* this proc combines "sleep" while also checking for if the battle should continue
|
||||
* this proc combines "sleep" while also checking for if the battle should continue
|
||||
*
|
||||
* this goes through some of the checks - the toys need to be next to each other to fight!
|
||||
* if it's player vs themself: They need to be able to "control" both mechs (either must be adjacent or using TK).
|
||||
@@ -112,7 +112,7 @@
|
||||
// If all that is good, then we can sleep peacefully.
|
||||
sleep(delay)
|
||||
return TRUE
|
||||
|
||||
|
||||
//all credit to skasi for toy mech fun ideas
|
||||
/obj/item/toy/mecha/attack_self(mob/user)
|
||||
if(timer < world.time)
|
||||
@@ -130,15 +130,15 @@
|
||||
attack_self(user)
|
||||
|
||||
/**
|
||||
* If you attack a mech with a mech, initiate combat between them
|
||||
* If you attack a mech with a mech, initiate combat between them
|
||||
*/
|
||||
/obj/item/toy/mecha/attackby(obj/item/user_toy, mob/living/user)
|
||||
if(istype(user_toy, /obj/item/toy/mecha))
|
||||
if(istype(user_toy, /obj/item/toy/mecha))
|
||||
var/obj/item/toy/mecha/M = user_toy
|
||||
if(check_battle_start(user, M))
|
||||
mecha_brawl(M, user)
|
||||
..()
|
||||
|
||||
|
||||
/**
|
||||
* Attack is called from the user's toy, aimed at target(another human), checking for target's toy.
|
||||
*/
|
||||
@@ -241,9 +241,9 @@
|
||||
|
||||
sleep(1 SECONDS)
|
||||
//--THE BATTLE BEGINS--
|
||||
while(combat_health > 0 && attacker.combat_health > 0 && battle_length < MAX_BATTLE_LENGTH)
|
||||
while(combat_health > 0 && attacker.combat_health > 0 && battle_length < MAX_BATTLE_LENGTH)
|
||||
if(!combat_sleep(0.5 SECONDS, attacker, attacker_controller, opponent)) //combat_sleep checks everything we need to have checked for combat to continue
|
||||
break
|
||||
break
|
||||
|
||||
//before we do anything - deal with charged attacks
|
||||
if(special_attack_charged)
|
||||
@@ -269,7 +269,7 @@
|
||||
attacker.special_attack_charged = TRUE
|
||||
attacker_controller.visible_message("<span class='danger'> [attacker] begins charging its special attack!! </span>", \
|
||||
"<span class='danger'> You begin charging [attacker]'s special attack! </span>")
|
||||
else //just attack
|
||||
else //just attack
|
||||
attacker.SpinAnimation(5, 0)
|
||||
playsound(attacker, 'sound/mecha/mechstep.ogg', 30, TRUE)
|
||||
combat_health--
|
||||
@@ -322,7 +322,7 @@
|
||||
special_attack_charged = TRUE
|
||||
src_controller.visible_message("<span class='danger'> [src] begins charging its special attack!! </span>", \
|
||||
"<span class='danger'> You begin charging [src]'s special attack! </span>")
|
||||
else //just attack
|
||||
else //just attack
|
||||
SpinAnimation(5, 0)
|
||||
playsound(src, 'sound/mecha/mechstep.ogg', 30, TRUE)
|
||||
attacker.combat_health--
|
||||
@@ -333,12 +333,12 @@
|
||||
attacker.combat_health--
|
||||
playsound(attacker, 'sound/effects/meteorimpact.ogg', 20, TRUE)
|
||||
src_controller.visible_message("<span class='boldwarning'> ...and lands a CRIPPLING BLOW! </span>", \
|
||||
"<span class='boldwarning'> ...and you land a CRIPPLING blow on [attacker]! </span>", null)
|
||||
"<span class='boldwarning'> ...and you land a CRIPPLING blow on [attacker]! </span>", null)
|
||||
else
|
||||
attacker_controller.visible_message("<span class='notice'> [src] and [attacker] stand around awkwardly.</span>", \
|
||||
"<span class='notice'> You don't know what to do next.</span>")
|
||||
"<span class='notice'> You don't know what to do next.</span>")
|
||||
|
||||
battle_length++
|
||||
battle_length++
|
||||
sleep(0.5 SECONDS)
|
||||
|
||||
/// Lines chosen for the winning mech
|
||||
@@ -347,7 +347,7 @@
|
||||
if(attacker.combat_health <= 0 && combat_health <= 0) //both lose
|
||||
playsound(src, 'sound/machines/warning-buzzer.ogg', 20, TRUE)
|
||||
attacker_controller.visible_message("<span class='boldnotice'> MUTUALLY ASSURED DESTRUCTION!! [src] and [attacker] both end up destroyed!</span>", \
|
||||
"<span class='boldnotice'> Both [src] and [attacker] are destroyed!</span>")
|
||||
"<span class='boldnotice'> Both [src] and [attacker] are destroyed!</span>")
|
||||
else if(attacker.combat_health <= 0) //src wins
|
||||
wins++
|
||||
attacker.losses++
|
||||
@@ -359,7 +359,7 @@
|
||||
"<span class='notice'> You raise up [src] victoriously over [attacker]!</span>")
|
||||
else if (combat_health <= 0) //attacker wins
|
||||
attacker.wins++
|
||||
losses++
|
||||
losses++
|
||||
playsound(src, 'sound/effects/light_flicker.ogg', 20, TRUE)
|
||||
src_controller.visible_message("<span class='notice'> [src] collapses!</span>", \
|
||||
"<span class='notice'> [src] collapses!</span>", null)
|
||||
@@ -374,7 +374,7 @@
|
||||
in_combat = FALSE
|
||||
attacker.in_combat = FALSE
|
||||
|
||||
combat_health = max_combat_health
|
||||
combat_health = max_combat_health
|
||||
attacker.combat_health = attacker.max_combat_health
|
||||
|
||||
return
|
||||
@@ -382,49 +382,49 @@
|
||||
/**
|
||||
* This proc checks if a battle can be initiated between src and attacker.
|
||||
*
|
||||
* Both SRC and attacker (if attacker is included) timers are checked if they're on cooldown, and
|
||||
* Both SRC and attacker (if attacker is included) timers are checked if they're on cooldown, and
|
||||
* both SRC and attacker (if attacker is included) are checked if they are in combat already.
|
||||
* If any of the above are true, the proc returns FALSE and sends a message to user (and target, if included) otherwise, it returns TRUE
|
||||
* Arguments:
|
||||
* * user: the user who is initiating the battle
|
||||
* * attacker: optional arg for checking two mechs at once
|
||||
* * attacker: optional arg for checking two mechs at once
|
||||
* * target: optional arg used in Mech PvP battles (if used, attacker is target's toy)
|
||||
*/
|
||||
/obj/item/toy/mecha/proc/check_battle_start(mob/living/carbon/user, obj/item/toy/mecha/attacker, mob/living/carbon/target)
|
||||
var/datum/gender/T
|
||||
/obj/item/toy/mecha/proc/check_battle_start(mob/living/carbon/user, obj/item/toy/mecha/attacker, mob/living/carbon/target)
|
||||
var/datum/gender/T
|
||||
if(target)
|
||||
T = gender_datums[target.get_visible_gender()] // Doing this because Polaris Code has shitty gender datums and it's clunkier than FUCK.
|
||||
if(attacker && attacker.in_combat)
|
||||
to_chat(user, "<span class='notice'>[target ? T.His : "Your" ] [attacker.name] is in combat.</span>")
|
||||
if(target)
|
||||
if(target)
|
||||
to_chat(target, "<span class='notice'>Your [attacker.name] is in combat.</span>")
|
||||
return FALSE
|
||||
return FALSE
|
||||
if(in_combat)
|
||||
to_chat(user, "<span class='notice'>Your [name] is in combat.</span>")
|
||||
if(target)
|
||||
if(target)
|
||||
to_chat(target, "<span class='notice'>[T.His] [name] is in combat.</span>")
|
||||
return FALSE
|
||||
return FALSE
|
||||
if(attacker && attacker.timer > world.time)
|
||||
to_chat(user, "<span class='notice'>[target?T.His : "Your" ] [attacker.name] isn't ready for battle.</span>")
|
||||
if(target)
|
||||
if(target)
|
||||
to_chat(target, "<span class='notice'>Your [attacker.name] isn't ready for battle.</span>")
|
||||
return FALSE
|
||||
return FALSE
|
||||
if(timer > world.time)
|
||||
to_chat(user, "<span class='notice'>Your [name] isn't ready for battle.</span>")
|
||||
if(target)
|
||||
if(target)
|
||||
to_chat(target, "<span class='notice'>[T.His] [name] isn't ready for battle.</span>")
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Processes any special attack moves that happen in the battle (called in the mechaBattle proc).
|
||||
* Processes any special attack moves that happen in the battle (called in the mechaBattle proc).
|
||||
*
|
||||
* Makes the toy shout their special attack cry and updates its cooldown. Then, does the special attack.
|
||||
* Arguments:
|
||||
* * victim - the toy being hit by the special move
|
||||
*/
|
||||
/obj/item/toy/mecha/proc/special_attack_move(obj/item/toy/mecha/victim)
|
||||
/obj/item/toy/mecha/proc/special_attack_move(obj/item/toy/mecha/victim)
|
||||
visible_message(special_attack_cry + "!!")
|
||||
|
||||
special_attack_charged = FALSE
|
||||
@@ -447,15 +447,15 @@
|
||||
visible_message("I FORGOT MY SPECIAL ATTACK...")
|
||||
|
||||
/**
|
||||
* Base proc for 'other' special attack moves.
|
||||
* Base proc for 'other' special attack moves.
|
||||
*
|
||||
* This one is only for inheritance, each mech with an 'other' type move has their procs below.
|
||||
* This one is only for inheritance, each mech with an 'other' type move has their procs below.
|
||||
* Arguments:
|
||||
* * victim - the toy being hit by the super special move (doesn't necessarily need to be used)
|
||||
*/
|
||||
/obj/item/toy/mecha/proc/super_special_attack(obj/item/toy/mecha/victim)
|
||||
/obj/item/toy/mecha/proc/super_special_attack(obj/item/toy/mecha/victim)
|
||||
visible_message("<span class='notice'> [src] does a cool flip.</span>")
|
||||
|
||||
|
||||
/obj/random/mech_toy
|
||||
name = "Random Mech Toy"
|
||||
desc = "This is a random mech toy."
|
||||
@@ -488,8 +488,8 @@
|
||||
special_attack_type = SPECIAL_ATTACK_OTHER
|
||||
special_attack_type_message = "instantly destroys the opposing mech if its health is less than this mech's health."
|
||||
special_attack_cry = "KILLER CLAMP"
|
||||
|
||||
/obj/item/toy/mecha/deathripley/super_special_attack(obj/item/toy/mecha/victim)
|
||||
|
||||
/obj/item/toy/mecha/deathripley/super_special_attack(obj/item/toy/mecha/victim)
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 20, TRUE)
|
||||
if(victim.combat_health < combat_health) // Instantly kills the other mech if it's health is below our's.
|
||||
visible_message("EXECUTE!!")
|
||||
@@ -522,7 +522,7 @@
|
||||
special_attack_type_message = "puts the opposing mech's special move on cooldown and heals this mech."
|
||||
special_attack_cry = "MEGA HORN"
|
||||
|
||||
/obj/item/toy/mecha/honk/super_special_attack(obj/item/toy/mecha/victim)
|
||||
/obj/item/toy/mecha/honk/super_special_attack(obj/item/toy/mecha/victim)
|
||||
playsound(src, 'sound/machines/honkbot_evil_laugh.ogg', 20, TRUE)
|
||||
victim.special_attack_cooldown += 3 // Adds cooldown to the other mech and gives a minor self heal
|
||||
combat_health++
|
||||
@@ -577,7 +577,7 @@
|
||||
special_attack_type_message = "has a lower cooldown than normal special moves, increases the opponent's cooldown, and deals damage."
|
||||
special_attack_cry = "*wave"
|
||||
|
||||
/obj/item/toy/mecha/reticence/super_special_attack(obj/item/toy/mecha/victim)
|
||||
/obj/item/toy/mecha/reticence/super_special_attack(obj/item/toy/mecha/victim)
|
||||
special_attack_cooldown-- //Has a lower cooldown...
|
||||
victim.special_attack_cooldown++ //and increases the opponent's cooldown by 1...
|
||||
victim.combat_health-- //and some free damage.
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
* Balloons
|
||||
* Fake telebeacon
|
||||
* Fake singularity
|
||||
* Toy gun
|
||||
* Toy crossbow
|
||||
* Toy swords
|
||||
* Toy bosun's whistle
|
||||
* Snap pops
|
||||
@@ -145,127 +143,6 @@
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "singularity_s1"
|
||||
|
||||
/*
|
||||
* Toy crossbow
|
||||
*/
|
||||
|
||||
/obj/item/toy/crossbow
|
||||
name = "foam dart crossbow"
|
||||
desc = "A weapon favored by many overactive children. Ages 8 and up."
|
||||
icon = 'icons/obj/gun.dmi'
|
||||
icon_state = "crossbow"
|
||||
item_icons = list(
|
||||
icon_l_hand = 'icons/mob/items/lefthand_guns.dmi',
|
||||
icon_r_hand = 'icons/mob/items/righthand_guns.dmi',
|
||||
)
|
||||
slot_flags = SLOT_HOLSTER
|
||||
w_class = ITEMSIZE_SMALL
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
var/bullets = 5
|
||||
drop_sound = 'sound/items/drop/gun.ogg'
|
||||
|
||||
/obj/item/toy/crossbow/examine(mob/user)
|
||||
. = ..()
|
||||
if(bullets && get_dist(user, src) <= 2)
|
||||
. += "<span class='notice'>It is loaded with [bullets] foam darts!</span>"
|
||||
|
||||
/obj/item/toy/crossbow/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(istype(I, /obj/item/toy/ammo/crossbow))
|
||||
if(bullets <= 4)
|
||||
user.drop_item()
|
||||
qdel(I)
|
||||
bullets++
|
||||
to_chat(user, "<span class='notice'>You load the foam dart into the crossbow.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>It's already fully loaded.</span>")
|
||||
|
||||
|
||||
/obj/item/toy/crossbow/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
|
||||
if(!isturf(target.loc) || target == user) return
|
||||
if(flag) return
|
||||
|
||||
if (locate (/obj/structure/table, src.loc))
|
||||
return
|
||||
else if (bullets)
|
||||
var/turf/trg = get_turf(target)
|
||||
var/obj/effect/foam_dart_dummy/D = new/obj/effect/foam_dart_dummy(get_turf(src))
|
||||
bullets--
|
||||
D.icon_state = "foamdart"
|
||||
D.name = "foam dart"
|
||||
playsound(src, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
|
||||
for(var/i=0, i<6, i++)
|
||||
if (D)
|
||||
if(D.loc == trg) break
|
||||
step_towards(D,trg)
|
||||
|
||||
for(var/mob/living/M in D.loc)
|
||||
if(!istype(M,/mob/living)) continue
|
||||
if(M == user) continue
|
||||
for(var/mob/O in viewers(world.view, D))
|
||||
O.show_message(text("<span class='warning'>\The [] was hit by the foam dart!</span>", M), 1)
|
||||
new /obj/item/toy/ammo/crossbow(M.loc)
|
||||
qdel(D)
|
||||
return
|
||||
|
||||
for(var/atom/A in D.loc)
|
||||
if(A == user) continue
|
||||
if(A.density)
|
||||
new /obj/item/toy/ammo/crossbow(A.loc)
|
||||
qdel(D)
|
||||
|
||||
sleep(1)
|
||||
|
||||
spawn(10)
|
||||
if(D)
|
||||
new /obj/item/toy/ammo/crossbow(D.loc)
|
||||
qdel(D)
|
||||
|
||||
return
|
||||
else if (bullets == 0)
|
||||
user.Weaken(5)
|
||||
for(var/mob/O in viewers(world.view, user))
|
||||
O.show_message(text("<span class='warning'>\The [] realized they were out of ammo and starting scrounging for some!</span>", user), 1)
|
||||
|
||||
|
||||
/obj/item/toy/crossbow/attack(mob/M as mob, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
|
||||
// ******* Check
|
||||
|
||||
if (src.bullets > 0 && M.lying)
|
||||
|
||||
for(var/mob/O in viewers(M, null))
|
||||
if(O.client)
|
||||
O.show_message(text("<span class='danger'>\The [] casually lines up a shot with []'s head and pulls the trigger!</span>", user, M), 1, "<span class='warning'>You hear the sound of foam against skull</span>", 2)
|
||||
O.show_message(text("<span class='warning'>\The [] was hit in the head by the foam dart!</span>", M), 1)
|
||||
|
||||
playsound(src, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
new /obj/item/toy/ammo/crossbow(M.loc)
|
||||
src.bullets--
|
||||
else if (M.lying && src.bullets == 0)
|
||||
for(var/mob/O in viewers(M, null))
|
||||
if (O.client) O.show_message(text("<span class='danger'>\The [] casually lines up a shot with []'s head, pulls the trigger, then realizes they are out of ammo and drops to the floor in search of some!</span>", user, M), 1, "<span class='warning'>You hear someone fall</span>", 2)
|
||||
user.Weaken(5)
|
||||
return
|
||||
|
||||
/obj/item/toy/ammo/crossbow
|
||||
name = "foam dart"
|
||||
desc = "It's nerf or nothing! Ages 8 and up."
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "foamdart"
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_EARS
|
||||
drop_sound = 'sound/items/drop/food.ogg'
|
||||
|
||||
/obj/effect/foam_dart_dummy
|
||||
name = ""
|
||||
desc = ""
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "null"
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
|
||||
/*
|
||||
* Toy swords
|
||||
*/
|
||||
@@ -394,7 +271,6 @@
|
||||
/*
|
||||
* Bosun's whistle
|
||||
*/
|
||||
|
||||
/obj/item/toy/bosunwhistle
|
||||
name = "bosun's whistle"
|
||||
desc = "A genuine Admiral Krush Bosun's Whistle, for the aspiring ship's captain! Suitable for ages 8 and up, do not swallow."
|
||||
@@ -945,7 +821,7 @@
|
||||
else
|
||||
searching = FALSE
|
||||
|
||||
if(world.time - last_message <= 1 SECOND)
|
||||
if(world.time - last_message <= 15 SECONDS)
|
||||
return
|
||||
if(user.a_intent == I_HELP)
|
||||
user.visible_message("<span class='notice'><b>\The [user]</b> hugs [src]!</span>","<span class='notice'>You hug [src]!</span>")
|
||||
@@ -1526,7 +1402,7 @@
|
||||
name = "black king"
|
||||
desc = "A black king chess piece."
|
||||
description_info = "The King can move exactly one square horizontally, vertically, or diagonally. If your opponent captures this piece, you lose."
|
||||
icon_state = "black_king"
|
||||
icon_state = "black_king"
|
||||
|
||||
/// Balloon structures
|
||||
|
||||
|
||||
@@ -1,9 +1,44 @@
|
||||
/* Virgo Toys!
|
||||
* Contains:
|
||||
* Mistletoe
|
||||
* Plushies
|
||||
* Pet rocks
|
||||
* Chew toys
|
||||
* Cat toys
|
||||
* Fake flash
|
||||
* Big red button
|
||||
* Garden gnome
|
||||
* Toy AI
|
||||
* Hand buzzer
|
||||
* Toy cuffs
|
||||
* Toy nuke
|
||||
* Toy gibber
|
||||
* Toy xeno
|
||||
* Russian revolver
|
||||
* Trick revolver
|
||||
* Toy chainsaw
|
||||
* Random miniature spawner
|
||||
* Snake popper
|
||||
* Professor Who universal ID
|
||||
* Professor Who sonic driver
|
||||
* Action figures
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Mistletoe
|
||||
*/
|
||||
/obj/item/toy/mistletoe
|
||||
name = "mistletoe"
|
||||
desc = "You are supposed to kiss someone under these"
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "mistletoe"
|
||||
|
||||
/*
|
||||
* Plushies
|
||||
*/
|
||||
// HEY FUTURE PLUSHIE CODERS: IF YOU'RE ADDING A SNOWFLAKE PLUSH ITEM USE PATH /obj/item/toy/plushie/fluff
|
||||
// the loadout entry shouldn't be able to grab those if everything goes right
|
||||
/obj/item/toy/plushie/lizardplushie
|
||||
name = "lizard plushie"
|
||||
desc = "An adorable stuffed toy that resembles a lizardperson."
|
||||
@@ -101,38 +136,6 @@
|
||||
/obj/item/toy/plushie/vox/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/*
|
||||
* 4/9/21 *
|
||||
* IPC Plush
|
||||
* Toaster plush
|
||||
* Snake plush
|
||||
* Cube plush
|
||||
* Pip plush
|
||||
* Moth plush
|
||||
* Crab plush
|
||||
* Possum plush
|
||||
* Goose plush
|
||||
* White mouse plush
|
||||
* Pet rock
|
||||
* Pet rock (m)
|
||||
* Pet rock (f)
|
||||
* Chew toys
|
||||
* Cat toy * 2
|
||||
* Toy flash
|
||||
* Toy button
|
||||
* Gnome
|
||||
* Toy AI
|
||||
* Buzzer ring
|
||||
* Fake handcuffs
|
||||
* Nuke toy
|
||||
* Toy gibber
|
||||
* Toy xeno
|
||||
* Fake gun * 2
|
||||
* Toy chainsaw
|
||||
* Random tabletop miniature spawner
|
||||
* snake popper
|
||||
*/
|
||||
|
||||
/obj/item/toy/plushie/ipc
|
||||
name = "IPC plushie"
|
||||
desc = "A pleasing soft-toy of a monitor-headed robot. Toaster functionality included."
|
||||
@@ -172,7 +175,6 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/toy/plushie/ipc/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/machines/ping.ogg', 10, 0)
|
||||
@@ -274,7 +276,9 @@
|
||||
|
||||
/obj/item/toy/plushie/goose
|
||||
name = "goose plushie"
|
||||
desc = "An adorable likeness of a terrifying beast. It's simple existance chills you to the bone and compells you to hide any loose objects it might steal."
|
||||
desc = "An adorable likeness of a terrifying beast. \
|
||||
It's simple existance chills you to the bone and \
|
||||
compells you to hide any loose objects it might steal."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "goose"
|
||||
attack_verb = list("honked")
|
||||
@@ -284,9 +288,54 @@
|
||||
icon_state = "mouse"
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
|
||||
/obj/item/toy/plushie/susred
|
||||
name = "red spaceman plushie"
|
||||
desc = "A suspicious looking red spaceman plushie. Why does it smell like the vents?"
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "sus_red"
|
||||
attack_verb = list("stabbed", "slashed")
|
||||
|
||||
/obj/item/toy/plushie/ipc/toaster/attack_self(mob/user as mob)
|
||||
if(!cooldown)
|
||||
playsound(user, 'sound/weapons/slice.ogg', 10, 0)
|
||||
src.visible_message("<span class='danger'>Stab!</span>")
|
||||
cooldown = 1
|
||||
addtimer(CALLBACK(src, .proc/cooldownreset), 50)
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/plushie/susblue
|
||||
name = "blue spaceman plushie"
|
||||
desc = "A dapper looking blue spaceman plushie. Looks very intuitive."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "sus_blue"
|
||||
|
||||
/obj/item/toy/plushie/suswhite
|
||||
name = "white spaceman plushie"
|
||||
desc = "A whiny looking white spaceman plushie. Looks like it could cry at any moment."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "sus_white"
|
||||
|
||||
/obj/item/toy/plushie/bigcat
|
||||
name = "big cat plushie"
|
||||
desc = "A big, fluffy looking cat that just looks very huggable."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "big_cat"
|
||||
|
||||
/obj/item/toy/plushie/basset
|
||||
name = "basset plushie"
|
||||
desc = "A sleepy looking basset hound plushie."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "basset"
|
||||
|
||||
/*
|
||||
* Pet rocks
|
||||
*/
|
||||
/obj/item/toy/rock
|
||||
name = "pet rock"
|
||||
desc = "A stuffed version of the classic pet. The soft ones were made after kids kept throwing them at each other. It has a small piece of soft plastic that you can draw on if you wanted."
|
||||
desc = "A stuffed version of the classic pet. \
|
||||
The soft ones were made after kids kept throwing \
|
||||
them at each other. It has a small piece of soft \
|
||||
plastic that you can draw on if you wanted."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "rock"
|
||||
attack_verb = list("grug'd", "unga'd")
|
||||
@@ -307,6 +356,9 @@
|
||||
to_chat(user, "You draw a face on the rock and pull aside the plastic slightly, revealing a small pink bow.")
|
||||
return
|
||||
|
||||
/*
|
||||
* Chew toys
|
||||
*/
|
||||
/obj/item/toy/chewtoy
|
||||
name = "chew toy"
|
||||
desc = "A red hard-rubber chew toy shaped like a bone. Perfect for your dog! You wouldn't want to chew on it, right?"
|
||||
@@ -330,6 +382,9 @@
|
||||
playsound(loc, 'sound/items/drop/plushie.ogg', 50, 1)
|
||||
user.visible_message("<span class='notice'><b>\The [user]</b> gnaws on [src]!</span>","<span class='notice'>You gnaw on [src]!</span>")
|
||||
|
||||
/*
|
||||
* Cat toys
|
||||
*/
|
||||
/obj/item/toy/cat_toy
|
||||
name = "toy mouse"
|
||||
desc = "A colorful toy mouse!"
|
||||
@@ -349,6 +404,9 @@
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_material.dmi',
|
||||
)
|
||||
|
||||
/*
|
||||
* Fake flash
|
||||
*/
|
||||
/obj/item/toy/flash
|
||||
name = "toy flash"
|
||||
desc = "FOR THE REVOLU- Oh wait, that's just a toy."
|
||||
@@ -374,6 +432,9 @@
|
||||
/obj/item/toy/flash/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/*
|
||||
* Big red button
|
||||
*/
|
||||
/obj/item/toy/redbutton
|
||||
name = "big red button"
|
||||
desc = "A big, plastic red button. Reads 'From HonkCo Pranks?' on the back."
|
||||
@@ -394,12 +455,18 @@
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Nothing happens.</span>")
|
||||
|
||||
/*
|
||||
* Garden gnome
|
||||
*/
|
||||
/obj/item/toy/gnome
|
||||
name = "garden gnome"
|
||||
desc = "It's a gnome, not a gnelf. Made of weak ceramic."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "gnome"
|
||||
|
||||
/*
|
||||
* Toy AI
|
||||
*/
|
||||
/obj/item/toy/AI
|
||||
name = "toy AI"
|
||||
desc = "A little toy model AI core with real law announcing action!"
|
||||
@@ -434,6 +501,9 @@
|
||||
/obj/item/toy/AI/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/*
|
||||
* Hand buzzer
|
||||
*/
|
||||
/obj/item/clothing/gloves/ring/buzzer/toy
|
||||
name = "steel ring"
|
||||
desc = "Torus shaped finger decoration. It has a small piece of metal on the palm-side."
|
||||
@@ -460,6 +530,9 @@
|
||||
|
||||
return 0
|
||||
|
||||
/*
|
||||
* Toy cuffs
|
||||
*/
|
||||
/obj/item/weapon/handcuffs/fake
|
||||
name = "plastic handcuffs"
|
||||
desc = "Use this to keep plastic prisoners in line."
|
||||
@@ -484,6 +557,9 @@
|
||||
foldable = null
|
||||
can_hold = list(/obj/item/weapon/handcuffs/fake, /obj/item/weapon/handcuffs/legcuffs/fake)
|
||||
|
||||
/*
|
||||
* Toy nuke
|
||||
*/
|
||||
/obj/item/toy/nuke
|
||||
name = "\improper Nuclear Fission Explosive toy"
|
||||
desc = "A plastic model of a Nuclear Fission Explosive."
|
||||
@@ -510,6 +586,9 @@
|
||||
if(istype(I, /obj/item/weapon/disk/nuclear))
|
||||
to_chat(user, "<span class='alert'>Nice try. Put that disk back where it belongs.</span>")
|
||||
|
||||
/*
|
||||
* Toy gibber
|
||||
*/
|
||||
/obj/item/toy/minigibber
|
||||
name = "miniature gibber"
|
||||
desc = "A miniature recreation of NanoTrasen's famous meat grinder. Equipped with a special interlock that prevents insertion of organic material."
|
||||
@@ -547,6 +626,9 @@
|
||||
|
||||
else ..()
|
||||
|
||||
/*
|
||||
* Toy xeno
|
||||
*/
|
||||
/obj/item/toy/toy_xeno
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "xeno"
|
||||
@@ -571,6 +653,9 @@
|
||||
to_chat(user, "<span class='warning'>The string on [src] hasn't rewound all the way!</span>")
|
||||
return
|
||||
|
||||
/*
|
||||
* Russian revolver
|
||||
*/
|
||||
/obj/item/toy/russian_revolver
|
||||
name = "russian revolver"
|
||||
desc = "For fun and games!"
|
||||
@@ -641,6 +726,9 @@
|
||||
to_chat(user, "<span class='warning'>[src] needs to be reloaded.</span>")
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
* Trick revolver
|
||||
*/
|
||||
/obj/item/toy/russian_revolver/trick_revolver
|
||||
name = "\improper .357 revolver"
|
||||
desc = "A suspicious revolver. Uses .357 ammo."
|
||||
@@ -668,6 +756,9 @@
|
||||
sleep(5)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/*
|
||||
* Toy chainsaw
|
||||
*/
|
||||
/obj/item/toy/chainsaw
|
||||
name = "Toy Chainsaw"
|
||||
desc = "A toy chainsaw with a rubber edge. Ages 8 and up"
|
||||
@@ -690,6 +781,9 @@
|
||||
/obj/item/toy/chainsaw/proc/cooldownreset()
|
||||
cooldown = 0
|
||||
|
||||
/*
|
||||
* Random miniature spawner
|
||||
*/
|
||||
/obj/random/miniature
|
||||
name = "Random miniature"
|
||||
desc = "This is a random miniature."
|
||||
@@ -699,6 +793,9 @@
|
||||
/obj/random/miniature/item_to_spawn()
|
||||
return pick(typesof(/obj/item/toy/character))
|
||||
|
||||
/*
|
||||
* Snake popper
|
||||
*/
|
||||
/obj/item/toy/snake_popper
|
||||
name = "bread tube"
|
||||
desc = "Bread in a tube. Chewy...and surprisingly tasty."
|
||||
@@ -775,3 +872,93 @@
|
||||
real = 2
|
||||
to_chat(user, "<span class='notice'>You short out the bluespace refill system of [src].</span>")
|
||||
|
||||
/*
|
||||
* Professor Who universal ID
|
||||
*/
|
||||
/obj/item/clothing/under/universalid
|
||||
name = "identification card"
|
||||
desc = "A novelty identification card based on Professor Who's Universal ID."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "universal_id"
|
||||
w_class = ITEMSIZE_TINY
|
||||
slot_flags = SLOT_ID | SLOT_EARS
|
||||
body_parts_covered = 0
|
||||
equip_sound = null
|
||||
|
||||
sprite_sheets = null
|
||||
|
||||
item_state = "golem" //This is dumb and hacky but was here when I got here.
|
||||
worn_state = "golem" //It's basically just a coincidentally black iconstate in the file.
|
||||
|
||||
/*
|
||||
* Professor Who sonic driver
|
||||
*/
|
||||
/obj/item/weapon/tool/screwdriver/sdriver
|
||||
name = "sonic driver"
|
||||
desc = "A novelty screwdriver that uses tiny magnets to manipulate screws."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "sonic_driver"
|
||||
item_state = "screwdriver_black"
|
||||
usesound = 'sound/items/sonic_driver.ogg'
|
||||
toolspeed = 1
|
||||
random_color = FALSE
|
||||
|
||||
/*
|
||||
* Professor Who time capsule
|
||||
*/
|
||||
/obj/item/weapon/storage/box/timecap
|
||||
name = "action time capsule"
|
||||
desc = "A toy recreation of the Time Capsule from Professor Who. Can hold up to two action figures."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "time_cap"
|
||||
can_hold = list(/obj/item/toy/figure)
|
||||
max_w_class = ITEMSIZE_TINY
|
||||
max_storage_space = ITEMSIZE_COST_TINY * 2
|
||||
use_sound = 'sound/machines/click.ogg'
|
||||
drop_sound = 'sound/items/drop/accessory.ogg'
|
||||
pickup_sound = 'sound/items/pickup/accessory.ogg'
|
||||
|
||||
/*
|
||||
* Action figures
|
||||
*/
|
||||
/obj/item/toy/figure/ranger
|
||||
name = "Space Ranger action figure"
|
||||
desc = "A \"Space Life\" brand Space Ranger action figure."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "ranger"
|
||||
toysay = "To the Fontier and beyond!"
|
||||
|
||||
/obj/item/toy/figure/leadbandit
|
||||
name = "Bandit Leader action figure"
|
||||
desc = "A \"Space Life\" brand Bandit Leader action figure."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "bandit_lead"
|
||||
toysay = "Give us yer bluespace crystals!"
|
||||
|
||||
/obj/item/toy/figure/bandit
|
||||
name = "Bandit action figure"
|
||||
desc = "A \"Space Life\" brand Bandit action figure."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "bandit"
|
||||
toysay = "Stick em' up!"
|
||||
|
||||
/obj/item/toy/figure/abe
|
||||
name = "Action Abe action figure"
|
||||
desc = "A \"Space Life\" brand Action Abe action figure."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "action_abe"
|
||||
toysay = "Four score and seven decades ago..."
|
||||
|
||||
/obj/item/toy/figure/profwho
|
||||
name = "Professor Who action figure"
|
||||
desc = "A \"Space Life\" brand Professor Who action figure."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "prof_who"
|
||||
toysay = "Smells like... bad wolf..."
|
||||
|
||||
/obj/item/toy/figure/prisoner
|
||||
name = "prisoner action figure"
|
||||
desc = "A \"Space Life\" brand prisoner action figure."
|
||||
icon = 'icons/obj/toy_vr.dmi'
|
||||
icon_state = "prisoner"
|
||||
toysay = "I did not hit her! I did not!"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
|
||||
)
|
||||
)
|
||||
flags = NOBLUDGEON
|
||||
force = 10
|
||||
throwforce = 10
|
||||
@@ -184,9 +184,9 @@
|
||||
activate()
|
||||
animate_deletion(A)
|
||||
return
|
||||
|
||||
|
||||
if((mode & PAINT_MODE)) //Paint pipes
|
||||
if(istype(A, /obj/machinery/atmospherics/pipe))
|
||||
if(!istype(A, /obj/machinery/atmospherics/pipe/simple/heat_exchanging) && istype(A, /obj/machinery/atmospherics/pipe))
|
||||
var/obj/machinery/atmospherics/pipe/P = A
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
P.change_color(pipe_colors[paint_color])
|
||||
|
||||
@@ -0,0 +1,845 @@
|
||||
/obj/item/capture_crystal
|
||||
name = "curious crystal"
|
||||
desc = "A silent, unassuming crystal in what appears to be some kind of steel housing."
|
||||
icon = 'icons/obj/capture_crystal_vr.dmi'
|
||||
icon_state = "inactive"
|
||||
drop_sound = 'sound/items/drop/ring.ogg'
|
||||
pickup_sound = 'sound/items/pickup/ring.ogg'
|
||||
throwforce = 0
|
||||
force = 0
|
||||
action_button_name = "Command"
|
||||
|
||||
var/active = FALSE //Is it set up?
|
||||
var/mob/living/owner //Reference to the owner
|
||||
var/mob/living/bound_mob //Reference to our bound mob
|
||||
var/spawn_mob_type //The kind of mob an inactive crystal will try to spawn when activated
|
||||
var/activate_cooldown = 30 SECONDS //How long do we wait between unleashing and recalling
|
||||
var/last_activate //Automatically set by things that try to move the bound mob or capture things
|
||||
var/empty_icon = "empty"
|
||||
var/full_icon = "full"
|
||||
var/capture_chance_modifier = 1 //So we can have special subtypes with different capture rates!
|
||||
|
||||
/obj/item/capture_crystal/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
//Let's make sure we clean up our references and things if the crystal goes away (such as when it's digested)
|
||||
/obj/item/capture_crystal/Destroy()
|
||||
if(bound_mob)
|
||||
if(bound_mob in contents)
|
||||
unleash()
|
||||
to_chat(bound_mob, "<span class='notice'>You feel like yourself again. You are no longer under the influence of \the [src]'s command.</span>")
|
||||
UnregisterSignal(bound_mob, COMSIG_PARENT_QDELETING)
|
||||
bound_mob.capture_caught = FALSE
|
||||
bound_mob = null
|
||||
if(owner)
|
||||
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/obj/item/capture_crystal/examine(user)
|
||||
. = ..()
|
||||
if(user == owner && bound_mob)
|
||||
. += "<span class = 'notice'>[bound_mob]'s crystal</span>"
|
||||
if(isanimal(bound_mob))
|
||||
. += "<span class = 'notice'>[bound_mob.health / bound_mob.maxHealth * 100]%</span>"
|
||||
if(bound_mob.ooc_notes)
|
||||
. += "<span class = 'deptradio'>OOC Notes:</span> <a href='?src=\ref[bound_mob];ooc_notes=1'>\[View\]</a>"
|
||||
. += "<span class='deptradio'><a href='?src=\ref[bound_mob];vore_prefs=1'>\[Mechanical Vore Preferences\]</a></span>"
|
||||
|
||||
//Command! This lets the owner toggle hostile on AI controlled mobs, or send a silent command message to your bound mob, wherever they may be.
|
||||
/obj/item/capture_crystal/ui_action_click()
|
||||
if(!ismob(loc))
|
||||
return
|
||||
var/mob/living/M = src.loc
|
||||
if(M != owner)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... It does not respond to your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(!bound_mob)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... There is nothing to command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(isanimal(bound_mob) && !bound_mob.client)
|
||||
if(!isnull(bound_mob.get_AI_stance()))
|
||||
var/datum/ai_holder/AI = bound_mob.ai_holder
|
||||
AI.hostile = !AI.hostile
|
||||
if(!AI.hostile)
|
||||
AI.set_stance(STANCE_IDLE)
|
||||
to_chat(M, span("notice", "\The [bound_mob] is now [AI.hostile ? "hostile" : "passive"]."))
|
||||
log_admin("[key_name_admin(M)] set [bound_mob] to [AI.hostile].")
|
||||
else if(bound_mob.client)
|
||||
var/transmit_msg = tgui_input_text(usr, "What is your command?", "Command")
|
||||
if(length(transmit_msg) >= MAX_MESSAGE_LEN)
|
||||
to_chat(M, "<span class='danger'>Your message was TOO LONG!:[transmit_msg]</span>")
|
||||
return
|
||||
transmit_msg = sanitize(transmit_msg, max_length = MAX_MESSAGE_LEN)
|
||||
if(isnull(transmit_msg))
|
||||
to_chat(M, "<span class='notice'>You decided against it.</span>")
|
||||
return
|
||||
to_chat(bound_mob, "<span class='notice'>\The [owner] commands, '[transmit_msg]'</span>")
|
||||
to_chat(M, "<span class='notice'>Your command has been transmitted, '[transmit_msg]'</span>")
|
||||
log_admin("[key_name_admin(M)] sent the command, '[transmit_msg]' to [bound_mob].")
|
||||
else
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is unresponsive.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
|
||||
//Lets the owner get AI controlled bound mobs to follow them, or tells player controlled mobs to follow them.
|
||||
/obj/item/capture_crystal/verb/follow_owner()
|
||||
set name = "Toggle Follow"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(!ismob(loc))
|
||||
return
|
||||
var/mob/living/M = src.loc
|
||||
if(M != owner)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... It does not respond to your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(bound_mob.stat != CONSCIOUS)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not able to hear your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(bound_mob.client)
|
||||
to_chat(bound_mob, "<span class='notice'>\The [owner] wishes for you to follow them.</span>")
|
||||
else if(bound_mob in contents)
|
||||
if(!bound_mob.ai_holder)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not able to follow your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
var/datum/ai_holder/AI = bound_mob.ai_holder
|
||||
if(AI.leader)
|
||||
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] stopped following [AI.leader].</span>")
|
||||
AI.lose_follow(AI.leader)
|
||||
else
|
||||
AI.set_follow(M)
|
||||
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] started following following [AI.leader].</span>")
|
||||
else if(!(bound_mob in view(M)))
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not able to hear your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
if(!bound_mob.ai_holder)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not able to follow your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
var/datum/ai_holder/AI = bound_mob.ai_holder
|
||||
if(AI.leader)
|
||||
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] stopped following [AI.leader].</span>")
|
||||
AI.lose_follow(AI.leader)
|
||||
else
|
||||
AI.set_follow(M)
|
||||
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] started following following [AI.leader].</span>")
|
||||
|
||||
//Don't really want people 'haha funny' capturing and releasing one another willy nilly. So! If you wanna release someone, you gotta destroy the thingy.
|
||||
//(Which is consistent with how it works with digestion anyway.)
|
||||
/obj/item/capture_crystal/verb/destroy_crystal()
|
||||
set name = "Destroy Crystal"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(!ismob(loc))
|
||||
return
|
||||
var/mob/living/M = src.loc
|
||||
if(M != owner)
|
||||
to_chat(M, "<span class='notice'>\The [src] is too hard for you to break.</span>")
|
||||
else
|
||||
M.visible_message("\The [M] crushes \the [src] into dust...", "\The [src] cracks and disintegrates in your hand.")
|
||||
qdel(src)
|
||||
|
||||
//If you catch something/someone and want to give it to someone else though, that's fine.
|
||||
/obj/item/capture_crystal/verb/release_ownership()
|
||||
set name = "Release Ownership"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(!ismob(loc))
|
||||
return
|
||||
var/mob/living/M = src.loc
|
||||
if(M != owner)
|
||||
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... It does not respond to your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else
|
||||
M.visible_message("\The [src] flickers in \the [M]'s hand and emits a little tone.", "\The [src] flickers in your hand and emits a little tone.")
|
||||
playsound(src, 'sound/effects/capture-crystal-out.ogg', 75, 1, -1)
|
||||
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
|
||||
owner = null
|
||||
|
||||
//Let's make inviting ghosts be an option you can do instead of an automatic thing!
|
||||
/obj/item/capture_crystal/verb/invite_ghost()
|
||||
set name = "Enhance (Toggle Ghost Join)"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(!ismob(loc))
|
||||
return
|
||||
var/mob/living/U = src.loc
|
||||
if(!bound_mob)
|
||||
to_chat(U, "<span class='notice'>\The [src] emits an unpleasant tone... There is nothing to enhance.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
else if(U != owner)
|
||||
to_chat(U, "<span class='notice'>\The [src] emits an unpleasant tone... It does not respond to your command.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
else if(bound_mob.client || !isanimal(bound_mob))
|
||||
to_chat(U, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not eligable for enhancement.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-problem.ogg', 75, 1, -1)
|
||||
return //Need to type cast the mob so it can detect ghostjoin
|
||||
var/mob/living/simple_mob/M = bound_mob
|
||||
if(M.ghostjoin)
|
||||
M.ghostjoin = FALSE
|
||||
to_chat(U, "<span class='notice'>\The [bound_mob] is no longer eligable to be joined by ghosts.</span>")
|
||||
else if(tgui_alert(U, "Do you want to offer your [bound_mob] up to ghosts to play as? There is no way undo this once a ghost takes over.", "Invite ghosts?",list("No","Yes")) == "Yes")
|
||||
M.ghostjoin = TRUE
|
||||
to_chat(U, "<span class='notice'>\The [bound_mob] is now eligable to be joined by ghosts. It will need to be out of the crystal to be able to be joined.</span>")
|
||||
else
|
||||
to_chat(U, "<span class='notice'>You decided against it.</span>")
|
||||
|
||||
/obj/item/capture_crystal/update_icon()
|
||||
. = ..()
|
||||
if(spawn_mob_type)
|
||||
icon_state = full_icon
|
||||
else if(!bound_mob)
|
||||
icon_state = "inactive"
|
||||
else if(bound_mob in contents)
|
||||
icon_state = full_icon
|
||||
else
|
||||
icon_state = empty_icon
|
||||
if(!cooldown_check())
|
||||
icon_state = "[icon_state]-busy"
|
||||
spawn(activate_cooldown) //If it's busy then we want to wait a bit to fix the sprite after the cooldown is done.
|
||||
update_icon()
|
||||
|
||||
/obj/item/capture_crystal/proc/cooldown_check()
|
||||
if(world.time < last_activate + activate_cooldown)
|
||||
return FALSE
|
||||
else return TRUE
|
||||
|
||||
/obj/item/capture_crystal/attack(mob/living/M, mob/living/user)
|
||||
if(bound_mob)
|
||||
if(!bound_mob.devourable) //Don't eat if prefs are bad
|
||||
return
|
||||
if(user.zone_sel.selecting == "mouth") //Click while targetting the mouth and you eat/feed the stored mob to whoever you clicked on
|
||||
if(bound_mob in contents)
|
||||
user.visible_message("\The [user] moves \the [src] to [M]'s [M.vore_selected]...")
|
||||
M.perform_the_nom(M, bound_mob, M, M.vore_selected)
|
||||
else if(M == user) //You don't have a mob, you ponder the orb instead of trying to capture yourself
|
||||
user.visible_message("\The [user] ponders \the [src]...", "You ponder \the [src]...")
|
||||
else if (cooldown_check()) //Try to capture someone without throwing
|
||||
user.visible_message("\The [user] taps \the [M] with \the [src].")
|
||||
activate(user, M)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] emits an unpleasant tone... It is not ready yet.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
|
||||
//Tries to unleash or recall your stored mob
|
||||
/obj/item/capture_crystal/attack_self(mob/living/user)
|
||||
if(!cooldown_check())
|
||||
to_chat(user, "<span class='notice'>\The [src] emits an unpleasant tone... It is not ready yet.</span>")
|
||||
if(bound_mob)
|
||||
playsound(src, 'sound/effects/capture-crystal-problem.ogg', 75, 1, -1)
|
||||
else
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(user == bound_mob) //You can't recall yourself
|
||||
to_chat(user, "<span class='notice'>\The [src] emits an unpleasant tone... It does not activate for you.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(!active)
|
||||
activate(user)
|
||||
else
|
||||
determine_action(user)
|
||||
|
||||
//Make it so the crystal knows if its mob references get deleted to make sure things get cleaned up
|
||||
/obj/item/capture_crystal/proc/knowyoursignals(mob/living/M, mob/living/U)
|
||||
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/mob_was_deleted, TRUE)
|
||||
RegisterSignal(U, COMSIG_PARENT_QDELETING, .proc/owner_was_deleted, TRUE)
|
||||
|
||||
//The basic capture command does most of the registration work.
|
||||
/obj/item/capture_crystal/proc/capture(mob/living/M, mob/living/U)
|
||||
if(!M.capture_crystal || M.capture_caught)
|
||||
to_chat(U, "<span class='warning'>This creature is not suitable for capture.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
knowyoursignals(M, U)
|
||||
owner = U
|
||||
if(isanimal(M))
|
||||
var/mob/living/simple_mob/S = M
|
||||
S.revivedby = U.name
|
||||
if(!bound_mob)
|
||||
bound_mob = M
|
||||
bound_mob.capture_caught = TRUE
|
||||
persist_storable = FALSE
|
||||
desc = "A glowing crystal in what appears to be some kind of steel housing."
|
||||
|
||||
//Determines the capture chance! So you can't capture AI mobs if they're perfectly healthy and all that
|
||||
/obj/item/capture_crystal/proc/capture_chance(mob/living/M, user)
|
||||
if(capture_chance_modifier >= 100) //Master crystal always work
|
||||
return 100
|
||||
var/capture_chance = ((1 - (M.health / M.maxHealth)) * 100) //Inverted health percent! 100% = 0%
|
||||
//So I don't know how this works but here's a kind of explanation
|
||||
//Basic chance + ((Mob's max health - minimum calculated health) / (Max allowed health - Min allowed health)*(Chance at Max allowed health - Chance at minimum allowed health)
|
||||
capture_chance += 35 + ((M.maxHealth - 5)/ (1000-5)*(-100 - 35))
|
||||
//Basically! Mobs over 1000 max health will be unable to be caught without using status effects.
|
||||
//Thanks Aronai!
|
||||
var/effect_count = 0 //This will give you a smol chance to capture if you have applied status effects, even if the chance would ordinarily be <0
|
||||
if(M.stat == UNCONSCIOUS)
|
||||
capture_chance += 0.1
|
||||
effect_count += 1
|
||||
else if(M.stat == CONSCIOUS)
|
||||
capture_chance *= 0.9
|
||||
else
|
||||
capture_chance = 0
|
||||
if(M.weakened) //Haha you fall down
|
||||
capture_chance += 0.1
|
||||
effect_count += 1
|
||||
if(M.stunned) //What's the matter???
|
||||
capture_chance += 0.1
|
||||
effect_count += 1
|
||||
if(M.on_fire) //AAAAAAAA
|
||||
capture_chance += 0.1
|
||||
effect_count += 1
|
||||
if(M.paralysis) //Oh noooo
|
||||
capture_chance += 0.1
|
||||
effect_count += 1
|
||||
if(M.ai_holder.stance == STANCE_IDLE) //SNEAK ATTACK???
|
||||
capture_chance += 0.1
|
||||
effect_count += 1
|
||||
|
||||
capture_chance *= capture_chance_modifier
|
||||
|
||||
if(capture_chance <= 0)
|
||||
capture_chance = 0 + effect_count
|
||||
if(capture_chance <= 0)
|
||||
capture_chance = 0
|
||||
to_chat(user, "<span class='notice'>There's no chance... It needs to be weaker.</span>")
|
||||
|
||||
last_activate = world.time
|
||||
log_admin("[user] threw a capture crystal at [M] and got [capture_chance]% chance to catch.")
|
||||
return capture_chance
|
||||
|
||||
//Handles checking relevent bans, preferences, and asking the player if they want to be caught
|
||||
/obj/item/capture_crystal/proc/capture_player(mob/living/M, mob/living/U)
|
||||
if(jobban_isbanned(M, "GhostRoles"))
|
||||
to_chat(U, "<span class='warning'>This creature is not suitable for capture.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(!M.capture_crystal || M.capture_caught)
|
||||
to_chat(U, "<span class='warning'>This creature is not suitable for capture.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(tgui_alert(M, "Would you like to be caught by in [src] by [U]? You will be bound to their will.", "Become Caught",list("No","Yes")) == "Yes")
|
||||
if(tgui_alert(M, "Are you really sure? The only way to undo this is to OOC escape while you're in the crystal.", "Become Caught", list("No","Yes")) == "Yes")
|
||||
log_admin("[key_name(M)] has agreed to become caught by [key_name(U)].")
|
||||
capture(M, U)
|
||||
recall(U)
|
||||
return
|
||||
to_chat(U, "<span class='warning'>This creature is too strong willed to be captured.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
|
||||
//The clean up procs!
|
||||
/obj/item/capture_crystal/proc/mob_was_deleted()
|
||||
UnregisterSignal(bound_mob, COMSIG_PARENT_QDELETING)
|
||||
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
|
||||
bound_mob.capture_caught = FALSE
|
||||
bound_mob = null
|
||||
owner = null
|
||||
active = FALSE
|
||||
persist_storable = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/item/capture_crystal/proc/owner_was_deleted()
|
||||
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
|
||||
owner = null
|
||||
active = FALSE
|
||||
update_icon()
|
||||
|
||||
//If the crystal hasn't been set up, it does this
|
||||
/obj/item/capture_crystal/proc/activate(mob/living/user, target)
|
||||
if(!cooldown_check()) //Are we ready to do things yet?
|
||||
to_chat(thrower, "<span class='notice'>\The [src] clicks unsatisfyingly... It is not ready yet.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
if(spawn_mob_type && !bound_mob) //We don't already have a mob, but we know what kind of mob we want
|
||||
bound_mob = new spawn_mob_type(src) //Well let's spawn it then!
|
||||
bound_mob.faction = user.faction
|
||||
spawn_mob_type = null
|
||||
capture(bound_mob, user)
|
||||
if(bound_mob) //We have a mob! Let's finish setting up.
|
||||
user.visible_message("\The [src] clicks, and then emits a small chime.", "\The [src] grows warm in your hand, something inside is awake.")
|
||||
active = TRUE
|
||||
if(!owner) //Do we have an owner? It's pretty unlikely that this would ever happen! But it happens, let's claim the crystal.
|
||||
owner = user
|
||||
if(isanimal(bound_mob))
|
||||
var/mob/living/simple_mob/S = bound_mob
|
||||
S.revivedby = user.name
|
||||
determine_action(user, target)
|
||||
return
|
||||
else if(isliving(target)) //So we don't have a mob, let's try to claim one! Is the target a mob?
|
||||
var/mob/living/M = target
|
||||
last_activate = world.time
|
||||
if(M.capture_caught) //Can't capture things that were already caught.
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly... \The [M] is already under someone else's control.</span>")
|
||||
return
|
||||
else if(M.stat == DEAD) //Is it dead? We can't influence dead things.
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly... \The [M] is not in a state to be captured.</span>")
|
||||
return
|
||||
else if(M.client) //Is it player controlled?
|
||||
capture_player(M, user) //We have to do things a little differently if so.
|
||||
return
|
||||
else if(!isanimal(M)) //So it's not player controlled, but it's also not a simplemob?
|
||||
to_chat(user, "<span class='warning'>This creature is not suitable for capture.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return
|
||||
var/mob/living/simple_mob/S = M
|
||||
if(!S.ai_holder) //We don't really want to capture simplemobs that don't have an AI
|
||||
to_chat(user, "<span class='warning'>This creature is not suitable for capture.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(prob(capture_chance(S, user))) //OKAY! So we have an NPC simplemob with an AI, let's calculate its capture chance! It varies based on the mob's condition.
|
||||
capture(S, user) //We did it! Woo! We capture it!
|
||||
user.visible_message("\The [src] clicks, and then emits a small chime.", "Alright! \The [S] was caught!")
|
||||
recall(user)
|
||||
active = TRUE
|
||||
else //Shoot, it didn't work and now it's mad!!!
|
||||
S.ai_holder.go_wake()
|
||||
S.ai_holder.target = user
|
||||
S.ai_holder.track_target_position()
|
||||
S.ai_holder.set_stance(STANCE_FIGHT)
|
||||
user.visible_message("\The [src] bonks into \the [S], angering it!")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly.</span>")
|
||||
update_icon()
|
||||
return
|
||||
//The target is not a mob, so let's not do anything.
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly.</span>")
|
||||
|
||||
//We're using the crystal, but what will it do?
|
||||
/obj/item/capture_crystal/proc/determine_action(mob/living/U, T)
|
||||
if(!cooldown_check()) //Are we ready yet?
|
||||
to_chat(thrower, "<span class='notice'>\The [src] clicks unsatisfyingly... It is not ready yet.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
return //No
|
||||
if(bound_mob in contents) //Do we have our mob?
|
||||
if(T)
|
||||
unleash(U, T) //Yes, let's let it out!
|
||||
else
|
||||
unleash(U)
|
||||
else if (bound_mob) //Do we HAVE a mob?
|
||||
recall(U) //Yes, let's try to put it back in the crystal
|
||||
else //No we don't have a mob, let's reset the crystal.
|
||||
to_chat(U, "<span class='notice'>\The [src] clicks unsatisfyingly.</span>")
|
||||
active = FALSE
|
||||
update_icon()
|
||||
owner = null
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
|
||||
//Let's try to call our mob back!
|
||||
/obj/item/capture_crystal/proc/recall(mob/living/user)
|
||||
if(bound_mob in view(user)) //We can only recall it if we can see it
|
||||
var/turf/turfmemory = get_turf(bound_mob)
|
||||
if(isanimal(bound_mob))
|
||||
var/mob/living/simple_mob/M = bound_mob
|
||||
M.ai_holder.go_sleep() //AI doesn't need to think when it's in the crystal
|
||||
bound_mob.forceMove(src)
|
||||
last_activate = world.time
|
||||
bound_mob.visible_message("\The [user]'s [src] flashes, disappearing [bound_mob] in an instant!!!", "\The [src] pulls you back into confinement in a flash of light!!!")
|
||||
animate_action(turfmemory)
|
||||
playsound(src, 'sound/effects/capture-crystal-in.ogg', 75, 1, -1)
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] clicks and emits a small, unpleasant tone. \The [bound_mob] cannot be recalled.</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
|
||||
//Let's let our mob out!
|
||||
/obj/item/capture_crystal/proc/unleash(mob/living/user, atom/target)
|
||||
if(!user && !target) //We got thrown but we're not sure who did it, let's go to where the crystal is
|
||||
bound_mob.forceMove(src.drop_location())
|
||||
return
|
||||
if(!target) //We know who wants to let us out, but they didn't say where, so let's drop us on them
|
||||
bound_mob.forceMove(user.drop_location())
|
||||
else //We got thrown! Let's go where we got thrown
|
||||
bound_mob.forceMove(target.drop_location())
|
||||
last_activate = world.time
|
||||
if(isanimal(bound_mob))
|
||||
var/mob/living/simple_mob/M = bound_mob
|
||||
M.ai_holder.go_wake() //Okay it's time to do work, let's wake up!
|
||||
bound_mob.faction = owner.faction //Let's make sure we aren't hostile to our owner or their friends
|
||||
bound_mob.visible_message("\The [user]'s [src] flashes, \the [bound_mob] appears in an instant!!!", "The world around you rematerialize as you are unleashed from the [src] next to \the [user]. You feel a strong compulsion to enact \the [owner]'s will.")
|
||||
animate_action(get_turf(bound_mob))
|
||||
playsound(src, 'sound/effects/capture-crystal-out.ogg', 75, 1, -1)
|
||||
update_icon()
|
||||
|
||||
//Let's make a flashy sparkle when someone appears or disappears!
|
||||
/obj/item/capture_crystal/proc/animate_action(atom/thing)
|
||||
var/image/coolanimation = image('icons/obj/capture_crystal_vr.dmi', null, "animation")
|
||||
coolanimation.plane = PLANE_LIGHTING_ABOVE
|
||||
thing.overlays += coolanimation
|
||||
sleep(11)
|
||||
thing.overlays -= coolanimation
|
||||
|
||||
//IF the crystal somehow ends up in a tummy and digesting with a bound mob who doesn't want to be eaten, let's move them to the ground
|
||||
/obj/item/capture_crystal/digest_act(var/atom/movable/item_storage = null)
|
||||
if(bound_mob in contents && !bound_mob.devourable)
|
||||
bound_mob.forceMove(src.drop_location())
|
||||
return ..()
|
||||
|
||||
//We got thrown! Let's figure out what to do
|
||||
/obj/item/capture_crystal/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, datum/callback/callback)
|
||||
. = ..()
|
||||
if(target == bound_mob && thrower != bound_mob) //We got thrown at our bound mob (and weren't thrown by the bound mob) let's ignore the cooldown and just put them back in
|
||||
recall(thrower)
|
||||
else if(!cooldown_check()) //OTHERWISE let's obey the cooldown
|
||||
to_chat(thrower, "<span class='notice'>\The [src] emits an soft tone... It is not ready yet.</span>")
|
||||
if(bound_mob)
|
||||
playsound(src, 'sound/effects/capture-crystal-problem.ogg', 75, 1, -1)
|
||||
else
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(!active) //The ball isn't set up, let's try to set it up.
|
||||
if(isliving(target)) //We're hitting a mob, let's try to capture it.
|
||||
sleep(10)
|
||||
activate(thrower, target)
|
||||
return
|
||||
sleep(10)
|
||||
activate(thrower, src)
|
||||
else if(!bound_mob) //We hit something else, and we don't have a mob, so we can't really do anything!
|
||||
to_chat(thrower, "<span class='notice'>\The [src] clicks unpleasantly...</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
else if(bound_mob in contents) //We have our mob! Let's try to let it out.
|
||||
sleep(10)
|
||||
unleash(thrower, src)
|
||||
update_icon()
|
||||
else //Our mob isn't here, we can't do anything.
|
||||
to_chat(thrower, "<span class='notice'>\The [src] clicks unpleasantly...</span>")
|
||||
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
|
||||
|
||||
/obj/item/capture_crystal/great
|
||||
capture_chance_modifier = 1.5
|
||||
|
||||
/obj/item/capture_crystal/ultra
|
||||
capture_chance_modifier = 2
|
||||
|
||||
/obj/item/capture_crystal/master
|
||||
capture_chance_modifier = 100
|
||||
|
||||
/obj/item/capture_crystal/cass
|
||||
spawn_mob_type = /mob/living/simple_mob/vore/woof/cass
|
||||
/obj/item/capture_crystal/adg
|
||||
spawn_mob_type = /mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced
|
||||
/obj/item/capture_crystal/bigdragon
|
||||
spawn_mob_type = /mob/living/simple_mob/vore/bigdragon
|
||||
/obj/item/capture_crystal/bigdragon/friendly
|
||||
spawn_mob_type = /mob/living/simple_mob/vore/bigdragon/friendly
|
||||
/obj/item/capture_crystal/teppi
|
||||
spawn_mob_type = /mob/living/simple_mob/vore/alienanimals/teppi
|
||||
/obj/item/capture_crystal/broodmother
|
||||
spawn_mob_type = /mob/living/simple_mob/animal/giant_spider/broodmother
|
||||
/obj/item/capture_crystal/skeleton
|
||||
spawn_mob_type = /mob/living/simple_mob/vore/alienanimals/skeleton
|
||||
/obj/item/capture_crystal/dustjumper
|
||||
spawn_mob_type = /mob/living/simple_mob/vore/alienanimals/dustjumper
|
||||
|
||||
/obj/item/capture_crystal/random
|
||||
var/static/list/possible_mob_types = list(
|
||||
list(/mob/living/simple_mob/animal/goat),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/passive/bird,
|
||||
/mob/living/simple_mob/animal/passive/bird/azure_tit,
|
||||
/mob/living/simple_mob/animal/passive/bird/black_bird,
|
||||
/mob/living/simple_mob/animal/passive/bird/european_robin,
|
||||
/mob/living/simple_mob/animal/passive/bird/goldcrest,
|
||||
/mob/living/simple_mob/animal/passive/bird/ringneck_dove,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/black_headed_caique,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/blue,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/bluegreen,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/grey,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/white,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/yellowish,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/eclectus,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/grey_parrot,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/kea,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/pink_cockatoo,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/sulphur_cockatoo,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/white_caique,
|
||||
/mob/living/simple_mob/animal/passive/bird/parrot/white_cockatoo
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/passive/cat,
|
||||
/mob/living/simple_mob/animal/passive/cat/black
|
||||
),
|
||||
list(/mob/living/simple_mob/animal/passive/chick),
|
||||
list(/mob/living/simple_mob/animal/passive/cow),
|
||||
list(/mob/living/simple_mob/animal/passive/dog/brittany),
|
||||
list(/mob/living/simple_mob/animal/passive/dog/corgi),
|
||||
list(/mob/living/simple_mob/animal/passive/dog/tamaskan),
|
||||
list(/mob/living/simple_mob/animal/passive/fox),
|
||||
list(/mob/living/simple_mob/animal/passive/hare),
|
||||
list(/mob/living/simple_mob/animal/passive/lizard),
|
||||
list(/mob/living/simple_mob/animal/passive/mouse),
|
||||
list(/mob/living/simple_mob/animal/passive/mouse/jerboa),
|
||||
list(/mob/living/simple_mob/animal/passive/opossum),
|
||||
list(/mob/living/simple_mob/animal/passive/pillbug),
|
||||
list(/mob/living/simple_mob/animal/passive/snake),
|
||||
list(/mob/living/simple_mob/animal/passive/tindalos),
|
||||
list(/mob/living/simple_mob/animal/passive/yithian),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/rabbit),
|
||||
list(/mob/living/simple_mob/vore/redpanda),
|
||||
list(/mob/living/simple_mob/vore/woof),
|
||||
list(/mob/living/simple_mob/vore/fennec),
|
||||
list(/mob/living/simple_mob/vore/fennix),
|
||||
list(/mob/living/simple_mob/vore/hippo),
|
||||
list(/mob/living/simple_mob/vore/horse),
|
||||
list(/mob/living/simple_mob/vore/bee),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/space/bear,
|
||||
/mob/living/simple_mob/animal/space/bear/brown
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/otie/feral,
|
||||
/mob/living/simple_mob/otie/feral/chubby,
|
||||
/mob/living/simple_mob/otie/red,
|
||||
/mob/living/simple_mob/otie/red/chubby
|
||||
),
|
||||
list(/mob/living/simple_mob/animal/sif/diyaab),
|
||||
list(/mob/living/simple_mob/animal/sif/duck),
|
||||
list(/mob/living/simple_mob/animal/sif/frostfly),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/sif/glitterfly =50,
|
||||
/mob/living/simple_mob/animal/sif/glitterfly/rare = 1
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/sif/kururak = 10,
|
||||
/mob/living/simple_mob/animal/sif/kururak/leader = 1,
|
||||
/mob/living/simple_mob/animal/sif/kururak/hibernate = 2,
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/sif/sakimm = 10,
|
||||
/mob/living/simple_mob/animal/sif/sakimm/intelligent = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/animal/sif/savik) = 5,
|
||||
list(
|
||||
/mob/living/simple_mob/animal/sif/shantak = 10,
|
||||
/mob/living/simple_mob/animal/sif/shantak/leader = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/animal/sif/siffet),
|
||||
list(/mob/living/simple_mob/animal/sif/tymisian),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/giant_spider/nurse = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/electric = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/frost = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/hunter = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/ion = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/lurker = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/pepper = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/phorogenic = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/thermic = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/tunneler = 10,
|
||||
/mob/living/simple_mob/animal/giant_spider/webslinger = 5,
|
||||
/mob/living/simple_mob/animal/giant_spider/broodmother = 1),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/wolf = 10,
|
||||
/mob/living/simple_mob/animal/wolf/direwolf = 5,
|
||||
/mob/living/simple_mob/vore/greatwolf = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/black = 1,
|
||||
/mob/living/simple_mob/vore/greatwolf/grey = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/creature/strong),
|
||||
list(/mob/living/simple_mob/faithless/strong),
|
||||
list(/mob/living/simple_mob/animal/goat),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/sif/shantak/leader = 1,
|
||||
/mob/living/simple_mob/animal/sif/shantak = 10),
|
||||
list(/mob/living/simple_mob/animal/sif/savik,),
|
||||
list(/mob/living/simple_mob/animal/sif/hooligan_crab),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/space/alien = 50,
|
||||
/mob/living/simple_mob/animal/space/alien/drone = 40,
|
||||
/mob/living/simple_mob/animal/space/alien/sentinel = 25,
|
||||
/mob/living/simple_mob/animal/space/alien/sentinel/praetorian = 15,
|
||||
/mob/living/simple_mob/animal/space/alien/queen = 10,
|
||||
/mob/living/simple_mob/animal/space/alien/queen/empress = 5,
|
||||
/mob/living/simple_mob/animal/space/alien/queen/empress/mother = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/animal/space/bats/cult/strong),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/space/bear,
|
||||
/mob/living/simple_mob/animal/space/bear/brown
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/animal/space/carp = 50,
|
||||
/mob/living/simple_mob/animal/space/carp/large = 10,
|
||||
/mob/living/simple_mob/animal/space/carp/large/huge = 5
|
||||
),
|
||||
list(/mob/living/simple_mob/animal/space/goose),
|
||||
list(/mob/living/simple_mob/animal/space/jelly),
|
||||
list(/mob/living/simple_mob/animal/space/tree),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/aggressive/corrupthound = 10,
|
||||
/mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi = 1,
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/aggressive/deathclaw),
|
||||
list(/mob/living/simple_mob/vore/aggressive/dino),
|
||||
list(/mob/living/simple_mob/vore/aggressive/dragon),
|
||||
list(/mob/living/simple_mob/vore/aggressive/dragon/virgo3b),
|
||||
list(/mob/living/simple_mob/vore/aggressive/frog),
|
||||
list(/mob/living/simple_mob/vore/aggressive/giant_snake),
|
||||
list(/mob/living/simple_mob/vore/aggressive/mimic),
|
||||
list(/mob/living/simple_mob/vore/aggressive/panther),
|
||||
list(/mob/living/simple_mob/vore/aggressive/rat),
|
||||
list(/mob/living/simple_mob/vore/bee),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/sect_drone = 10,
|
||||
/mob/living/simple_mob/vore/sect_queen = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/solargrub),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/oregrub = 5,
|
||||
/mob/living/simple_mob/vore/oregrub/lava = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/catgirl),
|
||||
list(/mob/living/simple_mob/vore/wolfgirl),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/lamia,
|
||||
/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/bra,
|
||||
/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
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/humanoid/merc = 100,
|
||||
/mob/living/simple_mob/humanoid/merc/melee/sword = 50,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged = 25,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/grenadier = 1,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/ionrifle = 10,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/laser = 5,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/rifle = 5,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/smg = 5,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/sniper = 1,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/space = 10,
|
||||
/mob/living/simple_mob/humanoid/merc/ranged/technician = 5
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/humanoid/pirate = 3,
|
||||
/mob/living/simple_mob/humanoid/pirate/ranged = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/mechanical/combat_drone),
|
||||
list(/mob/living/simple_mob/mechanical/corrupt_maint_drone),
|
||||
list(
|
||||
/mob/living/simple_mob/mechanical/hivebot = 100,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/backline = 10,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/basic = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/dot = 5,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/ion = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/laser = 10,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/rapid = 2,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege = 1,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/emp = 5,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/fragmentation = 1,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/radiation = 1,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong = 3,
|
||||
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard = 3,
|
||||
/mob/living/simple_mob/mechanical/hivebot/support = 8,
|
||||
/mob/living/simple_mob/mechanical/hivebot/support/commander = 5,
|
||||
/mob/living/simple_mob/mechanical/hivebot/support/commander/autofollow = 10,
|
||||
/mob/living/simple_mob/mechanical/hivebot/swarm = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/tank = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/tank/armored = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_bullet = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_laser = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_melee = 20,
|
||||
/mob/living/simple_mob/mechanical/hivebot/tank/meatshield = 20
|
||||
),
|
||||
list(/mob/living/simple_mob/mechanical/infectionbot),
|
||||
list(/mob/living/simple_mob/mechanical/mining_drone),
|
||||
list(/mob/living/simple_mob/mechanical/technomancer_golem),
|
||||
list(
|
||||
/mob/living/simple_mob/mechanical/viscerator,
|
||||
/mob/living/simple_mob/mechanical/viscerator/piercing
|
||||
),
|
||||
list(/mob/living/simple_mob/mechanical/wahlem),
|
||||
list(/mob/living/simple_mob/animal/passive/fox/syndicate),
|
||||
list(/mob/living/simple_mob/animal/passive/fox),
|
||||
list(/mob/living/simple_mob/animal/wolf/direwolf),
|
||||
list(/mob/living/simple_mob/animal/space/jelly),
|
||||
list(
|
||||
/mob/living/simple_mob/otie/feral,
|
||||
/mob/living/simple_mob/otie/feral/chubby,
|
||||
/mob/living/simple_mob/otie/red,
|
||||
/mob/living/simple_mob/otie/red/chubby
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/shadekin/blue = 100,
|
||||
/mob/living/simple_mob/shadekin/green = 50,
|
||||
/mob/living/simple_mob/shadekin/orange = 20,
|
||||
/mob/living/simple_mob/shadekin/purple = 60,
|
||||
/mob/living/simple_mob/shadekin/red = 40,
|
||||
/mob/living/simple_mob/shadekin/yellow = 1
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/aggressive/corrupthound,
|
||||
/mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/aggressive/deathclaw),
|
||||
list(/mob/living/simple_mob/vore/aggressive/dino),
|
||||
list(/mob/living/simple_mob/vore/aggressive/dragon),
|
||||
list(/mob/living/simple_mob/vore/aggressive/dragon/virgo3b),
|
||||
list(/mob/living/simple_mob/vore/aggressive/frog),
|
||||
list(/mob/living/simple_mob/vore/aggressive/giant_snake),
|
||||
list(/mob/living/simple_mob/vore/aggressive/mimic),
|
||||
list(/mob/living/simple_mob/vore/aggressive/panther),
|
||||
list(/mob/living/simple_mob/vore/aggressive/rat),
|
||||
list(/mob/living/simple_mob/vore/bee),
|
||||
list(/mob/living/simple_mob/vore/catgirl),
|
||||
list(/mob/living/simple_mob/vore/cookiegirl),
|
||||
list(/mob/living/simple_mob/vore/fennec),
|
||||
list(/mob/living/simple_mob/vore/fennix),
|
||||
list(/mob/living/simple_mob/vore/hippo),
|
||||
list(/mob/living/simple_mob/vore/horse),
|
||||
list(/mob/living/simple_mob/vore/oregrub),
|
||||
list(/mob/living/simple_mob/vore/rabbit),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/redpanda = 50,
|
||||
/mob/living/simple_mob/vore/redpanda/fae = 1
|
||||
),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/sect_drone = 10,
|
||||
/mob/living/simple_mob/vore/sect_queen = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/solargrub),
|
||||
list(/mob/living/simple_mob/vore/woof),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/teppi),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_ghost),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/catslug),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/startreader),
|
||||
list(/mob/living/simple_mob/vore/bigdragon),
|
||||
list(
|
||||
/mob/living/simple_mob/vore/leopardmander = 50,
|
||||
/mob/living/simple_mob/vore/leopardmander/blue = 10,
|
||||
/mob/living/simple_mob/vore/leopardmander/exotic = 1
|
||||
),
|
||||
list(/mob/living/simple_mob/vore/sheep),
|
||||
list(/mob/living/simple_mob/vore/weretiger),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/skeleton),
|
||||
list(/mob/living/simple_mob/vore/alienanimals/dustjumper)
|
||||
)
|
||||
|
||||
/obj/item/capture_crystal/random/Initialize()
|
||||
var/subchoice = pickweight(possible_mob_types) //Some of the lists have nested lists, so let's pick one of them
|
||||
var/choice = pickweight(subchoice) //And then we'll pick something from whatever's left
|
||||
spawn_mob_type = choice //Now when someone uses this, we'll spawn whatever we picked!
|
||||
return ..()
|
||||
|
||||
/mob/living
|
||||
var/capture_crystal = TRUE //If TRUE, the mob is capturable. Otherwise it isn't.
|
||||
var/capture_caught = FALSE //If TRUE, the mob has already been caught, and so cannot be caught again.
|
||||
@@ -254,6 +254,7 @@
|
||||
desc = "A chocolate-coated biscuit stick."
|
||||
icon_state = "pockystick"
|
||||
item_state = "pocky"
|
||||
type_butt = null
|
||||
|
||||
/obj/item/clothing/mask/chewable/candy/pocky/process()
|
||||
chew()
|
||||
|
||||
@@ -85,8 +85,8 @@
|
||||
/obj/item/weapon/beach_ball/holoball,
|
||||
/obj/item/toy/balloon,
|
||||
/obj/item/toy/blink,
|
||||
/obj/item/toy/crossbow,
|
||||
/obj/item/weapon/gun/projectile/revolver/capgun,
|
||||
/obj/item/weapon/gun/projectile/revolver/toy/crossbow,
|
||||
/obj/item/weapon/storage/box/capguntoy,
|
||||
/obj/item/toy/katana,
|
||||
/obj/item/toy/mecha/deathripley,
|
||||
/obj/item/toy/mecha/durand,
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && path != 2)
|
||||
if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && !detonator && path != 2)
|
||||
var/obj/item/device/assembly_holder/det = W
|
||||
if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right)))
|
||||
to_chat(user, "<span class='warning'>Assembly must contain one igniter.</span>")
|
||||
@@ -314,4 +314,3 @@
|
||||
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
@@ -141,6 +141,7 @@ var/last_chew = 0
|
||||
/obj/item/weapon/handcuffs/fuzzy
|
||||
name = "fuzzy cuffs"
|
||||
icon_state = "fuzzycuff"
|
||||
breakouttime = 100 //VOREstation edit
|
||||
desc = "Use this to keep... 'prisoners' in line."
|
||||
|
||||
/obj/item/weapon/handcuffs/cable
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user