Merge branch 'embed-changes' of https://github.com/timothyteakettle/Citadel-Station-13 into embed-changes
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
//FLAGS BITMASK
|
||||
///This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
|
||||
#define HEAR_1 (1<<3)
|
||||
///Projectiles will use default chance-based ricochet handling on things with this.
|
||||
#define DEFAULT_RICOCHET_1 (1<<4)
|
||||
///Conducts electricity (metal etc.).
|
||||
#define CONDUCT_1 (1<<5)
|
||||
///For machines and structures that should not break into parts, eg, holodeck stuff.
|
||||
@@ -44,11 +46,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
/// Early returns mob.face_atom()
|
||||
#define BLOCK_FACE_ATOM_1 (1<<17)
|
||||
|
||||
/// If the thing can reflect light (lasers/energy)
|
||||
#define RICOCHET_SHINY (1<<0)
|
||||
/// If the thing can reflect matter (bullets/bomb shrapnel)
|
||||
#define RICOCHET_HARD (1<<1)
|
||||
|
||||
//turf-only flags
|
||||
#define NOJAUNT_1 (1<<0)
|
||||
#define UNUSED_RESERVATION_TURF_1 (1<<1)
|
||||
@@ -140,3 +137,12 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
|
||||
|
||||
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST)
|
||||
#define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
|
||||
|
||||
// melee_attack_chain() attackchain_flags
|
||||
/// The attack is from a parry counterattack.
|
||||
#define ATTACKCHAIN_PARRY_COUNTERATTACK (1<<0)
|
||||
|
||||
/// If the thing can reflect light (lasers/energy)
|
||||
#define RICOCHET_SHINY (1<<0)
|
||||
/// If the thing can reflect matter (bullets/bomb shrapnel)
|
||||
#define RICOCHET_HARD (1<<1)
|
||||
@@ -1,20 +1,3 @@
|
||||
// Flags for the obj_flags var on /obj
|
||||
|
||||
|
||||
#define EMAGGED (1<<0)
|
||||
#define IN_USE (1<<1) //If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
|
||||
#define CAN_BE_HIT (1<<2) //can this be bludgeoned by items?
|
||||
#define BEING_SHOCKED (1<<3) //Whether this thing is currently (already) being shocked by a tesla
|
||||
#define DANGEROUS_POSSESSION (1<<4) //Admin possession yes/no
|
||||
#define ON_BLUEPRINTS (1<<5) //Are we visible on the station blueprints at roundstart?
|
||||
#define UNIQUE_RENAME (1<<6) //can you customize the description/name of the thing?
|
||||
#define USES_TGUI (1<<7) //put on things that use tgui on ui_interact instead of custom/old UI.
|
||||
#define FROZEN (1<<8)
|
||||
#define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
|
||||
#define BLOCK_Z_FALL (1<<10)
|
||||
|
||||
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
|
||||
|
||||
// Flags for the item_flags var on /obj/item
|
||||
|
||||
#define BEING_REMOVED (1<<0)
|
||||
@@ -41,6 +24,10 @@
|
||||
#define NO_UNIFORM_REQUIRED (1<<11)
|
||||
///Damage when attacking people is not affected by combat mode.
|
||||
#define NO_COMBAT_MODE_FORCE_MODIFIER (1<<12)
|
||||
/// This item can be used to parry. Only a basic check used to determine if we should proceed with parry chain at all.
|
||||
#define ITEM_CAN_PARRY (1<<13)
|
||||
/// This item can be used in the directional blocking system. Only a basic check used to determine if we should proceed with directional block handling at all.
|
||||
#define ITEM_CAN_BLOCK (1<<14)
|
||||
|
||||
// Flags for the clothing_flags var on /obj/item/clothing
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Flags for the obj_flags var on /obj
|
||||
|
||||
#define EMAGGED (1<<0)
|
||||
#define IN_USE (1<<1) //If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
|
||||
#define CAN_BE_HIT (1<<2) //can this be bludgeoned by items?
|
||||
#define BEING_SHOCKED (1<<3) //Whether this thing is currently (already) being shocked by a tesla
|
||||
#define DANGEROUS_POSSESSION (1<<4) //Admin possession yes/no
|
||||
#define ON_BLUEPRINTS (1<<5) //Are we visible on the station blueprints at roundstart?
|
||||
#define UNIQUE_RENAME (1<<6) //can you customize the description/name of the thing?
|
||||
#define USES_TGUI (1<<7) //put on things that use tgui on ui_interact instead of custom/old UI.
|
||||
#define FROZEN (1<<8)
|
||||
#define SHOVABLE_ONTO (1<<9) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
|
||||
#define BLOCK_Z_FALL (1<<10)
|
||||
|
||||
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
|
||||
+20
-89
@@ -29,10 +29,11 @@
|
||||
#define EFFECT_DROWSY "drowsy"
|
||||
#define EFFECT_JITTER "jitter"
|
||||
|
||||
// mob/living/var/combat_flags variable.
|
||||
/// Default combat flags for those affected by sprinting (combat mode has been made into its own component)
|
||||
#define COMBAT_FLAGS_DEFAULT NONE
|
||||
#define COMBAT_FLAGS_DEFAULT (COMBAT_FLAG_PARRY_CAPABLE | COMBAT_FLAG_BLOCK_CAPABLE)
|
||||
/// 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)
|
||||
#define COMBAT_FLAGS_SPRINT_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED | COMBAT_FLAG_PARRY_CAPABLE | COMBAT_FLAG_BLOCK_CAPABLE)
|
||||
|
||||
/// The user wants sprint mode on
|
||||
#define COMBAT_FLAG_SPRINT_TOGGLED (1<<0)
|
||||
@@ -50,6 +51,16 @@
|
||||
#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<<7)
|
||||
/// This mob is capable of using the active parrying system.
|
||||
#define COMBAT_FLAG_PARRY_CAPABLE (1<<8)
|
||||
/// This mob is capable of using the active blocking system.
|
||||
#define COMBAT_FLAG_BLOCK_CAPABLE (1<<9)
|
||||
/// This mob is capable of unarmed parrying
|
||||
#define COMBAT_FLAG_UNARMED_PARRY (1<<10)
|
||||
/// This mob is currently actively blocking
|
||||
#define COMBAT_FLAG_ACTIVE_BLOCKING (1<<11)
|
||||
/// This mob is currently starting an active block
|
||||
#define COMBAT_FLAG_ACTIVE_BLOCK_STARTING (1<<12)
|
||||
|
||||
// Helpers for getting someone's stamcrit state. Cast to living.
|
||||
#define NOT_STAMCRIT 0
|
||||
@@ -112,18 +123,6 @@
|
||||
#define GRAB_NECK 2
|
||||
#define GRAB_KILL 3
|
||||
|
||||
/// Attack types for check_block()/run_block(). Flags, combinable.
|
||||
/// Attack was melee, whether or not armed.
|
||||
#define ATTACK_TYPE_MELEE (1<<0)
|
||||
/// Attack was with a gun or something that should count as a gun (but not if a gun shouldn't count for a gun, crazy right?)
|
||||
#define ATTACK_TYPE_PROJECTILE (1<<1)
|
||||
/// Attack was unarmed.. this usually means hand to hand combat.
|
||||
#define ATTACK_TYPE_UNARMED (1<<2)
|
||||
/// Attack was a thrown atom hitting the victim.
|
||||
#define ATTACK_TYPE_THROWN (1<<3)
|
||||
/// Attack was a bodyslam/leap/tackle. See: Xenomorph leap tackles.
|
||||
#define ATTACK_TYPE_TACKLE (1<<4)
|
||||
|
||||
//attack visual effects
|
||||
#define ATTACK_EFFECT_PUNCH "punch"
|
||||
#define ATTACK_EFFECT_KICK "kick"
|
||||
@@ -164,9 +163,8 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
/obj/item/gun)))
|
||||
|
||||
|
||||
//Combat object defines
|
||||
|
||||
//Embedded objects
|
||||
|
||||
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
|
||||
#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object)
|
||||
#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp)
|
||||
@@ -175,7 +173,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class)
|
||||
#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 150 //A Time in ticks, total removal time = (this/item.w_class)
|
||||
#define EMBEDDED_UNSAFE_REMOVAL_TIME 30 //A Time in ticks, total removal time = (this*item.w_class)
|
||||
#define EMBEDDED_JOSTLE_CHANCE 5 //Chance for embedded objects to cause pain every time they move (jostle)
|
||||
#define EMBEDDED_JOSTLE_PAIN_MULTIPLIER 1 //Coefficient of multiplication for the damage the item does while
|
||||
#define EMBEDDED_PAIN_STAM_PCT 0.0 //This percentage of all pain will be dealt as stam damage rather than brute (0-1)
|
||||
@@ -199,11 +197,14 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
#define EGUN_SELFCHARGE 1
|
||||
#define EGUN_SELFCHARGE_BORG 2
|
||||
|
||||
//suppression defines
|
||||
//Gun suppression
|
||||
#define SUPPRESSED_NONE 0
|
||||
#define SUPPRESSED_QUIET 1 ///standard suppressed
|
||||
#define SUPPRESSED_VERY 2 /// no message
|
||||
|
||||
//Nice shot bonus
|
||||
#define NICE_SHOT_RICOCHET_BONUS 10 //if the shooter has the NICE_SHOT trait and they fire a ricocheting projectile, add this to the ricochet chance and auto aim angle
|
||||
|
||||
///Time to spend without clicking on other things required for your shots to become accurate.
|
||||
#define GUN_AIMING_TIME (2 SECONDS)
|
||||
|
||||
@@ -287,74 +288,4 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
|
||||
* should the current-attack-damage be lower than the item force multiplied by this value,
|
||||
* a "inefficiently" prefix will be added to the message.
|
||||
*/
|
||||
#define INEFFICIENT_ATTACK_MSG_THRESHOLD 0.7
|
||||
|
||||
|
||||
//bullet_act() return values
|
||||
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
|
||||
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
|
||||
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
|
||||
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
|
||||
|
||||
#define NICE_SHOT_RICOCHET_BONUS 10 //if the shooter has the NICE_SHOT trait and they fire a ricocheting projectile, add this to the ricochet chance and auto aim angle
|
||||
|
||||
/// Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields.
|
||||
/// Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
#define mob_check_block(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)\
|
||||
do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/// Runs a block "sequence", effectively checking and then doing effects if necessary.
|
||||
/// Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
#define mob_run_block(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)\
|
||||
do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/// Bitflags for check_block() and run_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
|
||||
/// Attack was not blocked
|
||||
#define BLOCK_NONE NONE
|
||||
/// Attack was blocked, do not do damage. THIS FLAG MUST BE THERE FOR DAMAGE/EFFECT PREVENTION!
|
||||
#define BLOCK_SUCCESS (1<<1)
|
||||
|
||||
/// The below are for "metadata" on "how" the attack was blocked.
|
||||
|
||||
/// Attack was and should be redirected according to list argument REDIRECT_METHOD (NOTE: the SHOULD here is important, as it says "the thing blocking isn't handling the reflecting for you so do it yourself"!)
|
||||
#define BLOCK_SHOULD_REDIRECT (1<<2)
|
||||
/// Attack was redirected (whether by us or by SHOULD_REDIRECT flagging for automatic handling)
|
||||
#define BLOCK_REDIRECTED (1<<3)
|
||||
/// Attack was blocked by something like a shield.
|
||||
#define BLOCK_PHYSICAL_EXTERNAL (1<<4)
|
||||
/// Attack was blocked by something worn on you.
|
||||
#define BLOCK_PHYSICAL_INTERNAL (1<<5)
|
||||
/// Attack outright missed because the target dodged. Should usually be combined with redirection passthrough or something (see martial arts)
|
||||
#define BLOCK_TARGET_DODGED (1<<7)
|
||||
/// Meta-flag for run_block/do_run_block : By default, BLOCK_SUCCESS tells do_run_block() to assume the attack is completely blocked and not continue the block chain. If this is present, it will continue to check other items in the chain rather than stopping.
|
||||
#define BLOCK_CONTINUE_CHAIN (1<<8)
|
||||
|
||||
/// For keys in associative list/block_return as we don't want to saturate our (somewhat) limited flags.
|
||||
#define BLOCK_RETURN_REDIRECT_METHOD "REDIRECT_METHOD"
|
||||
/// Pass through victim
|
||||
#define REDIRECT_METHOD_PASSTHROUGH "passthrough"
|
||||
/// Deflect at randomish angle
|
||||
#define REDIRECT_METHOD_DEFLECT "deflect"
|
||||
/// reverse 180 angle, basically (as opposed to "realistic" wall reflections)
|
||||
#define REDIRECT_METHOD_REFLECT "reflect"
|
||||
/// "do not taser the bad man with the desword" - actually aims at the firer/attacker rather than just reversing
|
||||
#define REDIRECT_METHOD_RETURN_TO_SENDER "no_you"
|
||||
|
||||
/// These keys are generally only applied to the list if real_attack is FALSE. Used incase we want to make "smarter" mob AI in the future or something.
|
||||
/// Tells the caller how likely from 0 (none) to 100 (always) we are to reflect energy projectiles
|
||||
#define BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE "reflect_projectile_chance"
|
||||
/// Tells the caller how likely we are to block attacks from 0 to 100 in general
|
||||
#define BLOCK_RETURN_NORMAL_BLOCK_CHANCE "normal_block_chance"
|
||||
/// Tells the caller about how many hits we can soak on average before our blocking fails.
|
||||
#define BLOCK_RETURN_BLOCK_CAPACITY "block_capacity"
|
||||
|
||||
/// Default if the above isn't set in the list.
|
||||
#define DEFAULT_REDIRECT_METHOD_PROJECTILE REDIRECT_METHOD_DEFLECT
|
||||
|
||||
/// Block priorities
|
||||
#define BLOCK_PRIORITY_HELD_ITEM 100
|
||||
#define BLOCK_PRIORITY_WEAR_SUIT 75
|
||||
#define BLOCK_PRIORITY_CLOTHING 50
|
||||
#define BLOCK_PRIORITY_UNIFORM 25
|
||||
|
||||
#define BLOCK_PRIORITY_DEFAULT BLOCK_PRIORITY_HELD_ITEM
|
||||
#define FEEBLE_ATTACK_MSG_THRESHOLD 0.5
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Attack types for check_block()/run_block(). Flags, combinable.
|
||||
/// Attack was melee, whether or not armed.
|
||||
#define ATTACK_TYPE_MELEE (1<<0)
|
||||
/// Attack was with a gun or something that should count as a gun (but not if a gun shouldn't count for a gun, crazy right?)
|
||||
#define ATTACK_TYPE_PROJECTILE (1<<1)
|
||||
/// Attack was unarmed.. this usually means hand to hand combat.
|
||||
#define ATTACK_TYPE_UNARMED (1<<2)
|
||||
/// Attack was a thrown atom hitting the victim.
|
||||
#define ATTACK_TYPE_THROWN (1<<3)
|
||||
/// Attack was a bodyslam/leap/tackle. See: Xenomorph leap tackles.
|
||||
#define ATTACK_TYPE_TACKLE (1<<4)
|
||||
/// Attack was from a parry counterattack. Do not attempt to parry-this!
|
||||
#define ATTACK_TYPE_PARRY_COUNTERATTACK (1<<5)
|
||||
|
||||
// Requires for datum definitions to not error with must be a constant statement when used in lists as text associative keys.
|
||||
// KEEP IN SYNC WITH ABOVE!
|
||||
|
||||
#define TEXT_ATTACK_TYPE_MELEE "1"
|
||||
#define TEXT_ATTACK_TYPE_PROJECTILE "2"
|
||||
#define TEXT_ATTACK_TYPE_UNARMED "4"
|
||||
#define TEXT_ATTACK_TYPE_THROWN "8"
|
||||
#define TEXT_ATTACK_TYPE_TACKLE "16"
|
||||
#define TEXT_ATTACK_TYPE_PARRY_COUNTERATTACK "32"
|
||||
|
||||
GLOBAL_LIST_INIT(attack_type_names, list(
|
||||
TEXT_ATTACK_TYPE_MELEE = "Melee",
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = "Projectile",
|
||||
TEXT_ATTACK_TYPE_UNARMED = "Unarmed",
|
||||
TEXT_ATTACK_TYPE_THROWN = "Thrown",
|
||||
TEXT_ATTACK_TYPE_TACKLE = "Tackle",
|
||||
TEXT_ATTACK_TYPE_PARRY_COUNTERATTACK = "Parry Counterattack"
|
||||
))
|
||||
@@ -0,0 +1,80 @@
|
||||
/// Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields.
|
||||
/// Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
#define mob_check_block(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)\
|
||||
do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/// Runs a block "sequence", effectively checking and then doing effects if necessary.
|
||||
/// Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
#define mob_run_block(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)\
|
||||
do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
// Don't ask why there's block_parry.dm and this. This is for the run_block() system, which is the "parent" system of the directional block and parry systems.
|
||||
|
||||
/// Bitflags for check_block() and handle_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
|
||||
/// Attack was not blocked
|
||||
#define BLOCK_NONE NONE
|
||||
/// Attack was blocked, do not do damage. THIS FLAG MUST BE THERE FOR DAMAGE/EFFECT PREVENTION!
|
||||
#define BLOCK_SUCCESS (1<<1)
|
||||
|
||||
/// The below are for "metadata" on "how" the attack was blocked.
|
||||
|
||||
/// Attack was and should be redirected according to list argument REDIRECT_METHOD (NOTE: the SHOULD here is important, as it says "the thing blocking isn't handling the reflecting for you so do it yourself"!)
|
||||
#define BLOCK_SHOULD_REDIRECT (1<<2)
|
||||
/// Attack was redirected (whether by us or by SHOULD_REDIRECT flagging for automatic handling)
|
||||
#define BLOCK_REDIRECTED (1<<3)
|
||||
/// Attack was blocked by something like a shield.
|
||||
#define BLOCK_PHYSICAL_EXTERNAL (1<<4)
|
||||
/// Attack was blocked by something worn on you.
|
||||
#define BLOCK_PHYSICAL_INTERNAL (1<<5)
|
||||
/// Attack outright missed because the target dodged. Should usually be combined with redirection passthrough or something (see martial arts)
|
||||
#define BLOCK_TARGET_DODGED (1<<7)
|
||||
/// Meta-flag for run_block/do_run_block : By default, BLOCK_SUCCESS tells do_run_block() to assume the attack is completely blocked and not continue the block chain. If this is present, it will continue to check other items in the chain rather than stopping.
|
||||
#define BLOCK_CONTINUE_CHAIN (1<<8)
|
||||
/// Attack should change the amount of damage incurred. This means something calling run_block() has to handle it!
|
||||
#define BLOCK_SHOULD_CHANGE_DAMAGE (1<<9)
|
||||
/// Attack should scale by this percent, 0 for no block and 100 for full blocked
|
||||
#define BLOCK_SHOULD_PARTIAL_MITIGATE (1<<10)
|
||||
|
||||
/// For keys in associative list/block_return as we don't want to saturate our (somewhat) limited flags.
|
||||
#define BLOCK_RETURN_REDIRECT_METHOD "REDIRECT_METHOD"
|
||||
/// Pass through victim
|
||||
#define REDIRECT_METHOD_PASSTHROUGH "passthrough"
|
||||
/// Deflect at randomish angle
|
||||
#define REDIRECT_METHOD_DEFLECT "deflect"
|
||||
/// reverse 180 angle, basically (as opposed to "realistic" wall reflections)
|
||||
#define REDIRECT_METHOD_REFLECT "reflect"
|
||||
/// "do not taser the bad man with the desword" - actually aims at the firer/attacker rather than just reversing
|
||||
#define REDIRECT_METHOD_RETURN_TO_SENDER "no_you"
|
||||
|
||||
/// These keys are generally only applied to the list if real_attack is FALSE. Used incase we want to make "smarter" mob AI in the future or something.
|
||||
/// Tells the caller how likely from 0 (none) to 100 (always) we are to reflect energy projectiles
|
||||
#define BLOCK_RETURN_REFLECT_PROJECTILE_CHANCE "reflect_projectile_chance"
|
||||
/// Tells the caller how likely we are to block attacks from 0 to 100 in general
|
||||
#define BLOCK_RETURN_NORMAL_BLOCK_CHANCE "normal_block_chance"
|
||||
/// Tells the caller about how many hits we can soak on average before our blocking fails.
|
||||
#define BLOCK_RETURN_BLOCK_CAPACITY "block_capacity"
|
||||
/// Tells the caller we got blocked by active directional block.
|
||||
#define BLOCK_RETURN_ACTIVE_BLOCK "active_block"
|
||||
/// Tells the caller our damage mitigation for their attack.
|
||||
#define BLOCK_RETURN_ACTIVE_BLOCK_DAMAGE_MITIGATED "damage_mitigated"
|
||||
/// For [BLOCK_CHANGE_DAMAGE]. Set damage to this.
|
||||
#define BLOCK_RETURN_SET_DAMAGE_TO "set_damage_to"
|
||||
/// For [BLOCK_SHOULD_PARTIAL_MITIGATE]. Percentage mitigation.
|
||||
#define BLOCK_RETURN_MITIGATION_PERCENT "partial_mitigation"
|
||||
/// Used internally by run_parry proc, use on an on_active_parry() proc to override parrying efficiency.
|
||||
#define BLOCK_RETURN_OVERRIDE_PARRY_EFFICIENCY "override_parry_efficiency"
|
||||
/// Always set to 100 by run_block() if BLOCK_SUCCESS is in return value. Otherwise, defaults to mitigation percent if not set. Used by projectile/proc/on_hit().
|
||||
#define BLOCK_RETURN_PROJECTILE_BLOCK_PERCENTAGE "projectile_block_percentage"
|
||||
|
||||
/// Default if the above isn't set in the list.
|
||||
#define DEFAULT_REDIRECT_METHOD_PROJECTILE REDIRECT_METHOD_DEFLECT
|
||||
|
||||
/// Block priorities. Higher means it's checked sooner.
|
||||
// THESE MUST NEVER BE 0! Block code uses ! instead of isnull for the speed boost.
|
||||
#define BLOCK_PRIORITY_ACTIVE_BLOCK 200
|
||||
#define BLOCK_PRIORITY_HELD_ITEM 100
|
||||
#define BLOCK_PRIORITY_CLOTHING 50
|
||||
#define BLOCK_PRIORITY_WEAR_SUIT 75
|
||||
#define BLOCK_PRIORITY_UNIFORM 25
|
||||
|
||||
#define BLOCK_PRIORITY_DEFAULT BLOCK_PRIORITY_HELD_ITEM
|
||||
@@ -0,0 +1,72 @@
|
||||
// We can't determine things like NORTHEAST vs NORTH *and* EAST without making our own flags :(
|
||||
#define BLOCK_DIR_NORTH (1<<0)
|
||||
#define BLOCK_DIR_NORTHEAST (1<<1)
|
||||
#define BLOCK_DIR_NORTHWEST (1<<2)
|
||||
#define BLOCK_DIR_WEST (1<<3)
|
||||
#define BLOCK_DIR_EAST (1<<4)
|
||||
#define BLOCK_DIR_SOUTH (1<<5)
|
||||
#define BLOCK_DIR_SOUTHEAST (1<<6)
|
||||
#define BLOCK_DIR_SOUTHWEST (1<<7)
|
||||
#define BLOCK_DIR_ONTOP (1<<8)
|
||||
|
||||
GLOBAL_LIST_INIT(dir2blockdir, list(
|
||||
"[NORTH]" = BLOCK_DIR_NORTH,
|
||||
"[NORTHEAST]" = BLOCK_DIR_NORTHEAST,
|
||||
"[NORTHWEST]" = BLOCK_DIR_NORTHWEST,
|
||||
"[WEST]" = BLOCK_DIR_WEST,
|
||||
"[EAST]" = BLOCK_DIR_EAST,
|
||||
"[SOUTH]" = BLOCK_DIR_SOUTH,
|
||||
"[SOUTHEAST]" = BLOCK_DIR_SOUTHEAST,
|
||||
"[SOUTHWEST]" = BLOCK_DIR_SOUTHWEST,
|
||||
"[NONE]" = BLOCK_DIR_ONTOP
|
||||
))
|
||||
|
||||
#define DIR2BLOCKDIR(d) (GLOB.dir2blockdir["[d]"])
|
||||
|
||||
GLOBAL_LIST_INIT(block_direction_names, list(
|
||||
"[BLOCK_DIR_NORTH]" = "Front",
|
||||
"[BLOCK_DIR_NORTHEAST]" = "Front Right",
|
||||
"[BLOCK_DIR_NORTHWEST]" = "Front Left",
|
||||
"[BLOCK_DIR_WEST]" = "Left",
|
||||
"[BLOCK_DIR_EAST]" = "Right",
|
||||
"[BLOCK_DIR_SOUTH]" = "Behind",
|
||||
"[BLOCK_DIR_SOUTHEAST]" = "Behind Right",
|
||||
"[BLOCK_DIR_SOUTHWEST]" = "Behind Left",
|
||||
"[BLOCK_DIR_ONTOP]" = "Ontop"
|
||||
))
|
||||
|
||||
/// If this is the value of active_block_starting it signals we want to interrupt the start
|
||||
#define ACTIVE_BLOCK_STARTING_INTERRUPT "INTERRUPT"
|
||||
|
||||
/// ""types"" of parry "items"
|
||||
#define UNARMED_PARRY "unarmed"
|
||||
#define MARTIAL_PARRY "martial"
|
||||
#define ITEM_PARRY "item"
|
||||
|
||||
/// Parry phase we're in
|
||||
#define NOT_PARRYING 0
|
||||
#define PARRY_WINDUP 1
|
||||
#define PARRY_ACTIVE 2
|
||||
#define PARRY_SPINDOWN 3
|
||||
|
||||
// /datum/block_parry_data/var/parry_flags
|
||||
/// Default handling for audio/visual feedback
|
||||
#define PARRY_DEFAULT_HANDLE_FEEDBACK (1<<0)
|
||||
/// Lock sprinting while parrying
|
||||
#define PARRY_LOCK_SPRINTING (1<<1)
|
||||
/// Lock attacking while parrying
|
||||
#define PARRY_LOCK_ATTACKING (1<<2)
|
||||
|
||||
/// Parry effects.
|
||||
/// Automatically melee attacks back normally, LMB equivalent action of an harm intent attack. List association should be defaulting to 1, being the attack damage multiplier for said counterattack
|
||||
#define PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN "melee_counterattack_chain"
|
||||
/// List association should be TRUE.
|
||||
#define PARRY_DISARM_ATTACKER "disarm_attacker"
|
||||
/// List association should be duration or null for just plain knockdown.
|
||||
#define PARRY_KNOCKDOWN_ATTACKER "knockdown_attacker"
|
||||
/// List association should be duration.
|
||||
#define PARRY_STAGGER_ATTACKER "stagger_attacker"
|
||||
/// List association should be amount of time to daze attacker.
|
||||
#define PARRY_DAZE_ATTACKER "daze_attacker"
|
||||
/// Set to TRUE in list association to ignore adjacency checks
|
||||
#define PARRY_COUNTERATTACK_IGNORE_ADJACENCY "ignore_adjacency"
|
||||
@@ -67,7 +67,9 @@
|
||||
//tablecrafting defines
|
||||
#define CAT_NONE ""
|
||||
#define CAT_WEAPONRY "Weaponry"
|
||||
#define CAT_WEAPON "Weapons"
|
||||
#define CAT_WEAPON "Ranged Weapons"
|
||||
#define CAT_MELEE "Melee Weapons"
|
||||
#define CAT_OTHER "Misc"
|
||||
#define CAT_AMMO "Ammunition"
|
||||
#define CAT_PARTS "Weapon Parts"
|
||||
#define CAT_ROBOT "Robots"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/// Requires absolute stillness from the user
|
||||
#define DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER (1<<0)
|
||||
/// Requires absolute stillness from the target
|
||||
#define DO_AFTER_DISALLOW_MOVING_ABSOLUTE_TARGET (1<<1)
|
||||
/// Requires that the user is on a turf.
|
||||
#define DO_AFTER_REQUIRES_USER_ON_TURF (1<<2)
|
||||
/// Requires relative stillness to our target via dx and dy coordinate difference but only if both are spacedrifting. Specify DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY to say otherwise.
|
||||
#define DO_AFTER_DISALLOW_MOVING_RELATIVE (1<<3)
|
||||
/// Breaks if active hand item changes. Requires a tool be specified, otherwise defaults to active item
|
||||
#define DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE (1<<4)
|
||||
/// Breaks if the user has no free hands. If a tool is specified, allows that as well.
|
||||
#define DO_AFTER_REQUIRE_FREE_HAND_OR_TOOL (1<<5)
|
||||
/// Do not display progressbar.
|
||||
#define DO_AFTER_NO_PROGRESSBAR (1<<6)
|
||||
/// Do not check do_after_coefficient()
|
||||
#define DO_AFTER_NO_COEFFICIENT (1<<7)
|
||||
/// For relative stillness, allow non spacedrift relative movement
|
||||
#define DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY (1<<8)
|
||||
|
||||
/// Ignores checks.
|
||||
#define DO_AFTER_PROCEED "PROCEED"
|
||||
/// Uses all other checks
|
||||
#define DO_AFTER_CONTINUE "CONTINUE"
|
||||
/// Breaks
|
||||
#define DO_AFTER_STOP "STOP"
|
||||
|
||||
/// Stage - initiating a do_after
|
||||
#define DO_AFTER_STARTING 1
|
||||
/// Stage - main loop of a do_after
|
||||
#define DO_AFTER_PROGRESSING 2
|
||||
/// Stage - Last check of a do_after
|
||||
#define DO_AFTER_FINISHING 3
|
||||
@@ -1,3 +1,6 @@
|
||||
/// Checks if something is a BYOND object datatype rather than a primitive, or whatever's closest to one.
|
||||
#define is_object_datatype(object) (object && !ispath(object) && !istext(object) && !isnum(object))
|
||||
|
||||
// simple is_type and similar inline helpers
|
||||
|
||||
#define in_range(source, user) (get_dist(source, user) <= 1 && (get_step(source, 0)?:z) == (get_step(user, 0)?:z))
|
||||
|
||||
@@ -8,5 +8,68 @@
|
||||
//ids
|
||||
#define MOVESPEED_ID_SANITY "mood_sanity"
|
||||
|
||||
#define MOVESPEED_ID_MOB_GRAB_STATE "mob_grab_state"
|
||||
#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN"
|
||||
#define MOVESPEED_ID_MOB_GRAB_STATE "MOB_GRAB_STATE"
|
||||
#define MOVESPEED_ID_MOB_EQUIPMENT "MOB_EQUIPMENT"
|
||||
#define MOVESPEED_ID_MOB_GRAVITY "MOB_GRAVITY"
|
||||
#define MOVESPEED_ID_CONFIG_SPEEDMOD "MOB_CONFIG_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_SLIME_REAGENTMOD "SLIME_REAGENT_MODIFIER"
|
||||
#define MOVESPEED_ID_SLIME_HEALTHMOD "SLIME_HEALTH_MODIFIER"
|
||||
#define MOVESPEED_ID_SLIME_TEMPMOD "SLIME_TEMPERATURE_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_SLIME_STATUS "SLIME_STATUS"
|
||||
|
||||
#define MOVESPEED_ID_TARANTULA_WEB "TARANTULA_WEB"
|
||||
|
||||
#define MOVESPEED_ID_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD"
|
||||
#define MOVESPEED_ID_LIVING_LIMBLESS "LIVING_LIMBLESS"
|
||||
|
||||
#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT"
|
||||
#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED"
|
||||
|
||||
#define MOVESPEED_ID_DNA_VAULT "DNA_VAULT"
|
||||
|
||||
#define MOVESPEED_ID_YELLOW_ORB "YELLOW_ORB"
|
||||
|
||||
#define MOVESPEED_ID_TARFOOT "TARFOOT"
|
||||
|
||||
#define MOVESPEED_ID_SEPIA "SEPIA"
|
||||
|
||||
#define MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD "MONKEY_REAGENT_SPEEDMOD"
|
||||
#define MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD "MONKEY_TEMPERATURE_SPEEDMOD"
|
||||
#define MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD "MONKEY_HEALTH_SPEEDMOD"
|
||||
|
||||
#define MOVESPEED_ID_CHANGELING_MUSCLES "CHANGELING_MUSCLES"
|
||||
|
||||
#define MOVESPEED_ID_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER"
|
||||
#define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_SPECIES "SPECIES_SPEED_MOD"
|
||||
|
||||
#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG"
|
||||
#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY"
|
||||
#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER"
|
||||
|
||||
#define MOVESPEED_ID_SLAUGHTER "SLAUGHTER"
|
||||
|
||||
#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER"
|
||||
#define MOVESPEED_ID_JETPACK "JETPACK"
|
||||
|
||||
#define MOVESPEED_ID_MKULTRA "MKULTRA"
|
||||
|
||||
#define MOVESPEED_ID_TASED_STATUS "TASED"
|
||||
#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF"
|
||||
|
||||
#define MOVESPEED_ID_SHOVE "SHOVE"
|
||||
#define MOVESPEED_ID_FAT "FAT"
|
||||
#define MOVESPEED_ID_COLD "COLD"
|
||||
#define MOVESPEED_ID_HUNGRY "HUNGRY"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE"
|
||||
#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING"
|
||||
|
||||
#define MOVESPEED_ID_ACTIVE_BLOCK "ACTIVE_BLOCK"
|
||||
|
||||
#define MOVESPEED_ID_MOB_WALK_RUN "mob_walk_run"
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/// This atom should be ricocheted off of from its inherent properties using standard % chance handling.
|
||||
#define PROJECTILE_RICOCHET_YES 1
|
||||
/// This atom should not be ricocheted off of from its inherent properties.
|
||||
#define PROJECTILE_RICOCHET_NO 2
|
||||
/// This atom should prevent any kind of projectile ricochet from its inherent properties.
|
||||
#define PROJECTILE_RICOCHET_PREVENT 3
|
||||
/// This atom should force a projectile ricochet from its inherent properties.
|
||||
#define PROJECTILE_RICOCHET_FORCE 4
|
||||
|
||||
//bullet_act() return values
|
||||
#define BULLET_ACT_HIT "HIT" //It's a successful hit, whatever that means in the context of the thing it's hitting.
|
||||
#define BULLET_ACT_BLOCK "BLOCK" //It's a blocked hit, whatever that means in the context of the thing it's hitting.
|
||||
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
|
||||
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
|
||||
@@ -24,7 +24,7 @@ GLOBAL_LIST_INIT(default_weight_class_to_volume, list(
|
||||
// Let's keep all of this in one place. given what we put above anyways..
|
||||
|
||||
// volume amount for items
|
||||
#define ITEM_VOLUME_DISK DEFAULT_VOLUME_TINY
|
||||
#define ITEM_VOLUME_DISK 1
|
||||
|
||||
// #define SAMPLE_VOLUME_AMOUNT 2
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using
|
||||
#define SATURDAY "Sat"
|
||||
#define SUNDAY "Sun"
|
||||
|
||||
#define WEEKDAY2NUM(D) (D == SUNDAY ? 1 : D == MONDAY ? 2 : D == TUESDAY ? 3 : D == WEDNESDAY ? 4 : D == THURSDAY ? 5 : D == FRIDAY ? 6 : 7) //this looks ugly, but switch statements can't be used as vars, so *shrug
|
||||
|
||||
#define SECONDS *10
|
||||
|
||||
#define MINUTES SECONDS*60
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
#define TRAIT_BLIND "blind"
|
||||
#define TRAIT_MUTE "mute"
|
||||
#define TRAIT_EMOTEMUTE "emotemute"
|
||||
#define TRAIT_LOOC_MUTE "looc_mute" //Just like unconsciousness, it disables LOOC salt.
|
||||
#define TRAIT_AOOC_MUTE "aooc_mute" //Same as above but for AOOC.
|
||||
#define TRAIT_DEAF "deaf"
|
||||
#define TRAIT_NEARSIGHT "nearsighted"
|
||||
#define TRAIT_FAT "fat"
|
||||
@@ -157,7 +159,6 @@
|
||||
#define TRAIT_PASSTABLE "passtable"
|
||||
#define TRAIT_GIANT "giant"
|
||||
#define TRAIT_DWARF "dwarf"
|
||||
#define TRAIT_NICE_SHOT "nice_shot" //hnnnnnnnggggg..... you're pretty good....
|
||||
#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance"
|
||||
#define TRAIT_AGEUSIA "ageusia"
|
||||
#define TRAIT_HEAVY_SLEEPER "heavy_sleeper"
|
||||
@@ -195,6 +196,7 @@
|
||||
#define TRAIT_NO_ALCOHOL "alcohol_intolerance"
|
||||
#define TRAIT_MUTATION_STASIS "mutation_stasis" //Prevents processed genetics mutations from processing.
|
||||
#define TRAIT_FAST_PUMP "fast_pump"
|
||||
#define TRAIT_NICE_SHOT "nice_shot" //hnnnnnnnggggg..... you're pretty good....
|
||||
|
||||
// mobility flag traits
|
||||
// IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it)
|
||||
@@ -255,7 +257,7 @@
|
||||
#define BOOK_TRAIT "granter (book)" // knowledge is power
|
||||
|
||||
// unique trait sources, still defines
|
||||
#define STATUE_MUTE "statue"
|
||||
#define STATUE_TRAIT "statue"
|
||||
#define CLONING_POD_TRAIT "cloning-pod"
|
||||
#define VIRTUAL_REALITY_TRAIT "vr_trait"
|
||||
#define CHANGELING_DRAIN "drain"
|
||||
@@ -296,4 +298,8 @@
|
||||
#define CLOWNOP_TRAIT "clown-op"
|
||||
#define MEGAFAUNA_TRAIT "megafauna"
|
||||
#define DEATHSQUAD_TRAIT "deathsquad"
|
||||
#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name
|
||||
/// This trait is added by the active directional block system.
|
||||
#define ACTIVE_BLOCK_TRAIT "active_block"
|
||||
/// This trait is added by the parry system.
|
||||
#define ACTIVE_PARRY_TRAIT "active_parry"
|
||||
#define STICKY_NODROP "sticky-nodrop" //sticky nodrop sounds like a bad soundcloud rapper's name
|
||||
@@ -104,7 +104,7 @@ GLOBAL_VAR_INIT(cmp_field, "name")
|
||||
var/a_sign = num2sign(initial(A.value) * -1)
|
||||
var/b_sign = num2sign(initial(B.value) * -1)
|
||||
|
||||
// Neutral traits go last.
|
||||
// Neutral traits go last
|
||||
if(a_sign == 0)
|
||||
a_sign = 2
|
||||
if(b_sign == 0)
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
/**
|
||||
* Higher overhead "advanced" version of do_after.
|
||||
* @params
|
||||
* - atom/user is the atom doing the action or the "physical" user
|
||||
* - delay is time in deciseconds
|
||||
* - atom/target is the atom the action is being done to, defaults to user
|
||||
* - do_after_flags see __DEFINES/flags/do_after.dm for details.
|
||||
* - datum/callback/extra_checks - Every time this ticks, extra_checks() is invoked with (user, delay, target, time_left, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool).
|
||||
* Stage can be DO_AFTER_STARTING, DO_AFTER_PROGRESSING, DO_AFTER_FINISHING
|
||||
* If it returns DO_AFTER_STOP, this breaks.
|
||||
* If it returns nothing, all other checks are done.
|
||||
* If it returns DO_AFTER_PROCEED, all other checks are ignored.
|
||||
* - required_mobility_flags is checked with CHECK_ALL_MOBILITY. Will immediately fail if the user isn't a mob.
|
||||
* - requried_combat_flags is checked with CHECK_MULTIPLE_BITFIELDS. Will immediately fail if the user isn't a mob.
|
||||
* - mob/living/mob_redirect - advanced option: If this is specified, movement and mobility/combat flag checks will use this instead of user. Progressbars will also go to this.
|
||||
* - obj/item/tool - The tool we're using. See do_after flags for details.
|
||||
*/
|
||||
#define INVOKE_CALLBACK cb_return = extra_checks?.Invoke(user, delay, target, world.time - starttime, do_after_flags, required_mobility_flags, required_combat_flags, mob_redirect, stage, initially_held_item, tool)
|
||||
#define CHECK_FLAG_FAILURE ((required_mobility_flags || required_combat_flags) && (!living_user || (required_mobility_flags && !CHECK_ALL_MOBILITY(living_user, required_mobility_flags)) || (required_combat_flags && !CHECK_MULTIPLE_BITFIELDS(living_user.combat_flags, required_combat_flags))))
|
||||
#define TIMELEFT (world.time - starttime)
|
||||
/proc/do_after_advanced(atom/user, delay, atom/target, do_after_flags, datum/callback/extra_checks, required_mobility_flags, required_combat_flags, mob/living/mob_redirect, obj/item/tool)
|
||||
// CHECK AND SET VARIABLES
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(!target)
|
||||
target = user
|
||||
if((user.loc == null) || (target.loc == null))
|
||||
return FALSE
|
||||
var/mob/living/living_user = mob_redirect
|
||||
if(!living_user && isliving(user))
|
||||
living_user = user
|
||||
var/stage = DO_AFTER_STARTING
|
||||
var/startlocuser = user.loc
|
||||
var/startloctarget = target.loc
|
||||
var/turf/userturf = get_turf(user)
|
||||
var/turf/targetturf = get_turf(target)
|
||||
if(!userturf || !targetturf)
|
||||
return FALSE
|
||||
if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc))
|
||||
return FALSE
|
||||
var/starttime = world.time
|
||||
var/endtime = world.time + delay
|
||||
var/obj/item/initially_held_item = mob_redirect?.get_active_held_item()
|
||||
if(!(do_after_flags & DO_AFTER_NO_COEFFICIENT) && living_user)
|
||||
delay *= living_user.do_after_coefficent()
|
||||
var/atom/movable/AM_user = ismovable(user) && user
|
||||
var/drifting = AM_user?.Process_Spacemove(NONE) && AM_user.inertia_dir
|
||||
var/initial_dx = targetturf.x - userturf.x
|
||||
var/initial_dy = targetturf.y - userturf.y
|
||||
var/dx = initial_dx
|
||||
var/dy = initial_dy
|
||||
// DO OUR STARTING CHECKS
|
||||
var/cb_return
|
||||
INVOKE_CALLBACK
|
||||
if(cb_return == DO_AFTER_STOP)
|
||||
return FALSE
|
||||
else if(cb_return != DO_AFTER_PROCEED)
|
||||
if(CHECK_FLAG_FAILURE)
|
||||
return FALSE
|
||||
// SETUP LOOP
|
||||
var/datum/progressbar/progbar
|
||||
if(living_user)
|
||||
if(!(do_after_flags & DO_AFTER_NO_PROGRESSBAR))
|
||||
progbar = new(living_user, delay, target)
|
||||
// MAIN LOOP
|
||||
. = TRUE
|
||||
if(!delay)
|
||||
return
|
||||
var/obj/item/held
|
||||
var/locchanged
|
||||
var/ctu
|
||||
var/ctt
|
||||
while(world.time < endtime)
|
||||
stoplag(1)
|
||||
progbar?.update(TIMELEFT)
|
||||
if(QDELETED(user) || QDELETED(target) || (user.loc == null) || (target.loc == null))
|
||||
. = FALSE
|
||||
break
|
||||
INVOKE_CALLBACK
|
||||
if(cb_return == DO_AFTER_STOP)
|
||||
. = FALSE
|
||||
break
|
||||
else if(cb_return == DO_AFTER_PROCEED)
|
||||
continue
|
||||
// otherwise, go through our normal checks.
|
||||
if(((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER) && (user.loc != startlocuser)) || ((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_TARGET) && (target.loc != startloctarget)))
|
||||
. = FALSE
|
||||
break
|
||||
else if(do_after_flags & DO_AFTER_DISALLOW_MOVING_RELATIVE)
|
||||
ctu = get_turf(user)
|
||||
ctt = get_turf(target)
|
||||
locchanged = (userturf != ctu) || (targetturf != ctt)
|
||||
userturf = ctu
|
||||
targetturf = ctt
|
||||
dx = targetturf.x - userturf.x
|
||||
dy = targetturf.y - userturf.y
|
||||
if((dx != initial_dx) || (dy != initial_dy))
|
||||
. = FALSE
|
||||
break
|
||||
if(locchanged && !drifting && !(do_after_flags & DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY))
|
||||
. = FALSE
|
||||
break
|
||||
if(!AM_user.inertia_dir)
|
||||
drifting = FALSE
|
||||
if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc))
|
||||
return FALSE
|
||||
if(CHECK_FLAG_FAILURE)
|
||||
. = FALSE
|
||||
break
|
||||
held = living_user?.get_active_held_item()
|
||||
if((do_after_flags & DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE) && (held != (tool || initially_held_item)))
|
||||
. = FALSE
|
||||
break
|
||||
if((do_after_flags & DO_AFTER_REQUIRE_FREE_HAND_OR_TOOL) && (!living_user?.is_holding(tool) && !length(living_user?.get_empty_held_indexes())))
|
||||
. = FALSE
|
||||
break
|
||||
|
||||
// CLEANUP
|
||||
qdel(progbar)
|
||||
// If we failed, just return.
|
||||
if(!.)
|
||||
return FALSE
|
||||
// DO FINISHING CHECKS
|
||||
if(QDELETED(user) || QDELETED(target))
|
||||
return FALSE
|
||||
INVOKE_CALLBACK
|
||||
if(cb_return == DO_AFTER_STOP)
|
||||
return FALSE
|
||||
else if(cb_return == DO_AFTER_PROCEED)
|
||||
return TRUE
|
||||
if(CHECK_FLAG_FAILURE)
|
||||
return FALSE
|
||||
if(((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_USER) && (user.loc != startlocuser)) || ((do_after_flags & DO_AFTER_DISALLOW_MOVING_ABSOLUTE_TARGET) && (target.loc != startloctarget)))
|
||||
return FALSE
|
||||
else if(do_after_flags & DO_AFTER_DISALLOW_MOVING_RELATIVE)
|
||||
ctu = get_turf(user)
|
||||
ctt = get_turf(target)
|
||||
locchanged = (userturf != ctu) || (targetturf != ctt)
|
||||
userturf = ctu
|
||||
targetturf = ctt
|
||||
dx = targetturf.x - userturf.x
|
||||
dy = targetturf.y - userturf.y
|
||||
if((dx != initial_dx) || (dy != initial_dy))
|
||||
return FALSE
|
||||
if(locchanged && !drifting && !(do_after_flags & DO_AFTER_ALLOW_NONSPACEDRIFT_RELATIVITY))
|
||||
return FALSE
|
||||
if((do_after_flags & DO_AFTER_REQUIRES_USER_ON_TURF) && !isturf(user.loc))
|
||||
return FALSE
|
||||
held = living_user?.get_active_held_item()
|
||||
if((do_after_flags & DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE) && (held != (tool || initially_held_item)))
|
||||
return FALSE
|
||||
if((do_after_flags & DO_AFTER_REQUIRE_FREE_HAND_OR_TOOL) && (!living_user?.is_holding(tool) && !length(living_user?.get_empty_held_indexes())))
|
||||
return FALSE
|
||||
|
||||
#undef INVOKE_CALLBACK
|
||||
#undef CHECK_FLAG_FAILURE
|
||||
|
||||
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = FALSE, resume_time = 0 SECONDS)
|
||||
if(!user || !target)
|
||||
return 0
|
||||
var/user_loc = user.loc
|
||||
|
||||
var/drifting = 0
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = 1
|
||||
|
||||
var/target_loc = target.loc
|
||||
|
||||
var/holding = user.get_active_held_item()
|
||||
var/datum/progressbar/progbar
|
||||
if (progress)
|
||||
progbar = new(user, time, target)
|
||||
|
||||
var/endtime = world.time+time
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
while (world.time + resume_time < endtime)
|
||||
stoplag(1)
|
||||
if (progress)
|
||||
progbar.update(world.time - starttime + resume_time)
|
||||
if(QDELETED(user) || QDELETED(target))
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = 0
|
||||
user_loc = user.loc
|
||||
|
||||
if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
|
||||
. = 0
|
||||
break
|
||||
if (progress)
|
||||
qdel(progbar)
|
||||
|
||||
|
||||
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
|
||||
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(check_clicks && next_move > world.time)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//pass a list in the format list("health" = mob's health var) to check health during this
|
||||
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(islist(checked_health))
|
||||
if(health < checked_health["health"])
|
||||
return FALSE
|
||||
checked_health["health"] = health
|
||||
return ..()
|
||||
|
||||
/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE), resume_time = 0 SECONDS)
|
||||
if(!user)
|
||||
return 0
|
||||
var/atom/Tloc = null
|
||||
if(target && !isturf(target))
|
||||
Tloc = target.loc
|
||||
|
||||
var/atom/Uloc = user.loc
|
||||
|
||||
var/drifting = 0
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = 1
|
||||
|
||||
var/holding = user.get_active_held_item()
|
||||
|
||||
var/holdingnull = 1 //User's hand started out empty, check for an empty hand
|
||||
if(holding)
|
||||
holdingnull = 0 //Users hand started holding something, check to see if it's still holding that
|
||||
|
||||
delay *= user.do_after_coefficent()
|
||||
|
||||
var/datum/progressbar/progbar
|
||||
if (progress)
|
||||
progbar = new(user, delay, target)
|
||||
|
||||
var/endtime = world.time + delay
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
var/mob/living/L = isliving(user) && user //evals to last thing eval'd
|
||||
while (world.time + resume_time < endtime)
|
||||
stoplag(1)
|
||||
if (progress)
|
||||
progbar.update(world.time - starttime + resume_time)
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = 0
|
||||
Uloc = user.loc
|
||||
|
||||
if(L && !CHECK_ALL_MOBILITY(L, required_mobility_flags))
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(QDELETED(user) || user.stat || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
|
||||
if((Uloc != Tloc || Tloc != user) && !drifting)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(needhand)
|
||||
//This might seem like an odd check, but you can still need a hand even when it's empty
|
||||
//i.e the hand is used to pull some item/tool out of the construction
|
||||
if(!holdingnull)
|
||||
if(!holding)
|
||||
. = 0
|
||||
break
|
||||
if(user.get_active_held_item() != holding)
|
||||
. = 0
|
||||
break
|
||||
if (progress)
|
||||
qdel(progbar)
|
||||
|
||||
/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
|
||||
. = 1
|
||||
return
|
||||
|
||||
/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks)
|
||||
if(!user || !targets)
|
||||
return 0
|
||||
if(!islist(targets))
|
||||
targets = list(targets)
|
||||
var/user_loc = user.loc
|
||||
|
||||
var/drifting = 0
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = 1
|
||||
|
||||
var/list/originalloc = list()
|
||||
for(var/atom/target in targets)
|
||||
originalloc[target] = target.loc
|
||||
|
||||
var/holding = user.get_active_held_item()
|
||||
var/datum/progressbar/progbar
|
||||
if(progress)
|
||||
progbar = new(user, time, targets[1])
|
||||
|
||||
var/endtime = world.time + time
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
mainloop:
|
||||
while(world.time < endtime)
|
||||
stoplag(1)
|
||||
if(progress)
|
||||
progbar.update(world.time - starttime)
|
||||
if(QDELETED(user) || !targets)
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = 0
|
||||
user_loc = user.loc
|
||||
|
||||
for(var/atom/target in targets)
|
||||
if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
|
||||
. = 0
|
||||
break mainloop
|
||||
if(progbar)
|
||||
qdel(progbar)
|
||||
@@ -320,173 +320,6 @@ GLOBAL_LIST_EMPTY(species_list)
|
||||
else
|
||||
return "unknown"
|
||||
|
||||
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = FALSE, resume_time = 0 SECONDS)
|
||||
if(!user || !target)
|
||||
return 0
|
||||
var/user_loc = user.loc
|
||||
|
||||
var/drifting = 0
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = 1
|
||||
|
||||
var/target_loc = target.loc
|
||||
|
||||
var/holding = user.get_active_held_item()
|
||||
var/datum/progressbar/progbar
|
||||
if (progress)
|
||||
progbar = new(user, time, target)
|
||||
|
||||
var/endtime = world.time+time
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
while (world.time + resume_time < endtime)
|
||||
stoplag(1)
|
||||
if (progress)
|
||||
progbar.update(world.time - starttime + resume_time)
|
||||
if(QDELETED(user) || QDELETED(target))
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = 0
|
||||
user_loc = user.loc
|
||||
|
||||
if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
|
||||
. = 0
|
||||
break
|
||||
if (progress)
|
||||
qdel(progbar)
|
||||
|
||||
|
||||
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
|
||||
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(check_clicks && next_move > world.time)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//pass a list in the format list("health" = mob's health var) to check health during this
|
||||
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(islist(checked_health))
|
||||
if(health < checked_health["health"])
|
||||
return FALSE
|
||||
checked_health["health"] = health
|
||||
return ..()
|
||||
|
||||
/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null, required_mobility_flags = (MOBILITY_USE|MOBILITY_MOVE), resume_time = 0 SECONDS)
|
||||
if(!user)
|
||||
return 0
|
||||
var/atom/Tloc = null
|
||||
if(target && !isturf(target))
|
||||
Tloc = target.loc
|
||||
|
||||
var/atom/Uloc = user.loc
|
||||
|
||||
var/drifting = 0
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = 1
|
||||
|
||||
var/holding = user.get_active_held_item()
|
||||
|
||||
var/holdingnull = 1 //User's hand started out empty, check for an empty hand
|
||||
if(holding)
|
||||
holdingnull = 0 //Users hand started holding something, check to see if it's still holding that
|
||||
|
||||
delay *= user.do_after_coefficent()
|
||||
|
||||
var/datum/progressbar/progbar
|
||||
if (progress)
|
||||
progbar = new(user, delay, target)
|
||||
|
||||
var/endtime = world.time + delay
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
var/mob/living/L = isliving(user) && user //evals to last thing eval'd
|
||||
while (world.time + resume_time < endtime)
|
||||
stoplag(1)
|
||||
if (progress)
|
||||
progbar.update(world.time - starttime + resume_time)
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = 0
|
||||
Uloc = user.loc
|
||||
|
||||
if(L && !CHECK_ALL_MOBILITY(L, required_mobility_flags))
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(QDELETED(user) || user.stat || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke()))
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc))
|
||||
if((Uloc != Tloc || Tloc != user) && !drifting)
|
||||
. = 0
|
||||
break
|
||||
|
||||
if(needhand)
|
||||
//This might seem like an odd check, but you can still need a hand even when it's empty
|
||||
//i.e the hand is used to pull some item/tool out of the construction
|
||||
if(!holdingnull)
|
||||
if(!holding)
|
||||
. = 0
|
||||
break
|
||||
if(user.get_active_held_item() != holding)
|
||||
. = 0
|
||||
break
|
||||
if (progress)
|
||||
qdel(progbar)
|
||||
|
||||
/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
|
||||
. = 1
|
||||
return
|
||||
|
||||
/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks)
|
||||
if(!user || !targets)
|
||||
return 0
|
||||
if(!islist(targets))
|
||||
targets = list(targets)
|
||||
var/user_loc = user.loc
|
||||
|
||||
var/drifting = 0
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = 1
|
||||
|
||||
var/list/originalloc = list()
|
||||
for(var/atom/target in targets)
|
||||
originalloc[target] = target.loc
|
||||
|
||||
var/holding = user.get_active_held_item()
|
||||
var/datum/progressbar/progbar
|
||||
if(progress)
|
||||
progbar = new(user, time, targets[1])
|
||||
|
||||
var/endtime = world.time + time
|
||||
var/starttime = world.time
|
||||
. = 1
|
||||
mainloop:
|
||||
while(world.time < endtime)
|
||||
stoplag(1)
|
||||
if(progress)
|
||||
progbar.update(world.time - starttime)
|
||||
if(QDELETED(user) || !targets)
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = 0
|
||||
user_loc = user.loc
|
||||
|
||||
for(var/atom/target in targets)
|
||||
if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke()))
|
||||
. = 0
|
||||
break mainloop
|
||||
if(progbar)
|
||||
qdel(progbar)
|
||||
|
||||
/proc/is_species(A, species_datum)
|
||||
. = FALSE
|
||||
if(ishuman(A))
|
||||
|
||||
@@ -49,6 +49,8 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"DROPDEL" = DROPDEL,
|
||||
"NOBLUDGEON" = NOBLUDGEON,
|
||||
"ABSTRACT" = ABSTRACT,
|
||||
"ITEM_CAN_BLOCK" = ITEM_CAN_BLOCK,
|
||||
"ITEM_CAN_PARRY" = ITEM_CAN_PARRY
|
||||
),
|
||||
"admin_flags" = list(
|
||||
"BUILDMODE" = R_BUILDMODE,
|
||||
@@ -123,6 +125,7 @@ GLOBAL_LIST_INIT(bitfields, list(
|
||||
"UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1,
|
||||
"CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1,
|
||||
"HEAR_1" = HEAR_1,
|
||||
"DEFAULT_RICOCHET_1" = DEFAULT_RICOCHET_1,
|
||||
"CONDUCT_1" = CONDUCT_1,
|
||||
"NO_LAVA_GEN_1" = NO_LAVA_GEN_1,
|
||||
"NODECONSTRUCT_1" = NODECONSTRUCT_1,
|
||||
|
||||
@@ -117,7 +117,8 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_MASO" = TRAIT_MASO,
|
||||
"TRAIT_HIGH_BLOOD" = TRAIT_HIGH_BLOOD,
|
||||
"TRAIT_EMPATH" = TRAIT_EMPATH,
|
||||
"TRAIT_FRIENDLY" = TRAIT_FRIENDLY
|
||||
"TRAIT_FRIENDLY" = TRAIT_FRIENDLY,
|
||||
"TRAIT_NICE_SHOT" = TRAIT_NICE_SHOT
|
||||
),
|
||||
/obj/item/bodypart = list(
|
||||
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
// eg: 10*0.5 = 5 deciseconds of delay
|
||||
// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK
|
||||
|
||||
/mob/proc/timeToNextMove()
|
||||
return max(0, next_move - world.time)
|
||||
|
||||
/mob/proc/changeNext_move(num)
|
||||
next_move = world.time + ((num+next_move_adjust)*next_move_modifier)
|
||||
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
*and lastly
|
||||
*afterattack. The return value does not matter.
|
||||
*/
|
||||
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
|
||||
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, flags, damage_multiplier = 1)
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(!CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(flags & ATTACKCHAIN_PARRY_COUNTERATTACK))
|
||||
to_chat(L, "<span class='warning'>You are unable to swing [src] right now!</span>")
|
||||
return
|
||||
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
|
||||
return
|
||||
if(pre_attack(target, user, params))
|
||||
return
|
||||
if(target.attackby(src,user, params))
|
||||
if(target.attackby(src, user, params, flags, damage_multiplier))
|
||||
return
|
||||
if(QDELETED(src) || QDELETED(target))
|
||||
return
|
||||
@@ -52,15 +52,15 @@
|
||||
/obj/attackby(obj/item/I, mob/living/user, params)
|
||||
return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user))
|
||||
|
||||
/mob/living/attackby(obj/item/I, mob/living/user, params)
|
||||
/mob/living/attackby(obj/item/I, mob/living/user, params, attackchain_flags, damage_multiplier)
|
||||
if(..())
|
||||
return TRUE
|
||||
I.attack_delay_done = FALSE //Should be set TRUE in pre_attacked_by()
|
||||
. = I.attack(src, user)
|
||||
. = I.attack(src, user, attackchain_flags, damage_multiplier)
|
||||
if(!I.attack_delay_done) //Otherwise, pre_attacked_by() should handle it.
|
||||
user.changeNext_move(I.click_delay)
|
||||
|
||||
/obj/item/proc/attack(mob/living/M, mob/living/user)
|
||||
/obj/item/proc/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK)
|
||||
return
|
||||
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user)
|
||||
@@ -79,7 +79,7 @@
|
||||
M.lastattackerckey = user.ckey
|
||||
|
||||
user.do_attack_animation(M)
|
||||
M.attacked_by(src, user)
|
||||
M.attacked_by(src, user, attackchain_flags, damage_multiplier)
|
||||
|
||||
log_combat(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
|
||||
add_fingerprint(user)
|
||||
@@ -104,8 +104,8 @@
|
||||
/atom/movable/proc/attacked_by()
|
||||
return
|
||||
|
||||
/obj/attacked_by(obj/item/I, mob/living/user)
|
||||
var/totitemdamage = I.force
|
||||
/obj/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/totitemdamage = I.force * damage_multiplier
|
||||
var/bad_trait
|
||||
|
||||
var/stamloss = user.getStaminaLoss()
|
||||
@@ -134,10 +134,12 @@
|
||||
take_damage(totitemdamage, I.damtype, "melee", 1)
|
||||
return TRUE
|
||||
|
||||
/mob/living/attacked_by(obj/item/I, mob/living/user)
|
||||
var/totitemdamage = pre_attacked_by(I, user)
|
||||
if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, null, null) & BLOCK_SUCCESS)
|
||||
/mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/list/block_return = list()
|
||||
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
|
||||
if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
|
||||
send_item_attack_message(I, user, null, totitemdamage)
|
||||
I.do_stagger_action(src, user, totitemdamage)
|
||||
if(I.force)
|
||||
@@ -151,7 +153,7 @@
|
||||
user.add_mob_blood(src)
|
||||
return TRUE //successful attack
|
||||
|
||||
/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user)
|
||||
/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
if(I.force < force_threshold || I.damtype == STAMINA)
|
||||
playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1)
|
||||
user.changeNext_move(I.click_delay) //pre_attacked_by not called
|
||||
@@ -211,8 +213,8 @@
|
||||
var/message_verb = "attacked"
|
||||
if(I.attack_verb && I.attack_verb.len)
|
||||
message_verb = "[pick(I.attack_verb)]"
|
||||
if(current_force < I.force * INEFFICIENT_ATTACK_MSG_THRESHOLD)
|
||||
message_verb = "inefficiently [message_verb]"
|
||||
if(current_force < I.force * FEEBLE_ATTACK_MSG_THRESHOLD)
|
||||
message_verb = "[pick("feebly", "limply", "saplessly")] [message_verb]"
|
||||
else if(!I.force)
|
||||
return
|
||||
var/message_hit_area = ""
|
||||
|
||||
@@ -117,6 +117,11 @@
|
||||
paralysis_type = "legs"
|
||||
resilience = TRAUMA_RESILIENCE_ABSOLUTE
|
||||
|
||||
/datum/brain_trauma/severe/paralysis/spinesnapped
|
||||
random_gain = FALSE
|
||||
paralysis_type = "legs"
|
||||
resilience = TRAUMA_RESILIENCE_LOBOTOMY
|
||||
|
||||
/datum/brain_trauma/severe/narcolepsy
|
||||
name = "Narcolepsy"
|
||||
desc = "Patient may involuntarily fall asleep during normal activities."
|
||||
|
||||
@@ -119,6 +119,8 @@
|
||||
if(hud_icon)
|
||||
hud_icon.combat_on = FALSE
|
||||
hud_icon.update_icon()
|
||||
source.stop_active_blocking()
|
||||
source.end_parry_sequence()
|
||||
|
||||
///Changes the user direction to (try) keep match the pointer.
|
||||
/datum/component/combat_mode/proc/on_move(atom/movable/source, dir, atom/oldloc, forced)
|
||||
|
||||
@@ -35,17 +35,34 @@ k// PARTS //
|
||||
desc = "A twenty bore shotgun barrel."
|
||||
icon_state = "barrel_shotgun"
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_pistol
|
||||
name = "pistol barrel"
|
||||
desc = "A pipe with a small diameter and some holes finely cut into it. It fits .32 ACP bullets. Probably."
|
||||
icon_state = "barrel_pistol"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
// 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."
|
||||
desc = "A crudely constructed receiver to create an improvised bolt-action breechloaded rifle. It's generic enough to modify to create other rifles, potentially."
|
||||
icon_state = "receiver_rifle"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/pistol_receiver
|
||||
name = "pistol receiver"
|
||||
desc = "A receiver to connect house and connects all the parts to make an improvised pistol."
|
||||
icon_state = "receiver_pistol"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/laser_receiver
|
||||
name = "energy emitter assembly"
|
||||
desc = "A mixture of components haphazardly wired together to form an energy emitter."
|
||||
icon_state = "laser_assembly"
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver
|
||||
name = "break-action assembly"
|
||||
desc = "An improvised receiver to create a break-action breechloaded shotgun."
|
||||
desc = "An improvised receiver to create a break-action breechloaded shotgun. Parts of this are still useful if you want to make another type of shotgun, however."
|
||||
icon_state = "receiver_shotgun"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
@@ -62,3 +79,14 @@ k// PARTS //
|
||||
desc = "A crudely fashioned wooden body to help keep higher calibre improvised weapons from blowing themselves apart."
|
||||
icon_state = "wooden_body"
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/wooden_grip
|
||||
name = "wooden pistol grip"
|
||||
desc = "A nice wooden grip hollowed out for pistol magazines."
|
||||
icon_state = "wooden_pistolgrip"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/weaponcrafting/improvised_parts/makeshift_lens
|
||||
name = "makeshift focusing lens"
|
||||
desc = "A properly made lens made with actual glassworking tools would perform much better, but this will have to do."
|
||||
icon_state = "focusing_lens"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_OTHER
|
||||
|
||||
/datum/crafting_recipe/pin_removal/check_requirements(mob/user, list/collected_requirements)
|
||||
var/obj/item/gun/G = collected_requirements[/obj/item/gun][1]
|
||||
@@ -22,7 +22,7 @@
|
||||
/obj/item/shield/riot = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/strobeshield/New()
|
||||
..()
|
||||
@@ -38,7 +38,7 @@
|
||||
tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 100
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/spear
|
||||
name = "Spear"
|
||||
@@ -49,7 +49,7 @@
|
||||
parts = list(/obj/item/shard = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/stunprod
|
||||
name = "Stunprod"
|
||||
@@ -59,7 +59,7 @@
|
||||
/obj/item/assembly/igniter = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/teleprod
|
||||
name = "Teleprod"
|
||||
@@ -70,7 +70,7 @@
|
||||
/obj/item/stack/ore/bluespace_crystal = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/bola
|
||||
name = "Bola"
|
||||
@@ -88,7 +88,7 @@
|
||||
/obj/item/stack/sheet/metal = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/tailwhip
|
||||
name = "Liz O' Nine Tails"
|
||||
@@ -97,7 +97,7 @@
|
||||
/obj/item/stack/cable_coil = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/catwhip
|
||||
name = "Cat O' Nine Tails"
|
||||
@@ -106,7 +106,7 @@
|
||||
/obj/item/stack/cable_coil = 1)
|
||||
time = 40
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
/datum/crafting_recipe/chainsaw
|
||||
name = "Chainsaw"
|
||||
@@ -117,7 +117,7 @@
|
||||
tools = list(TOOL_WELDER)
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
//////////////////
|
||||
///BOMB CRAFTING//
|
||||
@@ -134,7 +134,7 @@
|
||||
parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
|
||||
time = 30
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_OTHER
|
||||
|
||||
/datum/crafting_recipe/chemical_payload2
|
||||
name = "Chemical Payload (Gibtonite)"
|
||||
@@ -147,7 +147,7 @@
|
||||
parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_OTHER
|
||||
|
||||
/datum/crafting_recipe/molotov
|
||||
name = "Molotov"
|
||||
@@ -169,7 +169,7 @@
|
||||
parts = list(/obj/item/reagent_containers/food/drinks/soda_cans = 1)
|
||||
time = 15
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_OTHER
|
||||
|
||||
/datum/crafting_recipe/lance
|
||||
name = "Explosive Lance (Grenade)"
|
||||
@@ -180,7 +180,7 @@
|
||||
/obj/item/grenade = 1)
|
||||
time = 15
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
//////////////////
|
||||
///GUNS CRAFTING//
|
||||
@@ -276,6 +276,49 @@
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/ipistol
|
||||
name = "Improvised Pistol (.32)"
|
||||
result = /obj/item/gun/ballistic/automatic/pistol/improvised/nomag
|
||||
reqs = list(/obj/item/weaponcrafting/improvised_parts/barrel_pistol = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/pistol_receiver = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/wooden_grip = 1,
|
||||
/obj/item/stack/sheet/plastic = 15,
|
||||
/obj/item/stack/sheet/plasteel = 1)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER, TOOL_WIRECUTTER)
|
||||
time = 100
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/ilaser
|
||||
name = "Improvised Energy Gun"
|
||||
result = /obj/item/gun/energy/e_gun/old/improvised
|
||||
reqs = list(/obj/item/weaponcrafting/improvised_parts/laser_receiver = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/makeshift_lens = 1,
|
||||
/obj/item/stock_parts/cell = 1,
|
||||
/obj/item/stack/sheet/metal = 10,
|
||||
/obj/item/stack/sheet/plasteel = 5,
|
||||
/obj/item/stack/cable_coil = 10)
|
||||
tools = list(TOOL_SCREWDRIVER)
|
||||
time = 100
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
/datum/crafting_recipe/ilaser/upgraded
|
||||
name = "Improvised Energy Gun Upgrade"
|
||||
result = /obj/item/gun/energy/e_gun/old/improvised/upgraded
|
||||
reqs = list(/obj/item/gun/energy/e_gun/old/improvised = 1,
|
||||
/obj/item/glasswork/glass_base/lens = 1,
|
||||
/obj/item/stock_parts/capacitor/quadratic = 2,
|
||||
/obj/item/stock_parts/micro_laser/ultra = 1,
|
||||
/obj/item/stock_parts/cell/bluespace = 1,
|
||||
/obj/item/stack/cable_coil = 5)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_MULTITOOL)
|
||||
time = 100
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
|
||||
//////////////////
|
||||
///AMMO CRAFTING//
|
||||
//////////////////
|
||||
@@ -399,6 +442,17 @@
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
/datum/crafting_recipe/m32acp
|
||||
name = ".32ACP Empty Magazine"
|
||||
result = /obj/item/ammo_box/magazine/m32acp/empty
|
||||
reqs = list(/obj/item/stack/sheet/metal = 3,
|
||||
/obj/item/stack/sheet/plasteel = 1,
|
||||
/obj/item/stack/packageWrap = 1)
|
||||
tools = list(TOOL_WELDER,TOOL_SCREWDRIVER)
|
||||
time = 5
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_AMMO
|
||||
|
||||
////////////////////
|
||||
// PARTS CRAFTING //
|
||||
////////////////////
|
||||
@@ -423,13 +477,24 @@
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
/datum/crafting_recipe/pistol_barrel
|
||||
name = "Improvised Pistol Barrel"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/barrel_pistol
|
||||
reqs = list(/obj/item/pipe = 1,
|
||||
/obj/item/stack/sheet/plasteel = 1)
|
||||
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.
|
||||
reqs = list(/obj/item/stack/sheet/metal = 10,
|
||||
/obj/item/stack/sheet/plasteel = 1)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER)
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
@@ -439,11 +504,33 @@
|
||||
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
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER) // Dual wielding has been removed, plasteel is a soft timesink to obtain for most to make mass production harder.
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
/datum/crafting_recipe/pistol_receiver
|
||||
name = "Improvised Pistol Receiver"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/pistol_receiver
|
||||
reqs = list(/obj/item/stack/sheet/metal = 5,
|
||||
/obj/item/stack/sheet/plasteel = 1)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WELDER, TOOL_SAW)
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
/datum/crafting_recipe/laser_receiver
|
||||
name = "Energy Weapon Assembly"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/laser_receiver
|
||||
reqs = list(/obj/item/stack/sheet/metal = 10,
|
||||
/obj/item/stock_parts/capacitor = 2,
|
||||
/obj/item/stock_parts/micro_laser = 1,
|
||||
/obj/item/assembly/prox_sensor = 1)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_MULTITOOL, TOOL_WELDER) // Prox sensor and multitool for the circuit board, welder for extremely ghetto soldering.
|
||||
time = 150
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
// MISC
|
||||
|
||||
/datum/crafting_recipe/trigger_assembly
|
||||
@@ -455,3 +542,13 @@
|
||||
time = 150
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
/datum/crafting_recipe/makeshift_lens
|
||||
name = "Makeshift Lens"
|
||||
result = /obj/item/weaponcrafting/improvised_parts/makeshift_lens
|
||||
reqs = list(/obj/item/stack/sheet/metal = 1,
|
||||
/obj/item/stack/sheet/glass = 2)
|
||||
tools = list(TOOL_WELDER) // Glassmaking lets you make non-makeshift lenses.
|
||||
time = 50
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_PARTS
|
||||
|
||||
@@ -11,6 +11,17 @@
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/join_swarm)
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm)
|
||||
|
||||
/datum/component/swarming/Destroy()
|
||||
if(is_swarming)
|
||||
for(var/A in swarm_members)
|
||||
var/datum/component/swarming/other_swarm = A
|
||||
other_swarm.swarm_members -= src
|
||||
swarm_members -= other_swarm
|
||||
if(!length(other_swarm.swarm_members))
|
||||
other_swarm.unswarm()
|
||||
unswarm()
|
||||
return ..()
|
||||
|
||||
/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM)
|
||||
var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming)
|
||||
if(!other_swarm)
|
||||
|
||||
@@ -354,7 +354,7 @@
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 60, TRUE)
|
||||
playsound(user, 'sound/effects/splat.ogg', 70, TRUE)
|
||||
user.emote("scream")
|
||||
user.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic) // oopsie indeed!
|
||||
user.gain_trauma(/datum/brain_trauma/severe/paralysis/spinesnapped) // oopsie indeed!
|
||||
shake_camera(user, 7, 7)
|
||||
user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash)
|
||||
user.clear_fullscreen("flash", 4.5)
|
||||
|
||||
@@ -117,9 +117,9 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
|
||||
return FALSE
|
||||
|
||||
var/lower_name = lowertext(flavor_name)
|
||||
var/new_text = stripped_multiline_input(user, "Set the [lower_name] displayed on 'examine'. [addendum]", flavor_name, texts_by_atom[usr], max_len, TRUE)
|
||||
var/new_text = stripped_multiline_input(user, "Set the [lower_name] displayed on 'examine'. [addendum]", flavor_name, html_decode(texts_by_atom[usr]), max_len, TRUE)
|
||||
if(!isnull(new_text) && (user in texts_by_atom))
|
||||
texts_by_atom[user] = html_decode(new_text)
|
||||
texts_by_atom[user] = new_text
|
||||
to_chat(src, "Your [lower_name] has been updated.")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
var/help_verb
|
||||
var/pacifism_check = TRUE //are the martial arts combos/attacks unable to be used by pacifist.
|
||||
var/allow_temp_override = TRUE //if this martial art can be overridden by temporary martial arts
|
||||
/// Can we be used to unarmed parry?
|
||||
var/can_martial_parry = FALSE
|
||||
/// Set this variable to something not null, this'll be the preferred unarmed parry in most cases if [can_martial_parry] is TRUE. YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
var/datum/block_parry_data/block_parry_data
|
||||
var/pugilist = FALSE
|
||||
|
||||
/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
@@ -91,4 +95,4 @@
|
||||
|
||||
///Gets called when a projectile hits the owner. Returning anything other than BULLET_ACT_HIT will stop the projectile from hitting the mob.
|
||||
/datum/martial_art/proc/on_projectile_hit(mob/living/carbon/human/A, obj/item/projectile/P, def_zone)
|
||||
return BULLET_ACT_HIT
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
@@ -66,9 +66,9 @@
|
||||
return
|
||||
|
||||
/obj/item/clothing/gloves/boxing/dropped(mob/user)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(SLOT_GLOVES) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
@@ -203,6 +203,7 @@
|
||||
style.teach(H,1)
|
||||
|
||||
/obj/item/clothing/gloves/krav_maga/dropped(mob/user)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
@@ -480,12 +480,12 @@
|
||||
return
|
||||
|
||||
/obj/item/storage/belt/champion/wrestling/dropped(mob/user)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(SLOT_BELT) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
//Subtype of wrestling, reserved for the wrestling belts found in the holodeck
|
||||
/datum/martial_art/wrestling/holodeck
|
||||
|
||||
+8
-2
@@ -6,6 +6,7 @@
|
||||
|
||||
var/flags_1 = NONE
|
||||
var/interaction_flags_atom = NONE
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
var/flags_ricochet = NONE
|
||||
|
||||
@@ -14,8 +15,6 @@
|
||||
///When a projectile ricochets off this atom, it deals the normal damage * this modifier to this atom
|
||||
var/ricochet_damage_mod = 0.33
|
||||
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
//This atom's HUD (med/sec, etc) images. Associative list.
|
||||
var/list/image/hud_list = null
|
||||
//HUD images that this atom can provide.
|
||||
@@ -149,6 +148,13 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Checks if a projectile should ricochet off of us. Projectiles get final say.
|
||||
* [__DEFINES/projectiles.dm] for return values.
|
||||
*/
|
||||
/atom/proc/check_projectile_ricochet(obj/item/projectile/P)
|
||||
return (flags_1 & DEFAULT_RICOCHET_1)? PROJECTILE_RICOCHET_YES : PROJECTILE_RICOCHET_NO
|
||||
|
||||
/atom/proc/handle_ricochet(obj/item/projectile/P)
|
||||
var/turf/p_turf = get_turf(P)
|
||||
var/face_direction = get_dir(src, p_turf)
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
new /obj/item/stack/sheet/plasteel(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/dominator/attacked_by(obj/item/I, mob/living/user)
|
||||
/obj/machinery/dominator/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
add_fingerprint(user)
|
||||
return ..()
|
||||
|
||||
@@ -240,4 +240,4 @@
|
||||
|
||||
#undef DOM_BLOCKED_SPAM_CAP
|
||||
#undef DOM_REQUIRED_TURFS
|
||||
#undef DOM_HULK_HITS_REQUIRED
|
||||
#undef DOM_HULK_HITS_REQUIRED
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/porta_turret_cover/attacked_by(obj/item/I, mob/user)
|
||||
/obj/machinery/porta_turret_cover/attacked_by(obj/item/I, mob/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
return parent_turret.attacked_by(I, user)
|
||||
|
||||
/obj/machinery/porta_turret_cover/attack_alien(mob/living/carbon/alien/humanoid/user)
|
||||
|
||||
@@ -282,7 +282,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/mecha/attacked_by(obj/item/I, mob/living/user)
|
||||
/obj/mecha/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
mecha_log_message("Attacked by [I]. Attacker - [user]")
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -611,13 +611,13 @@
|
||||
/obj/item/clothing/mask/breath = 5,
|
||||
/obj/item/clothing/mask/breath/medical = 1
|
||||
)
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/welder_tools/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
/obj/effect/spawner/lootdrop/low_tools/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
|
||||
/obj/effect/spawner/lootdrop/breathing_tanks/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
@@ -644,3 +644,90 @@
|
||||
|
||||
/obj/effect/spawner/lootdrop/glowstick/no_turf
|
||||
spawn_on_turf = FALSE
|
||||
|
||||
// Random Parts
|
||||
|
||||
/obj/effect/spawner/lootdrop/stock_parts
|
||||
name = "random stock parts spawner"
|
||||
lootcount = 1
|
||||
loot = list(
|
||||
/obj/item/stock_parts/capacitor,
|
||||
/obj/item/stock_parts/scanning_module,
|
||||
/obj/item/stock_parts/manipulator,
|
||||
/obj/item/stock_parts/micro_laser,
|
||||
/obj/item/stock_parts/matter_bin,
|
||||
/obj/item/stock_parts/cell
|
||||
)
|
||||
|
||||
// Random Weapon Parts
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
name = "random weapon parts spawner 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_rifle = 10,
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_shotgun = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_pistol = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 10,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 3,
|
||||
/obj/item/weaponcrafting/improvised_parts/pistol_receiver = 3,
|
||||
/obj/item/weaponcrafting/improvised_parts/laser_receiver = 1,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 10,
|
||||
/obj/item/weaponcrafting/improvised_parts/makeshift_lens = 3,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/weapon_parts
|
||||
name = "random weapon parts spawner 25%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 75,
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_rifle = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/barrel_pistol = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/rifle_receiver = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/pistol_receiver = 2,
|
||||
/obj/item/weaponcrafting/improvised_parts/trigger_assembly = 5,
|
||||
/obj/item/weaponcrafting/improvised_parts/makeshift_lens = 3,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo
|
||||
name = "random ammo 75%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 25,
|
||||
/obj/item/ammo_box/c32mm = 15,
|
||||
/obj/item/ammo_box/r32mm = 15,
|
||||
/obj/item/ammo_box/magazine/wt550m9 = 1,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 7,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 7,
|
||||
/obj/item/ammo_casing/a762 = 15,
|
||||
/obj/item/ammo_box/a762 = 15,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo/fiftypercent
|
||||
name = "random ammo 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/ammo_box/c32mm = 7,
|
||||
/obj/item/ammo_box/r32mm = 7,
|
||||
/obj/item/ammo_box/magazine/wt550m9 = 2,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 10,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 10,
|
||||
/obj/item/ammo_casing/a762 = 7,
|
||||
/obj/item/ammo_box/a762 = 7,
|
||||
)
|
||||
|
||||
/obj/effect/spawner/lootdrop/ammo/shotgun
|
||||
name = "random ammo 50%"
|
||||
lootcount = 1
|
||||
spawn_on_turf = FALSE
|
||||
loot = list("" = 50,
|
||||
/obj/item/ammo_box/shotgun/loaded/buckshot = 5,
|
||||
/obj/item/ammo_box/shotgun/loaded/beanbag = 5,
|
||||
/obj/item/ammo_box/shotgun/loaded/incendiary = 5,
|
||||
/obj/item/ammo_casing/shotgun/buckshot = 8,
|
||||
/obj/item/ammo_casing/shotgun/rubbershot = 9,
|
||||
/obj/item/ammo_casing/shotgun = 8,
|
||||
/obj/item/ammo_casing/shotgun/incendiary = 10,
|
||||
)
|
||||
|
||||
@@ -144,6 +144,13 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
|
||||
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
|
||||
|
||||
/* Our block parry data. Should be set in init, or something if you are using it.
|
||||
* This won't be accessed without ITEM_CAN_BLOCK or ITEM_CAN_PARRY so do not set it unless you have to to save memory.
|
||||
* If you decide it's a good idea to leave this unset while turning the flags on, you will runtime. Enjoy.
|
||||
* If this is set to a path, it'll run get_block_parry_data(path). YOU MUST RUN [get_block_parry_data(this)] INSTEAD OF DIRECTLY ACCESSING!
|
||||
*/
|
||||
var/datum/block_parry_data/block_parry_data
|
||||
|
||||
///Skills vars
|
||||
//list of skill PATHS exercised when using this item. An associated bitfield can be set to indicate additional ways the skill is used by this specific item.
|
||||
var/list/datum/skill/used_skills
|
||||
@@ -250,9 +257,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
. += "[src] is made of cold-resistant materials."
|
||||
if(resistance_flags & FIRE_PROOF)
|
||||
. += "[src] is made of fire-retardant materials."
|
||||
|
||||
|
||||
|
||||
|
||||
if(item_flags & (ITEM_CAN_BLOCK | ITEM_CAN_PARRY))
|
||||
var/datum/block_parry_data/data = return_block_parry_datum(block_parry_data)
|
||||
. += "[src] has the capacity to be used to block and/or parry. <a href='?src=[REF(data)];name=[name];block=[item_flags & ITEM_CAN_BLOCK];parry=[item_flags & ITEM_CAN_PARRY];render=1'>\[Show Stats\]</a>"
|
||||
|
||||
if(!user.research_scanner)
|
||||
return
|
||||
@@ -414,6 +422,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/obj/item/proc/dropped(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.Remove(user)
|
||||
@@ -426,6 +435,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
|
||||
|
||||
// called just as an item is picked up (loc is not yet changed)
|
||||
/obj/item/proc/pickup(mob/user)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_PICKUP, user)
|
||||
item_flags |= IN_INVENTORY
|
||||
|
||||
|
||||
@@ -187,6 +187,15 @@
|
||||
if(ID_LOCKED_BANK_ACCOUNT)
|
||||
registered_account = new /datum/bank_account/remote/non_transferable(pick(GLOB.redacted_strings))
|
||||
|
||||
/obj/item/card/id/Destroy()
|
||||
if(bank_support == ID_LOCKED_BANK_ACCOUNT)
|
||||
QDEL_NULL(registered_account)
|
||||
else
|
||||
registered_account = null
|
||||
if(my_store)
|
||||
my_store.my_card = null
|
||||
my_store = null
|
||||
return ..()
|
||||
|
||||
/obj/item/card/id/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
|
||||
@@ -803,6 +803,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
to_chat(user, "<span class='warning'>You need to close the cap first!</span>")
|
||||
|
||||
/obj/item/clothing/mask/vape/dropped(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.get_item_by_slot(SLOT_WEAR_MASK) == src)
|
||||
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
|
||||
|
||||
@@ -655,9 +655,10 @@ GENETICS SCANNER
|
||||
amount += inaccurate
|
||||
return DisplayTimeText(max(1,amount))
|
||||
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src)
|
||||
/proc/atmosanalyzer_scan(mixture, mob/living/user, atom/target = src, visible = TRUE)
|
||||
var/icon = target
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
if(visible)
|
||||
user.visible_message("[user] has used the analyzer on [icon2html(icon, viewers(user))] [target].", "<span class='notice'>You use the analyzer on [icon2html(icon, user)] [target].</span>")
|
||||
to_chat(user, "<span class='boldnotice'>Results of analysis of [icon2html(icon, user)] [target].</span>")
|
||||
|
||||
var/list/airs = islist(mixture) ? mixture : list(mixture)
|
||||
|
||||
@@ -105,9 +105,28 @@
|
||||
sharpness = IS_SHARP
|
||||
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
|
||||
armour_penetration = 35
|
||||
block_chance = 50
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/energy_sword
|
||||
var/list/possible_colors = list("red" = LIGHT_COLOR_RED, "blue" = LIGHT_COLOR_LIGHT_CYAN, "green" = LIGHT_COLOR_GREEN, "purple" = LIGHT_COLOR_LAVENDER)
|
||||
|
||||
/datum/block_parry_data/energy_sword
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 25
|
||||
parry_time_spindown = 0
|
||||
// we want to signal to players the most dangerous phase, the time when automatic counterattack is a thing.
|
||||
parry_time_windup_visual_override = 1
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 12
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // esword users can attack while
|
||||
parry_time_perfect = 2.5 // first ds isn't perfect
|
||||
parry_time_perfect_leeway = 1.5
|
||||
parry_imperfect_falloff_percent = 5
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 65 // VERY generous
|
||||
parry_efficiency_perfect = 100
|
||||
parry_failed_stagger_duration = 4 SECONDS
|
||||
parry_cooldown = 0.5 SECONDS
|
||||
|
||||
/obj/item/melee/transforming/energy/sword/Initialize(mapload)
|
||||
. = ..()
|
||||
set_sword_color()
|
||||
|
||||
@@ -61,13 +61,25 @@
|
||||
force = 18
|
||||
throwforce = 15
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
block_chance = 50
|
||||
armour_penetration = 75
|
||||
sharpness = IS_SHARP
|
||||
attack_verb = list("slashed", "cut")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
custom_materials = list(/datum/material/iron = 1000)
|
||||
total_mass = 3.4
|
||||
item_flags = NEEDS_PERMIT | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/captain_saber
|
||||
|
||||
/datum/block_parry_data/captain_saber
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 4
|
||||
parry_time_spindown = 1
|
||||
parry_time_perfect = 0.75
|
||||
parry_time_perfect_leeway = 0.75
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_perfect = 100
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = 2 SECONDS
|
||||
|
||||
/obj/item/melee/sabre/Initialize()
|
||||
. = ..()
|
||||
@@ -150,7 +162,6 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
force = 15
|
||||
throwforce = 25
|
||||
block_chance = 50
|
||||
armour_penetration = 200 //Apparently this gives it the ability to pierce block
|
||||
flags_1 = CONDUCT_1
|
||||
obj_flags = UNIQUE_RENAME
|
||||
@@ -159,16 +170,47 @@
|
||||
attack_verb = list("stabs", "punctures", "pierces", "pokes")
|
||||
hitsound = 'sound/weapons/rapierhit.ogg'
|
||||
total_mass = 0.4
|
||||
item_flags = ITEM_CAN_PARRY | NEEDS_PERMIT
|
||||
block_parry_data = /datum/block_parry_data/traitor_rapier
|
||||
|
||||
// Fast, efficient parry.
|
||||
/datum/block_parry_data/traitor_rapier
|
||||
parry_time_windup = 0.5
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 2
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 3
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1
|
||||
)
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 50 // useless after 3rd decisecond
|
||||
)
|
||||
parry_imperfect_falloff_percent = 30
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 1
|
||||
parry_efficiency_perfect = 100
|
||||
parry_data = list(
|
||||
PARRY_DISARM_ATTACKER = TRUE,
|
||||
PARRY_KNOCKDOWN_ATTACKER = 10
|
||||
)
|
||||
parry_failed_stagger_duration = 2 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_RANGE
|
||||
parry_cooldown = 0
|
||||
|
||||
/obj/item/melee/rapier/active_parry_reflex_counter(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, parry_efficiency, list/effect_text)
|
||||
. = ..()
|
||||
if((attack_type & ATTACK_TYPE_PROJECTILE) && (parry_efficiency >= 100))
|
||||
. |= BLOCK_SHOULD_REDIRECT
|
||||
return_list[BLOCK_RETURN_REDIRECT_METHOD] = REDIRECT_METHOD_DEFLECT
|
||||
|
||||
/obj/item/melee/rapier/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/butchering, 20, 65, 0)
|
||||
|
||||
/obj/item/melee/rapier/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(attack_type == ATTACK_TYPE_PROJECTILE)
|
||||
final_block_chance = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/melee/rapier/on_exit_storage(datum/component/storage/S)
|
||||
var/obj/item/storage/belt/sabre/rapier/B = S.parent
|
||||
if(istype(B))
|
||||
@@ -191,10 +233,9 @@
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/H = target
|
||||
var/loss = H.getStaminaLoss()
|
||||
H.Dizzy(10)
|
||||
H.adjustStaminaLoss(30)
|
||||
if((loss > 40) && prob(loss)) // if above 40, roll for sleep using 1% every 1 stamina damage
|
||||
if(CHECK_STAMCRIT(H) != NOT_STAMCRIT)
|
||||
H.Sleeping(180)
|
||||
|
||||
/obj/item/melee/classic_baton
|
||||
@@ -664,4 +705,4 @@
|
||||
. = ..()
|
||||
overlay = mutable_appearance(icon, overlay_state)
|
||||
overlay.appearance_flags = RESET_COLOR
|
||||
add_overlay(overlay)
|
||||
add_overlay(overlay)
|
||||
|
||||
@@ -140,7 +140,8 @@
|
||||
if(jsonlist["icon_state"])
|
||||
icon_state = jsonlist["icon_state"]
|
||||
item_state = jsonlist["item_state"]
|
||||
icon = 'config/plushies/sprites.dmi'
|
||||
var/static/config_sprites = file("config/plushies/sprites.dmi")
|
||||
icon = config_sprites
|
||||
if(jsonlist["attack_verb"])
|
||||
attack_verb = jsonlist["attack_verb"]
|
||||
if(jsonlist["squeak_override"])
|
||||
|
||||
@@ -358,6 +358,7 @@
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/dropped(mob/user)
|
||||
. = ..()
|
||||
check_amount()
|
||||
|
||||
/obj/item/borg/lollipop/proc/check_amount() //Doesn't even use processing ticks.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/obj/item/shield
|
||||
name = "shield"
|
||||
icon = 'icons/obj/shields.dmi'
|
||||
block_chance = 50
|
||||
item_flags = ITEM_CAN_BLOCK
|
||||
block_parry_data = /datum/block_parry_data/shield
|
||||
armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70)
|
||||
/// Shield flags
|
||||
var/shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
@@ -22,6 +23,18 @@
|
||||
/// Shield bashing push distance
|
||||
var/shieldbash_push_distance = 1
|
||||
|
||||
/datum/block_parry_data/shield
|
||||
block_damage_multiplier = 0.25
|
||||
block_stamina_efficiency = 2.5
|
||||
block_stamina_cost_per_second = 3.5
|
||||
block_slowdown = 0
|
||||
block_lock_attacking = FALSE
|
||||
block_lock_sprinting = TRUE
|
||||
block_start_delay = 1.5
|
||||
block_damage_absorption = 5
|
||||
block_resting_stamina_penalty_multiplier = 2
|
||||
block_projectile_mitigation = 75
|
||||
|
||||
/obj/item/shield/examine(mob/user)
|
||||
. = ..()
|
||||
if(shield_flags & SHIELD_CAN_BASH)
|
||||
@@ -154,6 +167,22 @@
|
||||
icon_state = "shield_bash"
|
||||
duration = 3
|
||||
|
||||
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(ismovable(object))
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
final_block_chance = 100
|
||||
. = ..()
|
||||
if(. & BLOCK_SUCCESS)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
|
||||
/obj/item/shield/on_active_block(mob/living/owner, atom/object, damage, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance)
|
||||
|
||||
/obj/item/shield/riot
|
||||
name = "riot shield"
|
||||
desc = "A shield adept at blocking blunt objects from connecting with the torso of the shield wielder."
|
||||
@@ -172,20 +201,7 @@
|
||||
var/repair_material = /obj/item/stack/sheet/mineral/titanium
|
||||
var/can_shatter = TRUE
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_TRANSPARENT
|
||||
max_integrity = 75
|
||||
|
||||
/obj/item/shield/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(ismovable(object))
|
||||
var/atom/movable/AM = object
|
||||
if(CHECK_BITFIELD(shield_flags, SHIELD_TRANSPARENT) && (AM.pass_flags & PASSGLASS))
|
||||
return BLOCK_NONE
|
||||
if(attack_type & ATTACK_TYPE_THROWN)
|
||||
final_block_chance += 30
|
||||
if(attack_type & ATTACK_TYPE_TACKLE)
|
||||
final_block_chance = 100
|
||||
. = ..()
|
||||
if(. & BLOCK_SUCCESS)
|
||||
on_shield_block(owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
max_integrity = 450
|
||||
|
||||
/obj/item/shield/riot/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/melee/baton))
|
||||
@@ -238,13 +254,13 @@
|
||||
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 55 //Weak
|
||||
max_integrity = 300
|
||||
|
||||
obj/item/shield/riot/bullet_proof
|
||||
name = "bullet resistant shield"
|
||||
desc = "A far more frail shield made of resistant plastics and kevlar meant to block ballistics."
|
||||
armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50)
|
||||
max_integrity = 55 //Weaker
|
||||
max_integrity = 300
|
||||
|
||||
/obj/item/shield/riot/roman
|
||||
name = "\improper Roman shield"
|
||||
@@ -255,13 +271,13 @@ obj/item/shield/riot/bullet_proof
|
||||
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 65
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/roman/fake
|
||||
desc = "Bears an inscription on the inside: <i>\"Romanes venio domus\"</i>. It appears to be a bit flimsy."
|
||||
block_chance = 0
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
max_integrity = 30
|
||||
max_integrity = 40
|
||||
|
||||
/obj/item/shield/riot/roman/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/grillehit.ogg', 100)
|
||||
@@ -279,7 +295,7 @@ obj/item/shield/riot/bullet_proof
|
||||
repair_material = /obj/item/stack/sheet/mineral/wood
|
||||
block_chance = 30
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 55
|
||||
max_integrity = 150
|
||||
|
||||
/obj/item/shield/riot/buckler/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/effects/bang.ogg', 50)
|
||||
@@ -297,13 +313,16 @@ obj/item/shield/riot/bullet_proof
|
||||
throw_speed = 3
|
||||
throw_range = 4
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/active = 0
|
||||
var/active = FALSE
|
||||
|
||||
/obj/item/shield/riot/tele/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!active)
|
||||
return BLOCK_NONE
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/riot/tele/can_active_block()
|
||||
return ..() && active
|
||||
|
||||
/obj/item/shield/riot/tele/attack_self(mob/living/user)
|
||||
active = !active
|
||||
icon_state = "teleriot[active]"
|
||||
@@ -335,8 +354,7 @@ obj/item/shield/riot/bullet_proof
|
||||
icon_state = "makeshift_shield"
|
||||
custom_materials = list(/datum/material/iron = 18000)
|
||||
slot_flags = null
|
||||
block_chance = 35
|
||||
max_integrity = 100 //Made of metal welded together its strong but not unkillable
|
||||
max_integrity = 300 //Made of metal welded together its strong but not unkillable
|
||||
force = 10
|
||||
throwforce = 7
|
||||
|
||||
@@ -346,7 +364,6 @@ obj/item/shield/riot/bullet_proof
|
||||
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
block_chance = 75 //1/4 shots will hit*
|
||||
force = 16
|
||||
slowdown = 2
|
||||
throwforce = 15 //Massive pice of metal
|
||||
@@ -357,19 +374,17 @@ obj/item/shield/riot/bullet_proof
|
||||
/obj/item/shield/riot/tower/swat
|
||||
name = "swat shield"
|
||||
desc = "A massive, heavy shield that can block a lot of attacks, can take a lot of abuse before breaking."
|
||||
max_integrity = 175
|
||||
block_chance = 50
|
||||
max_integrity = 250
|
||||
|
||||
/obj/item/shield/riot/implant
|
||||
name = "telescoping shield implant"
|
||||
desc = "A compact, arm-mounted telescopic shield. While nigh-indestructible when powered by a host user, it will eventually overload from damage. Recharges while inside its implant."
|
||||
item_state = "metal"
|
||||
icon_state = "metal"
|
||||
block_chance = 50
|
||||
slowdown = 1
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 60
|
||||
obj_integrity = 60
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
can_shatter = FALSE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
var/recharge_timerid
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
ricochet_chance = 40
|
||||
shrapnel_type = /obj/item/shrapnel
|
||||
ricochet_incidence_leeway = 60
|
||||
hit_stunned_targets = TRUE
|
||||
|
||||
/obj/item/projectile/bullet/shrapnel/mega
|
||||
name = "flying shrapnel hunk"
|
||||
@@ -63,6 +62,3 @@
|
||||
name = "megastingball pellet"
|
||||
ricochets_max = 6
|
||||
ricochet_chance = 110
|
||||
|
||||
/obj/item/projectile/bullet/pellet/stingball/on_ricochet(atom/A)
|
||||
hit_stunned_targets = TRUE // ducking will save you from the first wave, but not the rebounds
|
||||
|
||||
@@ -242,6 +242,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
|
||||
null, \
|
||||
new/datum/stack_recipe("wooden firearm body", /obj/item/weaponcrafting/improvised_parts/wooden_body, 10, time = 40), \
|
||||
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \
|
||||
new/datum/stack_recipe("pistol grip", /obj/item/weaponcrafting/improvised_parts/wooden_grip, 5, time = 40), \
|
||||
new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wood, 2, time = 30), \
|
||||
new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \
|
||||
|
||||
@@ -170,10 +170,12 @@
|
||||
return disarming || (user.a_intent != INTENT_HARM)
|
||||
|
||||
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user, disarming = FALSE)
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
var/list/return_list = list()
|
||||
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; check_shields() handles that
|
||||
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
var/stunpwr = stamforce
|
||||
stunpwr = block_calculate_resultant_damage(stunpwr, return_list)
|
||||
var/obj/item/stock_parts/cell/our_cell = get_cell()
|
||||
if(!our_cell)
|
||||
switch_status(FALSE)
|
||||
|
||||
@@ -153,6 +153,10 @@
|
||||
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/tank/attack_ghost(mob/dead/observer/O)
|
||||
. = ..()
|
||||
atmosanalyzer_scan(air_contents, O, src, FALSE)
|
||||
|
||||
/obj/item/tank/attackby(obj/item/W, mob/user, params)
|
||||
add_fingerprint(user)
|
||||
if(istype(W, /obj/item/assembly_holder))
|
||||
|
||||
@@ -446,6 +446,7 @@
|
||||
throw_range = 5
|
||||
force_unwielded = 0
|
||||
force_wielded = 0
|
||||
block_parry_data = null
|
||||
attack_verb = list("attacked", "struck", "hit")
|
||||
total_mass_on = TOTAL_MASS_TOY_SWORD
|
||||
sharpness = IS_BLUNT
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
var/wieldsound = null
|
||||
var/unwieldsound = null
|
||||
var/slowdown_wielded = 0
|
||||
/// Do we need to be wielded to actively block/parry?
|
||||
var/requires_wield_to_block_parry = TRUE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
|
||||
/obj/item/twohanded/proc/unwield(mob/living/carbon/user, show_message = TRUE)
|
||||
@@ -90,6 +92,12 @@
|
||||
user.put_in_inactive_hand(O)
|
||||
set_slowdown(slowdown + slowdown_wielded)
|
||||
|
||||
/obj/item/twohanded/can_active_block()
|
||||
return ..() && (!requires_wield_to_block_parry || wielded)
|
||||
|
||||
/obj/item/twohanded/can_active_parry()
|
||||
return ..() && (!requires_wield_to_block_parry || wielded)
|
||||
|
||||
/obj/item/twohanded/dropped(mob/user)
|
||||
. = ..()
|
||||
//handles unwielding a twohanded weapon when dropped as well as clearing up the offhand
|
||||
@@ -129,6 +137,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/offhand/dropped(mob/living/user, show_message = TRUE) //Only utilized by dismemberment since you can't normally switch to the offhand to drop it.
|
||||
. = ..()
|
||||
var/obj/I = user.get_active_held_item()
|
||||
if(I && istype(I, /obj/item/twohanded))
|
||||
var/obj/item/twohanded/thw = I
|
||||
@@ -274,6 +283,8 @@
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/w_class_on = WEIGHT_CLASS_BULKY
|
||||
item_flags = ITEM_CAN_PARRY | SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK
|
||||
block_parry_data = /datum/block_parry_data/dual_esword
|
||||
force_unwielded = 3
|
||||
force_wielded = 34
|
||||
wieldsound = 'sound/weapons/saberon.ogg'
|
||||
@@ -284,7 +295,6 @@
|
||||
var/saber_color = "green"
|
||||
light_color = "#00ff00"//green
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
block_chance = 75
|
||||
max_integrity = 200
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
|
||||
resistance_flags = FIRE_PROOF
|
||||
@@ -298,6 +308,42 @@
|
||||
total_mass = 0.4 //Survival flashlights typically weigh around 5 ounces.
|
||||
var/total_mass_on = 3.4
|
||||
|
||||
/datum/block_parry_data/dual_esword
|
||||
block_damage_absorption = 2
|
||||
block_damage_multiplier = 0.15
|
||||
block_damage_multiplier_override = list(
|
||||
ATTACK_TYPE_MELEE = 0.25
|
||||
)
|
||||
block_start_delay = 0 // instantaneous block
|
||||
block_stamina_cost_per_second = 2.5
|
||||
block_stamina_efficiency = 3
|
||||
block_lock_sprinting = TRUE
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
block_projectile_mitigation = 75
|
||||
|
||||
parry_time_windup = 0
|
||||
parry_time_active = 8
|
||||
parry_time_spindown = 0
|
||||
// we want to signal to players the most dangerous phase, the time when automatic counterattack is a thing.
|
||||
parry_time_windup_visual_override = 1
|
||||
parry_time_active_visual_override = 3
|
||||
parry_time_spindown_visual_override = 4
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK // esword users can attack while parrying.
|
||||
parry_time_perfect = 2 // first ds isn't perfect
|
||||
parry_time_perfect_leeway = 1
|
||||
parry_imperfect_falloff_percent = 10
|
||||
parry_efficiency_to_counterattack = 100
|
||||
parry_efficiency_considered_successful = 25 // VERY generous
|
||||
parry_efficiency_perfect = 90
|
||||
parry_failed_stagger_duration = 3 SECONDS
|
||||
parry_failed_clickcd_duration = CLICK_CD_MELEE
|
||||
|
||||
// more efficient vs projectiles
|
||||
block_stamina_efficiency_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 4
|
||||
)
|
||||
|
||||
/obj/item/twohanded/dualsaber/suicide_act(mob/living/carbon/user)
|
||||
if(wielded)
|
||||
user.visible_message("<span class='suicide'>[user] begins spinning way too fast! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -849,6 +895,7 @@
|
||||
return (BRUTELOSS)
|
||||
|
||||
/obj/item/twohanded/pitchfork/demonic/pickup(mob/living/user)
|
||||
. = ..()
|
||||
if(isliving(user) && user.mind && user.owns_soul() && !is_devil(user))
|
||||
var/mob/living/U = user
|
||||
U.visible_message("<span class='warning'>As [U] picks [src] up, [U]'s arms briefly catch fire.</span>", \
|
||||
@@ -1030,13 +1077,12 @@
|
||||
force_wielded = 10
|
||||
throwforce = 15 //if you are a madman and finish someone off with this, power to you.
|
||||
throw_speed = 1
|
||||
item_flags = NO_MAT_REDEMPTION | SLOWS_WHILE_IN_HAND
|
||||
block_chance = 30
|
||||
item_flags = NO_MAT_REDEMPTION | SLOWS_WHILE_IN_HAND | ITEM_CAN_BLOCK | ITEM_CAN_PARRY
|
||||
block_parry_data = /datum/block_parry_data/electrostaff
|
||||
attack_verb = list("struck", "beaten", "thwacked", "pulped")
|
||||
total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on)
|
||||
var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high
|
||||
var/on = FALSE
|
||||
var/can_block_projectiles = FALSE //can't block guns
|
||||
var/lethal_cost = 400 //10000/400*20 = 500. decent enough?
|
||||
var/lethal_damage = 20
|
||||
var/lethal_stam_cost = 4
|
||||
@@ -1046,6 +1092,43 @@
|
||||
var/stun_status_duration = 25
|
||||
var/stun_stam_cost = 3.5
|
||||
|
||||
// haha security desword time /s
|
||||
/datum/block_parry_data/electrostaff
|
||||
block_damage_absorption = 0
|
||||
block_damage_multiplier = 1
|
||||
can_block_attack_types = ~ATTACK_TYPE_PROJECTILE // only able to parry non projectiles
|
||||
block_damage_multiplier_override = list(
|
||||
TEXT_ATTACK_TYPE_MELEE = 0.5, // only useful on melee and unarmed
|
||||
TEXT_ATTACK_TYPE_UNARMED = 0.3
|
||||
)
|
||||
block_start_delay = 0.5 // near instantaneous block
|
||||
block_stamina_cost_per_second = 3
|
||||
block_stamina_efficiency = 2 // haha this is a horrible idea
|
||||
// more slowdown that deswords because security
|
||||
block_slowdown = 2
|
||||
// no attacking while blocking
|
||||
block_lock_attacking = TRUE
|
||||
|
||||
parry_time_windup = 1
|
||||
parry_time_active = 5
|
||||
parry_time_spindown = 0
|
||||
parry_time_spindown_visual_override = 1
|
||||
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING // no attacking while parrying
|
||||
parry_time_perfect = 0
|
||||
parry_time_perfect_leeway = 0.5
|
||||
parry_efficiency_perfect = 100
|
||||
parry_imperfect_falloff_percent = 1
|
||||
parry_imperfect_falloff_percent_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 45 // really crappy vs projectiles
|
||||
)
|
||||
parry_time_perfect_leeway_override = list(
|
||||
TEXT_ATTACK_TYPE_PROJECTILE = 1 // extremely harsh window for projectiles
|
||||
)
|
||||
// not extremely punishing to fail, but no spamming the parry.
|
||||
parry_cooldown = 2.5 SECONDS
|
||||
parry_failed_stagger_duration = 1.5 SECONDS
|
||||
parry_failed_clickcd_duration = 1 SECONDS
|
||||
|
||||
/obj/item/twohanded/electrostaff/Initialize(mapload)
|
||||
. = ..()
|
||||
if(ispath(cell))
|
||||
@@ -1061,11 +1144,6 @@
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
. = R.get_cell()
|
||||
|
||||
/obj/item/twohanded/electrostaff/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!on || (!can_block_projectiles && (attack_type & ATTACK_TYPE_PROJECTILE)))
|
||||
return BLOCK_NONE
|
||||
return ..()
|
||||
|
||||
/obj/item/twohanded/electrostaff/proc/min_hitcost()
|
||||
return min(stun_cost, lethal_cost)
|
||||
|
||||
@@ -1183,22 +1261,23 @@
|
||||
return
|
||||
if(iscyborg(target))
|
||||
return ..()
|
||||
if(target.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS) //No message; run_block() handles that
|
||||
var/list/return_list = list()
|
||||
if(target.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, return_list) & BLOCK_SUCCESS) //No message; run_block() handles that
|
||||
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return FALSE
|
||||
if(user.a_intent != INTENT_HARM)
|
||||
if(stun_act(target, user))
|
||||
if(stun_act(target, user, null, return_list))
|
||||
user.do_attack_animation(target)
|
||||
user.adjustStaminaLossBuffered(stun_stam_cost)
|
||||
return
|
||||
else if(!harm_act(target, user))
|
||||
else if(!harm_act(target, user, null, return_list))
|
||||
return ..() //if you can't fry them just beat them with it
|
||||
else //we did harm act them
|
||||
user.do_attack_animation(target)
|
||||
user.adjustStaminaLossBuffered(lethal_stam_cost)
|
||||
|
||||
/obj/item/twohanded/electrostaff/proc/stun_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE)
|
||||
var/stunforce = stun_stamdmg
|
||||
/obj/item/twohanded/electrostaff/proc/stun_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE, list/block_return = list())
|
||||
var/stunforce = block_calculate_resultant_damage(stun_stamdmg, block_return)
|
||||
if(!no_charge_and_force)
|
||||
if(!on)
|
||||
target.visible_message("<span class='warning'>[user] has bapped [target] with [src]. Luckily it was off.</span>", \
|
||||
@@ -1228,8 +1307,8 @@
|
||||
H.forcesay(GLOB.hit_appends)
|
||||
return TRUE
|
||||
|
||||
/obj/item/twohanded/electrostaff/proc/harm_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE)
|
||||
var/lethal_force = lethal_damage
|
||||
/obj/item/twohanded/electrostaff/proc/harm_act(mob/living/target, mob/living/user, no_charge_and_force = FALSE, list/block_return = list())
|
||||
var/lethal_force = block_calculate_resultant_damage(lethal_damage, block_return)
|
||||
if(!no_charge_and_force)
|
||||
if(!on)
|
||||
return FALSE //standard item attack
|
||||
|
||||
@@ -122,11 +122,13 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
|
||||
|
||||
/obj/item/claymore/highlander/pickup(mob/living/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>The power of Scotland protects you! You are shielded from all stuns and knockdowns.</span>")
|
||||
user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!")
|
||||
user.ignore_slowdown(HIGHLANDER)
|
||||
|
||||
/obj/item/claymore/highlander/dropped(mob/living/user)
|
||||
. = ..()
|
||||
user.unignore_slowdown(HIGHLANDER)
|
||||
if(!QDELETED(src))
|
||||
qdel(src) //If this ever happens, it's because you lost an arm
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
icon_state = "human_male"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
|
||||
max_integrity = 200
|
||||
var/timer = 240 //eventually the person will be freed
|
||||
var/timer = 8 MINUTES //eventually the person will be freed
|
||||
var/mob/living/petrified_mob
|
||||
|
||||
/obj/structure/statue/petrified/New(loc, mob/living/L, statue_timer)
|
||||
/obj/structure/statue/petrified/Initialize(mapload, mob/living/L, statue_timer)
|
||||
. = ..()
|
||||
if(statue_timer)
|
||||
timer = statue_timer
|
||||
if(L)
|
||||
@@ -17,25 +19,18 @@
|
||||
L.buckled.unbuckle_mob(L,force=1)
|
||||
L.visible_message("<span class='warning'>[L]'s skin rapidly turns to marble!</span>", "<span class='userdanger'>Your body freezes up! Can't... move... can't... think...</span>")
|
||||
L.forceMove(src)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_EMOTEMUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_LOOC_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_AOOC_MUTE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT)
|
||||
ADD_TRAIT(L, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT)
|
||||
L.faction += "mimic" //Stops mimics from instaqdeling people in statues
|
||||
L.status_flags |= GODMODE
|
||||
obj_integrity = L.health + 100 //stoning damaged mobs will result in easier to shatter statues
|
||||
max_integrity = obj_integrity
|
||||
START_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/structure/statue/petrified/process()
|
||||
if(!petrified_mob)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
timer--
|
||||
petrified_mob.Stun(40) //So they can't do anything while petrified
|
||||
if(timer <= 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/statue/petrified/contents_explosion(severity, target)
|
||||
return
|
||||
QDEL_IN(src, timer)
|
||||
|
||||
/obj/structure/statue/petrified/handle_atom_del(atom/A)
|
||||
if(A == petrified_mob)
|
||||
@@ -59,7 +54,13 @@
|
||||
if(petrified_mob)
|
||||
petrified_mob.status_flags &= ~GODMODE
|
||||
petrified_mob.forceMove(loc)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_MUTE)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_EMOTEMUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_LOOC_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_AOOC_MUTE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOMOVE, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOPICKUP, STATUE_TRAIT)
|
||||
REMOVE_TRAIT(petrified_mob, TRAIT_MOBILITY_NOUSE, STATUE_TRAIT)
|
||||
petrified_mob.take_overall_damage((petrified_mob.health - obj_integrity + 100)) //any new damage the statue incurred is transfered to the mob
|
||||
petrified_mob.faction -= "mimic"
|
||||
petrified_mob = null
|
||||
|
||||
@@ -191,8 +191,7 @@
|
||||
icon = 'icons/turf/walls/shuttle_wall.dmi'
|
||||
icon_state = "map-shuttle"
|
||||
explosion_block = 3
|
||||
flags_1 = CAN_BE_DIRTY_1
|
||||
flags_ricochet = RICOCHET_SHINY | RICOCHET_HARD
|
||||
flags_1 = CAN_BE_DIRTY_1 | DEFAULT_RICOCHET_1
|
||||
sheet_type = /obj/item/stack/sheet/mineral/titanium
|
||||
smooth = SMOOTH_MORE|SMOOTH_DIAGONAL
|
||||
canSmoothWith = list(/turf/closed/wall/mineral/titanium, /obj/machinery/door/airlock/shuttle, /obj/machinery/door/airlock, /obj/structure/window/shuttle, /obj/structure/shuttle/engine/heater, /obj/structure/falsewall/titanium)
|
||||
@@ -303,4 +302,4 @@
|
||||
|
||||
/turf/closed/wall/mineral/plastitanium/copyTurf(turf/T)
|
||||
. = ..()
|
||||
T.transform = transform
|
||||
T.transform = transform
|
||||
|
||||
@@ -12,10 +12,7 @@
|
||||
|
||||
baseturfs = /turf/open/floor/plating
|
||||
|
||||
flags_ricochet = RICOCHET_HARD
|
||||
|
||||
///lower numbers are harder. Used to determine the probability of a hulk smashing through. Also, (hardness - 40) is used as a modifier for objects trying to embed in this (hardness of 30 results in a -10% chance)
|
||||
var/hardness = 40
|
||||
var/hardness = 40 //lower numbers are harder. Used to determine the probability of a hulk smashing through.
|
||||
var/slicing_duration = 100 //default time taken to slice the wall
|
||||
var/sheet_type = /obj/item/stack/sheet/metal
|
||||
var/sheet_amount = 2
|
||||
|
||||
@@ -346,7 +346,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
//print the key
|
||||
if(islist(key))
|
||||
recursive_list_print(output, key, datum_handler, atom_handler)
|
||||
else if(is_proper_datum(key) && (datum_handler || (isatom(key) && atom_handler)))
|
||||
else if(is_object_datatype(key) && (datum_handler || (isatom(key) && atom_handler)))
|
||||
if(isatom(key) && atom_handler)
|
||||
output += atom_handler.Invoke(key)
|
||||
else
|
||||
@@ -360,7 +360,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
var/value = input[key]
|
||||
if(islist(value))
|
||||
recursive_list_print(output, value, datum_handler, atom_handler)
|
||||
else if(is_proper_datum(value) && (datum_handler || (isatom(value) && atom_handler)))
|
||||
else if(is_object_datatype(value) && (datum_handler || (isatom(value) && atom_handler)))
|
||||
if(isatom(value) && atom_handler)
|
||||
output += atom_handler.Invoke(value)
|
||||
else
|
||||
@@ -498,7 +498,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
if(length(select_text))
|
||||
var/text = islist(select_text)? select_text.Join() : select_text
|
||||
var/static/result_offset = 0
|
||||
showmob << browse(text, "window=SDQL-result-[result_offset++]")
|
||||
showmob << browse(text, "window=SDQL-result-[result_offset++];size=800x1200")
|
||||
show_next_to_key = null
|
||||
if(qdel_on_finish)
|
||||
qdel(src)
|
||||
@@ -646,7 +646,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
switch(query_tree[1])
|
||||
if("call")
|
||||
for(var/i in found)
|
||||
if(!is_proper_datum(i))
|
||||
if(!is_object_datatype(i))
|
||||
continue
|
||||
world.SDQL_var(i, query_tree["call"][1], null, i, superuser, src)
|
||||
obj_count_finished++
|
||||
@@ -664,7 +664,10 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
var/list/text_list = list()
|
||||
var/print_nulls = !(options & SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS)
|
||||
obj_count_finished = select_refs
|
||||
var/n = 0
|
||||
for(var/i in found)
|
||||
if(++n == 20000)
|
||||
text_list += "<br><font color='red'><b>TRUNCATED - 20000 OBJECT LIMIT HIT</b></font>"
|
||||
SDQL_print(i, text_list, print_nulls)
|
||||
select_refs[REF(i)] = TRUE
|
||||
SDQL2_TICK_CHECK
|
||||
@@ -675,7 +678,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
if("set" in query_tree)
|
||||
var/list/set_list = query_tree["set"]
|
||||
for(var/d in found)
|
||||
if(!is_proper_datum(d))
|
||||
if(!is_object_datatype(d))
|
||||
continue
|
||||
SDQL_internal_vv(d, set_list)
|
||||
obj_count_finished++
|
||||
@@ -685,47 +688,72 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
obj_count_finished = length(obj_count_finished)
|
||||
state = SDQL2_STATE_SWITCHING
|
||||
|
||||
/datum/SDQL2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE)
|
||||
if(is_proper_datum(object))
|
||||
text_list += "<A HREF='?_src_=vars;[HrefToken(TRUE)];Vars=[REF(object)]'>[REF(object)]</A> : [object]"
|
||||
if(istype(object, /atom))
|
||||
var/atom/A = object
|
||||
var/turf/T = A.loc
|
||||
var/area/a
|
||||
if(istype(T))
|
||||
text_list += " <font color='gray'>at</font> [T] [ADMIN_COORDJMP(T)]"
|
||||
a = T.loc
|
||||
else
|
||||
var/turf/final = get_turf(T) //Recursive, hopefully?
|
||||
if(istype(final))
|
||||
text_list += " <font color='gray'>at</font> [final] [ADMIN_COORDJMP(final)]"
|
||||
a = final.loc
|
||||
/**
|
||||
* Recursively prints out an object to text list for SDQL2 output to admins, with VV links and all.
|
||||
* Recursion limit: 50
|
||||
* Limit imposed by callers should be around 10000 objects
|
||||
* Seriously, if you hit those limits, you're doing something wrong.
|
||||
*/
|
||||
/datum/SDQL2_query/proc/SDQL_print(datum/object, list/text_list, print_nulls = TRUE, recursion = 1, linebreak = TRUE)
|
||||
if(recursion > 50)
|
||||
text_list += "<br><font color='red'><b>RECURSION LIMIT REACHED.</font></b><br>"
|
||||
return
|
||||
if(is_object_datatype(object))
|
||||
if(!islist(object))
|
||||
text_list += "<A HREF='?_src_=vars;[HrefToken(TRUE)];Vars=[REF(object)]'>[object.type] [REF(object)]</A>: [object]"
|
||||
if(istype(object, /atom))
|
||||
if(istype(object, /turf))
|
||||
var/turf/T = object
|
||||
text_list += " [ADMIN_COORDJMP(T)] <font color='gray'>at</font> [T.loc]"
|
||||
else
|
||||
text_list += " <font color='gray'>at</font> nonexistant location"
|
||||
if(a)
|
||||
text_list += " <font color='gray'>in</font> area [a]"
|
||||
if(T.loc != a)
|
||||
text_list += " <font color='gray'>inside</font> [T]"
|
||||
text_list += "<br>"
|
||||
else if(islist(object))
|
||||
var/list/L = object
|
||||
var/first = TRUE
|
||||
text_list += "\["
|
||||
for (var/x in L)
|
||||
if (!first)
|
||||
text_list += ", "
|
||||
first = FALSE
|
||||
SDQL_print(x, text_list)
|
||||
if (!isnull(x) && !isnum(x) && L[x] != null)
|
||||
text_list += " -> "
|
||||
SDQL_print(L[L[x]], text_list)
|
||||
text_list += "]<br>"
|
||||
var/atom/A = object
|
||||
var/atom/container = A.loc
|
||||
if(isturf(container))
|
||||
text_list += " <font color='gray'>in</font> [container] [ADMIN_COORDJMP(container)] <font color='gray'>at</font> [container.loc]"
|
||||
else if(container)
|
||||
var/turf/T = get_turf(container)
|
||||
var/cref = REF(container)
|
||||
text_list += " <font color='gray'>in</font> <A HREF='?_src_=vars;[HrefToken(TRUE)];Vars=[cref]'>[container]([cref])</A>"
|
||||
if(T)
|
||||
text_list += " <font color='gray'>on</font> [T] [ADMIN_COORDJMP(T)] <font color='gray'>at</font>[T.loc]"
|
||||
else
|
||||
text_list += " <font color='gray'>in</font> nullspace"
|
||||
else // lists are snowflake and get special treatment.
|
||||
text_list += "<A HREF='?_src_=vars;[HrefToken(TRUE)];Vars=[REF(object)]'>/list [REF(object)]</A> \[<br>"
|
||||
var/list/L = object
|
||||
if(length(L))
|
||||
for(var/key in object)
|
||||
if(islist(key))
|
||||
text_list += "<span style='margin-left: [min(10, recursion) * 2]em;'>"
|
||||
SDQL_print(key, text_list, TRUE, recursion + 1, FALSE)
|
||||
text_list += "</span>"
|
||||
else
|
||||
SDQL_print(key, text_list, TRUE, recursion, FALSE)
|
||||
if(IS_VALID_ASSOC_KEY(key) && !isnull(L[key]))
|
||||
var/value = L[key]
|
||||
text_list += " --> "
|
||||
if(islist(value))
|
||||
text_list += "<span style='margin-left: [min(10, recursion) * 2]em;'>"
|
||||
SDQL_print(value, text_list, TRUE, recursion + 1, FALSE)
|
||||
text_list += "</span>"
|
||||
else
|
||||
SDQL_print(value, text_list, TRUE, recursion, FALSE)
|
||||
text_list += "<br>"
|
||||
text_list += "\]"
|
||||
if(linebreak)
|
||||
text_list += "<br>"
|
||||
else
|
||||
if(isnull(object))
|
||||
if(print_nulls)
|
||||
text_list += "NULL<br>"
|
||||
text_list += "NULL"
|
||||
else if(istext(object))
|
||||
text_list += "\"[object]\""
|
||||
else if(isnum(object) || ispath(object))
|
||||
text_list += "[object]"
|
||||
else
|
||||
text_list += "[object]<br>"
|
||||
text_list += "UNKNOWN: [object]"
|
||||
if(linebreak)
|
||||
text_list += "<br>"
|
||||
|
||||
/datum/SDQL2_query/CanProcCall()
|
||||
if(!allow_admin_interact)
|
||||
@@ -957,7 +985,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
var/static/list/exclude = list("usr", "src", "marked", "global")
|
||||
var/long = start < expression.len
|
||||
var/datum/D
|
||||
if(is_proper_datum(object))
|
||||
if(is_object_datatype(object))
|
||||
D = object
|
||||
|
||||
if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude)) //3 == length("SS") + 1
|
||||
@@ -1161,9 +1189,6 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
query_list += word
|
||||
return query_list
|
||||
|
||||
/proc/is_proper_datum(thing)
|
||||
return istype(thing, /datum) || istype(thing, /client)
|
||||
|
||||
/obj/effect/statclick/SDQL2_delete/Click()
|
||||
var/datum/SDQL2_query/Q = target
|
||||
Q.delete_click()
|
||||
|
||||
@@ -16,11 +16,19 @@
|
||||
header = "<li>"
|
||||
|
||||
var/item
|
||||
var/name_part = VV_HTML_ENCODE(name)
|
||||
if(level > 0 || islist(D)) //handling keys in assoc lists
|
||||
if(istype(name,/datum))
|
||||
name_part = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(name)]'>[VV_HTML_ENCODE(name)] [REF(name)]</a>"
|
||||
else if(islist(name))
|
||||
var/list/L = name
|
||||
name_part = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(name)]'> /list ([length(L)]) [REF(name)]</a>"
|
||||
|
||||
if (isnull(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>null</span>"
|
||||
item = "[name_part] = <span class='value'>null</span>"
|
||||
|
||||
else if (istext(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
item = "[name_part] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
|
||||
else if (isicon(value))
|
||||
#ifdef VARSICON
|
||||
@@ -28,33 +36,31 @@
|
||||
var/rnd = rand(1,10000)
|
||||
var/rname = "tmp[REF(I)][rnd].png"
|
||||
usr << browse_rsc(I, rname)
|
||||
item = "[VV_HTML_ENCODE(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
item = "[name_part] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
#else
|
||||
item = "[VV_HTML_ENCODE(name)] = /icon (<span class='value'>[value]</span>)"
|
||||
item = "[name_part] = /icon (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
else if (isfile(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>'[value]'</span>"
|
||||
item = "[name_part] = <span class='value'>'[value]'</span>"
|
||||
|
||||
else if(istype(value, /matrix)) // Needs to be before datum
|
||||
else if(istype(value,/matrix)) // Needs to be before datum
|
||||
var/matrix/M = value
|
||||
item = {"[VV_HTML_ENCODE(name)] = <span class='value'>
|
||||
<table class='matrixbrak'><tbody><tr>
|
||||
<td class='lbrak'> </td>
|
||||
<td><table class='matrix'><tbody>
|
||||
<tr><td>[M.a]</td><td>[M.d]</td><td>0</td></tr>
|
||||
<tr><td>[M.b]</td><td>[M.e]</td><td>0</td></tr>
|
||||
<tr><td>[M.c]</td><td>[M.f]</td><td>1</td></tr>
|
||||
</tbody></table></td>
|
||||
<td class='rbrak'> </td>
|
||||
</tr></tbody></table></span>"} //TODO link to modify_transform wrapper for all matrices
|
||||
|
||||
item = {"[name_part] = <span class='value'>
|
||||
<table class='matrixbrak'><tbody><tr><td class='lbrak'> </td><td>
|
||||
<table class='matrix'>
|
||||
<tbody>
|
||||
<tr><td>[M.a]</td><td>[M.d]</td><td>0</td></tr>
|
||||
<tr><td>[M.b]</td><td>[M.e]</td><td>0</td></tr>
|
||||
<tr><td>[M.c]</td><td>[M.f]</td><td>1</td></tr>
|
||||
</tbody>
|
||||
</table></td><td class='rbrak'> </td></tr></tbody></table></span>"} //TODO link to modify_transform wrapper for all matrices
|
||||
else if (istype(value, /datum))
|
||||
var/datum/DV = value
|
||||
if ("[DV]" != "[DV.type]") //if the thing as a name var, lets use it.
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [DV] [DV.type]"
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[DV] [DV.type] [REF(value)]</a>"
|
||||
else
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [DV.type]"
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[DV.type] [REF(value)]</a>"
|
||||
|
||||
else if (islist(value))
|
||||
var/list/L = value
|
||||
@@ -72,19 +78,19 @@
|
||||
|
||||
items += debug_variable(key, val, level + 1, sanitize = sanitize)
|
||||
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>/list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
else
|
||||
item = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>/list ([L.len])</a>"
|
||||
|
||||
else if (name in GLOB.bitfields)
|
||||
var/list/flags = list()
|
||||
for (var/i in GLOB.bitfields[name])
|
||||
if (value & GLOB.bitfields[name][i])
|
||||
flags += i
|
||||
item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(jointext(flags, ", "))]"
|
||||
item = "[name_part] = [VV_HTML_ENCODE(jointext(flags, ", "))]"
|
||||
else
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
item = "[name_part] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
|
||||
return "[header][item]</li>"
|
||||
|
||||
#undef VV_HTML_ENCODE
|
||||
#undef VV_HTML_ENCODE
|
||||
@@ -45,8 +45,11 @@
|
||||
desc = "A solid wall of slightly twitching tendrils with a reflective glow."
|
||||
damaged_desc = "A wall of twitching tendrils with a reflective glow."
|
||||
icon_state = "blob_glow"
|
||||
flags_ricochet = RICOCHET_SHINY
|
||||
point_return = 8
|
||||
max_integrity = 100
|
||||
brute_resist = 1
|
||||
explosion_block = 2
|
||||
|
||||
/obj/structure/blob/shield/reflective/check_projectile_ricochet(obj/item/projectile/P)
|
||||
return PROJECTILE_RICOCHET_FORCE
|
||||
|
||||
|
||||
@@ -167,4 +167,4 @@
|
||||
///obj/item/pipe = 2)
|
||||
time = 80
|
||||
category = CAT_WEAPONRY
|
||||
subcategory = CAT_WEAPON
|
||||
subcategory = CAT_MELEE
|
||||
|
||||
@@ -432,15 +432,18 @@
|
||||
/obj/item/shield/changeling
|
||||
name = "shield-like mass"
|
||||
desc = "A mass of tough, boney tissue. You can still see the fingers as a twisted pattern in the shield."
|
||||
item_flags = ABSTRACT | DROPDEL
|
||||
item_flags = ABSTRACT | DROPDEL | ITEM_CAN_BLOCK
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "ling_shield"
|
||||
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
|
||||
block_chance = 50
|
||||
block_parry_data = /datum/block_parry_data/shield/changeling
|
||||
|
||||
var/remaining_uses //Set by the changeling ability.
|
||||
|
||||
/datum/block_parry_data/shield/changeling
|
||||
block_slowdown = 0
|
||||
|
||||
/obj/item/shield/changeling/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
@@ -451,7 +454,7 @@
|
||||
block_return[BLOCK_RETURN_BLOCK_CAPACITY] = (block_return[BLOCK_RETURN_BLOCK_CAPACITY] || 0) + remaining_uses
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/changeling/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
/obj/item/shield/changeling/active_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
. = ..()
|
||||
if(--remaining_uses < 1)
|
||||
if(ishuman(loc))
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/clockwork/attacked_by(obj/item/I, mob/living/user)
|
||||
/obj/structure/destructible/clockwork/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
if(is_servant_of_ratvar(user) && immune_to_servant_attacks)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -273,6 +273,7 @@
|
||||
knockdown = 20
|
||||
|
||||
/obj/item/restraints/legcuffs/bola/cult/pickup(mob/living/user)
|
||||
. = ..()
|
||||
if(!iscultist(user))
|
||||
to_chat(user, "<span class='warning'>The bola seems to take on a life of its own!</span>")
|
||||
ensnare(user)
|
||||
|
||||
@@ -116,8 +116,7 @@
|
||||
/mob/living/carbon/true_devil/get_ear_protection()
|
||||
return 2
|
||||
|
||||
|
||||
/mob/living/carbon/true_devil/attacked_by(obj/item/I, mob/living/user, def_zone)
|
||||
/mob/living/carbon/true_devil/attacked_by(obj/item/I, mob/living/user, def_zone, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/totitemdamage = pre_attacked_by(I, user)
|
||||
totitemdamage *= check_weakness(I, user)
|
||||
apply_damage(totitemdamage, I.damtype, def_zone)
|
||||
|
||||
@@ -162,6 +162,9 @@
|
||||
to_chat(user, "<span class='danger'>Access denied.</span>")
|
||||
return UI_CLOSE
|
||||
|
||||
/obj/machinery/atmospherics/components/attack_ghost(mob/dead/observer/O)
|
||||
. = ..()
|
||||
atmosanalyzer_scan(airs, O, src, FALSE)
|
||||
|
||||
// Tool acts
|
||||
|
||||
|
||||
@@ -111,3 +111,10 @@
|
||||
pipe_color = paint_color
|
||||
update_node_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/pipe/attack_ghost(mob/dead/observer/O)
|
||||
. = ..()
|
||||
if(parent)
|
||||
atmosanalyzer_scan(parent.air, O, src, FALSE)
|
||||
else
|
||||
to_chat(O, "<span class='warning'>[src] doesn't have a pipenet, which is probably a bug.</span>")
|
||||
|
||||
@@ -147,10 +147,14 @@
|
||||
/obj/machinery/portable_atmospherics/analyzer_act(mob/living/user, obj/item/I)
|
||||
atmosanalyzer_scan(air_contents, user, src)
|
||||
|
||||
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user)
|
||||
/obj/machinery/portable_atmospherics/attacked_by(obj/item/I, mob/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
if(I.force < 10 && !(stat & BROKEN))
|
||||
take_damage(0)
|
||||
else
|
||||
investigate_log("was smacked with \a [I] by [key_name(user)].", INVESTIGATE_ATMOS)
|
||||
add_fingerprint(user)
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/attack_ghost(mob/dead/observer/O)
|
||||
. = ..()
|
||||
atmosanalyzer_scan(air_contents, O, src, FALSE)
|
||||
|
||||
@@ -133,3 +133,6 @@
|
||||
var/parallax_movedir = 0
|
||||
var/parallax_layers_max = 3
|
||||
var/parallax_animate_timer
|
||||
|
||||
//world.time of when the crew manifest can be accessed
|
||||
var/crew_manifest_delay
|
||||
|
||||
@@ -1638,19 +1638,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
|
||||
|
||||
if("flavor_text")
|
||||
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"], MAX_FLAVOR_LEN, TRUE)
|
||||
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(features["flavor_text"]), MAX_FLAVOR_LEN, TRUE)
|
||||
if(!isnull(msg))
|
||||
features["flavor_text"] = html_decode(msg)
|
||||
features["flavor_text"] = msg
|
||||
|
||||
if("silicon_flavor_text")
|
||||
var/msg = stripped_multiline_input(usr, "Set the silicon flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Silicon Flavor Text", features["silicon_flavor_text"], MAX_FLAVOR_LEN, TRUE)
|
||||
var/msg = stripped_multiline_input(usr, "Set the silicon flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Silicon Flavor Text", html_decode(features["silicon_flavor_text"]), MAX_FLAVOR_LEN, TRUE)
|
||||
if(!isnull(msg))
|
||||
features["silicon_flavor_text"] = html_decode(msg)
|
||||
features["silicon_flavor_text"] = msg
|
||||
|
||||
if("ooc_notes")
|
||||
var/msg = stripped_multiline_input(usr, "Set always-visible OOC notes related to content preferences. THIS IS NOT FOR CHARACTER DESCRIPTIONS!", "OOC notes", features["ooc_notes"], MAX_FLAVOR_LEN, TRUE)
|
||||
var/msg = stripped_multiline_input(usr, "Set always-visible OOC notes related to content preferences. THIS IS NOT FOR CHARACTER DESCRIPTIONS!", "OOC notes", html_decode(features["ooc_notes"]), MAX_FLAVOR_LEN, TRUE)
|
||||
if(!isnull(msg))
|
||||
features["ooc_notes"] = html_decode(msg)
|
||||
features["ooc_notes"] = msg
|
||||
|
||||
if("hair")
|
||||
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 32
|
||||
#define SAVEFILE_VERSION_MAX 33
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -194,6 +194,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
if(current_version < 31)
|
||||
S["wing_color"] >> features["wings_color"]
|
||||
S["horn_color"] >> features["horns_color"]
|
||||
|
||||
if(current_version < 33)
|
||||
features["flavor_text"] = html_encode(features["flavor_text"])
|
||||
features["silicon_flavor_text"] = html_encode(features["silicon_flavor_text"])
|
||||
features["ooc_notes"] = html_encode(features["ooc_notes"])
|
||||
|
||||
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
|
||||
if(!ckey)
|
||||
|
||||
@@ -13,21 +13,38 @@ GLOBAL_VAR_INIT(normal_aooc_colour, "#ce254f")
|
||||
if(!mob)
|
||||
return
|
||||
|
||||
if(!(prefs.toggles & CHAT_OOC))
|
||||
to_chat(src, "<span class='danger'> You have OOC muted.</span>")
|
||||
return
|
||||
if(jobban_isbanned(mob, "OOC"))
|
||||
to_chat(src, "<span class='danger'>You have been banned from OOC.</span>")
|
||||
return
|
||||
|
||||
if(!holder)
|
||||
if(mob.stat == DEAD)
|
||||
to_chat(usr, "<span class='danger'>You cannot use AOOC while dead.</span>")
|
||||
return
|
||||
if(!is_special_character(mob))
|
||||
to_chat(usr, "<span class='danger'>You aren't an antagonist!</span>")
|
||||
if(prefs.muted & MUTE_OOC)
|
||||
to_chat(src, "<span class='danger'>You cannot use AOOC (muted).</span>")
|
||||
return
|
||||
if(jobban_isbanned(src.mob, "OOC"))
|
||||
to_chat(src, "<span class='danger'>You are banned from OOC.</span>")
|
||||
return
|
||||
if(!GLOB.aooc_allowed)
|
||||
to_chat(src, "<span class='danger'>AOOC is currently muted.</span>")
|
||||
return
|
||||
if(prefs.muted & MUTE_OOC)
|
||||
to_chat(src, "<span class='danger'>You cannot use AOOC (muted).</span>")
|
||||
return
|
||||
if(!is_special_character(mob))
|
||||
to_chat(usr, "<span class='danger'>You aren't an antagonist!</span>")
|
||||
if(handle_spam_prevention(msg,MUTE_OOC))
|
||||
return
|
||||
if(findtext(msg, "byond://"))
|
||||
to_chat(src, "<B>Advertising other servers is not allowed.</B>")
|
||||
log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
|
||||
return
|
||||
if(mob.stat)
|
||||
to_chat(usr, "<span class='danger'>You cannot use AOOC while unconscious or dead.</span>")
|
||||
return
|
||||
if(isdead(mob))
|
||||
to_chat(src, "<span class='danger'>You cannot use AOOC while ghosting.</span>")
|
||||
return
|
||||
if(HAS_TRAIT(mob, TRAIT_AOOC_MUTE))
|
||||
to_chat(src, "<span class='danger'>You cannot use AOOC right now.</span>")
|
||||
return
|
||||
|
||||
if(QDELETED(src))
|
||||
return
|
||||
|
||||
|
||||
@@ -38,11 +38,15 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")
|
||||
log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
|
||||
return
|
||||
if(mob.stat)
|
||||
to_chat(src, "<span class='danger'>You cannot salt in LOOC while unconscious or dead.</span>")
|
||||
to_chat(src, "<span class='danger'>You cannot use LOOC while unconscious or dead.</span>")
|
||||
return
|
||||
if(istype(mob, /mob/dead))
|
||||
if(isdead(mob))
|
||||
to_chat(src, "<span class='danger'>You cannot use LOOC while ghosting.</span>")
|
||||
return
|
||||
if(HAS_TRAIT(mob, TRAIT_LOOC_MUTE))
|
||||
to_chat(src, "<span class='danger'>You cannot use LOOC right now.</span>")
|
||||
return
|
||||
|
||||
|
||||
msg = emoji_parse(msg)
|
||||
|
||||
|
||||
@@ -469,7 +469,7 @@ Contains:
|
||||
desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome."
|
||||
armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
|
||||
slowdown = 0.8
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old
|
||||
charges = 6
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old
|
||||
|
||||
@@ -330,8 +330,8 @@
|
||||
if(!override)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user)
|
||||
var/damage_dealt = I.force
|
||||
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/damage_dealt = I.force * damage_multiplier
|
||||
if(I.get_sharpness())
|
||||
damage_dealt *= 4
|
||||
if(I.damtype == BURN)
|
||||
|
||||
@@ -54,6 +54,15 @@
|
||||
tastes = list("fish" = 1, "chips" = 1)
|
||||
foodtype = MEAT | VEGETABLES | FRIED
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/fishfry
|
||||
name = "fish fry"
|
||||
desc = "All that and no bag of chips..."
|
||||
icon_state = "fish_fry"
|
||||
list_reagents = list (/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 3)
|
||||
filling_color = "#ee7676"
|
||||
tastes = list("fish" = 1, "pan seared vegtables" = 1)
|
||||
foodtype = MEAT | VEGETABLES | FRIED
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/sushi_basic
|
||||
name = "funa hosomaki"
|
||||
desc = "A small cylindrical kudzu skin, filled with rice and fish."
|
||||
|
||||
@@ -144,6 +144,15 @@
|
||||
is_decorated = TRUE
|
||||
filling_color = "#879630"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/laugh
|
||||
name = "sweet pea donut"
|
||||
desc = "Goes great with a glass of Bastion Burbon!"
|
||||
icon_state = "donut_laugh"
|
||||
bonus_reagents = list(/datum/reagent/consumable/laughter = 3)
|
||||
tastes = list("donut" = 3, "fizzy tutti frutti" = 1,)
|
||||
is_decorated = TRUE
|
||||
filling_color = "#803280"
|
||||
|
||||
//////////////////////JELLY DONUTS/////////////////////////
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly
|
||||
@@ -234,6 +243,15 @@
|
||||
is_decorated = TRUE
|
||||
filling_color = "#879630"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/laugh
|
||||
name = "sweet pea jelly donut"
|
||||
desc = "Goes great with a glass of Bastion Burbon!"
|
||||
icon_state = "jelly_laugh"
|
||||
bonus_reagents = list(/datum/reagent/consumable/laughter = 3)
|
||||
tastes = list("jelly" = 3, "donut" = 1, "fizzy tutti frutti" = 1)
|
||||
is_decorated = TRUE
|
||||
filling_color = "#803280"
|
||||
|
||||
//////////////////////////SLIME DONUTS/////////////////////////
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly
|
||||
@@ -315,6 +333,15 @@
|
||||
is_decorated = TRUE
|
||||
filling_color = "#879630"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly/laugh
|
||||
name = "sweet pea jelly donut"
|
||||
desc = "Goes great with a glass of Bastion Burbon!"
|
||||
icon_state = "jelly_laugh"
|
||||
bonus_reagents = list(/datum/reagent/consumable/laughter = 3)
|
||||
tastes = list("jelly" = 3, "donut" = 1, "fizzy tutti frutti" = 1)
|
||||
is_decorated = TRUE
|
||||
filling_color = "#803280"
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/donut/glaze
|
||||
name = "glazed donut"
|
||||
desc = "A sugar glazed donut."
|
||||
|
||||
@@ -124,4 +124,22 @@
|
||||
trash = /obj/item/kitchen/knife
|
||||
bonus_reagents = list(/datum/reagent/medicine/earthsblood = 1, /datum/reagent/iron = 4)
|
||||
tastes = list("iron" = 1, "conspiracy" = 1)
|
||||
foodtype = VEGETABLES
|
||||
foodtype = VEGETABLES
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/salad/edensalad
|
||||
name = "\improper Salad of Eden"
|
||||
desc = "A salad brimming with untapped potential."
|
||||
icon_state = "eden_salad"
|
||||
trash = /obj/item/reagent_containers/glass/bowl
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 7, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/medicine/earthsblood = 3, /datum/reagent/medicine/omnizine = 5, /datum/reagent/drug/happiness = 2)
|
||||
tastes = list("hope" = 1)
|
||||
foodtype = VEGETABLES
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/salad/gumbo
|
||||
name = "black eyed gumbo"
|
||||
desc = "A spicy and savory meat and rice dish."
|
||||
icon_state = "gumbo"
|
||||
trash = /obj/item/reagent_containers/glass/bowl
|
||||
list_reagents = list(/datum/reagent/consumable/capsaicin = 2, /datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/consumable/nutriment = 5)
|
||||
tastes = list("building heat" = 2, "savory meat and vegtables" = 1)
|
||||
foodtype = GRAIN | MEAT | VEGETABLES
|
||||
|
||||
@@ -262,3 +262,13 @@
|
||||
tastes = list("bungo" = 2, "hot curry" = 4, "tropical sweetness" = 1)
|
||||
filling_color = "#E6A625"
|
||||
foodtype = VEGETABLES | FRUIT | DAIRY
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/soup/peasoup
|
||||
name = "pea soup"
|
||||
desc = "A humble split pea soup."
|
||||
icon_state = "peasoup"
|
||||
bonus_reagents = list (/datum/reagent/consumable/nutriment/vitamin = 6, /datum/reagent/medicine/oculine = 2)
|
||||
list_reagents = list (/datum/reagent/consumable/nutriment = 8)
|
||||
tastes = list("creamy peas"= 2, "parsnip" = 1)
|
||||
filling_color = "#9dc530"
|
||||
foodtype = VEGETABLES
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#define STORAGE_CAPACITY 30
|
||||
#define LIQUID_CAPACIY 200
|
||||
#define LIQUID_CAPACITY 200
|
||||
#define MIXER_CAPACITY 100
|
||||
|
||||
/obj/machinery/food_cart
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/machinery/food_cart/Initialize()
|
||||
. = ..()
|
||||
create_reagents(LIQUID_CAPACIY, OPENCONTAINER | NO_REACT)
|
||||
create_reagents(LIQUID_CAPACITY, OPENCONTAINER | NO_REACT)
|
||||
mixer = new /obj/item/reagent_containers(src, MIXER_CAPACITY)
|
||||
mixer.name = "Mixer"
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
return food_stored >= STORAGE_CAPACITY
|
||||
|
||||
/obj/machinery/food_cart/attackby(obj/item/O, mob/user, params)
|
||||
if(O.tool_behaviour == TOOL_WRENCH)
|
||||
default_unfasten_wrench(user, O, 0)
|
||||
return TRUE
|
||||
if(istype(O, /obj/item/reagent_containers/food/drinks/drinkingglass))
|
||||
var/obj/item/reagent_containers/food/drinks/drinkingglass/DG = O
|
||||
if(!DG.reagents.total_volume) //glass is empty
|
||||
@@ -106,7 +109,7 @@
|
||||
return
|
||||
|
||||
if(href_list["disposeI"])
|
||||
reagents.del_reagent(href_list["disposeI"])
|
||||
reagents.del_reagent(text2path(href_list["disposeI"]))
|
||||
|
||||
if(href_list["dispense"])
|
||||
if(stored_food[href_list["dispense"]]-- <= 0)
|
||||
@@ -116,9 +119,13 @@
|
||||
if(sanitize(O.name) == href_list["dispense"])
|
||||
O.forceMove(drop_location())
|
||||
break
|
||||
log_combat(usr, src, "dispensed [O] from", null, "with [stored_food[href_list["dispense"]]] remaining")
|
||||
|
||||
if(href_list["portion"])
|
||||
portion = clamp(input("How much drink do you want to dispense per glass?") as num, 0, 50)
|
||||
portion = clamp(input("How much drink do you want to dispense per glass?") as num|null, 0, 50)
|
||||
|
||||
if (isnull(portion))
|
||||
return
|
||||
|
||||
if(href_list["pour"] || href_list["m_pour"])
|
||||
if(glasses-- <= 0)
|
||||
@@ -127,16 +134,16 @@
|
||||
else
|
||||
var/obj/item/reagent_containers/food/drinks/drinkingglass/DG = new(loc)
|
||||
if(href_list["pour"])
|
||||
reagents.trans_id_to(DG, href_list["pour"], portion)
|
||||
reagents.trans_id_to(DG, text2path(href_list["pour"]), portion)
|
||||
if(href_list["m_pour"])
|
||||
mixer.reagents.trans_id_to(DG, href_list["m_pour"], portion)
|
||||
mixer.reagents.trans_id_to(DG, text2path(href_list["m_pour"]), portion)
|
||||
|
||||
if(href_list["mix"])
|
||||
if(reagents.trans_id_to(mixer, href_list["mix"], portion) == 0)
|
||||
if(reagents.trans_id_to(mixer, text2path(href_list["mix"]), portion) == 0)
|
||||
to_chat(usr, "<span class='warning'>[mixer] is full!</span>")
|
||||
|
||||
if(href_list["transfer"])
|
||||
if(mixer.reagents.trans_id_to(src, href_list["transfer"], portion) == 0)
|
||||
if(mixer.reagents.trans_id_to(src, text2path(href_list["transfer"]), portion) == 0)
|
||||
to_chat(usr, "<span class='warning'>[src] is full!</span>")
|
||||
|
||||
updateDialog()
|
||||
@@ -152,5 +159,5 @@
|
||||
qdel(src)
|
||||
|
||||
#undef STORAGE_CAPACITY
|
||||
#undef LIQUID_CAPACIY
|
||||
#undef LIQUID_CAPACITY
|
||||
#undef MIXER_CAPACITY
|
||||
|
||||
@@ -121,6 +121,15 @@ datum/crafting_recipe/food/donut/meat
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/donut/matcha
|
||||
|
||||
|
||||
/datum/crafting_recipe/food/donut/laugh
|
||||
name = "Sweet Pea Donut"
|
||||
reqs = list(
|
||||
/datum/reagent/consumable/laughsyrup = 3,
|
||||
/obj/item/reagent_containers/food/snacks/donut/plain = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/donut/laugh
|
||||
|
||||
////////////////////////////////////////////////////JELLY DONUTS///////////////////////////////////////////////////////
|
||||
|
||||
/datum/crafting_recipe/food/donut/jelly/apple
|
||||
@@ -187,6 +196,14 @@ datum/crafting_recipe/food/donut/meat
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/donut/jelly/trumpet
|
||||
|
||||
/datum/crafting_recipe/food/donut/jelly/laugh
|
||||
name = "Sweet Pea Jelly Donut"
|
||||
reqs = list(
|
||||
/datum/reagent/consumable/laughsyrup = 3,
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/plain = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/donut/jelly/laugh
|
||||
|
||||
////////////////////////////////////////////////////SLIME DONUTS///////////////////////////////////////////////////////
|
||||
|
||||
/datum/crafting_recipe/food/donut/slimejelly/apple
|
||||
@@ -253,3 +270,11 @@ datum/crafting_recipe/food/donut/meat
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly/plain = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly/matcha
|
||||
|
||||
/datum/crafting_recipe/food/donut/slimejelly/laugh
|
||||
name = "Sweet Pea Jelly Donut"
|
||||
reqs = list(
|
||||
/datum/reagent/consumable/laughsyrup = 3,
|
||||
/obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly/plain = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly/laugh
|
||||
|
||||
@@ -171,3 +171,14 @@
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/salad/ricepork
|
||||
subcategory = CAT_MEAT
|
||||
|
||||
/datum/crafting_recipe/food/gumbo
|
||||
name = "Black eyed gumbo"
|
||||
reqs = list(
|
||||
/obj/item/reagent_containers/food/snacks/salad/boiledrice = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peas = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/chili = 1,
|
||||
/obj/item/reagent_containers/food/snacks/meat/cutlet = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/salad/gumbo
|
||||
subcategory = CAT_MEAT
|
||||
|
||||
@@ -93,4 +93,17 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/cabbage = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/salad/caesar
|
||||
subcategory = CAT_SALAD
|
||||
subcategory = CAT_SALAD
|
||||
|
||||
|
||||
/datum/crafting_recipe/food/edensalad
|
||||
name = "Salad of Eden"
|
||||
reqs = list(
|
||||
/obj/item/reagent_containers/glass/bowl =1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/ambrosia/deus = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/ambrosia/gaia = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peace = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/salad/edensalad
|
||||
subcategory = CAT_SALAD
|
||||
|
||||
@@ -135,4 +135,14 @@
|
||||
/obj/item/reagent_containers/food/snacks/carpmeat = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/fishandchips
|
||||
subcategory = CAT_SEAFOOD
|
||||
subcategory = CAT_SEAFOOD
|
||||
|
||||
/datum/crafting_recipe/food/fishfry
|
||||
name = "Fish fry"
|
||||
reqs = list(
|
||||
/obj/item/reagent_containers/food/snacks/grown/corn = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peas =1,
|
||||
/obj/item/reagent_containers/food/snacks/carpmeat = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/fishfry
|
||||
subcategory = CAT_SEAFOOD
|
||||
|
||||
@@ -255,4 +255,16 @@
|
||||
/obj/item/reagent_containers/glass/bowl = 1
|
||||
)
|
||||
result= /obj/item/reagent_containers/food/snacks/soup/wish
|
||||
subcategory = CAT_SOUP
|
||||
subcategory = CAT_SOUP
|
||||
|
||||
|
||||
/datum/crafting_recipe/food/peasoup
|
||||
name = "Pea soup"
|
||||
reqs = list(
|
||||
/datum/reagent/water = 10,
|
||||
/obj/item/reagent_containers/food/snacks/grown/peas = 2,
|
||||
/obj/item/reagent_containers/food/snacks/grown/parsnip = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/carrot = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/soup/peasoup
|
||||
subcategory = CAT_SOUP
|
||||
|
||||
@@ -189,6 +189,14 @@
|
||||
begin_day = 22
|
||||
begin_month = APRIL
|
||||
|
||||
/datum/holiday/lesbianvisibility
|
||||
name = "Lesbian Visibility Day"
|
||||
begin_day = 26
|
||||
begin_month = APRIL
|
||||
|
||||
/datum/holiday/lesbianvisibility/greet()
|
||||
return "Today is Lesbian Visibility Day!"
|
||||
|
||||
/datum/holiday/labor
|
||||
name = "Labor Day"
|
||||
begin_day = 1
|
||||
@@ -292,6 +300,14 @@
|
||||
/datum/holiday/programmers/getStationPrefix()
|
||||
return pick("span>","DEBUG: ","null","/list","EVENT PREFIX NOT FOUND") //Portability
|
||||
|
||||
/datum/holiday/bivisibility
|
||||
name = "Bisexual Visibility Day"
|
||||
begin_day = 23
|
||||
begin_month = SEPTEMBER
|
||||
|
||||
/datum/holiday/bivisibility/greet()
|
||||
return "Today is Bisexual Visibility Day!"
|
||||
|
||||
/datum/holiday/questions
|
||||
name = "Stupid-Questions Day"
|
||||
begin_day = 28
|
||||
@@ -314,12 +330,25 @@
|
||||
begin_month = OCTOBER
|
||||
drone_hat = /obj/item/clothing/head/papersack/smiley
|
||||
|
||||
/datum/holiday/comingoutday
|
||||
name = "Coming Out Day"
|
||||
begin_day = 11
|
||||
begin_month = OCTOBER
|
||||
|
||||
/datum/holiday/boss
|
||||
name = "Boss' Day"
|
||||
begin_day = 16
|
||||
begin_month = OCTOBER
|
||||
drone_hat = /obj/item/clothing/head/that
|
||||
|
||||
/datum/holiday/intersexawareness
|
||||
name = "Intersex Awareness Day"
|
||||
begin_day = 26
|
||||
begin_month = OCTOBER
|
||||
|
||||
/datum/holiday/intersexawareness/greet()
|
||||
return "Today is Intersex Awareness Day! It has been [text2num(time2text(world.timeofday, "YYYY")) - 1996] years since the first public protest speaking out against the human rights issues faced by intersex people."
|
||||
|
||||
/datum/holiday/halloween
|
||||
name = HALLOWEEN
|
||||
begin_day = 28
|
||||
@@ -359,6 +388,23 @@
|
||||
begin_month = NOVEMBER
|
||||
drone_hat = /obj/item/reagent_containers/food/snacks/grown/moonflower
|
||||
|
||||
/datum/holiday/transawareness
|
||||
name = "Transgender Awareness Week"
|
||||
begin_day = 13
|
||||
begin_month = NOVEMBER
|
||||
end_day = 19
|
||||
|
||||
/datum/holiday/transawareness/greet()
|
||||
return "This week is Transgender Awareness Week!"
|
||||
|
||||
/datum/holiday/transremembrance
|
||||
name = "Transgender Day of Remembrance"
|
||||
begin_day = 20
|
||||
begin_month = NOVEMBER
|
||||
|
||||
/datum/holiday/transremembrance/greet()
|
||||
return "Today is the Transgender Day of Remembrance."
|
||||
|
||||
/datum/holiday/hello
|
||||
name = "Saying-'Hello' Day"
|
||||
begin_day = 21
|
||||
@@ -397,6 +443,26 @@
|
||||
begin_month = OCTOBER
|
||||
begin_weekday = MONDAY
|
||||
|
||||
/datum/holiday/aceawareness
|
||||
name = "Asexual Awareness Week"
|
||||
begin_month = OCTOBER
|
||||
|
||||
/datum/holiday/aceawareness/greet()
|
||||
return "This week is Asexual Awareness Week!"
|
||||
|
||||
/datum/holiday/aceawareness/shouldCelebrate(dd, mm, yy, ww, ddd) //Ace awareness week falls on the last full week of October.
|
||||
if(mm != begin_month)
|
||||
return FALSE //it's not even the right month
|
||||
var/daypointer = world.timeofday - ((WEEKDAY2NUM(ddd) - 1) * 24 HOURS)
|
||||
if(text2num(time2text(daypointer, "MM")) != mm)
|
||||
return FALSE //it's the beginning of the month and it isn't even a full week
|
||||
daypointer += (24 HOURS * 6)
|
||||
if(text2num(time2text(daypointer, "MM")) != mm)
|
||||
return FALSE //this is the end of the month, and it is not a full week.
|
||||
daypointer += (24 HOURS * 7)
|
||||
if(text2num(time2text(daypointer, "MM")) != mm)
|
||||
return TRUE //the end of next week falls on a different month, meaning that the current week is the last full week
|
||||
|
||||
/datum/holiday/mother
|
||||
name = "Mother's Day"
|
||||
begin_week = 2
|
||||
@@ -421,11 +487,30 @@
|
||||
/datum/holiday/pride/getStationPrefix()
|
||||
return pick("Pride", "Gay", "Bi", "Trans", "Lesbian", "Ace", "Aro", "Agender", pick("Enby", "Enbie"), "Pan", "Intersex", "Demi", "Poly", "Closeted", "Genderfluid")
|
||||
|
||||
/datum/holiday/stonewall
|
||||
name = "Stonewall Riots Anniversary"
|
||||
begin_day = 28
|
||||
begin_month = JUNE
|
||||
|
||||
/datum/holiday/stonewall/greet() //Not gonna lie, I was fairly tempted to make this use the IC year instead of the IRL year, but I was worried that it would have caused too much confusion.
|
||||
return "Today marks the [text2num(time2text(world.timeofday, "YYYY")) - 1969]\th anniversary of the riots at the Stonewall Inn!"
|
||||
|
||||
/datum/holiday/moth
|
||||
name = "Moth Week"
|
||||
begin_month = JULY
|
||||
|
||||
/datum/holiday/moth/shouldCelebrate(dd, mm, yy, ww, ddd) //National Moth Week falls on the last full week of July
|
||||
return mm == JULY && (ww == 4 || (ww == 5 && ddd == SUNDAY))
|
||||
if(mm != begin_month)
|
||||
return FALSE //it's not even the right month
|
||||
var/daypointer = world.timeofday - ((WEEKDAY2NUM(ddd) - 1) * 24 HOURS)
|
||||
if(text2num(time2text(daypointer, "MM")) != mm)
|
||||
return FALSE //it's the beginning of the month and it isn't even a full week
|
||||
daypointer += (24 HOURS * 6)
|
||||
if(text2num(time2text(daypointer, "MM")) != mm)
|
||||
return FALSE //this is the end of the month, and it is not a full week.
|
||||
daypointer += (24 HOURS * 7)
|
||||
if(text2num(time2text(daypointer, "MM")) != mm)
|
||||
return TRUE //the end of next week falls on a different month, meaning that the current week is the last full week
|
||||
|
||||
/datum/holiday/moth/getStationPrefix()
|
||||
return pick("Mothball","Lepidopteran","Lightbulb","Moth","Giant Atlas","Twin-spotted Sphynx","Madagascan Sunset","Luna","Death's Head","Emperor Gum","Polyphenus","Oleander Hawk","Io","Rosy Maple","Cecropia","Noctuidae","Giant Leopard","Dysphania Militaris","Garden Tiger")
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define CATEGORY_MISC "MISC"
|
||||
#define CATEGORY_MOVEMENT "MOVEMENT"
|
||||
#define CATEGORY_TARGETING "TARGETING"
|
||||
#define CATEGORY_COMBAT "COMBAT"
|
||||
|
||||
#define WEIGHT_HIGHEST 0
|
||||
#define WEIGHT_ADMIN 10
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/datum/keybinding/living/toggle_combat_mode
|
||||
hotkey_keys = list("C")
|
||||
name = "toggle_combat_mode"
|
||||
full_name = "Toggle combat mode"
|
||||
category = CATEGORY_COMBAT
|
||||
description = "Toggles whether or not you're in combat mode."
|
||||
|
||||
/datum/keybinding/living/toggle_combat_mode/down(client/user)
|
||||
SEND_SIGNAL(user.mob, COMSIG_TOGGLE_COMBAT_MODE)
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/active_block
|
||||
hotkey_keys = list("Northwest", "F") // HOME
|
||||
name = "active_block"
|
||||
full_name = "Block (Hold)"
|
||||
category = CATEGORY_COMBAT
|
||||
description = "Hold down to actively block with your currently in-hand object."
|
||||
|
||||
/datum/keybinding/living/active_block/down(client/user)
|
||||
var/mob/living/L = user.mob
|
||||
L.keybind_start_active_blocking()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/active_block/up(client/user)
|
||||
var/mob/living/L = user.mob
|
||||
L.keybind_stop_active_blocking()
|
||||
|
||||
/datum/keybinding/living/active_parry
|
||||
hotkey_keys = list("Insert", "G")
|
||||
name = "active_parry"
|
||||
full_name = "Parry"
|
||||
category = CATEGORY_COMBAT
|
||||
description = "Press to initiate a parry sequence with your currently in-hand object."
|
||||
|
||||
/datum/keybinding/living/active_parry/down(client/user)
|
||||
var/mob/living/L = user.mob
|
||||
L.keybind_parry()
|
||||
return TRUE
|
||||
@@ -16,16 +16,6 @@
|
||||
L.resist()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/toggle_combat_mode
|
||||
hotkey_keys = list("C")
|
||||
name = "toggle_combat_mode"
|
||||
full_name = "Toggle combat mode"
|
||||
description = "Toggles whether or not you're in combat mode."
|
||||
|
||||
/datum/keybinding/living/toggle_combat_mode/down(client/user)
|
||||
SEND_SIGNAL(user.mob, COMSIG_TOGGLE_COMBAT_MODE)
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/toggle_resting
|
||||
hotkey_keys = list("V")
|
||||
name = "toggle_resting"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/mob/cycle_intent_right
|
||||
hotkey_keys = list("Northwest", "F") // HOME
|
||||
hotkey_keys = list("Unbound")
|
||||
name = "cycle_intent_right"
|
||||
full_name = "Cycle Action Intent Right"
|
||||
description = ""
|
||||
@@ -28,7 +28,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/mob/cycle_intent_left
|
||||
hotkey_keys = list("Insert", "G")
|
||||
hotkey_keys = list("Unbound")
|
||||
name = "cycle_intent_left"
|
||||
full_name = "Cycle Action Intent Left"
|
||||
description = ""
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
plane = EMISSIVE_BLOCKER_PLANE
|
||||
layer = EMISSIVE_BLOCKER_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
rad_flags = RAD_NO_CONTAMINATE | RAD_PROTECT_CONTENTS
|
||||
//Why?
|
||||
//render_targets copy the transform of the target as well, but vis_contents also applies the transform
|
||||
//to what's in it. Applying RESET_TRANSFORM here makes vis_contents not apply the transform.
|
||||
|
||||
@@ -176,9 +176,6 @@
|
||||
SSticker.queue_delay = 4
|
||||
qdel(src)
|
||||
|
||||
if(!ready && href_list["preference"])
|
||||
if(client)
|
||||
client.prefs.process_link(src, href_list)
|
||||
else if(!href_list["late_join"])
|
||||
new_player_panel()
|
||||
|
||||
@@ -582,6 +579,12 @@
|
||||
qdel(src)
|
||||
|
||||
/mob/dead/new_player/proc/ViewManifest()
|
||||
if(!client)
|
||||
return
|
||||
if(world.time < client.crew_manifest_delay)
|
||||
return
|
||||
client.crew_manifest_delay = world.time + (1 SECONDS)
|
||||
|
||||
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></head><body>"
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += GLOB.data_core.get_manifest(OOC = 1)
|
||||
|
||||
@@ -717,6 +717,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "View Crew Manifest"
|
||||
set category = "Ghost"
|
||||
|
||||
if(!client)
|
||||
return
|
||||
if(world.time < client.crew_manifest_delay)
|
||||
return
|
||||
client.crew_manifest_delay = world.time + (1 SECONDS)
|
||||
|
||||
var/dat
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += GLOB.data_core.get_manifest()
|
||||
|
||||
@@ -333,6 +333,7 @@
|
||||
I.moveToNullspace()
|
||||
else
|
||||
I.forceMove(newloc)
|
||||
on_item_dropped(I)
|
||||
if(I.dropped(src) == ITEM_RELOCATED_BY_DROPPED)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -77,20 +77,18 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
|
||||
. = ..()
|
||||
if(leaping)
|
||||
return -32
|
||||
else if(custom_pixel_y_offset)
|
||||
return custom_pixel_y_offset
|
||||
else
|
||||
return initial(pixel_y)
|
||||
. -= 32
|
||||
if(custom_pixel_y_offset)
|
||||
. += custom_pixel_y_offset
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0)
|
||||
. = ..()
|
||||
if(leaping)
|
||||
return -32
|
||||
else if(custom_pixel_x_offset)
|
||||
return custom_pixel_x_offset
|
||||
else
|
||||
return initial(pixel_x)
|
||||
. -= 32
|
||||
if(custom_pixel_x_offset)
|
||||
. += custom_pixel_x_offset
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_permeability_protection(list/target_zones)
|
||||
return 0.8
|
||||
|
||||
@@ -440,10 +440,9 @@
|
||||
return
|
||||
|
||||
/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
|
||||
. = ..()
|
||||
if(lying)
|
||||
return -6
|
||||
else
|
||||
return initial(pixel_y)
|
||||
. -= 6
|
||||
|
||||
/mob/living/carbon/proc/accident(obj/item/I)
|
||||
if(!I || (I.item_flags & ABSTRACT) || HAS_TRAIT(I, TRAIT_NODROP))
|
||||
|
||||
@@ -76,11 +76,13 @@
|
||||
visible_message("<span class='danger'>[I] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>[I] embeds itself in your [L.name]!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
|
||||
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
|
||||
var/totitemdamage = pre_attacked_by(I, user)
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
|
||||
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
|
||||
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
|
||||
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, null) & BLOCK_SUCCESS))
|
||||
var/list/block_return = list()
|
||||
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, block_return) & BLOCK_SUCCESS))
|
||||
return FALSE
|
||||
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
|
||||
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
|
||||
affecting = bodyparts[1]
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if(istype(J) && (movement_dir || J.stabilizers) && J.allow_thrust(0.01, src))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
/mob/living/carbon/Moved()
|
||||
. = ..()
|
||||
if(. && (movement_type & FLOATING)) //floating is easy
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/mob/living/carbon/human/get_blocking_items()
|
||||
. = ..()
|
||||
if(wear_suit)
|
||||
. |= wear_suit
|
||||
if(!.[wear_suit])
|
||||
.[wear_suit] = wear_suit.block_priority
|
||||
if(w_uniform)
|
||||
. |= w_uniform
|
||||
if(!.[w_uniform])
|
||||
.[w_uniform] = w_uniform.block_priority
|
||||
if(wear_neck)
|
||||
. |= wear_neck
|
||||
if(!.[wear_neck])
|
||||
.[wear_neck] = wear_neck.block_priority
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user