diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 9a05a729285..78717281ebf 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -970,6 +970,9 @@ GLOBAL_LIST_INIT(layers_to_offset, list( /// Types of bullets that mining mobs take full damage from #define MINING_MOB_PROJECTILE_VULNERABILITY list(BRUTE) +/// The duration of the flip emote animation +#define FLIP_EMOTE_DURATION 0.7 SECONDS + // Sprites for photocopying butts #define BUTT_SPRITE_HUMAN_MALE "human_male" #define BUTT_SPRITE_HUMAN_FEMALE "human_female" diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index e73297b684f..4956a2c5284 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -497,6 +497,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_ADAMANTINE_EXTRACT_ARMOR "adamantine_extract_armor" /// Mobs with this trait won't be able to dual wield guns. #define TRAIT_NO_GUN_AKIMBO "no_gun_akimbo" +/// Mobs with this trait cannot be hit by projectiles, meaning the projectiles will just go through. +#define TRAIT_UNHITTABLE_BY_PROJECTILES "unhittable_by_projectiles" /// Projectile with this trait will always hit the defined zone of a struck living mob. #define TRAIT_ALWAYS_HIT_ZONE "always_hit_zone" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 6cc0707c195..37eeb70013e 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -10,6 +10,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_AI_PAUSED" = TRAIT_AI_PAUSED, "TRAIT_BANNED_FROM_CARGO_SHUTTLE" = TRAIT_BANNED_FROM_CARGO_SHUTTLE, "TRAIT_BEING_SHOCKED" = TRAIT_BEING_SHOCKED, + "TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED, "TRAIT_CLIMBABLE" = TRAIT_CLIMBABLE, "TRAIT_CURRENTLY_CLEANING" = TRAIT_CURRENTLY_CLEANING, "TRAIT_CUSTOMIZABLE_REAGENT_HOLDER" = TRAIT_CUSTOMIZABLE_REAGENT_HOLDER, @@ -25,7 +26,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_RUSTY" = TRAIT_RUSTY, "TRAIT_SPINNING" = TRAIT_SPINNING, "TRAIT_STICKERED" = TRAIT_STICKERED, - "TRAIT_COMMISSIONED" = TRAIT_COMMISSIONED, + "TRAIT_UNHITTABLE_BY_PROJECTILES" = TRAIT_UNHITTABLE_BY_PROJECTILES, ), /atom/movable = list( "TRAIT_ACTIVE_STORAGE" = TRAIT_ACTIVE_STORAGE, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index e424b014b3a..98fa115e2fb 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -4,6 +4,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( /atom = list( + "TRAIT_UNHITTABLE_BY_PROJECTILES" = TRAIT_UNHITTABLE_BY_PROJECTILES, "TRAIT_KEEP_TOGETHER" = TRAIT_KEEP_TOGETHER, ), /atom/movable = list( diff --git a/code/modules/bitrunning/orders/bepis.dm b/code/modules/bitrunning/orders/bepis.dm new file mode 100644 index 00000000000..286e9817f3c --- /dev/null +++ b/code/modules/bitrunning/orders/bepis.dm @@ -0,0 +1,23 @@ +/datum/orderable_item/bepis + category_index = CATEGORY_BEPIS + +/datum/orderable_item/bepis/circuit_stack + item_path = /obj/item/stack/circuit_stack/full + cost_per_order = 150 + +/datum/orderable_item/bepis/survival_pen + item_path = /obj/item/pen/survival + cost_per_order = 150 + +/datum/orderable_item/bepis/party_sleeper + item_path = /obj/item/circuitboard/machine/sleeper/party + cost_per_order = 750 + desc = "A decommissioned sleeper circuitboard, repurposed for recreational purposes." + +/datum/orderable_item/bepis/sprayoncan + item_path = /obj/item/toy/sprayoncan + cost_per_order = 750 + +/datum/orderable_item/bepis/pristine + item_path = /obj/item/disk/design_disk/bepis/remove_tech + cost_per_order = 1000 diff --git a/code/modules/bitrunning/orders/disks.dm b/code/modules/bitrunning/orders/disks.dm deleted file mode 100644 index 3015cd1ee61..00000000000 --- a/code/modules/bitrunning/orders/disks.dm +++ /dev/null @@ -1,32 +0,0 @@ -/datum/orderable_item/bitrunning_tech - category_index = CATEGORY_BITRUNNING_TECH - -/datum/orderable_item/bitrunning_tech/item_tier1 - cost_per_order = 1000 - item_path = /obj/item/bitrunning_disk/item/tier1 - desc = "This disk contains a program that lets you equip a medical beamgun, a C4 explosive, or a box of infinite pizza." - -/datum/orderable_item/bitrunning_tech/item_tier2 - cost_per_order = 1500 - item_path = /obj/item/bitrunning_disk/item/tier2 - desc = "This disk contains a program that lets you equip a luxury medipen, a pistol, or an armour vest." - -/datum/orderable_item/bitrunning_tech/item_tier3 - cost_per_order = 2500 - item_path = /obj/item/bitrunning_disk/item/tier3 - desc = "This disk contains a program that lets you equip an advanced energy gun, a dual bladed energy sword, or a minibomb." - -/datum/orderable_item/bitrunning_tech/ability_tier1 - cost_per_order = 1000 - item_path = /obj/item/bitrunning_disk/ability/tier1 - desc = "This disk contains a program that lets you cast Summon Cheese or Lesser Heal." - -/datum/orderable_item/bitrunning_tech/ability_tier2 - cost_per_order = 1800 - item_path = /obj/item/bitrunning_disk/ability/tier2 - desc = "This disk contains a program that lets you cast Fireball, Lightning Bolt, or Forcewall." - -/datum/orderable_item/bitrunning_tech/ability_tier3 - cost_per_order = 3200 - item_path = /obj/item/bitrunning_disk/ability/tier3 - desc = "This disk contains a program that lets you shapeshift into a lesser ashdrake, or a polar bear." diff --git a/code/modules/bitrunning/orders/tech.dm b/code/modules/bitrunning/orders/tech.dm index 286e9817f3c..a4bf59ce18d 100644 --- a/code/modules/bitrunning/orders/tech.dm +++ b/code/modules/bitrunning/orders/tech.dm @@ -1,23 +1,36 @@ -/datum/orderable_item/bepis - category_index = CATEGORY_BEPIS +/datum/orderable_item/bitrunning_tech + category_index = CATEGORY_BITRUNNING_TECH -/datum/orderable_item/bepis/circuit_stack - item_path = /obj/item/stack/circuit_stack/full - cost_per_order = 150 - -/datum/orderable_item/bepis/survival_pen - item_path = /obj/item/pen/survival - cost_per_order = 150 - -/datum/orderable_item/bepis/party_sleeper - item_path = /obj/item/circuitboard/machine/sleeper/party - cost_per_order = 750 - desc = "A decommissioned sleeper circuitboard, repurposed for recreational purposes." - -/datum/orderable_item/bepis/sprayoncan - item_path = /obj/item/toy/sprayoncan - cost_per_order = 750 - -/datum/orderable_item/bepis/pristine - item_path = /obj/item/disk/design_disk/bepis/remove_tech +/datum/orderable_item/bitrunning_tech/item_tier1 cost_per_order = 1000 + item_path = /obj/item/bitrunning_disk/item/tier1 + desc = "This disk contains a program that lets you equip a medical beamgun, a C4 explosive, or a box of infinite pizza." + +/datum/orderable_item/bitrunning_tech/item_tier2 + cost_per_order = 1500 + item_path = /obj/item/bitrunning_disk/item/tier2 + desc = "This disk contains a program that lets you equip a luxury medipen, a pistol, or an armour vest." + +/datum/orderable_item/bitrunning_tech/item_tier3 + cost_per_order = 2500 + item_path = /obj/item/bitrunning_disk/item/tier3 + desc = "This disk contains a program that lets you equip an advanced energy gun, a dual bladed energy sword, or a minibomb." + +/datum/orderable_item/bitrunning_tech/ability_tier1 + cost_per_order = 1000 + item_path = /obj/item/bitrunning_disk/ability/tier1 + desc = "This disk contains a program that lets you cast Summon Cheese or Lesser Heal." + +/datum/orderable_item/bitrunning_tech/ability_tier2 + cost_per_order = 1800 + item_path = /obj/item/bitrunning_disk/ability/tier2 + desc = "This disk contains a program that lets you cast Fireball, Lightning Bolt, or Forcewall." + +/datum/orderable_item/bitrunning_tech/ability_tier3 + cost_per_order = 3200 + item_path = /obj/item/bitrunning_disk/ability/tier3 + desc = "This disk contains a program that lets you shapeshift into a lesser ashdrake, or a polar bear." + +/datum/orderable_item/bitrunning_tech/flip_skillchip + item_path = /obj/item/skillchip/matrix_flip + cost_per_order = 2000 diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm index ab17682fb6f..a2acbf121e7 100644 --- a/code/modules/bitrunning/server/obj_generation.dm +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -187,3 +187,11 @@ if(failed) to_chat(neo, span_warning("One of your disks failed to load. Check for duplicate or inactive disks.")) + + var/obj/item/organ/internal/brain/neo_brain = neo.get_organ_slot(ORGAN_SLOT_BRAIN) + for(var/obj/item/skillchip/skill_chip as anything in neo_brain?.skillchips) + if(!skill_chip.active) + continue + var/obj/item/skillchip/clone_chip = new skill_chip.type + avatar.implant_skillchip(clone_chip, force = TRUE) + clone_chip.try_activate_skillchip(silent = TRUE, force = TRUE) diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index a6afa3398bc..9657a330527 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -507,4 +507,29 @@ activate_message = span_notice("You think of your favourite food and realise that you can rotate its flavour in your mind.") deactivate_message = span_notice("You feel your food-based mind palace crumbling...") +/obj/item/skillchip/matrix_flip + name = "BULLET_DODGER skillchip" + skill_name = "Flip 2 Dodge" + skill_description = "At the cost of stamina, your flips can also be used to dodge incoming projectiles." + skill_icon = FA_ICON_SPINNER + activate_message = span_notice("You feel the urge to flip scenically as if you are the 'Chosen One'.") + deactivate_message = span_notice("The urge to flip goes away.") + +/obj/item/skillchip/matrix_flip/on_activate(mob/living/carbon/user, silent = FALSE) + . = ..() + RegisterSignal(user, COMSIG_MOB_EMOTED("flip"), PROC_REF(on_flip)) + +/obj/item/skillchip/matrix_flip/on_deactivate(mob/living/carbon/user, silent=FALSE) + UnregisterSignal(user, COMSIG_MOB_EMOTED("flip")) + return ..() + +/obj/item/skillchip/matrix_flip/proc/on_flip(mob/living/source) + SIGNAL_HANDLER + if(HAS_TRAIT_FROM(source, TRAIT_UNHITTABLE_BY_PROJECTILES, SKILLCHIP_TRAIT)) + return + playsound(source, 'sound/weapons/fwoosh.ogg', 90, FALSE) + ADD_TRAIT(source, TRAIT_UNHITTABLE_BY_PROJECTILES, SKILLCHIP_TRAIT) + source.adjustStaminaLoss(20) + addtimer(TRAIT_CALLBACK_REMOVE(source, TRAIT_UNHITTABLE_BY_PROJECTILES, SKILLCHIP_TRAIT), FLIP_EMOTE_DURATION + 0.1 SECONDS) + #undef SKILLCHIP_CATEGORY_GENERAL diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 1bb8e61ef2b..bf9e099e5c9 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -79,7 +79,7 @@ /datum/emote/flip/run_emote(mob/user, params , type_override, intentional) . = ..() if(.) - user.SpinAnimation(7,1) + user.SpinAnimation(FLIP_EMOTE_DURATION,1) /datum/emote/flip/check_cooldown(mob/user, intentional) . = ..() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 60adbfed24d..602bbcc8c4c 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -594,6 +594,8 @@ // if pass_flags match, pass through entirely - unless direct target is set. if((target.pass_flags_self & pass_flags) && !direct_target) return FALSE + if(HAS_TRAIT(target, TRAIT_UNHITTABLE_BY_PROJECTILES)) + return FALSE if(!ignore_source_check && firer) var/mob/M = firer if((target == firer) || ((target == firer.loc) && ismecha(firer.loc)) || (target in firer.buckled_mobs) || (istype(M) && (M.buckled == target))) diff --git a/tgstation.dme b/tgstation.dme index ada0d93f13f..3390d046f58 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3437,7 +3437,7 @@ #include "code\modules\bitrunning\objects\netpod.dm" #include "code\modules\bitrunning\objects\quantum_console.dm" #include "code\modules\bitrunning\objects\vendor.dm" -#include "code\modules\bitrunning\orders\disks.dm" +#include "code\modules\bitrunning\orders\bepis.dm" #include "code\modules\bitrunning\orders\flair.dm" #include "code\modules\bitrunning\orders\tech.dm" #include "code\modules\bitrunning\server\_parent.dm"