Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit792
This commit is contained in:
@@ -101,8 +101,5 @@
|
||||
|
||||
#define TOGGLES_CITADEL 0
|
||||
|
||||
//component stuff
|
||||
#define COMSIG_VORE_TOGGLED "voremode_toggled" // totally not copypasta
|
||||
|
||||
//belly sound pref things
|
||||
#define NORMIE_HEARCHECK 4
|
||||
|
||||
+11
-22
@@ -29,38 +29,27 @@
|
||||
#define EFFECT_DROWSY "drowsy"
|
||||
#define EFFECT_JITTER "jitter"
|
||||
|
||||
// /mob/living/combat_flags
|
||||
#define CAN_TOGGLE_COMBAT_MODE(mob) FORCE_BOOLEAN((mob.stat == CONSCIOUS) && !(mob.combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
|
||||
/// Default combat flags for those affected by ((stamina combat))
|
||||
/// Default combat flags for those affected by sprinting (combat mode has been made into its own component)
|
||||
#define COMBAT_FLAGS_DEFAULT NONE
|
||||
/// Default combat flags for everyone else (so literally everyone but humans)
|
||||
#define COMBAT_FLAGS_STAMSYSTEM_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_COMBAT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED | COMBAT_FLAG_COMBAT_FORCED)
|
||||
/// Default combat flags for those only affected by sprint (so just silicons)
|
||||
#define COMBAT_FLAGS_STAMEXEMPT_YESSPRINT (COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_COMBAT_TOGGLED | COMBAT_FLAG_COMBAT_FORCED)
|
||||
/// Default combat flags for everyone else (so literally everyone but humans).
|
||||
#define COMBAT_FLAGS_SPRINT_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED)
|
||||
|
||||
/// The user wants combat mode on
|
||||
#define COMBAT_FLAG_COMBAT_TOGGLED (1<<0)
|
||||
/// The user wants sprint mode on
|
||||
#define COMBAT_FLAG_SPRINT_TOGGLED (1<<1)
|
||||
/// Combat mode is currently active
|
||||
#define COMBAT_FLAG_COMBAT_ACTIVE (1<<2)
|
||||
#define COMBAT_FLAG_SPRINT_TOGGLED (1<<0)
|
||||
/// Sprint is currently active
|
||||
#define COMBAT_FLAG_SPRINT_ACTIVE (1<<3)
|
||||
#define COMBAT_FLAG_SPRINT_ACTIVE (1<<1)
|
||||
/// Currently attempting to crawl under someone
|
||||
#define COMBAT_FLAG_ATTEMPTING_CRAWL (1<<4)
|
||||
#define COMBAT_FLAG_ATTEMPTING_CRAWL (1<<2)
|
||||
/// Currently stamcritted
|
||||
#define COMBAT_FLAG_HARD_STAMCRIT (1<<5)
|
||||
#define COMBAT_FLAG_HARD_STAMCRIT (1<<3)
|
||||
/// Currently attempting to resist up from the ground
|
||||
#define COMBAT_FLAG_RESISTING_REST (1<<6)
|
||||
#define COMBAT_FLAG_RESISTING_REST (1<<4)
|
||||
/// Intentionally resting
|
||||
#define COMBAT_FLAG_INTENTIONALLY_RESTING (1<<7)
|
||||
#define COMBAT_FLAG_INTENTIONALLY_RESTING (1<<5)
|
||||
/// Currently stamcritted but not as violently
|
||||
#define COMBAT_FLAG_SOFT_STAMCRIT (1<<8)
|
||||
/// Force combat mode on at all times, overrides everything including combat disable traits.
|
||||
#define COMBAT_FLAG_COMBAT_FORCED (1<<9)
|
||||
#define COMBAT_FLAG_SOFT_STAMCRIT (1<<6)
|
||||
/// Force sprint mode on at all times, overrides everything including sprint disable traits.
|
||||
#define COMBAT_FLAG_SPRINT_FORCED (1<<10)
|
||||
#define COMBAT_FLAG_SPRINT_FORCED (1<<7)
|
||||
|
||||
// Helpers for getting someone's stamcrit state. Cast to living.
|
||||
#define NOT_STAMCRIT 0
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
#define CAT_WEAPONRY "Weaponry"
|
||||
#define CAT_WEAPON "Weapons"
|
||||
#define CAT_AMMO "Ammunition"
|
||||
#define CAT_PARTS "Weapon Parts"
|
||||
#define CAT_ROBOT "Robots"
|
||||
#define CAT_MISC "Misc"
|
||||
#define CAT_MISCELLANEOUS "Miscellaneous"
|
||||
|
||||
@@ -75,3 +75,11 @@
|
||||
#define ID_COMPONENT_KNOWLEDGE_NONE 0
|
||||
/// Has full knowledge
|
||||
#define ID_COMPONENT_KNOWLEDGE_FULL 1
|
||||
|
||||
// Combat mode flags.
|
||||
/// The user wants combat mode on
|
||||
#define COMBAT_MODE_TOGGLED (1<<0)
|
||||
/// combat mode is active.
|
||||
#define COMBAT_MODE_ACTIVE (1<<1)
|
||||
/// combat mode is not active
|
||||
#define COMBAT_MODE_INACTIVE (1<<2)
|
||||
@@ -149,7 +149,8 @@
|
||||
|
||||
// /mob signals
|
||||
#define COMSIG_MOB_CLICKED_SHIFT_ON "mob_shift_click_on" //from base of /atom/ShiftClick(): (atom/A), for return values, see COMSIG_CLICK_SHIFT
|
||||
#define COMSIG_MOB_FOV_VIEW "mob_visible_atoms" //from base of mob/fov_view(): (list/visible_atoms)
|
||||
#define COMSIG_MOB_FOV_VIEW "mob_visible_atoms" //from base of /mob/fov_view(): (list/visible_atoms)
|
||||
#define COMSIG_MOB_POINTED "mob_pointed" //from base of /mob/verb/pointed(): (atom/A)
|
||||
#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A), for return values, see COMSIG_CLICK_SHIFT
|
||||
#define COMPONENT_EXAMINATE_BLIND 3 //outputs the "something is there but you can't see it" message.
|
||||
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
|
||||
@@ -192,7 +193,12 @@
|
||||
|
||||
#define COMSIG_MOB_SPELL_CAN_CAST "mob_spell_can_cast" //from base of /obj/effect/proc_holder/spell/can_cast(): (spell)
|
||||
|
||||
#define COMSIG_ROBOT_UPDATE_ICONS "robot_update_icons" //from base of robot/update_icons(): ()
|
||||
// /client signals
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client)
|
||||
#define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client)
|
||||
#define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc)
|
||||
#define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view)
|
||||
#define COMSIG_MOB_CLIENT_MOUSEMOVE "mob_client_mousemove" //from base of /client/MouseMove(): (object, location, control, params)
|
||||
|
||||
// /mob/living signals
|
||||
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
|
||||
@@ -200,20 +206,14 @@
|
||||
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
|
||||
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
|
||||
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
|
||||
#define COMSIG_LIVING_SHOCK_PREVENTED "living_shock_prevented" //sent when items with siemen coeff. of 0 block a shock: (power_source, source, siemens_coeff, dist_check)
|
||||
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
|
||||
#define COMSIG_LIVING_REVIVE "living_revive" //from base of mob/living/revive() (full_heal, admin_revive)
|
||||
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "mob_client_login" //sent when a mob/login() finishes: (client)
|
||||
#define COMSIG_MOB_CLIENT_LOGOUT "mob_client_logout" //sent when a mob/logout() starts: (client)
|
||||
#define COMSIG_MOB_CLIENT_MOVE "mob_client_move" //sent when client/Move() finishes with no early returns: (client, direction, n, oldloc)
|
||||
#define COMSIG_MOB_CLIENT_CHANGE_VIEW "mob_client_change_view" //from base of /client/change_view(): (client, old_view, view)
|
||||
|
||||
#define COMSIG_MOB_RESET_PERSPECTIVE "mob_reset_perspective" //from base of /mob/reset_perspective(): (atom/target)
|
||||
#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override)
|
||||
// This returns flags as defined for block in __DEFINES/combat.dm!
|
||||
#define COMSIG_LIVING_RUN_BLOCK "living_do_run_block" //from base of mob/living/do_run_block(): (real_attack, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone)
|
||||
#define COMSIG_LIVING_COMBAT_ENABLED "combatmode_enabled" //from base of mob/living/enable_combat_mode() (was_forced)
|
||||
#define COMSIG_LIVING_COMBAT_DISABLED "combatmode_disabled" //from base of mob/living/disable_combat_mode() (was_forced)
|
||||
#define COMSIG_LIVING_GET_BLOCKING_ITEMS "get_blocking_items" //from base of mob/living/get_blocking_items(): (list/items)
|
||||
|
||||
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
|
||||
@@ -231,6 +231,10 @@
|
||||
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
|
||||
#define COMSIG_CARBON_IDENTITY_TRANSFERRED_TO "carbon_id_transferred_to" //from datum/dna/transfer_identity(): (datum/dna, transfer_SE)
|
||||
#define COMSIG_CARBON_TACKLED "carbon_tackled" //sends from tackle.dm on tackle completion
|
||||
|
||||
// /mob/living/silicon signals
|
||||
#define COMSIG_ROBOT_UPDATE_ICONS "robot_update_icons" //from base of robot/update_icons(): ()
|
||||
|
||||
// /mob/living/simple_animal/hostile signals
|
||||
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
|
||||
#define COMPONENT_HOSTILE_NO_ATTACK 1
|
||||
@@ -341,6 +345,14 @@
|
||||
//NTnet
|
||||
#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
|
||||
|
||||
//Combat mode
|
||||
#define COMSIG_TOGGLE_COMBAT_MODE "toggle_combat_mode" //safely toggles combat mode.
|
||||
#define COMSIG_DISABLE_COMBAT_MODE "disable_combat_mode" //safely disables combat mode.
|
||||
#define COMSIG_ENABLE_COMBAT_MODE "enable_combat_mode" //safely enables combat mode.
|
||||
#define COMSIG_LIVING_COMBAT_ENABLED "combatmode_enabled" //from base of datum/component/combat_mode/enable_combat_mode() (was_forced)
|
||||
#define COMSIG_LIVING_COMBAT_DISABLED "combatmode_disabled" //from base of datum/component/combat_mode/disable_combat_mode() (was_forced)
|
||||
#define COMSIG_COMBAT_MODE_CHECK "combatmode_check" //called when checking the combat mode flags (enabled/disabled/forced)
|
||||
|
||||
//Nanites
|
||||
#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
|
||||
#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy" //() returns TRUE if nanites have stealth
|
||||
|
||||
@@ -74,8 +74,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
#define FLYING (1<<1)
|
||||
#define VENTCRAWLING (1<<2)
|
||||
#define FLOATING (1<<3)
|
||||
#define UNSTOPPABLE (1<<4) //When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
|
||||
#define CRAWLING (1<<5) //Applied if you're crawling around on the ground/resting.
|
||||
///When moving, will Bump()/Cross()/Uncross() everything, but won't be stopped.
|
||||
#define UNSTOPPABLE (1<<4)
|
||||
///Applied if you're crawling around on the ground/resting.
|
||||
#define CRAWLING (1<<5)
|
||||
|
||||
//Fire and Acid stuff, for resistance_flags
|
||||
#define LAVA_PROOF (1<<0)
|
||||
|
||||
@@ -209,3 +209,5 @@
|
||||
|
||||
/// Make sure something is a boolean TRUE/FALSE 1/0 value, since things like bitfield & bitflag doesn't always give 1s and 0s.
|
||||
#define FORCE_BOOLEAN(x) ((x)? TRUE : FALSE)
|
||||
|
||||
#define TILES_TO_PIXELS(tiles) (tiles * PIXELS)
|
||||
|
||||
+30
-26
@@ -9,6 +9,9 @@
|
||||
#define TEXT_EAST "[EAST]"
|
||||
#define TEXT_WEST "[WEST]"
|
||||
|
||||
/// world.icon_size
|
||||
#define PIXELS 32
|
||||
|
||||
//These get to go at the top, because they're special
|
||||
//You can use these defines to get the typepath of the currently running proc/verb (yes procs + verbs are objects)
|
||||
/* eg:
|
||||
@@ -27,31 +30,32 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
|
||||
//Human Overlays Indexes/////////
|
||||
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
|
||||
#define MUTATIONS_LAYER 32 //mutations. Tk headglows, cold resistance glow, etc
|
||||
#define GENITALS_BEHIND_LAYER 31 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
|
||||
#define BODY_BEHIND_LAYER 30 //certain mutantrace features (tail when looking south) that must appear behind the body parts
|
||||
#define BODYPARTS_LAYER 29 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
|
||||
#define MARKING_LAYER 28 //Matrixed body markings because clashing with snouts?
|
||||
#define BODY_ADJ_LAYER 27 //certain mutantrace features (snout, body markings) that must appear above the body parts
|
||||
#define GENITALS_FRONT_LAYER 26 //Draws some genitalia above clothes and the TAUR body if need be.
|
||||
#define BODY_LAYER 25 //underwear, undershirts, socks, eyes, lips(makeup)
|
||||
#define BODY_ADJ_UPPER_LAYER 24
|
||||
#define FRONT_MUTATIONS_LAYER 23 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
|
||||
#define DAMAGE_LAYER 22 //damage indicators (cuts and burns)
|
||||
#define UNIFORM_LAYER 21
|
||||
#define ID_LAYER 20
|
||||
#define HANDS_PART_LAYER 19
|
||||
#define SHOES_LAYER 18
|
||||
#define GLOVES_LAYER 17
|
||||
#define EARS_LAYER 16
|
||||
#define SUIT_LAYER 15
|
||||
#define GENITALS_EXPOSED_LAYER 14
|
||||
#define GLASSES_LAYER 13
|
||||
#define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 11
|
||||
#define NECK_LAYER 10
|
||||
#define BACK_LAYER 9
|
||||
#define HAIR_LAYER 8 //TODO: make part of head layer?
|
||||
#define MUTATIONS_LAYER 33 //mutations. Tk headglows, cold resistance glow, etc
|
||||
#define GENITALS_BEHIND_LAYER 32 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
|
||||
#define BODY_BEHIND_LAYER 31 //certain mutantrace features (tail when looking south) that must appear behind the body parts
|
||||
#define BODYPARTS_LAYER 30 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
|
||||
#define MARKING_LAYER 29 //Matrixed body markings because clashing with snouts?
|
||||
#define BODY_ADJ_LAYER 28 //certain mutantrace features (snout, body markings) that must appear above the body parts
|
||||
#define GENITALS_FRONT_LAYER 27 //Draws some genitalia above clothes and the TAUR body if need be.
|
||||
#define BODY_LAYER 26 //underwear, undershirts, socks, eyes, lips(makeup)
|
||||
#define BODY_ADJ_UPPER_LAYER 25
|
||||
#define FRONT_MUTATIONS_LAYER 24 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
|
||||
#define DAMAGE_LAYER 23 //damage indicators (cuts and burns)
|
||||
#define UNIFORM_LAYER 22
|
||||
#define ID_LAYER 21
|
||||
#define HANDS_PART_LAYER 20
|
||||
#define SHOES_LAYER 19
|
||||
#define GLOVES_LAYER 18
|
||||
#define EARS_LAYER 17
|
||||
#define SUIT_LAYER 16
|
||||
#define GENITALS_EXPOSED_LAYER 15
|
||||
#define GLASSES_LAYER 14
|
||||
#define BELT_LAYER 13 //Possible make this an overlay of somethign required to wear a belt?
|
||||
#define SUIT_STORE_LAYER 12
|
||||
#define NECK_LAYER 11
|
||||
#define BACK_LAYER 10
|
||||
#define HAIR_LAYER 9 //TODO: make part of head layer?
|
||||
#define HORNS_LAYER 8
|
||||
#define FACEMASK_LAYER 7
|
||||
#define HEAD_LAYER 6
|
||||
#define HANDCUFF_LAYER 5
|
||||
@@ -59,7 +63,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
|
||||
#define HANDS_LAYER 3
|
||||
#define BODY_FRONT_LAYER 2
|
||||
#define FIRE_LAYER 1 //If you're on fire
|
||||
#define TOTAL_LAYERS 32 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
#define TOTAL_LAYERS 33 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
|
||||
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
|
||||
//Because I *KNOW* somebody will think layer+1 means "above"
|
||||
|
||||
@@ -126,6 +126,13 @@
|
||||
#define SCREWYHUD_DEAD 2
|
||||
#define SCREWYHUD_HEALTHY 3
|
||||
|
||||
//Threshold levels for beauty for humans
|
||||
#define BEAUTY_LEVEL_HORRID -66
|
||||
#define BEAUTY_LEVEL_BAD -33
|
||||
#define BEAUTY_LEVEL_DECENT 33
|
||||
#define BEAUTY_LEVEL_GOOD 66
|
||||
#define BEAUTY_LEVEL_GREAT 100
|
||||
|
||||
//Moods levels for humans
|
||||
#define MOOD_LEVEL_HAPPY4 15
|
||||
#define MOOD_LEVEL_HAPPY3 10
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
|
||||
#define PROFILE_ITEM_LEN 2
|
||||
#define PROFILE_ITEM_TIME 1
|
||||
#define PROFILE_ITEM_COUNT 2
|
||||
#define PROFILE_ITEM_COUNT 2
|
||||
|
||||
@@ -36,4 +36,5 @@ GLOBAL_LIST_INIT(default_weight_class_to_volume, list(
|
||||
#define STORAGE_VOLUME_BACKPACK (DEFAULT_VOLUME_NORMAL * 7)
|
||||
#define STORAGE_VOLUME_DUFFLEBAG (DEFAULT_VOLUME_NORMAL * 10)
|
||||
#define STORAGE_VOLUME_BAG_OF_HOLDING (DEFAULT_VOLUME_NORMAL * 20)
|
||||
|
||||
#define STORAGE_VOLUME_CHEMISTRY_BAG (DEFAULT_VOLUME_TINY * 50)
|
||||
#define STORAGE_VOLUME_PILL_BOTTLE (DEFAULT_VOLUME_TINY * 7)
|
||||
|
||||
@@ -117,6 +117,7 @@
|
||||
#define FIRE_PRIORITY_NPC 80
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_PROJECTILES 200
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_ATMOS_ADJACENCY 300
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
|
||||
+199
-109
@@ -1,253 +1,343 @@
|
||||
//tgstation-server DMAPI
|
||||
// tgstation-server DMAPI
|
||||
|
||||
#define TGS_DMAPI_VERSION "5.1.1"
|
||||
#define TGS_DMAPI_VERSION "5.2.1"
|
||||
|
||||
//All functions and datums outside this document are subject to change with any version and should not be relied on
|
||||
// All functions and datums outside this document are subject to change with any version and should not be relied on.
|
||||
|
||||
//CONFIGURATION
|
||||
// CONFIGURATION
|
||||
|
||||
//create this define if you want to do configuration outside of this file
|
||||
/// Create this define if you want to do TGS configuration outside of this file.
|
||||
#ifndef TGS_EXTERNAL_CONFIGURATION
|
||||
|
||||
//Comment this out once you've filled in the below
|
||||
// Comment this out once you've filled in the below.
|
||||
#error TGS API unconfigured
|
||||
|
||||
//Uncomment this if you wish to allow the game to interact with TGS 3
|
||||
//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()()
|
||||
// Uncomment this if you wish to allow the game to interact with TGS 3.
|
||||
// This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()()
|
||||
//#define TGS_V3_API
|
||||
|
||||
//Required interfaces (fill in with your codebase equivalent):
|
||||
// Required interfaces (fill in with your codebase equivalent):
|
||||
|
||||
//create a global variable named `Name` and set it to `Value`
|
||||
/// Create a global variable named `Name` and set it to `Value`.
|
||||
#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value)
|
||||
|
||||
//Read the value in the global variable `Name`
|
||||
/// Read the value in the global variable `Name`.
|
||||
#define TGS_READ_GLOBAL(Name)
|
||||
|
||||
//Set the value in the global variable `Name` to `Value`
|
||||
/// Set the value in the global variable `Name` to `Value`.
|
||||
#define TGS_WRITE_GLOBAL(Name, Value)
|
||||
|
||||
//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities
|
||||
/// Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game use of DD -> TGS capabilities.
|
||||
#define TGS_PROTECT_DATUM(Path)
|
||||
|
||||
//Display an announcement `message` from the server to all players
|
||||
/// Display an announcement `message` from the server to all players.
|
||||
#define TGS_WORLD_ANNOUNCE(message)
|
||||
|
||||
//Notify current in-game administrators of a string `event`
|
||||
/// Notify current in-game administrators of a string `event`.
|
||||
#define TGS_NOTIFY_ADMINS(event)
|
||||
|
||||
//Write an info `message` to a server log
|
||||
/// Write an info `message` to a server log.
|
||||
#define TGS_INFO_LOG(message)
|
||||
|
||||
//Write an warning `message` to a server log
|
||||
/// Write an warning `message` to a server log.
|
||||
#define TGS_WARNING_LOG(message)
|
||||
|
||||
//Write an error `message` to a server log
|
||||
/// Write an error `message` to a server log.
|
||||
#define TGS_ERROR_LOG(message)
|
||||
|
||||
//Get the number of connected /clients
|
||||
/// Get the number of connected /clients.
|
||||
#define TGS_CLIENT_COUNT
|
||||
|
||||
#endif
|
||||
|
||||
//EVENT CODES
|
||||
// EVENT CODES
|
||||
|
||||
#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //Before a reboot mode change, extras parameters are the current and new reboot mode enums
|
||||
#define TGS_EVENT_PORT_SWAP -2 //Before a port change is about to happen, extra parameters is new port
|
||||
#define TGS_EVENT_INSTANCE_RENAMED -3 //Before the instance is renamed, extra parameter is the new name
|
||||
#define TGS_EVENT_WATCHDOG_REATTACH -4 //After the watchdog reattaches to DD, extra parameter is the new /datum/tgs_version of the server
|
||||
/// Before a reboot mode change, extras parameters are the current and new reboot mode enums
|
||||
#define TGS_EVENT_REBOOT_MODE_CHANGE -1
|
||||
/// Before a port change is about to happen, extra parameters is new port
|
||||
#define TGS_EVENT_PORT_SWAP -2
|
||||
/// Before the instance is renamed, extra parameter is the new name
|
||||
#define TGS_EVENT_INSTANCE_RENAMED -3
|
||||
/// After the watchdog reattaches to DD, extra parameter is the new [/datum/tgs_version] of the server
|
||||
#define TGS_EVENT_WATCHDOG_REATTACH -4
|
||||
|
||||
//See the descriptions for the parameters of these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs
|
||||
/// When the repository is reset to its origin reference. Parameters: Reference name, Commit SHA
|
||||
#define TGS_EVENT_REPO_RESET_ORIGIN 0
|
||||
/// When the repository performs a checkout. Parameters: Checkout git object
|
||||
#define TGS_EVENT_REPO_CHECKOUT 1
|
||||
/// When the repository performs a fetch operation. No parameters
|
||||
#define TGS_EVENT_REPO_FETCH 2
|
||||
/// When the repository merges a pull request. Parameters: PR Number, PR Sha, (Nullable) Comment made by TGS user
|
||||
#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3
|
||||
/// Before the repository makes a sychronize operation. Parameters: Absolute repostiory path
|
||||
#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4
|
||||
/// Before a BYOND install operation begins. Parameters: [/datum/tgs_version] of the installing BYOND
|
||||
#define TGS_EVENT_BYOND_INSTALL_START 5
|
||||
/// When a BYOND install operation fails. Parameters: Error message
|
||||
#define TGS_EVENT_BYOND_INSTALL_FAIL 6
|
||||
/// When the active BYOND version changes. Parameters: (Nullable) [/datum/tgs_version] of the current BYOND, [/datum/tgs_version] of the new BYOND
|
||||
#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7
|
||||
/// When the compiler starts running. Parameters: Game directory path, origin commit SHA
|
||||
#define TGS_EVENT_COMPILE_START 8
|
||||
/// When a compile is cancelled. No parameters
|
||||
#define TGS_EVENT_COMPILE_CANCELLED 9
|
||||
/// When a compile fails. Parameters: Game directory path, [TRUE]/[FALSE] based on if the cause for failure was DMAPI validation
|
||||
#define TGS_EVENT_COMPILE_FAILURE 10
|
||||
#define TGS_EVENT_COMPILE_COMPLETE 11 // Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the TGS_EVENT_DEPLOYMENT_COMPLETE instead
|
||||
/// When a compile operation completes. Note, this event fires before the new .dmb is loaded into the watchdog. Consider using the [TGS_EVENT_DEPLOYMENT_COMPLETE] instead. Parameters: Game directory path
|
||||
#define TGS_EVENT_COMPILE_COMPLETE 11
|
||||
/// When an automatic update for the current instance begins. No parameters
|
||||
#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12
|
||||
/// When the repository encounters a merge conflict: Parameters: Base SHA, target SHA, base reference, target reference
|
||||
#define TGS_EVENT_REPO_MERGE_CONFLICT 13
|
||||
/// When a deployment completes. No Parameters
|
||||
#define TGS_EVENT_DEPLOYMENT_COMPLETE 14
|
||||
/// Before the watchdog shuts down. Not sent for graceful shutdowns. No parameters.
|
||||
#define TGS_EVENT_WATCHDOG_SHUTDOWN 15
|
||||
/// Before the watchdog detaches for a TGS update/restart. No parameters.
|
||||
#define TGS_EVENT_WATCHDOG_DETACH 16
|
||||
|
||||
//OTHER ENUMS
|
||||
// OTHER ENUMS
|
||||
|
||||
/// The server will reboot normally.
|
||||
#define TGS_REBOOT_MODE_NORMAL 0
|
||||
/// The server will stop running on reboot.
|
||||
#define TGS_REBOOT_MODE_SHUTDOWN 1
|
||||
/// The watchdog will restart on reboot.
|
||||
#define TGS_REBOOT_MODE_RESTART 2
|
||||
|
||||
/// DreamDaemon Trusted security level.
|
||||
#define TGS_SECURITY_TRUSTED 0
|
||||
/// DreamDaemon Safe security level.
|
||||
#define TGS_SECURITY_SAFE 1
|
||||
/// DreamDaemon Ultrasafe security level.
|
||||
#define TGS_SECURITY_ULTRASAFE 2
|
||||
|
||||
//REQUIRED HOOKS
|
||||
|
||||
//Call this somewhere in /world/New() that is always run
|
||||
//IMPORTANT: This function may sleep!
|
||||
//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels
|
||||
//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated
|
||||
/**
|
||||
* Call this somewhere in [/world/proc/New] that is always run. This function may sleep!
|
||||
*
|
||||
* * event_handler - Optional user defined [/datum/tgs_event_handler].
|
||||
* * minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated. Can be one of [TGS_SECURITY_ULTRASAFE], [TGS_SECURITY_SAFE], or [TGS_SECURITY_TRUSTED].
|
||||
*/
|
||||
/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
|
||||
return
|
||||
|
||||
//Call this when your initializations are complete and your game is ready to play before any player interactions happen
|
||||
//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running
|
||||
//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this
|
||||
//This function should not be called before ..() in /world/New()
|
||||
/**
|
||||
* Call this when your initializations are complete and your game is ready to play before any player interactions happen.
|
||||
*
|
||||
* This may use [/world/var/sleep_offline] to make this happen so ensure no changes are made to it while this call is running.
|
||||
* Before this point, note that any static files or directories may be in use by another server. Your code should account for this.
|
||||
* This function should not be called before ..() in [/world/proc/New].
|
||||
*/
|
||||
/world/proc/TgsInitializationComplete()
|
||||
return
|
||||
|
||||
//Put this at the start of /world/Topic()
|
||||
/// Put this at the start of [/world/proc/Topic].
|
||||
#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return
|
||||
|
||||
//Call this at the beginning of world/Reboot(reason)
|
||||
/**
|
||||
* Call this at the beginning of [world/proc/Reboot].
|
||||
*/
|
||||
/world/proc/TgsReboot()
|
||||
return
|
||||
|
||||
//DATUM DEFINITIONS
|
||||
//unless otherwise specified all datums defined here should be considered read-only, warranty void if written
|
||||
// DATUM DEFINITIONS
|
||||
// All datums defined here should be considered read-only
|
||||
|
||||
//represents git revision information about the current world build
|
||||
/// Represents git revision information.
|
||||
/datum/tgs_revision_information
|
||||
var/commit //full sha of compiled commit
|
||||
var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch
|
||||
/// Full SHA of the commit.
|
||||
var/commit
|
||||
/// Full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch.
|
||||
var/origin_commit
|
||||
|
||||
//represents a version of tgstation-server
|
||||
/// Represents a version.
|
||||
/datum/tgs_version
|
||||
var/suite //The suite/major version, can be >=3
|
||||
/// The suite/major version number
|
||||
var/suite
|
||||
|
||||
//this group of variables can be null to represent a wild card
|
||||
var/minor //The minor version
|
||||
var/patch //The patch version
|
||||
var/deprecated_patch //The legacy version
|
||||
// This group of variables can be null to represent a wild card
|
||||
/// The minor version number. null for wildcards
|
||||
var/minor
|
||||
/// The patch version number. null for wildcards
|
||||
var/patch
|
||||
|
||||
var/raw_parameter //The unparsed parameter
|
||||
var/deprefixed_parameter //The version only bit of raw_parameter
|
||||
/// Legacy version number. Generally null
|
||||
var/deprecated_patch
|
||||
|
||||
//if the tgs_version is a wildcard version
|
||||
/// Unparsed string value
|
||||
var/raw_parameter
|
||||
/// String value minus prefix
|
||||
var/deprefixed_parameter
|
||||
|
||||
/**
|
||||
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] contains wildcards.
|
||||
*/
|
||||
/datum/tgs_version/proc/Wildcard()
|
||||
return
|
||||
|
||||
//if the tgs_version equals some other_version
|
||||
/**
|
||||
* Returns [TRUE]/[FALSE] based on if the [/datum/tgs_version] equals some other version.
|
||||
*
|
||||
* other_version - The [/datum/tgs_version] to compare against.
|
||||
*/
|
||||
/datum/tgs_version/proc/Equals(datum/tgs_version/other_version)
|
||||
return
|
||||
|
||||
//represents a merge of a GitHub pull request
|
||||
/// Represents a merge of a GitHub pull request.
|
||||
/datum/tgs_revision_information/test_merge
|
||||
var/number //pull request number
|
||||
var/title //pull request title
|
||||
var/body //pull request body
|
||||
var/author //pull request github author
|
||||
var/url //link to pull request html
|
||||
var/pull_request_commit //commit of the pull request when it was merged
|
||||
var/time_merged //timestamp of when the merge commit for the pull request was created
|
||||
var/comment //optional comment left by the one who initiated the test merge
|
||||
/// The pull request number.
|
||||
var/number
|
||||
/// The pull request title when it was merged.
|
||||
var/title
|
||||
/// The pull request body when it was merged.
|
||||
var/body
|
||||
/// The GitHub username of the pull request's author.
|
||||
var/author
|
||||
/// An http URL to the pull request.
|
||||
var/url
|
||||
/// The SHA of the pull request when that was merged.
|
||||
var/pull_request_commit
|
||||
/// ISO 8601 timestamp of when the pull request was merged.
|
||||
var/time_merged
|
||||
/// (Nullable) Comment left by the TGS user who initiated the merge..
|
||||
var/comment
|
||||
|
||||
//represents a connected chat channel
|
||||
/// Represents a connected chat channel.
|
||||
/datum/tgs_chat_channel
|
||||
var/id //internal channel representation
|
||||
var/friendly_name //user friendly channel name
|
||||
var/connection_name //the name of the configured chat connection
|
||||
var/is_admin_channel //if the server operator has marked this channel for game admins only
|
||||
var/is_private_channel //if this is a private chat channel
|
||||
var/custom_tag //user defined string associated with channel
|
||||
/// TGS internal channel ID.
|
||||
var/id
|
||||
/// User friendly name of the channel.
|
||||
var/friendly_name
|
||||
/// Name of the chat connection. This is the IRC server address or the Discord guild.
|
||||
var/connection_name
|
||||
/// [TRUE]/[FALSE] based on if the server operator has marked this channel for game admins only.
|
||||
var/is_admin_channel
|
||||
/// [TRUE]/[FALSE] if the channel is a private message channel for a [/datum/tgs_chat_user].
|
||||
var/is_private_channel
|
||||
/// Tag string associated with the channel in TGS
|
||||
var/custom_tag
|
||||
|
||||
//represents a chat user
|
||||
// Represents a chat user
|
||||
/datum/tgs_chat_user
|
||||
var/id //Internal user representation, requires channel to be unique
|
||||
var/friendly_name //The user's public name
|
||||
var/mention //The text to use to ping this user in a message
|
||||
var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from
|
||||
/// TGS internal user ID.
|
||||
var/id
|
||||
// The user's display name.
|
||||
var/friendly_name
|
||||
// The string to use to ping this user in a message.
|
||||
var/mention
|
||||
/// The [/datum/tgs_chat_channel] the user was from
|
||||
var/datum/tgs_chat_channel/channel
|
||||
|
||||
//user definable callback for handling events
|
||||
//extra parameters may be specified depending on the event
|
||||
/**
|
||||
* User definable callback for handling TGS events.
|
||||
*
|
||||
* event_code - One of the TGS_EVENT_ defines. Extra parameters will be documented in each
|
||||
*/
|
||||
/datum/tgs_event_handler/proc/HandleEvent(event_code, ...)
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
//user definable chat command
|
||||
/// User definable chat command
|
||||
/datum/tgs_chat_command
|
||||
var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command
|
||||
var/help_text = "" //help text for this command
|
||||
var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins
|
||||
/// The string to trigger this command on a chat bot. e.g `@bot name ...` or `!tgs name ...`
|
||||
var/name = ""
|
||||
/// The help text displayed for this command
|
||||
var/help_text = ""
|
||||
/// If this command should be available to game administrators only
|
||||
var/admin_only = FALSE
|
||||
|
||||
//override to implement command
|
||||
//sender: The tgs_chat_user who send to command
|
||||
//params: The trimmed string following the command name
|
||||
//The return value will be stringified and sent to the appropriate chat
|
||||
/**
|
||||
* Process command activation. Should return a string to respond to the issuer with.
|
||||
*
|
||||
* sender - The [/datum/tgs_chat_user] who issued the command.
|
||||
* params - The trimmed string following the command `/datum/tgs_chat_command/var/name].
|
||||
*/
|
||||
/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params)
|
||||
CRASH("[type] has no implementation for Run()")
|
||||
|
||||
//FUNCTIONS
|
||||
// API FUNCTIONS
|
||||
|
||||
//Returns the respective supported /datum/tgs_version of the API
|
||||
/// Returns the maximum supported [/datum/tgs_version] of the DMAPI.
|
||||
/world/proc/TgsMaximumAPIVersion()
|
||||
return
|
||||
|
||||
/// Returns the minimum supported [/datum/tgs_version] of the DMAPI.
|
||||
/world/proc/TgsMinimumAPIVersion()
|
||||
return
|
||||
|
||||
//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise
|
||||
//No function below this succeeds if it returns FALSE or if TgsNew() has yet to be called
|
||||
/**
|
||||
* Returns [TRUE] if DreamDaemon was launched under TGS, the API matches, and was properly initialized. [FALSE] will be returned otherwise.
|
||||
*/
|
||||
/world/proc/TgsAvailable()
|
||||
return
|
||||
|
||||
//Forces a hard reboot of BYOND by ending the process
|
||||
//unlike del(world) clients will try to reconnect
|
||||
//If the service has not requested a shutdown, the next server will take over
|
||||
// No function below this succeeds if it TgsAvailable() returns FALSE or if TgsNew() has yet to be called.
|
||||
|
||||
/**
|
||||
* Forces a hard reboot of DreamDaemon by ending the process.
|
||||
*
|
||||
* Unlike del(world) clients will try to reconnect.
|
||||
* If TGS has not requested a [TGS_REBOOT_MODE_SHUTDOWN] DreamDaemon will be launched again
|
||||
*/
|
||||
/world/proc/TgsEndProcess()
|
||||
return
|
||||
|
||||
//Send a message to non-admin connected chats
|
||||
//message: The message to send
|
||||
//admin_only: If TRUE, message will instead be sent to only admin connected chats
|
||||
/world/proc/TgsTargetedChatBroadcast(message, admin_only)
|
||||
/**
|
||||
* Send a message to connected chats.
|
||||
*
|
||||
* message - The string to send.
|
||||
* admin_only: If [TRUE], message will be sent to admin connected chats. Vice-versa applies.
|
||||
*/
|
||||
/world/proc/TgsTargetedChatBroadcast(message, admin_only = FALSE)
|
||||
return
|
||||
|
||||
//Send a private message to a specific user
|
||||
//message: The message to send
|
||||
//user: The /datum/tgs_chat_user to send to
|
||||
/**
|
||||
* Send a private message to a specific user.
|
||||
*
|
||||
* message - The string to send.
|
||||
* user: The [/datum/tgs_chat_user] to PM.
|
||||
*/
|
||||
/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user)
|
||||
return
|
||||
|
||||
//The following functions will sleep if a call to TgsNew() is sleeping
|
||||
// The following functions will sleep if a call to TgsNew() is sleeping
|
||||
|
||||
//Sends a message to connected game chats
|
||||
//message: The message to send
|
||||
//channels: optional channels to limit the broadcast to
|
||||
/world/proc/TgsChatBroadcast(message, list/channels)
|
||||
/**
|
||||
* Send a message to connected chats that are flagged as game-related in TGS.
|
||||
*
|
||||
* message - The string to send.
|
||||
* channels - Optional list of [/datum/tgs_chat_channel]s to restrict the message to.
|
||||
*/
|
||||
/world/proc/TgsChatBroadcast(message, list/channels = null)
|
||||
return
|
||||
|
||||
//Gets the current /datum/tgs_version of the server tools running the server
|
||||
/// Returns the current [/datum/tgs_version] of TGS if it is running the server, null otherwise.
|
||||
/world/proc/TgsVersion()
|
||||
return
|
||||
|
||||
//Gets the current /datum/tgs_version of the DMAPI being used
|
||||
/// Returns the current [/datum/tgs_version] of the DMAPI being used if it was activated, null otherwise.
|
||||
/world/proc/TgsApiVersion()
|
||||
return
|
||||
|
||||
//Gets the name of the TGS instance running the game
|
||||
/// Returns the name of the TGS instance running the game if TGS is present, null otherwise.
|
||||
/world/proc/TgsInstanceName()
|
||||
return
|
||||
|
||||
//Get the current `/datum/tgs_revision_information`
|
||||
/// Return the current [/datum/tgs_revision_information] of the running server if TGS is present, null otherwise.
|
||||
/world/proc/TgsRevision()
|
||||
return
|
||||
|
||||
//Get the current BYOND security level
|
||||
/// Returns the current BYOND security level as a TGS_SECURITY_ define if TGS is present, null otherwise.
|
||||
/world/proc/TgsSecurityLevel()
|
||||
return
|
||||
|
||||
//Gets a list of active `/datum/tgs_revision_information/test_merge`s
|
||||
/// Returns a list of active [/datum/tgs_revision_information/test_merge]s if TGS is present, null otherwise.
|
||||
/world/proc/TgsTestMerges()
|
||||
return
|
||||
|
||||
//Gets a list of connected tgs_chat_channel
|
||||
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise.
|
||||
/world/proc/TgsChatChannelInfo()
|
||||
return
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
|
||||
#define TRAIT_QUICK_CARRY "quick-carry"
|
||||
#define TRAIT_QUICKER_CARRY "quicker-carry"
|
||||
#define TRAIT_QUICK_BUILD "quick-build"
|
||||
#define TRAIT_STRONG_GRABBER "strong_grabber"
|
||||
#define TRAIT_CALCIUM_HEALER "calcium_healer"
|
||||
#define TRAIT_MAGIC_CHOKE "magic_choke"
|
||||
@@ -147,6 +148,8 @@
|
||||
#define TRAIT_NORUNNING "norunning" // You walk!
|
||||
#define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites.
|
||||
#define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat.
|
||||
#define TRAIT_NOGUT "nogutting" //Your chest cant be gutted of organs
|
||||
#define TRAIT_NODECAP "nodecapping" //Your head cant be cut off in combat
|
||||
#define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events"
|
||||
#define TRAIT_NO_MIDROUND_ANTAG "no-midround-antag" //can't be turned into an antag by random events
|
||||
#define TRAIT_PUGILIST "pugilist" //This guy punches people for a living
|
||||
@@ -179,6 +182,7 @@
|
||||
#define TRAIT_PARA "paraplegic"
|
||||
#define TRAIT_EMPATH "empath"
|
||||
#define TRAIT_FRIENDLY "friendly"
|
||||
#define TRAIT_SNOB "snob"
|
||||
#define TRAIT_CULT_EYES "cult_eyes"
|
||||
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
|
||||
#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman.
|
||||
|
||||
@@ -154,6 +154,9 @@
|
||||
/proc/log_subsystem(subsystem, text)
|
||||
WRITE_LOG(GLOB.subsystem_log, "[subsystem]: [text]")
|
||||
|
||||
/proc/log_click(atom/object, atom/location, control, params, client/C, event = "clicked", unexpected)
|
||||
WRITE_LOG(GLOB.click_log, "[unexpected? "ERROR" :"CLICK"]: [C.ckey] - [event] : [istype(object)? "[object] ([COORD(object)])" : object] | [istype(location)? "[location] ([COORD(location)])" : location] | [control] | [params]")
|
||||
|
||||
/* Log to both DD and the logfile. */
|
||||
/proc/log_world(text)
|
||||
#ifdef USE_CUSTOM_ERROR_HANDLER
|
||||
@@ -183,7 +186,7 @@
|
||||
/proc/start_log(log)
|
||||
WRITE_LOG(log, "Starting up round ID [GLOB.round_id].\n-------------------------")
|
||||
|
||||
/* ui logging */
|
||||
/* ui logging */
|
||||
|
||||
/proc/log_tgui(text)
|
||||
WRITE_LOG(GLOB.tgui_log, text)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/proc/get_projectile_angle(atom/source, atom/target)
|
||||
var/sx = source.x * world.icon_size
|
||||
var/sy = source.y * world.icon_size
|
||||
var/tx = target.x * world.icon_size
|
||||
var/ty = target.y * world.icon_size
|
||||
var/atom/movable/AM
|
||||
if(ismovable(source))
|
||||
AM = source
|
||||
sx += AM.step_x
|
||||
sy += AM.step_y
|
||||
if(ismovable(target))
|
||||
AM = target
|
||||
tx += AM.step_x
|
||||
ty += AM.step_y
|
||||
return SIMPLIFY_DEGREES(arctan(ty - sy, tx - sx))
|
||||
|
||||
/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams.
|
||||
if(!start || !end)
|
||||
return 0
|
||||
var/dy
|
||||
var/dx
|
||||
dy=(32*end.y+end.pixel_y)-(32*start.y+start.pixel_y)
|
||||
dx=(32*end.x+end.pixel_x)-(32*start.x+start.pixel_x)
|
||||
if(!dy)
|
||||
return (dx>=0)?90:270
|
||||
.=arctan(dx/dy)
|
||||
if(dy<0)
|
||||
.+=180
|
||||
else if(dx<0)
|
||||
.+=360
|
||||
|
||||
/proc/Get_Pixel_Angle(var/y, var/x)//for getting the angle when animating something's pixel_x and pixel_y
|
||||
if(!y)
|
||||
return (x>=0)?90:270
|
||||
.=arctan(x/y)
|
||||
if(y<0)
|
||||
.+=180
|
||||
else if(x<0)
|
||||
.+=360
|
||||
@@ -15,30 +15,8 @@
|
||||
var/textb = copytext(HTMLstring, 6, 8)
|
||||
return rgb(255 - hex2num(textr), 255 - hex2num(textg), 255 - hex2num(textb))
|
||||
|
||||
/proc/Get_Angle(atom/movable/start,atom/movable/end)//For beams.
|
||||
if(!start || !end)
|
||||
return 0
|
||||
var/dy
|
||||
var/dx
|
||||
dy=(32*end.y+end.pixel_y)-(32*start.y+start.pixel_y)
|
||||
dx=(32*end.x+end.pixel_x)-(32*start.x+start.pixel_x)
|
||||
if(!dy)
|
||||
return (dx>=0)?90:270
|
||||
.=arctan(dx/dy)
|
||||
if(dy<0)
|
||||
.+=180
|
||||
else if(dx<0)
|
||||
.+=360
|
||||
|
||||
/proc/Get_Pixel_Angle(var/y, var/x)//for getting the angle when animating something's pixel_x and pixel_y
|
||||
if(!y)
|
||||
return (x>=0)?90:270
|
||||
.=arctan(x/y)
|
||||
if(y<0)
|
||||
.+=180
|
||||
else if(x<0)
|
||||
.+=360
|
||||
|
||||
//Better performant than an artisanal proc and more reliable than Turn(). From TGMC.
|
||||
#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) )
|
||||
//Returns location. Returns null if no location was found.
|
||||
/proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = FALSE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0)
|
||||
/*
|
||||
|
||||
@@ -242,15 +242,14 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"MOBILITY_RESIST" = MOBILITY_RESIST
|
||||
),
|
||||
"combat_flags" = list(
|
||||
"COMBAT_FLAG_COMBAT_TOGGLED" = COMBAT_FLAG_COMBAT_TOGGLED,
|
||||
"COMBAT_FLAG_SPRINT_TOGGLED" = COMBAT_FLAG_SPRINT_TOGGLED,
|
||||
"COMBAT_FLAG_COMBAT_ACTIVE" = COMBAT_FLAG_COMBAT_ACTIVE,
|
||||
"COMBAT_FLAG_SPRINT_ACTIVE" = COMBAT_FLAG_SPRINT_ACTIVE,
|
||||
"COMBAT_FLAG_ATTEMPTING_CRAWL" = COMBAT_FLAG_ATTEMPTING_CRAWL,
|
||||
"COMBAT_FLAG_HARD_STAMCRIT" = COMBAT_FLAG_HARD_STAMCRIT,
|
||||
"COMBAT_FLAG_SOFT_STAMCRIT" = COMBAT_FLAG_SOFT_STAMCRIT,
|
||||
"COMBAT_FLAG_INTENTIONALLY_RESTING" = COMBAT_FLAG_INTENTIONALLY_RESTING,
|
||||
"COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST
|
||||
"COMBAT_FLAG_RESISTING_REST" = COMBAT_FLAG_RESISTING_REST,
|
||||
"COMBAT_FLAG_SPRINT_FORCED" = COMBAT_FLAG_SPRINT_FORCED
|
||||
),
|
||||
"shield_flags" = list(
|
||||
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
|
||||
|
||||
@@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/effect/spawner/lootdrop/welder_tools = 3,
|
||||
/obj/effect/spawner/lootdrop/low_tools = 5,
|
||||
/obj/item/relic = 3,
|
||||
/obj/item/weaponcrafting/receiver = 2,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 2,
|
||||
/obj/item/clothing/head/cone = 2,
|
||||
/obj/item/grenade/smokebomb = 2,
|
||||
/obj/item/geiger_counter = 3,
|
||||
|
||||
@@ -36,6 +36,8 @@ GLOBAL_VAR(reagent_log)
|
||||
GLOBAL_PROTECT(reagent_log)
|
||||
GLOBAL_VAR(world_crafting_log)
|
||||
GLOBAL_PROTECT(world_crafting_log)
|
||||
GLOBAL_VAR(click_log)
|
||||
GLOBAL_PROTECT(click_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(bombers)
|
||||
GLOBAL_PROTECT(bombers)
|
||||
|
||||
@@ -24,16 +24,6 @@
|
||||
return
|
||||
|
||||
|
||||
/client
|
||||
var/list/atom/selected_target[2]
|
||||
var/obj/item/active_mousedown_item = null
|
||||
var/mouseParams = ""
|
||||
var/mouseLocation = null
|
||||
var/mouseObject = null
|
||||
var/mouseControlObject = null
|
||||
var/middragtime = 0
|
||||
var/atom/middragatom
|
||||
|
||||
/client/MouseDown(object, location, control, params)
|
||||
if (mouse_down_icon)
|
||||
mouse_pointer_icon = mouse_down_icon
|
||||
@@ -84,12 +74,6 @@
|
||||
/obj/item/proc/onMouseUp(object, location, params, mob)
|
||||
return
|
||||
|
||||
/obj/item
|
||||
var/canMouseDown = FALSE
|
||||
|
||||
/obj/item/gun
|
||||
var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds
|
||||
|
||||
/obj/item/gun/CanItemAutoclick(object, location, params)
|
||||
. = automatic
|
||||
|
||||
@@ -108,16 +92,10 @@
|
||||
mouseLocation = location
|
||||
mouseObject = object
|
||||
mouseControlObject = control
|
||||
if(mob && LAZYLEN(mob.mousemove_intercept_objects))
|
||||
for(var/datum/D in mob.mousemove_intercept_objects)
|
||||
D.onMouseMove(object, location, control, params)
|
||||
if(!show_popup_menus && mob) //CIT CHANGE - passes onmousemove() to mobs
|
||||
mob.onMouseMove(object, location, control, params) //CIT CHANGE - ditto
|
||||
if(mob)
|
||||
SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOUSEMOVE, object, location, control, params)
|
||||
..()
|
||||
|
||||
/datum/proc/onMouseMove(object, location, control, params)
|
||||
return
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
var/list/L = params2list(params)
|
||||
if (L["middle"])
|
||||
|
||||
@@ -642,9 +642,6 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
mymob.client.screen |= alert
|
||||
return 1
|
||||
|
||||
/mob
|
||||
var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
|
||||
|
||||
/obj/screen/alert/Click(location, control, params)
|
||||
if(!usr || !usr.client)
|
||||
return
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
|
||||
/mob
|
||||
var/list/screens = list()
|
||||
|
||||
/mob/proc/overlay_fullscreen(category, type, severity)
|
||||
var/obj/screen/fullscreen/screen = screens[category]
|
||||
if (!screen || screen.type != type)
|
||||
|
||||
@@ -114,8 +114,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
|
||||
return ..()
|
||||
|
||||
/mob
|
||||
var/hud_type = /datum/hud
|
||||
|
||||
/mob/proc/create_mob_hud()
|
||||
if(!client || hud_used)
|
||||
|
||||
@@ -241,18 +241,11 @@
|
||||
using.hud = src
|
||||
hotkeybuttons += using
|
||||
|
||||
//CIT CHANGES - rest and combat mode buttons
|
||||
using = new /obj/screen/restbutton()
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using = new /obj/screen/rest()
|
||||
using.icon = ui_style
|
||||
using.screen_loc = ui_pull_resist
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/combattoggle()
|
||||
using.icon = tg_ui_icon_to_cit_ui(ui_style)
|
||||
using.screen_loc = ui_combat_toggle
|
||||
using.hud = src
|
||||
static_inventory += using
|
||||
//END OF CIT CHANGES
|
||||
|
||||
using = new /obj/screen/human/toggle()
|
||||
|
||||
@@ -1,16 +1,4 @@
|
||||
|
||||
/client
|
||||
var/list/parallax_layers
|
||||
var/list/parallax_layers_cached
|
||||
var/atom/movable/movingmob
|
||||
var/turf/previous_turf
|
||||
var/dont_animate_parallax //world.time of when we can state animate()ing parallax again
|
||||
var/last_parallax_shift //world.time of last update
|
||||
var/parallax_throttle = 0 //ds between updates
|
||||
var/parallax_movedir = 0
|
||||
var/parallax_layers_max = 3
|
||||
var/parallax_animate_timer
|
||||
|
||||
/datum/hud/proc/create_parallax(mob/viewmob)
|
||||
var/mob/screenmob = viewmob || mymob
|
||||
var/client/C = screenmob.client
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/screen/storage/volumetric_box/Destroy()
|
||||
makeItemInactive()
|
||||
our_item = null
|
||||
return ..()
|
||||
|
||||
@@ -87,10 +88,14 @@
|
||||
makeItemInactive()
|
||||
|
||||
/obj/screen/storage/volumetric_box/proc/makeItemInactive()
|
||||
if(!our_item)
|
||||
return
|
||||
our_item.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
|
||||
our_item.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
|
||||
|
||||
/obj/screen/storage/volumetric_box/proc/makeItemActive()
|
||||
if(!our_item)
|
||||
return
|
||||
our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others!
|
||||
our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
/obj/attacked_by(obj/item/I, mob/living/user)
|
||||
var/totitemdamage = I.force
|
||||
var/bad_trait
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && iscarbon(user))
|
||||
if(!SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
bad_trait = SKILL_COMBAT_MODE //blacklist combat skills.
|
||||
if(I.used_skills && user.mind)
|
||||
@@ -155,9 +155,11 @@
|
||||
/mob/living/proc/pre_attacked_by(obj/item/I, mob/living/user)
|
||||
. = I.force
|
||||
var/bad_trait
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) && iscarbon(user))
|
||||
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
. *= 0.5
|
||||
bad_trait = SKILL_COMBAT_MODE //blacklist combat skills.
|
||||
if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
. *= 1.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
. *= 0.5
|
||||
if(!user.mind || !I.used_skills)
|
||||
@@ -169,10 +171,6 @@
|
||||
continue
|
||||
user.mind.auto_gain_experience(skill, I.skill_gain)
|
||||
|
||||
/mob/living/carbon/pre_attacked_by(obj/item/I, mob/living/user)
|
||||
. = ..()
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
. *= 1.5
|
||||
|
||||
// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person.
|
||||
// Click parameters is the params string from byond Click() code, see that documentation.
|
||||
@@ -212,7 +210,7 @@
|
||||
if(!user)
|
||||
return
|
||||
var/bad_trait
|
||||
if(iscarbon(user) && !(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
. *= STAM_COST_NO_COMBAT_MULT
|
||||
bad_trait = SKILL_COMBAT_MODE
|
||||
if(used_skills && user.mind)
|
||||
|
||||
@@ -451,3 +451,18 @@ SUBSYSTEM_DEF(garbage)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TESTING
|
||||
/proc/writeDatumCount()
|
||||
var/list/datums = list()
|
||||
for(var/datum/D in world)
|
||||
datums[D.type] += 1
|
||||
for(var/datum/D)
|
||||
datums[D.type] += 1
|
||||
datums = sortTim(datums, /proc/cmp_numeric_dsc, associative = TRUE)
|
||||
if(fexists("data/DATUMCOUNT.txt"))
|
||||
fdel("data/DATUMCOUNT.txt")
|
||||
var/outfile = file("data/DATUMCOUNT.txt")
|
||||
for(var/path in datums)
|
||||
outfile << "[datums[path]]\t\t\t\t\t[path]"
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,7 @@ SUBSYSTEM_DEF(input)
|
||||
// LET'S PLAY THE BIND EVERY KEY GAME!
|
||||
// oh except for Backspace and Enter; if you want to use those you shouldn't have used oldmode!
|
||||
var/list/classic_ctrl_override_keys = list(
|
||||
"\[", "\]", "\\", ";", "'", ",", ".", "/", "-", "\\=", "`"
|
||||
"\[", "\]", "\\\\", ";", "'", ",", ".", "/", "-", "=", "`"
|
||||
)
|
||||
// i'm lazy let's play the list iteration game of numbers
|
||||
for(var/i in 0 to 9)
|
||||
@@ -58,8 +58,9 @@ SUBSYSTEM_DEF(input)
|
||||
macroset_classic_input["Ctrl+L"] = "looc"
|
||||
// let's play the list iteration game x2
|
||||
for(var/key in classic_ctrl_override_keys)
|
||||
macroset_classic_input["Ctrl+[key]"] = "\"KeyDown [key]\""
|
||||
macroset_classic_input["Ctrl+[key]+UP"] = "\"KeyUp [key]\""
|
||||
// make sure to double double quote to ensure things are treated as a key combo instead of addition/semicolon logic.
|
||||
macroset_classic_input["\"Ctrl+[key]\""] = "\"KeyDown [istext(classic_ctrl_override_keys[key])? classic_ctrl_override_keys[key] : key]\""
|
||||
macroset_classic_input["\"Ctrl+[key]+UP\""] = "\"KeyUp [istext(classic_ctrl_override_keys[key])? classic_ctrl_override_keys[key] : key]\""
|
||||
// Misc
|
||||
macroset_classic_input["Tab"] = "\".winset \\\"mainwindow.macro=[SKIN_MACROSET_CLASSIC_HOTKEYS] map.focus=true input.background-color=[COLOR_INPUT_DISABLED]\\\"\""
|
||||
macroset_classic_input["Escape"] = "\".winset \\\"input.text=\\\"\\\"\\\"\""
|
||||
|
||||
@@ -11,7 +11,11 @@ SUBSYSTEM_DEF(materials)
|
||||
///Dictionary of category || list of material refs
|
||||
var/list/materials_by_category
|
||||
///List of stackcrafting recipes for materials using rigid materials
|
||||
var/list/rigid_stack_recipes = list(new/datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE))
|
||||
var/list/rigid_stack_recipes = list(
|
||||
new /datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("toilet", /obj/structure/toilet/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("sink", /obj/structure/sink/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
)
|
||||
|
||||
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
|
||||
/datum/controller/subsystem/materials/proc/InitializeMaterials()
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(projectiles)
|
||||
name = "Projectiles"
|
||||
priority = FIRE_PRIORITY_PROJECTILES
|
||||
wait = 1
|
||||
stat_tag = "PP"
|
||||
flags = SS_NO_INIT|SS_TICKER
|
||||
var/global_pixel_speed = 2
|
||||
var/global_iterations_per_move = 16
|
||||
var/global_pixel_increment_amount = 4
|
||||
var/global_projectile_speed_multiplier = 1
|
||||
|
||||
/datum/controller/subsystem/processing/projectiles/proc/set_pixel_speed(new_speed)
|
||||
global_pixel_speed = new_speed
|
||||
global_pixel_increment_amount = new_speed
|
||||
for(var/i in processing)
|
||||
var/obj/item/projectile/P = i
|
||||
if(istype(P)) //there's non projectiles on this too.
|
||||
P.set_pixel_speed(new_speed)
|
||||
P.set_pixel_increment_amount(new_speed)
|
||||
|
||||
/datum/controller/subsystem/processing/projectiles/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if(NAMEOF(src, global_pixel_speed))
|
||||
if(NAMEOF(src, global_pixel_increment_amount))
|
||||
set_pixel_speed(var_value)
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -24,6 +24,7 @@ SUBSYSTEM_DEF(research)
|
||||
var/list/techweb_categories = list() //category name = list(node.id = TRUE)
|
||||
var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount))
|
||||
var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default.
|
||||
var/list/techweb_nodes_experimental = list() //Node ids that are exclusive to the BEPIS.
|
||||
|
||||
var/list/techweb_point_items = list( //path = list(point type = value)
|
||||
/obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000),
|
||||
@@ -508,6 +509,8 @@ SUBSYSTEM_DEF(research)
|
||||
D.unlocked_by += node.id
|
||||
if(node.hidden)
|
||||
techweb_nodes_hidden[node.id] = TRUE
|
||||
if(node.experimental)
|
||||
techweb_nodes_experimental[node.id] = TRUE
|
||||
CHECK_TICK
|
||||
generate_techweb_unlock_linking()
|
||||
|
||||
|
||||
@@ -731,14 +731,6 @@
|
||||
if(next_use_time > world.time)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
|
||||
//Stickmemes
|
||||
/datum/action/item_action/stickmen
|
||||
name = "Summon Stick Minions"
|
||||
desc = "Allows you to summon faithful stickmen allies to aide you in battle."
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "art_summon"
|
||||
|
||||
//surf_ss13
|
||||
/datum/action/item_action/bhop
|
||||
name = "Activate Jump Boots"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
if(prob(2))
|
||||
switch(rand(1,2))
|
||||
if(1)
|
||||
to_chat(owner, "<i>...[lowertext(hypnotic_phrase)]...</i>")
|
||||
to_chat(owner, "<span class='hypnophrase'><i>...[lowertext(hypnotic_phrase)]...</i></span>")
|
||||
if(2)
|
||||
new /datum/hallucination/chat(owner, TRUE, FALSE, "<span class='hypnophrase'>[hypnotic_phrase]</span>")
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//Magical traumas, caused by spells and curses.
|
||||
//Blurs the line between the victim's imagination and reality
|
||||
//Unlike regular traumas this can affect the victim's body and surroundings
|
||||
|
||||
/datum/brain_trauma/magic
|
||||
resilience = TRAUMA_RESILIENCE_LOBOTOMY
|
||||
|
||||
/datum/brain_trauma/magic/stalker
|
||||
name = "Stalking Phantom"
|
||||
desc = "Patient is stalked by a phantom only they can see."
|
||||
scan_desc = "extra-sensory paranoia"
|
||||
gain_text = "<span class='warning'>You feel like something wants to kill you...</span>"
|
||||
lose_text = "<span class='notice'>You no longer feel eyes on your back.</span>"
|
||||
var/obj/effect/hallucination/simple/stalker_phantom/stalker
|
||||
var/close_stalker = FALSE //For heartbeat
|
||||
|
||||
/datum/brain_trauma/magic/stalker/on_gain()
|
||||
create_stalker()
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/magic/stalker/proc/create_stalker()
|
||||
var/turf/stalker_source = locate(owner.x + pick(-12, 12), owner.y + pick(-12, 12), owner.z) //random corner
|
||||
stalker = new(stalker_source, owner)
|
||||
|
||||
/datum/brain_trauma/magic/stalker/on_lose()
|
||||
QDEL_NULL(stalker)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/magic/stalker/on_life()
|
||||
// Dead and unconscious people are not interesting to the psychic stalker.
|
||||
if(owner.stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
// Not even nullspace will keep it at bay.
|
||||
if(!stalker || !stalker.loc || stalker.z != owner.z)
|
||||
qdel(stalker)
|
||||
create_stalker()
|
||||
|
||||
if(get_dist(owner, stalker) <= 1)
|
||||
playsound(owner, 'sound/magic/demon_attack1.ogg', 50)
|
||||
owner.visible_message("<span class='warning'>[owner] is torn apart by invisible claws!</span>", "<span class='userdanger'>Ghostly claws tear your body apart!</span>")
|
||||
owner.take_bodypart_damage(rand(20, 45))
|
||||
else if(prob(50))
|
||||
stalker.forceMove(get_step_towards(stalker, owner))
|
||||
if(get_dist(owner, stalker) <= 8)
|
||||
if(!close_stalker)
|
||||
var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE)
|
||||
owner.playsound_local(owner, slowbeat, 40, 0, channel = CHANNEL_HEARTBEAT)
|
||||
close_stalker = TRUE
|
||||
else
|
||||
if(close_stalker)
|
||||
owner.stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
close_stalker = FALSE
|
||||
..()
|
||||
|
||||
/obj/effect/hallucination/simple/stalker_phantom
|
||||
name = "???"
|
||||
desc = "It's coming closer..."
|
||||
image_icon = 'icons/mob/lavaland/lavaland_monsters.dmi'
|
||||
image_state = "curseblob"
|
||||
@@ -265,3 +265,37 @@
|
||||
..()
|
||||
if(prob(1) && !owner.has_status_effect(/datum/status_effect/trance))
|
||||
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger
|
||||
name = "Hypnotic Trigger"
|
||||
desc = "Patient has a trigger phrase set in their subconscious that will trigger a suggestible trance-like state."
|
||||
scan_desc = "oneiric feedback loop"
|
||||
gain_text = "<span class='warning'>You feel odd, like you just forgot something important.</span>"
|
||||
lose_text = "<span class='notice'>You feel like a weight was lifted from your mind.</span>"
|
||||
random_gain = FALSE
|
||||
var/trigger_phrase = "Nanotrasen"
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/New(phrase)
|
||||
..()
|
||||
if(phrase)
|
||||
trigger_phrase = phrase
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/on_lose() //hypnosis must be cleared separately, but brain surgery should get rid of both anyway
|
||||
..()
|
||||
owner.remove_status_effect(/datum/status_effect/trance)
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/handle_hearing(datum/source, list/hearing_args)
|
||||
if(!owner.can_hear())
|
||||
return
|
||||
if(owner == hearing_args[HEARING_SPEAKER])
|
||||
return
|
||||
|
||||
var/regex/reg = new("(\\b[REGEX_QUOTE(trigger_phrase)]\\b)","ig")
|
||||
|
||||
if(findtext(hearing_args[HEARING_RAW_MESSAGE], reg))
|
||||
addtimer(CALLBACK(src, .proc/hypnotrigger), 10) //to react AFTER the chat message
|
||||
hearing_args[HEARING_RAW_MESSAGE] = reg.Replace(hearing_args[HEARING_RAW_MESSAGE], "<span class='hypnophrase'>*********</span>")
|
||||
|
||||
/datum/brain_trauma/severe/hypnotic_trigger/proc/hypnotrigger()
|
||||
to_chat(owner, "<span class='warning'>The words trigger something deep within you, and you feel your consciousness slipping away...</span>")
|
||||
owner.apply_status_effect(/datum/status_effect/trance, rand(100,300), FALSE)
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
|
||||
#define BAD_ART 12.5
|
||||
#define GOOD_ART 25
|
||||
#define GREAT_ART 50
|
||||
|
||||
/datum/component/art
|
||||
var/impressiveness = 0
|
||||
|
||||
/datum/component/art/Initialize(impress)
|
||||
impressiveness = impress
|
||||
if(isobj(parent))
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine)
|
||||
else
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_other_examine)
|
||||
if(isstructure(parent))
|
||||
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
|
||||
if(isitem(parent))
|
||||
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet)
|
||||
|
||||
/datum/component/art/proc/apply_moodlet(mob/M, impress)
|
||||
M.visible_message("<span class='notice'>[M] stops and looks intently at [parent].</span>", \
|
||||
"<span class='notice'>You stop to take in [parent].</span>")
|
||||
switch(impress)
|
||||
if (0 to BAD_ART)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
|
||||
if (BAD_ART to GOOD_ART)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok)
|
||||
if (GOOD_ART to GREAT_ART)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood)
|
||||
if(GREAT_ART to INFINITY)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
|
||||
|
||||
|
||||
/datum/component/art/proc/on_other_examine(datum/source, mob/M)
|
||||
apply_moodlet(M, impressiveness)
|
||||
|
||||
/datum/component/art/proc/on_obj_examine(datum/source, mob/M)
|
||||
var/obj/O = parent
|
||||
apply_moodlet(M, impressiveness *(O.obj_integrity/O.max_integrity))
|
||||
|
||||
/datum/component/art/proc/on_attack_hand(datum/source, mob/M)
|
||||
to_chat(M, "<span class='notice'>You start examining [parent]...</span>")
|
||||
if(!do_after(M, 20, target = parent))
|
||||
return
|
||||
on_obj_examine(source, M)
|
||||
|
||||
/datum/component/art/rev
|
||||
|
||||
/datum/component/art/rev/apply_moodlet(mob/M, impress)
|
||||
M.visible_message("<span class='notice'>[M] stops to inspect [parent].</span>", \
|
||||
"<span class='notice'>You take in [parent], inspecting the fine craftsmanship of the proletariat.</span>")
|
||||
|
||||
if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev))
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
|
||||
else
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
|
||||
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Combat mode component. It makes the user face whichever atom the mouse pointer is hovering,
|
||||
* amongst other things designed outside of this file, namely PvP and PvE stuff, hence the name.
|
||||
* Can be toggled on and off by clicking the screen hud object or by pressing the assigned hotkey (default 'C')
|
||||
*/
|
||||
/datum/component/combat_mode
|
||||
var/mode_flags = COMBAT_MODE_INACTIVE
|
||||
var/combatmessagecooldown
|
||||
var/lastmousedir
|
||||
var/obj/screen/combattoggle/hud_icon
|
||||
var/hud_loc
|
||||
|
||||
/datum/component/combat_mode/Initialize(hud_loc = ui_combat_toggle)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/mob/living/L = parent
|
||||
|
||||
src.hud_loc = hud_loc
|
||||
|
||||
RegisterSignal(L, SIGNAL_TRAIT(TRAIT_COMBAT_MODE_LOCKED), .proc/update_combat_lock)
|
||||
RegisterSignal(L, COMSIG_TOGGLE_COMBAT_MODE, .proc/user_toggle_intentional_combat_mode)
|
||||
RegisterSignal(L, COMSIG_DISABLE_COMBAT_MODE, .proc/safe_disable_combat_mode)
|
||||
RegisterSignal(L, COMSIG_ENABLE_COMBAT_MODE, .proc/safe_enable_combat_mode)
|
||||
RegisterSignal(L, COMSIG_MOB_DEATH, .proc/on_death)
|
||||
RegisterSignal(L, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_logout)
|
||||
RegisterSignal(L, COMSIG_MOB_HUD_CREATED, .proc/on_mob_hud_created)
|
||||
RegisterSignal(L, COMSIG_COMBAT_MODE_CHECK, .proc/check_flags)
|
||||
|
||||
update_combat_lock()
|
||||
|
||||
if(L.client)
|
||||
on_mob_hud_created(L)
|
||||
|
||||
/datum/component/combat_mode/Destroy()
|
||||
if(parent)
|
||||
safe_disable_combat_mode(parent)
|
||||
if(hud_icon)
|
||||
QDEL_NULL(hud_icon)
|
||||
return ..()
|
||||
|
||||
/// Creates the hud screen object.
|
||||
/datum/component/combat_mode/proc/on_mob_hud_created(mob/source)
|
||||
hud_icon = new
|
||||
hud_icon.hud = source.hud_used
|
||||
hud_icon.icon = tg_ui_icon_to_cit_ui(source.hud_used.ui_style)
|
||||
hud_icon.screen_loc = hud_loc
|
||||
source.hud_used.static_inventory += hud_icon
|
||||
hud_icon.update_icon()
|
||||
|
||||
/// Combat mode can be locked out, forcibly disabled by a status trait.
|
||||
/datum/component/combat_mode/proc/update_combat_lock()
|
||||
var/locked = HAS_TRAIT(parent, TRAIT_COMBAT_MODE_LOCKED)
|
||||
var/desired = (mode_flags & COMBAT_MODE_TOGGLED)
|
||||
var/actual = (mode_flags & COMBAT_MODE_ACTIVE)
|
||||
if(actual)
|
||||
if(locked)
|
||||
disable_combat_mode(parent, FALSE, TRUE)
|
||||
else if(!desired)
|
||||
disable_combat_mode(parent, TRUE, TRUE)
|
||||
else
|
||||
if(desired && !locked)
|
||||
enable_combat_mode(parent, FALSE, TRUE)
|
||||
|
||||
/// Enables combat mode. Please use 'safe_enable_combat_mode' instead, if you wish to also enable the toggle flag.
|
||||
/datum/component/combat_mode/proc/enable_combat_mode(mob/living/source, silent = TRUE, forced = TRUE, visible = FALSE, locked = FALSE, playsound = FALSE)
|
||||
if(locked)
|
||||
if(hud_icon)
|
||||
hud_icon.combat_on = TRUE
|
||||
hud_icon.update_icon()
|
||||
return
|
||||
if(mode_flags & COMBAT_MODE_ACTIVE)
|
||||
return
|
||||
mode_flags |= COMBAT_MODE_ACTIVE
|
||||
mode_flags &= ~COMBAT_MODE_INACTIVE
|
||||
SEND_SIGNAL(source, COMSIG_LIVING_COMBAT_ENABLED, forced)
|
||||
if(!silent)
|
||||
var/self_message = forced? "<span class='warning'>Your muscles reflexively tighten!</span>" : "<span class='warning'>You drop into a combative stance!</span>"
|
||||
if(visible && (forced || world.time >= combatmessagecooldown))
|
||||
combatmessagecooldown = world.time + 10 SECONDS
|
||||
if(!forced)
|
||||
if(source.a_intent != INTENT_HELP)
|
||||
source.visible_message("<span class='warning'>[source] [source.resting ? "tenses up" : "drops into a combative stance"].</span>", self_message)
|
||||
else
|
||||
source.visible_message("<span class='notice'>[source] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].</span>")
|
||||
else
|
||||
source.visible_message("<span class='warning'>[source] drops into a combative stance!</span>", self_message)
|
||||
else
|
||||
to_chat(source, self_message)
|
||||
if(playsound)
|
||||
source.playsound_local(source, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
|
||||
RegisterSignal(source, COMSIG_MOB_CLIENT_MOUSEMOVE, .proc/onMouseMove)
|
||||
RegisterSignal(source, COMSIG_MOVABLE_MOVED, .proc/on_move)
|
||||
RegisterSignal(source, COMSIG_MOB_CLIENT_MOVE, .proc/on_client_move)
|
||||
if(hud_icon)
|
||||
hud_icon.combat_on = TRUE
|
||||
hud_icon.update_icon()
|
||||
|
||||
/// Disables combat mode. Please use 'safe_disable_combat_mode' instead, if you wish to also disable the toggle flag.
|
||||
/datum/component/combat_mode/proc/disable_combat_mode(mob/living/source, silent = TRUE, forced = TRUE, visible = FALSE, locked = FALSE, playsound = FALSE)
|
||||
if(locked)
|
||||
if(hud_icon)
|
||||
hud_icon.combat_on = FALSE
|
||||
hud_icon.update_icon()
|
||||
return
|
||||
if(!(mode_flags & COMBAT_MODE_ACTIVE))
|
||||
return
|
||||
mode_flags &= ~COMBAT_MODE_ACTIVE
|
||||
mode_flags |= COMBAT_MODE_INACTIVE
|
||||
SEND_SIGNAL(source, COMSIG_LIVING_COMBAT_DISABLED, forced)
|
||||
if(!silent)
|
||||
var/self_message = forced? "<span class='warning'>Your muscles are forcibly relaxed!</span>" : "<span class='warning'>You relax your stance.</span>"
|
||||
if(visible)
|
||||
source.visible_message("<span class='warning'>[source] relaxes [source.p_their()] stance.</span>", self_message)
|
||||
else
|
||||
to_chat(source, self_message)
|
||||
if(playsound)
|
||||
source.playsound_local(source, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the toggleon sound!
|
||||
UnregisterSignal(source, list(COMSIG_MOB_CLIENT_MOUSEMOVE, COMSIG_MOVABLE_MOVED, COMSIG_MOB_CLIENT_MOVE))
|
||||
if(hud_icon)
|
||||
hud_icon.combat_on = FALSE
|
||||
hud_icon.update_icon()
|
||||
|
||||
///Changes the user direction to (try) keep match the pointer.
|
||||
/datum/component/combat_mode/proc/on_move(atom/movable/source, dir, atom/oldloc, forced)
|
||||
var/mob/living/L = source
|
||||
if(mode_flags & COMBAT_MODE_ACTIVE && L.client && lastmousedir && lastmousedir != dir)
|
||||
L.setDir(lastmousedir, ismousemovement = TRUE)
|
||||
|
||||
/// Added movement delay if moving backward.
|
||||
/datum/component/combat_mode/proc/on_client_move(mob/source, client/client, direction, n, oldloc, added_delay)
|
||||
if(oldloc != n && direction == REVERSE_DIR(source.dir))
|
||||
client.move_delay += added_delay*0.5
|
||||
|
||||
///Changes the user direction to (try) match the pointer.
|
||||
/datum/component/combat_mode/proc/onMouseMove(mob/source, object, location, control, params)
|
||||
if(source.client.show_popup_menus)
|
||||
return
|
||||
source.face_atom(object, TRUE)
|
||||
lastmousedir = source.dir
|
||||
|
||||
/// Toggles whether the user is intentionally in combat mode. THIS should be the proc you generally use! Has built in visual/to other player feedback, as well as an audible cue to ourselves.
|
||||
/datum/component/combat_mode/proc/user_toggle_intentional_combat_mode(mob/living/source)
|
||||
if(mode_flags & COMBAT_MODE_TOGGLED)
|
||||
safe_disable_combat_mode(source)
|
||||
else if(source.stat == CONSCIOUS && !(source.combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
safe_enable_combat_mode(source)
|
||||
|
||||
/// Enables intentionally being in combat mode. Please try to use the COMSIG_COMBAT_MODE_CHECK signal for feedback when possible.
|
||||
/datum/component/combat_mode/proc/safe_enable_combat_mode(mob/living/source, silent = FALSE, visible = TRUE)
|
||||
if((mode_flags & COMBAT_MODE_TOGGLED) && (mode_flags & COMBAT_MODE_ACTIVE))
|
||||
return TRUE
|
||||
mode_flags |= COMBAT_MODE_TOGGLED
|
||||
enable_combat_mode(source, silent, FALSE, visible, HAS_TRAIT(source, TRAIT_COMBAT_MODE_LOCKED), TRUE)
|
||||
if(source.client)
|
||||
source.client.show_popup_menus = FALSE
|
||||
if(iscarbon(source)) //I dislike this typecheck. It probably should be removed once that spoiled apple is componentized too.
|
||||
var/mob/living/carbon/C = source
|
||||
if(C.voremode)
|
||||
C.disable_vore_mode()
|
||||
return TRUE
|
||||
|
||||
/// Disables intentionally being in combat mode. Please try to use the COMSIG_COMBAT_MODE_CHECK signal for feedback when possible.
|
||||
/datum/component/combat_mode/proc/safe_disable_combat_mode(mob/living/source, silent = FALSE, visible = FALSE)
|
||||
if(!(mode_flags & COMBAT_MODE_TOGGLED) && !(mode_flags & COMBAT_MODE_ACTIVE))
|
||||
return TRUE
|
||||
mode_flags &= ~COMBAT_MODE_TOGGLED
|
||||
disable_combat_mode(source, silent, FALSE, visible, !(mode_flags & COMBAT_MODE_ACTIVE), TRUE)
|
||||
if(source.client)
|
||||
source.client.show_popup_menus = TRUE
|
||||
return TRUE
|
||||
|
||||
/// Returns a field of flags that are contained in both the second arg and our bitfield variable.
|
||||
/datum/component/combat_mode/proc/check_flags(mob/living/source, flags)
|
||||
return mode_flags & (flags)
|
||||
|
||||
/// Disables combat mode upon death.
|
||||
/datum/component/combat_mode/proc/on_death(mob/living/source)
|
||||
safe_disable_combat_mode(source)
|
||||
|
||||
/// Disables combat mode upon logout
|
||||
/datum/component/combat_mode/proc/on_logout(mob/living/source)
|
||||
safe_disable_combat_mode(source)
|
||||
|
||||
/// The screen button.
|
||||
/obj/screen/combattoggle
|
||||
name = "toggle combat mode"
|
||||
icon = 'modular_citadel/icons/ui/screen_midnight.dmi'
|
||||
icon_state = "combat_off"
|
||||
var/mutable_appearance/flashy
|
||||
var/combat_on = FALSE ///Wheter combat mode is enabled or not, so we don't have to store a reference.
|
||||
|
||||
/obj/screen/combattoggle/Click()
|
||||
if(hud && usr == hud.mymob)
|
||||
SEND_SIGNAL(hud.mymob, COMSIG_TOGGLE_COMBAT_MODE)
|
||||
|
||||
/obj/screen/combattoggle/update_icon_state()
|
||||
var/mob/living/user = hud?.mymob
|
||||
if(!user)
|
||||
return
|
||||
if(combat_on)
|
||||
icon_state = "combat"
|
||||
else if(HAS_TRAIT(user, TRAIT_COMBAT_MODE_LOCKED))
|
||||
icon_state = "combat_locked"
|
||||
else
|
||||
icon_state = "combat_off"
|
||||
|
||||
/obj/screen/combattoggle/update_overlays()
|
||||
. = ..()
|
||||
var/mob/living/carbon/user = hud?.mymob
|
||||
if(!(user?.client))
|
||||
return
|
||||
|
||||
if(combat_on)
|
||||
if(!flashy)
|
||||
flashy = mutable_appearance('icons/mob/screen_gen.dmi', "togglefull_flash")
|
||||
flashy.color = user.client.prefs.hud_toggle_color
|
||||
. += flashy //TODO - beg lummox jr for the ability to force mutable appearances or images to be created rendering from their first frame of animation rather than being based entirely around the client's frame count
|
||||
@@ -1,20 +1,64 @@
|
||||
//Gun crafting parts til they can be moved elsewhere
|
||||
|
||||
// PARTS //
|
||||
k// PARTS //
|
||||
/obj/item/weaponcrafting
|
||||
icon = 'icons/obj/improvised.dmi'
|
||||
|
||||
/obj/item/weaponcrafting/receiver
|
||||
name = "modular receiver"
|
||||
desc = "A prototype modular receiver and trigger assembly for a firearm."
|
||||
icon_state = "receiver"
|
||||
|
||||
/obj/item/weaponcrafting/stock
|
||||
name = "rifle stock"
|
||||
desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood."
|
||||
custom_materials = list(/datum/material/wood = MINERAL_MATERIAL_AMOUNT * 6)
|
||||
icon_state = "riflestock"
|
||||
|
||||
/obj/item/weaponcrafting/durathread_string
|
||||
name = "durathread string"
|
||||
desc = "A long piece of durathread with some resemblance to cable coil."
|
||||
icon_state = "durastring"
|
||||
|
||||
////////////////////////////////
|
||||
// KAT IMPROVISED WEAPON PARTS//
|
||||
////////////////////////////////
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts
|
||||
name = "Eerie bunch of coloured dots."
|
||||
desc = "You feel the urge to report to Central that the parent type of guncrafting, which should never appear in this reality, has appeared. Whatever that means."
|
||||
icon = 'icons/obj/guns/gun_parts.dmi'
|
||||
icon_state = "palette"
|
||||
|
||||
// BARRELS
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_rifle
|
||||
name = "rifle barrel"
|
||||
desc = "A pipe with a diameter just the right size to fire 7.62 rounds out of."
|
||||
icon_state = "barrel_rifle"
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_shotgun
|
||||
name = "shotgun barrel"
|
||||
desc = "A twenty bore shotgun barrel."
|
||||
icon_state = "barrel_shotgun"
|
||||
|
||||
// RECEIVERS
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver
|
||||
name = "bolt action receiver"
|
||||
desc = "A crudely constructed receiver to create an improvised bolt-action breechloaded rifle."
|
||||
icon_state = "receiver_rifle"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver
|
||||
name = "break-action assembly"
|
||||
desc = "An improvised receiver to create a break-action breechloaded shotgun."
|
||||
icon_state = "receiver_shotgun"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
// MISC
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly
|
||||
name = "firearm trigger assembly"
|
||||
desc = "A modular trigger assembly with a firing pin, this can be used to make a whole bunch of improvised firearss."
|
||||
icon_state = "trigger_assembly"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/wooden_body
|
||||
name = "wooden firearm body"
|
||||
desc = "A crudely fashioned wooden body to help keep higher calibre improvised weapons from blowing themselves apart."
|
||||
icon_state = "wooden_body"
|
||||
|
||||
|
||||
@@ -116,4 +116,41 @@
|
||||
always_availible = FALSE
|
||||
reqs = list(/obj/item/stack/rods = 1,
|
||||
/obj/item/stack/sheet/mineral/sandstone = 4)
|
||||
category = CAT_PRIMAL
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/rib
|
||||
name = "Collosal Rib"
|
||||
always_availible = FALSE
|
||||
reqs = list(
|
||||
/obj/item/stack/sheet/bone = 10,
|
||||
/datum/reagent/oil = 5)
|
||||
result = /obj/structure/statue/bone/rib
|
||||
subcategory = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/skull
|
||||
name = "Skull Carving"
|
||||
always_availible = FALSE
|
||||
reqs = list(
|
||||
/obj/item/stack/sheet/bone = 6,
|
||||
/datum/reagent/oil = 5)
|
||||
result = /obj/structure/statue/bone/skull
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/halfskull
|
||||
name = "Cracked Skull Carving"
|
||||
always_availible = FALSE
|
||||
reqs = list(
|
||||
/obj/item/stack/sheet/bone = 3,
|
||||
/datum/reagent/oil = 5)
|
||||
result = /obj/structure/statue/bone/skull/half
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/boneshovel
|
||||
name = "Serrated Bone Shovel"
|
||||
always_availible = FALSE
|
||||
reqs = list(
|
||||
/obj/item/stack/sheet/bone = 4,
|
||||
/datum/reagent/oil = 5,
|
||||
/obj/item/shovel/spade = 1)
|
||||
result = /obj/item/shovel/serrated
|
||||
category = CAT_PRIMAL
|
||||
|
||||
@@ -251,8 +251,10 @@
|
||||
/datum/crafting_recipe/ishotgun
|
||||
name = "Improvised Shotgun"
|
||||
result = /obj/item/gun/ballistic/revolver/doublebarrel/improvised
|
||||
reqs = list(/obj/item/weaponcrafting/receiver = 1,
|
||||
/obj/item/pipe = 1,
|
||||
reqs = list(/obj/item/weaponcrafting/improvised_parts/barrel_shotgun = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/wooden_body = 1,
|
||||
/obj/item/weaponcrafting/stock = 1,
|
||||
/obj/item/stack/packageWrap = 5)
|
||||
tools = list(TOOL_SCREWDRIVER)
|
||||
@@ -261,10 +263,12 @@
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/irifle
|
||||
name = "Improvised Rifle(7.62mm)"
|
||||
name = "Improvised Rifle (7.62mm)"
|
||||
result = /obj/item/gun/ballistic/shotgun/boltaction/improvised
|
||||
reqs = list(/obj/item/weaponcrafting/receiver = 1,
|
||||
/obj/item/pipe = 2,
|
||||
reqs = list(/obj/item/weaponcrafting/improvised_parts/barrel_rifle = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/wooden_body = 1,
|
||||
/obj/item/weaponcrafting/stock = 1,
|
||||
/obj/item/stack/packageWrap = 5)
|
||||
tools = list(TOOL_SCREWDRIVER)
|
||||
@@ -394,3 +398,60 @@
|
||||
time = 5
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
////////////////////
|
||||
// PARTS CRAFTING //
|
||||
////////////////////
|
||||
|
||||
// BARRELS
|
||||
|
||||
/datum/crafting_recipe/rifle_barrel
|
||||
name = "Improvised Rifle Barrel"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/barrel_rifle
|
||||
reqs = list(/obj/item/pipe = 2)
|
||||
tools = list(TOOL_WELDER,TOOL_SAW)
|
||||
time = 150
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
/datum/crafting_recipe/shotgun_barrel
|
||||
name = "Improvised Shotgun Barrel"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/barrel_shotgun
|
||||
reqs = list(/obj/item/pipe = 2)
|
||||
tools = list(TOOL_WELDER,TOOL_SAW)
|
||||
time = 150
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
// RECEIVERS
|
||||
|
||||
/datum/crafting_recipe/rifle_receiver
|
||||
name = "Improvised Rifle Receiver"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/rifle_receiver
|
||||
reqs = list(/obj/item/stack/sheet/metal = 20)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER) // Rifle is the easiest to craft and can be made at an autolathe, this is a very light kick in the shin for dual-wielding ishotguns.
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
/datum/crafting_recipe/shotgun_receiver
|
||||
name = "Improvised Shotgun Receiver"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/shotgun_receiver
|
||||
reqs = list(/obj/item/stack/sheet/metal = 10,
|
||||
/obj/item/stack/sheet/plasteel = 1)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER) // Increased cost is to stop dual-wield alpha striking. ishotgun is a rvolver and can be duel-wielded
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
// MISC
|
||||
|
||||
/datum/crafting_recipe/trigger_assembly
|
||||
name = "Trigger Assembly"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/trigger_assembly
|
||||
reqs = list(/obj/item/stack/sheet/metal = 3,
|
||||
/obj/item/assembly/igniter = 1)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER)
|
||||
time = 150
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/datum/component/decal
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
can_transfer = TRUE
|
||||
var/cleanable
|
||||
var/description
|
||||
var/mutable_appearance/pic
|
||||
|
||||
var/first_dir // This only stores the dir arg from init
|
||||
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
first_dir = _dir
|
||||
description = _description
|
||||
cleanable = _cleanable
|
||||
|
||||
apply()
|
||||
|
||||
/datum/component/decal/RegisterWithParent()
|
||||
. = ..()
|
||||
if(first_dir)
|
||||
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
|
||||
if(cleanable)
|
||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
||||
if(description)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
|
||||
/datum/component/decal/UnregisterFromParent()
|
||||
. = ..()
|
||||
UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE))
|
||||
|
||||
/datum/component/decal/Destroy()
|
||||
remove()
|
||||
return ..()
|
||||
|
||||
/datum/component/decal/PreTransfer()
|
||||
remove()
|
||||
|
||||
/datum/component/decal/PostTransfer()
|
||||
remove()
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha)
|
||||
if(!_icon || !_icon_state)
|
||||
return FALSE
|
||||
// It has to be made from an image or dir breaks because of a byond bug
|
||||
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
|
||||
pic = new(temp_image)
|
||||
pic.color = _color
|
||||
pic.alpha = _alpha
|
||||
return TRUE
|
||||
|
||||
/datum/component/decal/proc/apply(atom/thing)
|
||||
var/atom/master = thing || parent
|
||||
master.add_overlay(pic, TRUE)
|
||||
if(isitem(master))
|
||||
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/component/decal/proc/remove(atom/thing)
|
||||
var/atom/master = thing || parent
|
||||
master.cut_overlay(pic, TRUE)
|
||||
if(isitem(master))
|
||||
addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir)
|
||||
if(old_dir == new_dir)
|
||||
return
|
||||
remove()
|
||||
pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir))
|
||||
apply()
|
||||
|
||||
/datum/component/decal/proc/clean_react(datum/source, strength)
|
||||
if(strength >= cleanable)
|
||||
qdel(src)
|
||||
|
||||
/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list)
|
||||
examine_list += description
|
||||
@@ -1,13 +0,0 @@
|
||||
/datum/component/decal/blood
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE
|
||||
|
||||
/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name)
|
||||
|
||||
/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override)
|
||||
var/atom/A = parent
|
||||
|
||||
return COMPONENT_EXNAME_CHANGED
|
||||
@@ -1,11 +0,0 @@
|
||||
/datum/component/empprotection
|
||||
var/flags = NONE
|
||||
|
||||
/datum/component/empprotection/Initialize(_flags)
|
||||
if(!istype(parent, /atom))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
flags = _flags
|
||||
RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags)
|
||||
|
||||
/datum/component/empprotection/proc/getEmpFlags(datum/source, severity)
|
||||
return flags
|
||||
@@ -9,6 +9,7 @@
|
||||
var/originalName
|
||||
var/list/affixes
|
||||
var/list/appliedComponents
|
||||
var/list/appliedElements
|
||||
|
||||
var/static/list/affixListing
|
||||
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
src.affixes = affixes
|
||||
appliedComponents = list()
|
||||
appliedElements = list()
|
||||
randomAffixes()
|
||||
|
||||
/datum/component/fantasy/Destroy()
|
||||
@@ -118,6 +120,8 @@
|
||||
affix.remove(src)
|
||||
for(var/i in appliedComponents)
|
||||
qdel(i)
|
||||
for(var/i in appliedElements)
|
||||
master._RemoveElement(i)
|
||||
|
||||
master.force = max(0, master.force - quality)
|
||||
master.throwforce = max(0, master.throwforce - quality)
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
|
||||
/datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName)
|
||||
var/obj/item/master = comp.parent
|
||||
comp.appliedComponents += master.AddComponent(/datum/component/tactical)
|
||||
master.AddElement(/datum/element/tactical)
|
||||
comp.appliedElements += list(/datum/element/tactical)
|
||||
return "tactical [newName]"
|
||||
|
||||
/datum/fantasy_affix/pyromantic
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/datum/component/forced_gravity
|
||||
var/gravity
|
||||
var/ignore_space = FALSE //If forced gravity should also work on space turfs
|
||||
|
||||
/datum/component/forced_gravity/Initialize(forced_value = 1)
|
||||
if(!isatom(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
RegisterSignal(COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check)
|
||||
if(isturf(parent))
|
||||
RegisterSignal(COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check)
|
||||
|
||||
gravity = forced_value
|
||||
|
||||
/datum/component/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs)
|
||||
if(!ignore_space && isspaceturf(location))
|
||||
return
|
||||
gravs += gravity
|
||||
|
||||
/datum/component/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs)
|
||||
return gravity_check(parent, gravs)
|
||||
@@ -47,14 +47,11 @@
|
||||
if(icon_state)
|
||||
lock_icon_state = icon_state
|
||||
generate_lock_visuals()
|
||||
var/mob/M = parent
|
||||
LAZYOR(M.mousemove_intercept_objects, src)
|
||||
RegisterSignal(parent, COMSIG_MOB_CLIENT_MOUSEMOVE, .proc/onMouseMove)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/datum/component/lockon_aiming/Destroy()
|
||||
var/mob/M = parent
|
||||
clear_visuals()
|
||||
LAZYREMOVE(M.mousemove_intercept_objects, src)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
@@ -120,7 +117,7 @@
|
||||
return
|
||||
LAZYREMOVE(immune_weakrefs, A.weak_reference)
|
||||
|
||||
/datum/component/lockon_aiming/onMouseMove(object,location,control,params)
|
||||
/datum/component/lockon_aiming/proc/onMouseMove(object,location,control,params)
|
||||
var/mob/M = parent
|
||||
if(!istype(M) || !M.client)
|
||||
return
|
||||
|
||||
@@ -321,6 +321,28 @@
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
add_event(null, "nutrition", /datum/mood_event/starving)
|
||||
|
||||
/datum/component/mood/proc/update_beauty(area/A)
|
||||
if(A.outdoors) //if we're outside, we don't care.
|
||||
clear_event(null, "area_beauty")
|
||||
return FALSE
|
||||
if(HAS_TRAIT(parent, TRAIT_SNOB))
|
||||
switch(A.beauty)
|
||||
if(-INFINITY to BEAUTY_LEVEL_HORRID)
|
||||
add_event(null, "area_beauty", /datum/mood_event/horridroom)
|
||||
return
|
||||
if(BEAUTY_LEVEL_HORRID to BEAUTY_LEVEL_BAD)
|
||||
add_event(null, "area_beauty", /datum/mood_event/badroom)
|
||||
return
|
||||
switch(A.beauty)
|
||||
if(-INFINITY to BEAUTY_LEVEL_DECENT)
|
||||
clear_event(null, "area_beauty")
|
||||
if(BEAUTY_LEVEL_DECENT to BEAUTY_LEVEL_GOOD)
|
||||
add_event(null, "area_beauty", /datum/mood_event/decentroom)
|
||||
if(BEAUTY_LEVEL_GOOD to BEAUTY_LEVEL_GREAT)
|
||||
add_event(null, "area_beauty", /datum/mood_event/goodroom)
|
||||
if(BEAUTY_LEVEL_GREAT to INFINITY)
|
||||
add_event(null, "area_beauty", /datum/mood_event/greatroom)
|
||||
|
||||
///Called when parent is revived.
|
||||
/datum/component/mood/proc/on_revive(datum/source, full_heal)
|
||||
START_PROCESSING(SSdcs, src)
|
||||
|
||||
@@ -62,7 +62,9 @@
|
||||
orbiters[orbiter] = TRUE
|
||||
orbiter.orbiting = src
|
||||
RegisterSignal(orbiter, COMSIG_MOVABLE_MOVED, .proc/orbiter_move_react)
|
||||
|
||||
var/matrix/initial_transform = matrix(orbiter.transform)
|
||||
orbiters[orbiter] = initial_transform
|
||||
|
||||
// Head first!
|
||||
if(pre_rotation)
|
||||
@@ -79,8 +81,6 @@
|
||||
|
||||
orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE)
|
||||
|
||||
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
|
||||
orbiter.transform = initial_transform
|
||||
orbiter.forceMove(get_turf(parent))
|
||||
to_chat(orbiter, "<span class='notice'>Now orbiting [parent].</span>")
|
||||
|
||||
@@ -89,6 +89,8 @@
|
||||
return
|
||||
UnregisterSignal(orbiter, COMSIG_MOVABLE_MOVED)
|
||||
orbiter.SpinAnimation(0, 0)
|
||||
if(istype(orbiters[orbiter],/matrix)) //This is ugly.
|
||||
orbiter.transform = orbiters[orbiter]
|
||||
orbiters -= orbiter
|
||||
orbiter.stop_orbit(src)
|
||||
orbiter.orbiting = null
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
valid_slots = _valid_slots
|
||||
|
||||
/datum/component/wearertargeting/phantomthief/proc/handlefilterstuff(mob/living/user, was_forced = FALSE)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
if(!SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE))
|
||||
user.remove_filter("phantomthief")
|
||||
else
|
||||
user.add_filter("phantomthief", 4, list(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, color = filter_color))
|
||||
|
||||
@@ -23,18 +23,12 @@
|
||||
|
||||
if(can_user_rotate)
|
||||
src.can_user_rotate = can_user_rotate
|
||||
else
|
||||
src.can_user_rotate = CALLBACK(src,.proc/default_can_user_rotate)
|
||||
|
||||
if(can_be_rotated)
|
||||
src.can_be_rotated = can_be_rotated
|
||||
else
|
||||
src.can_be_rotated = CALLBACK(src,.proc/default_can_be_rotated)
|
||||
|
||||
if(after_rotation)
|
||||
src.after_rotation = after_rotation
|
||||
else
|
||||
src.after_rotation = CALLBACK(src,.proc/default_after_rotation)
|
||||
|
||||
//Try Clockwise,counter,flip in order
|
||||
if(src.rotation_flags & ROTATION_FLIP)
|
||||
@@ -103,14 +97,34 @@
|
||||
examine_list += "<span class='notice'>Alt-click to rotate it clockwise.</span>"
|
||||
|
||||
/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction)
|
||||
if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
|
||||
return
|
||||
if(can_be_rotated)
|
||||
if(!can_be_rotated.Invoke(user, default_rotation_direction))
|
||||
return
|
||||
else
|
||||
if(!default_can_be_rotated(user, default_rotation_direction))
|
||||
return
|
||||
if(can_user_rotate)
|
||||
if(!can_user_rotate.Invoke(user, default_rotation_direction))
|
||||
return
|
||||
else
|
||||
if(!default_can_user_rotate(user, default_rotation_direction))
|
||||
return
|
||||
BaseRot(user, rotation)
|
||||
return TRUE
|
||||
|
||||
/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
|
||||
if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
|
||||
return
|
||||
if(can_be_rotated)
|
||||
if(!can_be_rotated.Invoke(user, default_rotation_direction))
|
||||
return
|
||||
else
|
||||
if(!default_can_be_rotated(user, default_rotation_direction))
|
||||
return
|
||||
if(can_user_rotate)
|
||||
if(!can_user_rotate.Invoke(user, default_rotation_direction))
|
||||
return
|
||||
else
|
||||
if(!default_can_user_rotate(user, default_rotation_direction))
|
||||
return
|
||||
if(istype(I,/obj/item/wrench))
|
||||
BaseRot(user,default_rotation_direction)
|
||||
return COMPONENT_NO_AFTERATTACK
|
||||
@@ -126,7 +140,10 @@
|
||||
if(ROTATION_FLIP)
|
||||
rot_degree = 180
|
||||
AM.setDir(turn(AM.dir,rot_degree))
|
||||
after_rotation.Invoke(user,rotation_type)
|
||||
if(after_rotation)
|
||||
after_rotation.Invoke(user, rotation_type)
|
||||
else
|
||||
default_after_rotation(user, rotation_type)
|
||||
|
||||
/datum/component/simple_rotation/proc/default_can_user_rotate(mob/living/user, rotation_type)
|
||||
if(!istype(user) || !user.canUseTopic(parent, BE_CLOSE, NO_DEXTERY))
|
||||
|
||||
@@ -136,9 +136,7 @@
|
||||
var/mob/M = parent.loc
|
||||
I.dropped(M)
|
||||
if(new_location)
|
||||
//Reset the items values
|
||||
_removal_reset(AM)
|
||||
AM.forceMove(new_location)
|
||||
AM.forceMove(new_location) // exited comsig will handle removal reset.
|
||||
//We don't want to call this if the item is being destroyed
|
||||
AM.on_exit_storage(src)
|
||||
else
|
||||
|
||||
@@ -351,7 +351,6 @@
|
||||
return master._removal_reset(thing)
|
||||
|
||||
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
|
||||
_removal_reset(thing)
|
||||
if(LAZYACCESS(ui_item_blocks, thing))
|
||||
var/obj/screen/storage/volumetric_box/center/C = ui_item_blocks[thing]
|
||||
for(var/i in can_see_contents()) //runtimes result if mobs can access post deletion.
|
||||
@@ -359,6 +358,7 @@
|
||||
M.client?.screen -= C.on_screen_objects()
|
||||
ui_item_blocks -= thing
|
||||
qdel(C)
|
||||
_removal_reset(thing) // THIS NEEDS TO HAPPEN AFTER SO LAYERING DOESN'T BREAK!
|
||||
refresh_mob_views()
|
||||
|
||||
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
var/mob/living/simple_animal/L = new chosen_mob_type(spawn_location)
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L
|
||||
H.friends += summoner // do not attack our summon boy
|
||||
H.friends[summoner]++ // do not attack our summon boy
|
||||
spawned_mobs += L
|
||||
if(faction != null)
|
||||
L.faction = faction
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
/datum/component/tactical
|
||||
var/allowed_slot
|
||||
|
||||
/datum/component/tactical/Initialize(allowed_slot)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.allowed_slot = allowed_slot
|
||||
|
||||
/datum/component/tactical/RegisterWithParent()
|
||||
. = ..()
|
||||
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/modify)
|
||||
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/unmodify)
|
||||
|
||||
/datum/component/tactical/UnregisterFromParent()
|
||||
. = ..()
|
||||
UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
|
||||
unmodify()
|
||||
|
||||
/datum/component/tactical/Destroy()
|
||||
unmodify()
|
||||
return ..()
|
||||
|
||||
/datum/component/tactical/proc/modify(obj/item/source, mob/user, slot)
|
||||
if(allowed_slot && slot != allowed_slot)
|
||||
unmodify()
|
||||
return
|
||||
|
||||
var/obj/item/master = parent
|
||||
var/image/I = image(icon = master.icon, icon_state = master.icon_state, loc = user)
|
||||
I.copy_overlays(master)
|
||||
I.override = TRUE
|
||||
source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
|
||||
/datum/component/tactical/proc/unmodify(obj/item/source, mob/user)
|
||||
var/obj/item/master = source || parent
|
||||
if(!user)
|
||||
if(!ismob(master.loc))
|
||||
return
|
||||
user = master.loc
|
||||
|
||||
user.remove_alt_appearance("sneaking_mission")
|
||||
+11
-11
@@ -391,16 +391,6 @@
|
||||
|
||||
/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures)
|
||||
|
||||
if(newfeatures)
|
||||
var/old_size = dna.features["body_size"]
|
||||
dna.features = newfeatures
|
||||
dna.update_body_size(old_size)
|
||||
|
||||
if(mrace)
|
||||
var/datum/species/newrace = new mrace.type
|
||||
newrace.copy_properties_from(mrace)
|
||||
set_species(newrace, icon_update=0)
|
||||
|
||||
if(newreal_name)
|
||||
real_name = newreal_name
|
||||
dna.generate_unique_enzymes()
|
||||
@@ -410,7 +400,17 @@
|
||||
|
||||
if(ui)
|
||||
dna.uni_identity = ui
|
||||
updateappearance(icon_update=0)
|
||||
updateappearance(icon_update=FALSE)
|
||||
|
||||
if(newfeatures)
|
||||
var/old_size = dna.features["body_size"]
|
||||
dna.features = newfeatures
|
||||
dna.update_body_size(old_size)
|
||||
|
||||
if(mrace)
|
||||
var/datum/species/newrace = new mrace.type
|
||||
newrace.copy_properties_from(mrace)
|
||||
set_species(newrace, icon_update=FALSE)
|
||||
|
||||
if(LAZYLEN(mutation_index))
|
||||
dna.mutation_index = mutation_index.Copy()
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
#define BAD_ART 12.5
|
||||
#define GOOD_ART 25
|
||||
#define GREAT_ART 50
|
||||
|
||||
/datum/element/art
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 2
|
||||
var/impressiveness = 0
|
||||
|
||||
/datum/element/art/Attach(datum/target, impress)
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE || !isatom(target) || isarea(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
impressiveness = impress
|
||||
if(isobj(target))
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine)
|
||||
if(isstructure(target))
|
||||
RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
|
||||
if(isitem(target))
|
||||
RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet)
|
||||
else
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_other_examine)
|
||||
|
||||
/datum/element/art/Detach(datum/target)
|
||||
UnregisterSignal(target, list(COMSIG_PARENT_EXAMINE, COMSIG_ATOM_ATTACK_HAND, COMSIG_ITEM_ATTACK_SELF))
|
||||
return ..()
|
||||
|
||||
/datum/element/art/proc/apply_moodlet(atom/source, mob/M, impress)
|
||||
M.visible_message("<span class='notice'>[M] stops and looks intently at [source].</span>", \
|
||||
"<span class='notice'>You stop to take in [source].</span>")
|
||||
switch(impress)
|
||||
if (0 to BAD_ART)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
|
||||
if (BAD_ART to GOOD_ART)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok)
|
||||
if (GOOD_ART to GREAT_ART)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood)
|
||||
if(GREAT_ART to INFINITY)
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
|
||||
|
||||
/datum/element/art/proc/on_other_examine(atom/source, mob/M)
|
||||
apply_moodlet(source, M, impressiveness)
|
||||
|
||||
/datum/element/art/proc/on_obj_examine(atom/source, mob/M)
|
||||
var/obj/O = source
|
||||
apply_moodlet(source, M, impressiveness *(O.obj_integrity/O.max_integrity))
|
||||
|
||||
/datum/element/art/proc/on_attack_hand(atom/source, mob/M)
|
||||
to_chat(M, "<span class='notice'>You start examining [source]...</span>")
|
||||
if(!do_after(M, 20, target = source))
|
||||
return
|
||||
on_obj_examine(source, M)
|
||||
|
||||
/datum/element/art/rev
|
||||
|
||||
/datum/element/art/rev/apply_moodlet(atom/source, mob/M, impress)
|
||||
M.visible_message("<span class='notice'>[M] stops to inspect [source].</span>", \
|
||||
"<span class='notice'>You take in [source], inspecting the fine craftsmanship of the proletariat.</span>")
|
||||
|
||||
if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev))
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat)
|
||||
else
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad)
|
||||
@@ -0,0 +1,34 @@
|
||||
/datum/element/beauty
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 2
|
||||
var/beauty = 0
|
||||
|
||||
/datum/element/beauty/Attach(datum/target, beautyamount)
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE || !isatom(target) || isarea(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
beauty = beautyamount
|
||||
RegisterSignal(target, COMSIG_ENTER_AREA, .proc/enter_area)
|
||||
RegisterSignal(target, COMSIG_EXIT_AREA, .proc/exit_area)
|
||||
var/area/A = get_area(target)
|
||||
if(A)
|
||||
enter_area(null, A)
|
||||
|
||||
/datum/element/beauty/Detach(datum/target)
|
||||
UnregisterSignal(target, list(COMSIG_ENTER_AREA, COMSIG_EXIT_AREA))
|
||||
var/area/A = get_area(target)
|
||||
if(A)
|
||||
exit_area(null, A)
|
||||
return ..()
|
||||
|
||||
/datum/element/beauty/proc/enter_area(datum/source, area/A)
|
||||
if(A.outdoors)
|
||||
return
|
||||
A.totalbeauty += beauty
|
||||
A.update_beauty()
|
||||
|
||||
/datum/element/beauty/proc/exit_area(datum/source, area/A)
|
||||
if(A.outdoors)
|
||||
return
|
||||
A.totalbeauty -= beauty
|
||||
A.update_beauty()
|
||||
@@ -0,0 +1,75 @@
|
||||
/datum/element/decal
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 2
|
||||
var/cleanable
|
||||
var/description
|
||||
var/mutable_appearance/pic
|
||||
var/list/num_decals_per_atom
|
||||
|
||||
var/first_dir // This stores the direction of the decal compared to the parent facing NORTH
|
||||
|
||||
/datum/element/decal/Attach(datum/target, _icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE || !_icon || !_icon_state || !isatom(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
var/atom/A = target
|
||||
if(!pic)
|
||||
// It has to be made from an image or dir breaks because of a byond bug
|
||||
var/temp_image = image(_icon, null, _icon_state, _layer, _dir)
|
||||
pic = new(temp_image)
|
||||
pic.color = _color
|
||||
pic.alpha = _alpha
|
||||
first_dir = _dir
|
||||
description = _description
|
||||
cleanable = _cleanable
|
||||
|
||||
LAZYINITLIST(num_decals_per_atom)
|
||||
|
||||
if(!num_decals_per_atom[A])
|
||||
if(first_dir)
|
||||
RegisterSignal(A, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
|
||||
if(cleanable)
|
||||
RegisterSignal(A, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
||||
if(description)
|
||||
RegisterSignal(A, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||
|
||||
apply(A, TRUE)
|
||||
|
||||
num_decals_per_atom[A]++
|
||||
|
||||
/datum/element/decal/Detach(datum/target)
|
||||
var/atom/A = target
|
||||
remove(A, A.dir)
|
||||
UnregisterSignal(A, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE))
|
||||
LAZYREMOVE(num_decals_per_atom, A)
|
||||
return ..()
|
||||
|
||||
/datum/element/decal/proc/remove(atom/target, old_dir)
|
||||
pic.dir = first_dir == NORTH ? target.dir : turn(first_dir, dir2angle(old_dir))
|
||||
for(var/i in 1 to num_decals_per_atom[target])
|
||||
target.cut_overlay(pic, TRUE)
|
||||
if(isitem(target))
|
||||
addtimer(CALLBACK(target, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/element/decal/proc/apply(atom/target, init = FALSE)
|
||||
pic.dir = first_dir == NORTH ? target.dir : turn(first_dir, dir2angle(target.dir))
|
||||
if(init)
|
||||
target.add_overlay(pic, TRUE)
|
||||
else
|
||||
for(var/i in 1 to num_decals_per_atom[target])
|
||||
target.add_overlay(pic, TRUE)
|
||||
if(isitem(target))
|
||||
addtimer(CALLBACK(target, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE)
|
||||
|
||||
/datum/element/decal/proc/rotate_react(datum/source, old_dir, new_dir)
|
||||
if(old_dir == new_dir)
|
||||
return
|
||||
remove(source, old_dir)
|
||||
apply(source)
|
||||
|
||||
/datum/element/decal/proc/clean_react(datum/source, strength)
|
||||
if(strength >= cleanable)
|
||||
Detach(source)
|
||||
|
||||
/datum/element/decal/proc/examine(datum/source, mob/user, list/examine_list)
|
||||
examine_list += description
|
||||
@@ -0,0 +1,18 @@
|
||||
/datum/element/empprotection
|
||||
element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
|
||||
id_arg_index = 2
|
||||
var/flags = NONE
|
||||
|
||||
/datum/element/empprotection/Attach(datum/target, _flags)
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE || !isatom(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
flags = _flags
|
||||
RegisterSignal(target, COMSIG_ATOM_EMP_ACT, .proc/getEmpFlags)
|
||||
|
||||
/datum/element/empprotection/Detach(atom/target)
|
||||
UnregisterSignal(target, COMSIG_ATOM_EMP_ACT)
|
||||
return ..()
|
||||
|
||||
/datum/element/empprotection/proc/getEmpFlags(datum/source, severity)
|
||||
return flags
|
||||
@@ -0,0 +1,30 @@
|
||||
/datum/element/forced_gravity
|
||||
element_flags = ELEMENT_BESPOKE
|
||||
id_arg_index = 2
|
||||
var/gravity
|
||||
var/ignore_space
|
||||
|
||||
/datum/element/forced_gravity/Attach(datum/target, gravity=1, ignore_space=FALSE)
|
||||
. = ..()
|
||||
if(!isatom(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
src.gravity = gravity
|
||||
src.ignore_space = ignore_space
|
||||
|
||||
RegisterSignal(target, COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check)
|
||||
if(isturf(target))
|
||||
RegisterSignal(target, COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check)
|
||||
|
||||
/datum/element/forced_gravity/Detach(datum/source, force)
|
||||
. = ..()
|
||||
var/static/list/signals_b_gone = list(COMSIG_ATOM_HAS_GRAVITY, COMSIG_TURF_HAS_GRAVITY)
|
||||
UnregisterSignal(source, signals_b_gone)
|
||||
|
||||
/datum/element/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs)
|
||||
if(!ignore_space && isspaceturf(location))
|
||||
return
|
||||
gravs += gravity
|
||||
|
||||
/datum/element/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs)
|
||||
return gravity_check(null, source, gravs)
|
||||
@@ -0,0 +1,37 @@
|
||||
/datum/element/tactical
|
||||
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
|
||||
id_arg_index = 2
|
||||
var/allowed_slot
|
||||
|
||||
/datum/element/tactical/Attach(datum/target, allowed_slot)
|
||||
. = ..()
|
||||
if(. == ELEMENT_INCOMPATIBLE || !isitem(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
src.allowed_slot = allowed_slot
|
||||
RegisterSignal(target, COMSIG_ITEM_EQUIPPED, .proc/modify)
|
||||
RegisterSignal(target, COMSIG_ITEM_DROPPED, .proc/unmodify)
|
||||
|
||||
/datum/element/tactical/Detach(datum/target)
|
||||
UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
|
||||
unmodify(target)
|
||||
return ..()
|
||||
|
||||
/datum/element/tactical/proc/modify(obj/item/source, mob/user, slot)
|
||||
if(allowed_slot && slot != allowed_slot)
|
||||
unmodify(source, user)
|
||||
return
|
||||
|
||||
var/image/I = image(icon = source.icon, icon_state = source.icon_state, loc = user)
|
||||
I.copy_overlays(source)
|
||||
I.override = TRUE
|
||||
source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
|
||||
/datum/element/tactical/proc/unmodify(obj/item/source, mob/user)
|
||||
if(!user)
|
||||
if(!ismob(source.loc))
|
||||
return
|
||||
user = source.loc
|
||||
|
||||
user.remove_alt_appearance("sneaking_mission")
|
||||
@@ -39,11 +39,11 @@
|
||||
/datum/martial_art/proc/damage_roll(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
//Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode.
|
||||
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
|
||||
if(!(D.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
if(SEND_SIGNAL(D, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
damage *= 1.5
|
||||
if(!CHECK_MOBILITY(A, MOBILITY_STAND))
|
||||
damage *= 0.5
|
||||
if(!(A.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
if(SEND_SIGNAL(A, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
|
||||
damage *= 0.25
|
||||
return damage
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
var/datum/martial_art/X = H.mind.default_martial_art
|
||||
X.teach(H)
|
||||
REMOVE_TRAIT(H, TRAIT_PUGILIST, MARTIAL_ARTIST_TRAIT)
|
||||
|
||||
|
||||
/datum/martial_art/proc/on_remove(mob/living/carbon/human/H)
|
||||
if(help_verb)
|
||||
H.verbs -= help_verb
|
||||
|
||||
@@ -24,6 +24,8 @@ Simple datum which is instanced once per type and is used for every object of sa
|
||||
var/value_per_unit = 0
|
||||
///Armor modifiers, multiplies an items normal armor vars by these amounts.
|
||||
var/armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1)
|
||||
///How beautiful is this material per unit?
|
||||
var/beauty_modifier = 0
|
||||
|
||||
///This proc is called when the material is added to an object.
|
||||
/datum/material/proc/on_applied(atom/source, amount, material_flags)
|
||||
@@ -39,6 +41,9 @@ Simple datum which is instanced once per type and is used for every object of sa
|
||||
if(istype(source, /obj)) //objs
|
||||
on_applied_obj(source, amount, material_flags)
|
||||
|
||||
if(beauty_modifier)
|
||||
addtimer(CALLBACK(source, /datum.proc/_AddElement, list(/datum/element/beauty, beauty_modifier * amount)), 0)
|
||||
|
||||
///This proc is called when the material is added to an object specifically.
|
||||
/datum/material/proc/on_applied_obj(var/obj/o, amount, material_flags)
|
||||
if(material_flags & MATERIAL_AFFECT_STATISTICS)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
integrity_modifier = 0.1
|
||||
sheet_type = /obj/item/stack/sheet/glass
|
||||
value_per_unit = 0.0025
|
||||
beauty_modifier = 0.05
|
||||
armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok
|
||||
|
||||
/*
|
||||
@@ -35,6 +36,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/silver
|
||||
value_per_unit = 0.025
|
||||
beauty_modifier = 0.075
|
||||
|
||||
///Slight force increase
|
||||
/datum/material/gold
|
||||
@@ -46,6 +48,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/gold
|
||||
value_per_unit = 0.0625
|
||||
beauty_modifier = 0.15
|
||||
armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1)
|
||||
|
||||
///Has no special properties
|
||||
@@ -58,6 +61,8 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/diamond
|
||||
value_per_unit = 0.25
|
||||
beauty_modifier = 0.3
|
||||
armor_modifiers = list("melee" = 1.3, "bullet" = 1.3, "laser" = 0.6, "energy" = 1, "bomb" = 1.2, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1)
|
||||
|
||||
///Is slightly radioactive
|
||||
/datum/material/uranium
|
||||
@@ -68,6 +73,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/uranium
|
||||
value_per_unit = 0.05
|
||||
beauty_modifier = 0.3 //It shines so beautiful
|
||||
armor_modifiers = list("melee" = 1.5, "bullet" = 1.4, "laser" = 0.5, "energy" = 0.5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 1, "acid" = 1)
|
||||
|
||||
/datum/material/uranium/on_applied(atom/source, amount, material_flags)
|
||||
@@ -88,6 +94,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/plasma
|
||||
value_per_unit = 0.1
|
||||
beauty_modifier = 0.15
|
||||
armor_modifiers = list("melee" = 1.4, "bullet" = 0.7, "laser" = 0, "energy" = 1.2, "bomb" = 0, "bio" = 1.2, "rad" = 1, "fire" = 0, "acid" = 0.5)
|
||||
|
||||
/datum/material/plasma/on_applied(atom/source, amount, material_flags)
|
||||
@@ -109,6 +116,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
color = list(119/255, 217/255, 396/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
|
||||
alpha = 200
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE)
|
||||
beauty_modifier = 0.5
|
||||
sheet_type = /obj/item/stack/sheet/bluespace_crystal
|
||||
value_per_unit = 0.15
|
||||
|
||||
@@ -121,6 +129,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/bananium
|
||||
value_per_unit = 0.5
|
||||
beauty_modifier = 0.5
|
||||
armor_modifiers = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 0) //Clowns cant be blown away
|
||||
|
||||
/datum/material/bananium/on_applied(atom/source, amount, material_flags)
|
||||
@@ -144,6 +153,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/titanium
|
||||
value_per_unit = 0.0625
|
||||
beauty_modifier = 0.05
|
||||
armor_modifiers = list("melee" = 1.35, "bullet" = 1.3, "laser" = 1.3, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1)
|
||||
|
||||
/datum/material/runite
|
||||
@@ -154,6 +164,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
strength_modifier = 1.3
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/runite
|
||||
beauty_modifier = 0.5
|
||||
armor_modifiers = list("melee" = 1.35, "bullet" = 2, "laser" = 0.5, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 1.4, "acid" = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle.
|
||||
|
||||
///Force decrease
|
||||
@@ -165,6 +176,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
strength_modifier = 0.85
|
||||
sheet_type = /obj/item/stack/sheet/plastic
|
||||
value_per_unit = 0.0125
|
||||
beauty_modifier = -0.01
|
||||
armor_modifiers = list("melee" = 1.5, "bullet" = 1.1, "laser" = 0.3, "energy" = 0.5, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1.1, "acid" = 1)
|
||||
|
||||
///Force decrease and mushy sound effect. (Not yet implemented)
|
||||
@@ -176,6 +188,30 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
strength_modifier = 0.8
|
||||
value_per_unit = 0.025
|
||||
|
||||
/datum/material/wood
|
||||
name = "wood"
|
||||
id = "wood"
|
||||
desc = "Flexible, durable, but flamable. Hard to come across in space."
|
||||
color = "#bb8e53"
|
||||
strength_modifier = 0.5
|
||||
sheet_type = /obj/item/stack/sheet/mineral/wood
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
value_per_unit = 0.06
|
||||
beauty_modifier = 0.1
|
||||
armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 0.4, "energy" = 0.4, "bomb" = 1, "bio" = 0.2, "rad" = 0, "fire" = 0, "acid" = 0.3)
|
||||
|
||||
/datum/material/wood/on_applied_obj(obj/source, amount, material_flags)
|
||||
. = ..()
|
||||
if(material_flags & MATERIAL_AFFECT_STATISTICS)
|
||||
var/obj/wooden = source
|
||||
wooden.resistance_flags |= FLAMMABLE
|
||||
|
||||
/datum/material/wood/on_removed_obj(obj/source, material_flags)
|
||||
. = ..()
|
||||
if(material_flags & MATERIAL_AFFECT_STATISTICS)
|
||||
var/obj/wooden = source
|
||||
wooden.resistance_flags &= ~FLAMMABLE
|
||||
|
||||
///Stronk force increase
|
||||
/datum/material/adamantine
|
||||
name = "adamantine"
|
||||
@@ -186,6 +222,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/adamantine
|
||||
value_per_unit = 0.25
|
||||
beauty_modifier = 0.4
|
||||
armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1)
|
||||
|
||||
///RPG Magic. (Admin only)
|
||||
@@ -197,6 +234,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
|
||||
categories = list(MAT_CATEGORY_RIGID = TRUE)
|
||||
sheet_type = /obj/item/stack/sheet/mineral/mythril
|
||||
value_per_unit = 0.75
|
||||
beauty_modifier = 0.5
|
||||
armor_modifiers = list("melee" = 2, "bullet" = 2, "laser" = 2, "energy" = 2, "bomb" = 2, "bio" = 2, "rad" = 2, "fire" = 2, "acid" = 2)
|
||||
|
||||
/datum/material/mythril/on_applied_obj(atom/source, amount, material_flags)
|
||||
|
||||
@@ -97,9 +97,6 @@
|
||||
if(current) // remove ourself from our old body's mind variable
|
||||
current.mind = null
|
||||
SStgui.on_transfer(current, new_character)
|
||||
if(iscarbon(current))
|
||||
var/mob/living/carbon/C = current
|
||||
C.disable_intentional_combat_mode(TRUE)
|
||||
|
||||
if(key)
|
||||
if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
|
||||
|
||||
@@ -153,7 +153,13 @@
|
||||
mood_change = -4
|
||||
timeout = 2400
|
||||
|
||||
/datum/mood_event/graverobbing
|
||||
description ="<span class='boldwarning'>I just desecrated someone's grave... I can't believe I did that...</span>\n"
|
||||
mood_change = -8
|
||||
timeout = 3 MINUTES
|
||||
|
||||
//These are unused so far but I want to remember them to use them later
|
||||
|
||||
/datum/mood_event/cloned_corpse
|
||||
description = "<span class='boldwarning'>I recently saw my own corpse...</span>\n"
|
||||
mood_change = -6
|
||||
@@ -162,6 +168,8 @@
|
||||
description = "<span class='boldwarning'>HE'S CUTTING ME OPEN!!</span>\n"
|
||||
mood_change = -8
|
||||
|
||||
//End unused
|
||||
|
||||
/datum/mood_event/sad_empath
|
||||
description = "<span class='warning'>Someone seems upset...</span>\n"
|
||||
mood_change = -2
|
||||
@@ -199,6 +207,8 @@
|
||||
mood_change = -2
|
||||
timeout = 1 MINUTES
|
||||
|
||||
//Cursed stuff end.
|
||||
|
||||
/datum/mood_event/vampcandle
|
||||
description = "<span class='umbra'>Something is making your mind feel... loose...</span>\n"
|
||||
mood_change = -15
|
||||
|
||||
@@ -189,6 +189,12 @@
|
||||
x += mpx * (multiplier)
|
||||
y += mpy * (multiplier)
|
||||
|
||||
/datum/point/vector/proc/pixel_increment(pixels = 32, update_iteration = TRUE, realistic_iteration = FALSE)
|
||||
if(update_iteration)
|
||||
iteration += realistic_iteration? round(pixels / speed) : 1
|
||||
x += sin(angle) * pixels
|
||||
y += cos(angle) * pixels
|
||||
|
||||
/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
|
||||
var/datum/point/vector/v = copy_to()
|
||||
if(force_simulate)
|
||||
|
||||
@@ -250,4 +250,12 @@
|
||||
cost = 5
|
||||
placement_weight = 3
|
||||
always_place = TRUE
|
||||
allow_duplicates = TRUE
|
||||
allow_duplicates = TRUE
|
||||
|
||||
/datum/map_template/ruin/lavaland/elephant_graveyard
|
||||
name = "Elephant Graveyard"
|
||||
id = "Graveyard"
|
||||
description = "An abandoned graveyard, calling to those unable to continue."
|
||||
suffix = "lavaland_surface_elephant_graveyard.dmm"
|
||||
allow_duplicates = FALSE
|
||||
cost = 10
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
all_mods[id] = list(
|
||||
name = M.name,
|
||||
desc = M.desc,
|
||||
icon = assets.icon_class_name(M.icon)
|
||||
icon = assets.icon_class_name(M.icon_name)
|
||||
)
|
||||
|
||||
.["categories"] = list()
|
||||
|
||||
@@ -27,7 +27,7 @@ GLOBAL_LIST_EMPTY(potential_mods_per_skill)
|
||||
/// Priority of this skill modifier compared to other ones.
|
||||
var/priority = MODIFIER_SKILL_PRIORITY_DEF
|
||||
/// Skill modifier icon, used in the UI
|
||||
var/icon = "default"
|
||||
var/icon_name = "default_mod"
|
||||
|
||||
/datum/skill_modifier/New(id, register = FALSE)
|
||||
identifier = GET_SKILL_MOD_ID(type, id)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/datum/tgs_event_handler/impl
|
||||
var/datum/timedevent/reattach_timer
|
||||
|
||||
/datum/tgs_event_handler/impl/HandleEvent(event_code, ...)
|
||||
switch(event_code)
|
||||
if(TGS_EVENT_REBOOT_MODE_CHANGE)
|
||||
@@ -18,3 +21,19 @@
|
||||
if(TGS_EVENT_DEPLOYMENT_COMPLETE)
|
||||
message_admins("TGS: Deployment complete!")
|
||||
to_chat(world, "<span class='boldannounce'>Server updated, changes will be applied on the next round...</span>")
|
||||
if(TGS_EVENT_WATCHDOG_DETACH)
|
||||
message_admins("TGS restarting...")
|
||||
reattach_timer = addtimer(CALLBACK(src, .proc/LateOnReattach), 1 MINUTES)
|
||||
if(TGS_EVENT_WATCHDOG_REATTACH)
|
||||
var/datum/tgs_version/old_version = world.TgsVersion()
|
||||
var/datum/tgs_version/new_version = args[2]
|
||||
if(!old_version.Equals(new_version))
|
||||
to_chat(world, "<span class='boldannounce'>TGS updated to v[old_version.deprefixed_parameter]</span>")
|
||||
else
|
||||
message_admins("TGS: Back online")
|
||||
if(reattach_timer)
|
||||
deltimer(reattach_timer)
|
||||
reattach_timer = null
|
||||
|
||||
/datum/tgs_event_handler/impl/proc/LateOnReattach()
|
||||
message_admins("Warning: TGS hasn't notified us of it coming back for a full minute! Is there a problem?")
|
||||
|
||||
@@ -10,6 +10,15 @@
|
||||
lose_text = "<span class='notice'>You can taste again!</span>"
|
||||
medical_record_text = "Patient suffers from ageusia and is incapable of tasting food or reagents."
|
||||
|
||||
/datum/quirk/snob
|
||||
name = "Snob"
|
||||
desc = "You care about the finer things, if a room doesn't look nice its just not really worth it, is it?"
|
||||
value = 0
|
||||
gain_text = "<span class='notice'>You feel like you understand what things should look like.</span>"
|
||||
lose_text = "<span class='notice'>Well who cares about deco anyways?</span>"
|
||||
medical_record_text = "Patient seems to be rather stuck up."
|
||||
mob_trait = TRAIT_SNOB
|
||||
|
||||
/datum/quirk/pineapple_liker
|
||||
name = "Ananas Affinity"
|
||||
desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
if(A.attachable)
|
||||
return TRUE
|
||||
|
||||
/atom
|
||||
var/datum/wires/wires = null
|
||||
|
||||
/atom/proc/attempt_wire_interaction(mob/user)
|
||||
if(!wires)
|
||||
return WIRE_INTERACTION_FAIL
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
if(WIRE_POWER1, WIRE_POWER2) // Short for a long while.
|
||||
if(!A.shorted)
|
||||
A.shorted = TRUE
|
||||
A.update()
|
||||
addtimer(CALLBACK(A, /obj/machinery/power/apc.proc/reset, wire), 1200)
|
||||
if(WIRE_IDSCAN) // Unlock for a little while.
|
||||
A.locked = FALSE
|
||||
@@ -49,6 +50,7 @@
|
||||
else
|
||||
A.shorted = TRUE
|
||||
A.shock(usr, 50)
|
||||
A.update()
|
||||
if(WIRE_AI) // Disable AI control.
|
||||
if(mend)
|
||||
A.aidisabled = FALSE
|
||||
|
||||
+16
-1
@@ -38,6 +38,10 @@
|
||||
var/poweralm = TRUE
|
||||
var/lightswitch = TRUE
|
||||
|
||||
var/totalbeauty = 0 //All beauty in this area combined, only includes indoor area.
|
||||
var/beauty = 0 // Beauty average per open turf in the area
|
||||
var/beauty_threshold = 150 //If a room is too big it doesn't have beauty.
|
||||
|
||||
var/requires_power = TRUE
|
||||
/// This gets overridden to 1 for space in area/Initialize().
|
||||
var/always_unpowered = FALSE
|
||||
@@ -65,7 +69,7 @@
|
||||
/// Hides area from player Teleport function.
|
||||
var/hidden = FALSE
|
||||
/// Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
|
||||
var/safe = FALSE
|
||||
var/safe = FALSE
|
||||
/// If false, loading multiple maps with this area type will create multiple instances.
|
||||
var/unique = TRUE
|
||||
|
||||
@@ -192,6 +196,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
/area/LateInitialize()
|
||||
if(!base_area) //we don't want to run it twice.
|
||||
power_change() // all machines set to current power level, also updates icon
|
||||
update_beauty()
|
||||
|
||||
/area/proc/reg_in_areas_in_z()
|
||||
if(contents.len)
|
||||
@@ -538,6 +543,16 @@ GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
L.client.played = TRUE
|
||||
addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600)
|
||||
|
||||
///Divides total beauty in the room by roomsize to allow us to get an average beauty per tile.
|
||||
/area/proc/update_beauty()
|
||||
if(!areasize)
|
||||
beauty = 0
|
||||
return FALSE
|
||||
if(areasize >= beauty_threshold)
|
||||
beauty = 0
|
||||
return FALSE //Too big
|
||||
beauty = totalbeauty / areasize
|
||||
|
||||
/area/Exited(atom/movable/M)
|
||||
SEND_SIGNAL(src, COMSIG_AREA_EXITED, M)
|
||||
SEND_SIGNAL(M, COMSIG_EXIT_AREA, src) //The atom that exits the area
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
/area/centcom/vip
|
||||
name = "VIP Zone"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
/area/centcom/winterball
|
||||
|
||||
/area/centcom/winterball
|
||||
name = "winterball Zone"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
/area/ruin/powered/seedvault
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/unpowered/elephant_graveyard
|
||||
name = "Elephant Graveyard"
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
/area/ruin/powered/graveyard_shuttle
|
||||
name = "Elephant Graveyard"
|
||||
icon_state = "green"
|
||||
|
||||
/area/ruin/unpowered/syndicate_lava_base
|
||||
name = "Secret Base"
|
||||
icon_state = "dk_yellow"
|
||||
|
||||
+5
-2
@@ -47,6 +47,8 @@
|
||||
///Modifier that raises/lowers the effect of the amount of a material, prevents small and easy to get items from being death machines.
|
||||
var/material_modifier = 1
|
||||
|
||||
var/datum/wires/wires = null
|
||||
|
||||
var/icon/blood_splatter_icon
|
||||
var/list/fingerprints
|
||||
var/list/fingerprintshidden
|
||||
@@ -313,10 +315,11 @@
|
||||
. += desc
|
||||
|
||||
if(custom_materials)
|
||||
var/list/materials_list = list()
|
||||
for(var/i in custom_materials)
|
||||
var/datum/material/M = i
|
||||
. += "<u>It is made out of [M.name]</u>."
|
||||
|
||||
materials_list += "[M.name]"
|
||||
. += "<u>It is made out of [english_list(materials_list)]</u>."
|
||||
if(reagents)
|
||||
if(reagents.reagents_holder_flags & TRANSPARENT)
|
||||
. += "It contains:"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
targetitem = /obj/item/gun/energy/e_gun/hos
|
||||
difficulty = 10
|
||||
excludefromjob = list("Head Of Security")
|
||||
altitems = list(/obj/item/gun/ballistic/revolver/mws)
|
||||
|
||||
/datum/objective_item/steal/handtele
|
||||
name = "a hand teleporter."
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
GLOBAL_VAR_INIT(hsboxspawn, TRUE)
|
||||
|
||||
/mob
|
||||
var/datum/hSB/sandbox = null
|
||||
|
||||
/mob/proc/CanBuild()
|
||||
sandbox = new/datum/hSB
|
||||
sandbox.owner = src.ckey
|
||||
|
||||
@@ -434,3 +434,45 @@
|
||||
|
||||
/obj/machinery/sleeper/old
|
||||
icon_state = "oldpod"
|
||||
|
||||
/obj/machinery/sleeper/party
|
||||
name = "party pod"
|
||||
desc = "'Sleeper' units were once known for their healing properties, until a lengthy investigation revealed they were also dosing patients with deadly lead acetate. This appears to be one of those old 'sleeper' units repurposed as a 'Party Pod'. It’s probably not a good idea to use it."
|
||||
icon_state = "partypod"
|
||||
idle_power_usage = 3000
|
||||
circuit = /obj/item/circuitboard/machine/sleeper/party
|
||||
var/leddit = FALSE //Get it like reddit and lead alright fine
|
||||
ui_x = 310
|
||||
ui_y = 400
|
||||
|
||||
controls_inside = TRUE
|
||||
possible_chems = list(
|
||||
list(/datum/reagent/consumable/ethanol/beer, /datum/reagent/consumable/laughter),
|
||||
list(/datum/reagent/spraytan,/datum/reagent/barbers_aid),
|
||||
list(/datum/reagent/colorful_reagent,/datum/reagent/hair_dye),
|
||||
list(/datum/reagent/drug/space_drugs,/datum/reagent/baldium)
|
||||
)//Exclusively uses non-lethal, "fun" chems. At an obvious downside.
|
||||
var/spray_chems = list(
|
||||
/datum/reagent/spraytan, /datum/reagent/hair_dye, /datum/reagent/baldium, /datum/reagent/barbers_aid
|
||||
)//Chemicals that need to have a touch or vapor reaction to be applied, not the standard chamber reaction.
|
||||
enter_message = "<span class='notice'><b>You're surrounded by some funky music inside the chamber. You zone out as you feel waves of krunk vibe within you.</b></span>"
|
||||
|
||||
/obj/machinery/sleeper/party/inject_chem(chem, mob/user)
|
||||
if(leddit)
|
||||
occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, 4) //You're injecting chemicals into yourself from a recalled, decrepit medical machine. What did you expect?
|
||||
else if (prob(20))
|
||||
occupant.reagents.add_reagent(/datum/reagent/toxin/leadacetate, rand(1,3))
|
||||
if(chem in spray_chems)
|
||||
var/datum/reagents/holder = new()
|
||||
holder.add_reagent(chem_buttons[chem], 10) //I hope this is the correct way to do this.
|
||||
holder.reaction(occupant, VAPOR, 0)
|
||||
holder.trans_to(occupant, 10)
|
||||
playsound(src.loc, 'sound/effects/spray2.ogg', 50, TRUE, -6)
|
||||
if(user)
|
||||
log_combat(user, occupant, "sprayed [chem] into", addition = "via [src]")
|
||||
return TRUE
|
||||
..()
|
||||
|
||||
/obj/machinery/sleeper/party/emag_act(mob/user)
|
||||
..()
|
||||
leddit = TRUE
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
/datum/material/runite,
|
||||
/datum/material/plastic,
|
||||
/datum/material/adamantine,
|
||||
/datum/material/mythril
|
||||
/datum/material/mythril,
|
||||
/datum/material/wood
|
||||
)
|
||||
|
||||
/// Base print speed
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
desc = "A remote control switch."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "doorctrl"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
var/skin = "doorctrl"
|
||||
power_channel = ENVIRON
|
||||
var/obj/item/assembly/device
|
||||
@@ -17,10 +16,13 @@
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/machinery/button/Initialize(mapload, ndir = 0, built = 0)
|
||||
if(istext(id) && mapload)
|
||||
if(id[1] == "!")
|
||||
id = SSmapping.get_obfuscated_id(id)
|
||||
if(istext(id) && mapload && id[1] == "!")
|
||||
id = SSmapping.get_obfuscated_id(id)
|
||||
. = ..()
|
||||
var/turf/T = get_turf_pixel(src)
|
||||
if(iswallturf(T))
|
||||
plane = ABOVE_WALL_PLANE
|
||||
|
||||
if(built)
|
||||
setDir(ndir)
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
@@ -28,7 +30,6 @@
|
||||
panel_open = TRUE
|
||||
update_icon()
|
||||
|
||||
|
||||
if(!built && !device && device_type)
|
||||
device = new device_type(src)
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
// UPGRADE PROCS
|
||||
|
||||
/obj/machinery/camera/proc/upgradeEmpProof()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS)
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS)
|
||||
assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/plasma(assembly))
|
||||
upgrades |= CAMERA_UPGRADE_EMP_PROOF
|
||||
|
||||
|
||||
@@ -169,13 +169,18 @@
|
||||
desc = "Used for watching an empty arena."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "telescreen"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
network = list("thunder")
|
||||
density = FALSE
|
||||
circuit = null
|
||||
clockwork = TRUE //it'd look very weird
|
||||
light_power = 0
|
||||
|
||||
/obj/machinery/computer/security/telescreen/Initialize()
|
||||
. = ..()
|
||||
var/turf/T = get_turf_pixel(src)
|
||||
if(iswallturf(T))
|
||||
plane = ABOVE_WALL_PLANE
|
||||
|
||||
/obj/machinery/computer/security/telescreen/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
if(stat & BROKEN)
|
||||
|
||||
@@ -70,14 +70,13 @@
|
||||
if(W.amount < 5)
|
||||
to_chat(user, "<span class='warning'>You need at least five wooden planks to make a wall!</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You start adding [I] to [src]...</span>")
|
||||
if(do_after(user, 50, target=src))
|
||||
W.use(5)
|
||||
var/turf/T = get_turf(src)
|
||||
T.PlaceOnTop(/turf/closed/wall/mineral/wood/nonmetal)
|
||||
qdel(src)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start adding [I] to [src]...</span>")
|
||||
if(do_after(user, 50, target=src))
|
||||
W.use(5)
|
||||
var/turf/T = get_turf(src)
|
||||
T.PlaceOnTop(/turf/closed/wall/mineral/wood/nonmetal)
|
||||
qdel(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
@@ -470,15 +470,15 @@
|
||||
if(welded)
|
||||
weld_overlay = get_airlock_overlay("welded", overlays_file)
|
||||
if(obj_integrity < integrity_failure * max_integrity)
|
||||
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
else if(obj_integrity < (0.75 * max_integrity))
|
||||
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(lights && hasPower())
|
||||
|
||||
if(locked)
|
||||
lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
else if(emergency)
|
||||
lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(note)
|
||||
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
|
||||
|
||||
@@ -496,18 +496,18 @@
|
||||
else
|
||||
panel_overlay = get_airlock_overlay("panel_closed", overlays_file)
|
||||
if(obj_integrity < integrity_failure * max_integrity)
|
||||
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
else if(obj_integrity < (0.75 * max_integrity))
|
||||
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(welded)
|
||||
weld_overlay = get_airlock_overlay("welded", overlays_file)
|
||||
lights_overlay = get_airlock_overlay("lights_denied", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
lights_overlay = get_airlock_overlay("lights_denied", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(note)
|
||||
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
|
||||
|
||||
if(AIRLOCK_EMAG)
|
||||
frame_overlay = get_airlock_overlay("closed", icon)
|
||||
sparks_overlay = get_airlock_overlay("sparks", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
sparks_overlay = get_airlock_overlay("sparks", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(airlock_material)
|
||||
filling_overlay = get_airlock_overlay("[airlock_material]_closed", overlays_file)
|
||||
else
|
||||
@@ -518,9 +518,9 @@
|
||||
else
|
||||
panel_overlay = get_airlock_overlay("panel_closed", overlays_file)
|
||||
if(obj_integrity < integrity_failure * max_integrity)
|
||||
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
else if(obj_integrity < (0.75 * max_integrity))
|
||||
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(welded)
|
||||
weld_overlay = get_airlock_overlay("welded", overlays_file)
|
||||
if(note)
|
||||
@@ -533,7 +533,7 @@
|
||||
else
|
||||
filling_overlay = get_airlock_overlay("fill_closing", icon)
|
||||
if(lights && hasPower())
|
||||
lights_overlay = get_airlock_overlay("lights_closing", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
lights_overlay = get_airlock_overlay("lights_closing", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(panel_open)
|
||||
if(security_level)
|
||||
panel_overlay = get_airlock_overlay("panel_closing_protected", overlays_file)
|
||||
@@ -554,7 +554,7 @@
|
||||
else
|
||||
panel_overlay = get_airlock_overlay("panel_open", overlays_file)
|
||||
if(obj_integrity < (0.75 * max_integrity))
|
||||
damag_overlay = get_airlock_overlay("sparks_open", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
damag_overlay = get_airlock_overlay("sparks_open", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(note)
|
||||
note_overlay = get_airlock_overlay("[notetype]_open", note_overlay_file)
|
||||
|
||||
@@ -565,7 +565,7 @@
|
||||
else
|
||||
filling_overlay = get_airlock_overlay("fill_opening", icon)
|
||||
if(lights && hasPower())
|
||||
lights_overlay = get_airlock_overlay("lights_opening", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
|
||||
lights_overlay = get_airlock_overlay("lights_opening", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
|
||||
if(panel_open)
|
||||
if(security_level)
|
||||
panel_overlay = get_airlock_overlay("panel_opening_protected", overlays_file)
|
||||
@@ -577,11 +577,17 @@
|
||||
cut_overlays()
|
||||
add_overlay(frame_overlay)
|
||||
add_overlay(filling_overlay)
|
||||
add_overlay(lights_overlay)
|
||||
if(lights_overlay)
|
||||
add_overlay(lights_overlay)
|
||||
var/mutable_appearance/lights_vis = mutable_appearance(lights_overlay.icon, lights_overlay.icon_state)
|
||||
add_overlay(lights_vis)
|
||||
add_overlay(panel_overlay)
|
||||
add_overlay(weld_overlay)
|
||||
add_overlay(sparks_overlay)
|
||||
add_overlay(damag_overlay)
|
||||
if(damag_overlay)
|
||||
add_overlay(damag_overlay)
|
||||
var/mutable_appearance/damage_vis = mutable_appearance(damag_overlay.icon, damag_overlay.icon_state)
|
||||
add_overlay(damage_vis)
|
||||
add_overlay(note_overlay)
|
||||
check_unres()
|
||||
|
||||
|
||||
@@ -53,7 +53,9 @@
|
||||
if("opening")
|
||||
rad_insulation = 1
|
||||
if("closing")
|
||||
rad_insulation = 0.2
|
||||
rad_insulation = -0.5
|
||||
|
||||
// A 3x3 N2 SM setup won't irradiate you if you're behind the shutter at -0.9 insulation. If it starts to delam, it'll start irradiating you slowly. Keep the value between -0.1 to -0.9
|
||||
|
||||
/obj/machinery/door/poddoor/shutters/window
|
||||
name = "windowed shutters"
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
/obj/machinery/hypnochair
|
||||
name = "enhanced interrogation chamber"
|
||||
desc = "A device used to perform \"enhanced interrogation\" through invasive mental conditioning."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "hypnochair"
|
||||
circuit = /obj/item/circuitboard/machine/hypnochair
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
ui_x = 375
|
||||
ui_y = 480
|
||||
var/mob/living/carbon/victim = null ///Keeps track of the victim to apply effects if it teleports away
|
||||
var/interrogating = FALSE ///Is the device currently interrogating someone?
|
||||
var/start_time = 0 ///Time when the interrogation was started, to calculate effect in case of interruption
|
||||
var/trigger_phrase = "" ///Trigger phrase to implant
|
||||
var/timerid = 0 ///Timer ID for interrogations
|
||||
|
||||
var/message_cooldown = 0 ///Cooldown for breakout message
|
||||
|
||||
/obj/machinery/hypnochair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/hypnochair/attackby(obj/item/I, mob/user, params)
|
||||
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(default_pry_open(I))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/hypnochair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "hypnochair", name, ui_x, ui_y, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/hypnochair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? TRUE : FALSE
|
||||
data["open"] = state_open
|
||||
data["interrogating"] = interrogating
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["trigger"] = trigger_phrase
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/hypnochair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
if(!interrogating)
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("set_phrase")
|
||||
set_phrase(params["phrase"])
|
||||
. = TRUE
|
||||
if("interrogate")
|
||||
if(!interrogating)
|
||||
interrogate()
|
||||
else
|
||||
interrupt_interrogation()
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/hypnochair/proc/set_phrase(phrase)
|
||||
trigger_phrase = phrase
|
||||
|
||||
/obj/machinery/hypnochair/proc/interrogate()
|
||||
if(!trigger_phrase)
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE)
|
||||
return
|
||||
var/mob/living/carbon/C = occupant
|
||||
if(!istype(C))
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, TRUE)
|
||||
return
|
||||
victim = C
|
||||
if(!(C.get_eye_protection() > 0))
|
||||
to_chat(C, "<span class='warning'>Strobing coloured lights assault you relentlessly! You're losing your ability to think straight!</span>")
|
||||
C.become_blind("hypnochair")
|
||||
ADD_TRAIT(C, TRAIT_DEAF, "hypnochair")
|
||||
interrogating = TRUE
|
||||
START_PROCESSING(SSobj, src)
|
||||
start_time = world.time
|
||||
update_icon()
|
||||
timerid = addtimer(CALLBACK(src, .proc/finish_interrogation), 450, TIMER_STOPPABLE)
|
||||
|
||||
/obj/machinery/hypnochair/process()
|
||||
var/mob/living/carbon/C = occupant
|
||||
if(!istype(C) || C != victim)
|
||||
interrupt_interrogation()
|
||||
return
|
||||
if(prob(10) && !(C.get_eye_protection() > 0))
|
||||
to_chat(C, "<span class='hypnophrase'>[pick(\
|
||||
"...blue... red... green... blue, red, green, blueredgreen<span class='small'>blueredgreen</span>",\
|
||||
"...pretty colors...",\
|
||||
"...you keep hearing words, but you can't seem to understand them...",\
|
||||
"...so peaceful...",\
|
||||
"...an annoying buzz in your ears..."\
|
||||
)]</span>")
|
||||
|
||||
/obj/machinery/hypnochair/proc/finish_interrogation()
|
||||
interrogating = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
var/temp_trigger = trigger_phrase
|
||||
trigger_phrase = "" //Erase evidence, in case the subject is able to look at the panel afterwards
|
||||
audible_message("<span class='notice'>[src] pings!</span>")
|
||||
playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
|
||||
|
||||
if(QDELETED(victim) || victim != occupant)
|
||||
victim = null
|
||||
return
|
||||
victim.cure_blind("hypnochair")
|
||||
REMOVE_TRAIT(victim, TRAIT_DEAF, "hypnochair")
|
||||
if(!(victim.get_eye_protection() > 0))
|
||||
victim.cure_trauma_type(/datum/brain_trauma/severe/hypnotic_trigger, TRAUMA_RESILIENCE_SURGERY)
|
||||
if(prob(90))
|
||||
victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_trigger(temp_trigger), TRAUMA_RESILIENCE_SURGERY)
|
||||
else
|
||||
victim.gain_trauma(new /datum/brain_trauma/severe/hypnotic_stupor(), TRAUMA_RESILIENCE_SURGERY)
|
||||
victim = null
|
||||
|
||||
/obj/machinery/hypnochair/proc/interrupt_interrogation()
|
||||
deltimer(timerid)
|
||||
interrogating = FALSE
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
if(QDELETED(victim))
|
||||
victim = null
|
||||
return
|
||||
victim.cure_blind("hypnochair")
|
||||
REMOVE_TRAIT(victim, TRAIT_DEAF, "hypnochair")
|
||||
if(!(victim.get_eye_protection() > 0))
|
||||
var/time_diff = world.time - start_time
|
||||
switch(time_diff)
|
||||
if(0 to 100)
|
||||
victim.confused += 10
|
||||
victim.Dizzy(100)
|
||||
victim.blur_eyes(5)
|
||||
if(101 to 200)
|
||||
victim.confused += 15
|
||||
victim.Dizzy(200)
|
||||
victim.blur_eyes(10)
|
||||
if(prob(25))
|
||||
victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE)
|
||||
if(201 to INFINITY)
|
||||
victim.confused += 20
|
||||
victim.Dizzy(300)
|
||||
victim.blur_eyes(15)
|
||||
if(prob(65))
|
||||
victim.apply_status_effect(/datum/status_effect/trance, rand(50,150), FALSE)
|
||||
victim = null
|
||||
|
||||
/obj/machinery/hypnochair/update_icon_state()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
if(interrogating)
|
||||
icon_state += "_active"
|
||||
else
|
||||
icon_state += "_occupied"
|
||||
|
||||
/obj/machinery/hypnochair/container_resist(mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)</span>", \
|
||||
"<span class='hear'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(600), target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/hypnochair/relaymove(mob/user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/hypnochair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(!(L.mobility_flags & MOBILITY_STAND))
|
||||
return
|
||||
close_machine(target)
|
||||
@@ -679,7 +679,7 @@
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/energy
|
||||
icon_state = "standard_stun"
|
||||
@@ -788,7 +788,7 @@
|
||||
|
||||
/obj/machinery/porta_turret/centcom_shuttle/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
AddElement(/datum/element/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
|
||||
|
||||
/obj/machinery/porta_turret/centcom_shuttle/assess_perp(mob/living/carbon/human/perp)
|
||||
return 0
|
||||
|
||||
Executable → Regular
+25
@@ -17,6 +17,8 @@
|
||||
/obj/item/melee/baton,
|
||||
/obj/item/ammo_box/magazine/recharge,
|
||||
/obj/item/modular_computer,
|
||||
/obj/item/ammo_casing/mws_batt,
|
||||
/obj/item/ammo_box/magazine/mws_mag,
|
||||
/obj/item/twohanded/electrostaff,
|
||||
/obj/item/gun/ballistic/automatic/magrifle))
|
||||
|
||||
@@ -143,6 +145,29 @@
|
||||
using_power = TRUE
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(istype(charging, /obj/item/ammo_casing/mws_batt))
|
||||
var/obj/item/ammo_casing/mws_batt/R = charging
|
||||
if(R.cell.charge < R.cell.maxcharge)
|
||||
R.cell.give(R.cell.chargerate * recharge_coeff)
|
||||
use_power(250 * recharge_coeff)
|
||||
using_power = 1
|
||||
if(R.BB == null)
|
||||
R.chargeshot()
|
||||
update_icon(using_power)
|
||||
|
||||
if(istype(charging, /obj/item/ammo_box/magazine/mws_mag))
|
||||
var/obj/item/ammo_box/magazine/mws_mag/R = charging
|
||||
for(var/B in R.stored_ammo)
|
||||
var/obj/item/ammo_casing/mws_batt/batt = B
|
||||
if(batt.cell.charge < batt.cell.maxcharge)
|
||||
batt.cell.give(batt.cell.chargerate * recharge_coeff)
|
||||
use_power(250 * recharge_coeff)
|
||||
using_power = 1
|
||||
if(batt.BB == null)
|
||||
batt.chargeshot()
|
||||
update_icon(using_power)
|
||||
|
||||
else
|
||||
return PROCESS_KILL
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
icon = 'icons/obj/contraband.dmi'
|
||||
plane = ABOVE_WALL_PLANE
|
||||
anchored = TRUE
|
||||
buildable_sign = FALSE //Cannot be unwrenched from a wall.
|
||||
var/ruined = FALSE
|
||||
var/random_basetype
|
||||
var/never_random = FALSE // used for the 'random' subclasses.
|
||||
@@ -69,6 +70,8 @@
|
||||
name = "poster - [name]"
|
||||
desc = "A large piece of space-resistant printed paper. [desc]"
|
||||
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, 300)), 0)
|
||||
|
||||
/obj/structure/sign/poster/proc/randomise(base_type)
|
||||
var/list/poster_types = subtypesof(base_type)
|
||||
var/list/approved_types = list()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one?
|
||||
var/beauty = 0
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
|
||||
. = ..()
|
||||
@@ -26,6 +27,8 @@
|
||||
if(LAZYLEN(diseases_to_add))
|
||||
AddComponent(/datum/component/infective, diseases_to_add)
|
||||
|
||||
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, beauty)), 0)
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
|
||||
if(mergeable_decal)
|
||||
qdel(C)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
name = "xeno blood"
|
||||
desc = "It's green and acidic. It looks like... <i>blood?</i>"
|
||||
color = BLOOD_COLOR_XENO
|
||||
beauty = -250
|
||||
|
||||
/obj/effect/decal/cleanable/blood/splatter/xeno
|
||||
color = BLOOD_COLOR_XENO
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
blood_state = BLOOD_STATE_BLOOD
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
|
||||
if (C.blood_DNA)
|
||||
@@ -45,12 +46,14 @@
|
||||
icon_state = "tracks"
|
||||
desc = "They look like tracks left by wheels."
|
||||
random_icon_states = null
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
|
||||
name = "blood"
|
||||
icon_state = "ltrails_1"
|
||||
desc = "Your instincts say you shouldn't be following these."
|
||||
random_icon_states = null
|
||||
beauty = -50
|
||||
var/list/existing_dirs = list()
|
||||
|
||||
/obj/effect/decal/cleanable/trail_holder/update_icon()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "Someone should clean that up."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "shards"
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/ash
|
||||
name = "ashes"
|
||||
@@ -10,6 +11,7 @@
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "ash"
|
||||
mergeable_decal = FALSE
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/ash/Initialize()
|
||||
. = ..()
|
||||
@@ -24,6 +26,7 @@
|
||||
/obj/effect/decal/cleanable/ash/large
|
||||
name = "large pile of ashes"
|
||||
icon_state = "big_ash"
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/ash/large/Initialize()
|
||||
. = ..()
|
||||
@@ -34,6 +37,7 @@
|
||||
desc = "Back to sand."
|
||||
icon = 'icons/obj/shards.dmi'
|
||||
icon_state = "tiny"
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/glass/Initialize()
|
||||
. = ..()
|
||||
@@ -52,6 +56,7 @@
|
||||
canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/closed/wall, /obj/structure/falsewall)
|
||||
smooth = SMOOTH_FALSE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
beauty = -75
|
||||
|
||||
/obj/effect/decal/cleanable/dirt/Initialize()
|
||||
. = ..()
|
||||
@@ -72,6 +77,10 @@
|
||||
desc = "It's still good. Four second rule!"
|
||||
icon_state = "flour"
|
||||
|
||||
/obj/effect/decal/cleanable/dirt/dust
|
||||
name = "dust"
|
||||
desc = "A thin layer of dust coating the floor."
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/ecto
|
||||
name = "ectoplasmic puddle"
|
||||
desc = "You know who to call."
|
||||
@@ -80,8 +89,11 @@
|
||||
/obj/effect/decal/cleanable/greenglow
|
||||
name = "glowing goo"
|
||||
desc = "Jeez. I hope that's not for lunch."
|
||||
light_power = 1
|
||||
light_range = 1
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
icon_state = "greenglow"
|
||||
beauty = -300
|
||||
|
||||
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -97,6 +109,7 @@
|
||||
layer = WALL_OBJ_LAYER
|
||||
icon_state = "cobweb1"
|
||||
resistance_flags = FLAMMABLE
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/cobweb/cobweb2
|
||||
icon_state = "cobweb2"
|
||||
@@ -108,10 +121,12 @@
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "molten"
|
||||
mergeable_decal = FALSE
|
||||
beauty = -150
|
||||
|
||||
/obj/effect/decal/cleanable/molten_object/large
|
||||
name = "big gooey grey mass"
|
||||
icon_state = "big_molten"
|
||||
beauty = -300
|
||||
|
||||
//Vomit (sorry)
|
||||
/obj/effect/decal/cleanable/vomit
|
||||
@@ -120,6 +135,7 @@
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "vomit_1"
|
||||
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
|
||||
beauty = -150
|
||||
|
||||
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user)
|
||||
. = ..()
|
||||
@@ -152,6 +168,7 @@
|
||||
gender = NEUTER
|
||||
icon = 'icons/effects/tomatodecal.dmi'
|
||||
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/plant_smudge
|
||||
name = "plant smudge"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
blood_state = BLOOD_STATE_OIL
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
mergeable_decal = FALSE
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
|
||||
. = ..()
|
||||
@@ -50,6 +51,7 @@
|
||||
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
|
||||
blood_state = BLOOD_STATE_OIL
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
beauty = -100
|
||||
|
||||
/obj/effect/decal/cleanable/oil/Initialize()
|
||||
. = ..()
|
||||
@@ -58,6 +60,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/oil/streak
|
||||
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
|
||||
beauty = -50
|
||||
|
||||
/obj/effect/decal/cleanable/oil/slippery
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user