mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
Merge branch 'master' of https://github.com/tgstation/tgstation into upstream-2025-11-12
This commit is contained in:
@@ -295,10 +295,10 @@
|
||||
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
var/datum/camerachunk/chunk = GLOB.cameranet.getCameraChunk(x, y, epicenter.z)
|
||||
var/datum/camerachunk/chunk = SScameras.generate_chunk(x, y, epicenter.z)
|
||||
// removing cameras in build mode didnt affect it and i guess it needs an AI eye to update so we have to do this manually
|
||||
// unless we only want to see static in a jank manner only if an eye updates it
|
||||
chunk?.update() // UPDATE THE FUCK NOW
|
||||
chunk?.force_update(only_if_necessary = FALSE) // UPDATE THE FUCK NOW
|
||||
. |= chunk
|
||||
|
||||
/obj/item/multitool/ai_detect/proc/cleanup_static()
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
. = ..()
|
||||
if(!sliced)
|
||||
return
|
||||
user.visible_message(span_notice("You take a slice of [src]."), span_notice("[user] takes a slice of [src]."))
|
||||
user.visible_message(span_notice("[user] takes a slice of [src]."), span_notice("You take a slice of [src]."))
|
||||
produce_slice(user)
|
||||
|
||||
/obj/item/food/pizza/proc/get_slices_filter() //to not repeat code
|
||||
|
||||
@@ -17,4 +17,5 @@
|
||||
/obj/item/book/granter/action/spell/charge/recoil(mob/living/user)
|
||||
. = ..()
|
||||
to_chat(user,span_warning("[src] suddenly feels very warm!"))
|
||||
empulse(src, 1, 1)
|
||||
empulse(src, 1, 1, emp_source = src)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
update_mob()
|
||||
empulse(src, 4, 10)
|
||||
empulse(src, 4, 10, emp_source = src)
|
||||
qdel(src)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
/obj/item/implant/emp/activate()
|
||||
. = ..()
|
||||
uses--
|
||||
empulse(imp_in, 3, 5)
|
||||
empulse(imp_in, 3, 5, emp_source = src)
|
||||
if(!uses)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
var/active_force = 30
|
||||
/// Throwforce while active.
|
||||
var/active_throwforce = 20
|
||||
/// The throw speed of the weapon when on
|
||||
var/active_throw_speed = 4
|
||||
/// Sharpness while active.
|
||||
var/active_sharpness = SHARP_EDGED
|
||||
/// Hitsound played attacking while active.
|
||||
@@ -71,7 +73,7 @@
|
||||
/datum/component/transforming, \
|
||||
force_on = active_force, \
|
||||
throwforce_on = active_throwforce, \
|
||||
throw_speed_on = 4, \
|
||||
throw_speed_on = active_throw_speed, \
|
||||
sharpness_on = active_sharpness, \
|
||||
hitsound_on = active_hitsound, \
|
||||
w_class_on = active_w_class, \
|
||||
@@ -166,6 +168,7 @@
|
||||
|
||||
active_force = 150
|
||||
active_throwforce = 30
|
||||
active_throw_speed = 3
|
||||
active_w_class = WEIGHT_CLASS_HUGE
|
||||
|
||||
/obj/item/melee/energy/axe/make_transformable()
|
||||
@@ -173,7 +176,7 @@
|
||||
/datum/component/transforming, \
|
||||
force_on = active_force, \
|
||||
throwforce_on = active_throwforce, \
|
||||
throw_speed_on = throw_speed, \
|
||||
throw_speed_on = active_throw_speed, \
|
||||
sharpness_on = sharpness, \
|
||||
w_class_on = active_w_class, \
|
||||
)
|
||||
@@ -394,7 +397,7 @@
|
||||
icon_angle = 0
|
||||
|
||||
/obj/item/melee/energy/sword/surplus
|
||||
name = "\improper Type I 'Iaito' energy sword"
|
||||
name = "\improper Pattern I 'Iaito' energy sword"
|
||||
desc = "Oversized, overengineered, and somehow still mass-produced. The twin energy blades, theoretically, help make up for the poor cutting plane the emitter generates. \
|
||||
When there are no more heroes in a desperate struggle, it's kill or be killed."
|
||||
icon_state = "surplus_e_sword"
|
||||
@@ -406,6 +409,7 @@
|
||||
inhand_y_dimension = 64
|
||||
active_force = 15 // This force is augmented by the state of our target.
|
||||
active_throwforce = 15
|
||||
active_throw_speed = 3
|
||||
alt_continuous = list("whacks", "smacks", "bashes")
|
||||
alt_simple = list("whack", "smack", "bash")
|
||||
alt_sharpness = NONE
|
||||
@@ -509,6 +513,20 @@
|
||||
if(!HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE) || charge <= 0)
|
||||
return
|
||||
|
||||
expend_charge(user)
|
||||
|
||||
/obj/item/melee/energy/sword/surplus/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE)
|
||||
if(!HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE))
|
||||
return FALSE
|
||||
|
||||
if(prob(final_block_chance) && charge)
|
||||
expend_charge(owner)
|
||||
return TRUE
|
||||
|
||||
/obj/item/melee/energy/sword/surplus/proc/expend_charge(mob/user)
|
||||
if(!charge) // not that this will ever get here without charge, but...
|
||||
return
|
||||
|
||||
charge--
|
||||
if(charge <= 0)
|
||||
user.balloon_alert(user, "out of charge!")
|
||||
@@ -541,20 +559,17 @@
|
||||
armour_penetration = 0
|
||||
wound_bonus = -10
|
||||
demolition_mod = 1
|
||||
embed_type = /datum/embedding/holy_esword
|
||||
sword_color_icon = "blue"
|
||||
light_color = LIGHT_COLOR_LIGHT_CYAN
|
||||
active_force = 18
|
||||
active_throwforce = 10
|
||||
active_throw_speed = 3
|
||||
alt_force_mod = -3
|
||||
|
||||
/obj/item/melee/energy/sword/nullrod/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/nullrod_core)
|
||||
|
||||
/datum/embedding/holy_esword
|
||||
embed_chance = 0
|
||||
|
||||
/obj/item/melee/energy/sword/nullrod/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE)
|
||||
if(!HAS_TRAIT(src, TRAIT_TRANSFORM_ACTIVE))
|
||||
return FALSE
|
||||
|
||||
@@ -545,3 +545,4 @@
|
||||
if(attack_type == (PROJECTILE_ATTACK || LEAP_ATTACK || OVERWHELMING_ATTACK))
|
||||
final_block_chance = 0 //Don't bring a...mace to a gunfight, and also you aren't going to really block someone full body tackling you with a mace. Or a road roller, if one happened to hit you.
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -662,6 +662,15 @@
|
||||
worn_icon_state = "grass_sheath"
|
||||
storage_type = /datum/storage/green_sabre_belt
|
||||
|
||||
/obj/item/storage/belt/sheath/gladius
|
||||
name = "gladius scabbard"
|
||||
desc = "A fun-sized sheath for a fun-sized sword."
|
||||
icon_state = "gladius_sheath"
|
||||
inhand_icon_state = "gladius_sheath"
|
||||
worn_icon_state = "gladius_sheath"
|
||||
storage_type = /datum/storage/gladius_belt
|
||||
stored_blade = /obj/item/claymore/gladius
|
||||
|
||||
/obj/item/storage/belt/plant
|
||||
name = "botanical belt"
|
||||
desc = "A sturdy leather belt used to hold most hydroponics supplies."
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
if (COOLDOWN_FINISHED(src, clack_cooldown))
|
||||
click_clack()
|
||||
return ..()
|
||||
if (!IsEdible(attacked) || attacked.w_class > WEIGHT_CLASS_NORMAL || !isnull(tonged))
|
||||
if (!IS_EDIBLE(attacked) || attacked.w_class > WEIGHT_CLASS_NORMAL || !isnull(tonged))
|
||||
return ..()
|
||||
tonged = attacked
|
||||
attacked.do_pickup_animation(src)
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
#define ENGINE_COOLDOWN (5 SECONDS)
|
||||
#define DASH_COOLDOWN (2.5 SECONDS)
|
||||
#define ENGINE_COOLDOWN 5 SECONDS
|
||||
#define SLASH_COOLDOWN 1.2 SECONDS
|
||||
#define SLASH_WINDUP 1 SECONDS
|
||||
#define CHARGE_DAMAGE_MOD 10
|
||||
#define HOUSE_EDGE_ICONS_MAX 3
|
||||
#define HOUSE_EDGE_ICONS_MIN 0
|
||||
|
||||
/**
|
||||
* File for the House Edge sword and the V8 Engine, obtained from the black market.
|
||||
*/
|
||||
|
||||
/obj/item/v8_engine
|
||||
name = "ancient engine"
|
||||
desc = "An extremely well-preserved, massive V8 engine from the early 2000s. It seems to be missing the rest of the vehicle. There's a tiny label on the side."
|
||||
@@ -46,8 +52,9 @@
|
||||
name = "House Edge"
|
||||
desc = "Dangerous. Loud. Sleek. It has a built in roulette wheel. This thing could easily rip your arm off if you're not careful."
|
||||
icon = 'icons/obj/weapons/sword.dmi'
|
||||
icon_state = "house_edge0"
|
||||
inhand_icon_state = "house_edge0"
|
||||
icon_state = "house_edge"
|
||||
base_icon_state = "house_edge"
|
||||
inhand_icon_state = "house_edge"
|
||||
icon_angle = -45
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
@@ -57,6 +64,7 @@
|
||||
throwforce = 10
|
||||
throw_range = 5
|
||||
throw_speed = 1
|
||||
armour_penetration = 15
|
||||
hitsound = 'sound/items/car_engine_start.ogg'
|
||||
/// The number of charges the house edge has accrued through 2-handed hits, to charge a more powerful charge attack.
|
||||
var/fire_charges = 0
|
||||
@@ -74,14 +82,11 @@
|
||||
/obj/item/house_edge/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
|
||||
if(!ismob(target))
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_WIELDED))
|
||||
var/mob/mob_target = target
|
||||
if(HAS_TRAIT(src, TRAIT_WIELDED) && mob_target.stat != DEAD)
|
||||
//Add a fire charge to a max of 3, updates icon_state.
|
||||
fire_charges = clamp((fire_charges + 1), HOUSE_EDGE_ICONS_MIN, HOUSE_EDGE_ICONS_MAX)
|
||||
COOLDOWN_RESET(src, fire_charge_cooldown)
|
||||
else
|
||||
//Lose a fire charge to a min of 0, updates icon_state.
|
||||
fire_charges = clamp((fire_charges - 1), HOUSE_EDGE_ICONS_MIN, HOUSE_EDGE_ICONS_MAX)
|
||||
do_sparks(number = 0, cardinal_only = TRUE, source = src)
|
||||
update_appearance(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/item/house_edge/ranged_interact_with_atom_secondary(atom/interacting_with, mob/living/user, list/modifiers)
|
||||
@@ -90,26 +95,102 @@
|
||||
if(fire_charges <= 0)
|
||||
balloon_alert(user, "no fire charges!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
user.throw_at(target = get_turf(interacting_with), range = 2 * fire_charges, speed = 5, thrower = user, spin = FALSE, gentle = FALSE, quickstart = TRUE)
|
||||
COOLDOWN_START(src, fire_charge_cooldown, DASH_COOLDOWN)
|
||||
reset_charges(on_dash = TRUE)
|
||||
to_chat(user, span_boldnotice("You take aim at [interacting_with]..."))
|
||||
user.add_shared_particles(/particles/bonfire)
|
||||
|
||||
if(!do_after(user, SLASH_WINDUP, target = src))
|
||||
// Special attack fizzles, no slash and charges lost.
|
||||
reset_charges()
|
||||
drop_particles(user)
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
user.add_shared_particles(/particles/bonfire)
|
||||
new /obj/effect/temp_visual/focus_ring(get_turf(src))
|
||||
playsound(src, 'sound/items/car_engine_start.ogg', vol = 35, vary = FALSE, extrarange = 3)
|
||||
|
||||
if(!do_after(user, SLASH_WINDUP * 2, target = src) || fire_charges < 3)
|
||||
flaming_slash(interacting_with, user, upgraded = FALSE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
flaming_slash(interacting_with, user, upgraded = TRUE) //Upgraded slash.
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/house_edge/update_icon_state()
|
||||
inhand_icon_state = HAS_TRAIT(src, TRAIT_WIELDED) ? "house_edge1" : "house_edge0"
|
||||
icon_state = "house_edge[fire_charges]"
|
||||
inhand_icon_state = HAS_TRAIT(src, TRAIT_WIELDED) ? "house_edge1" : "house_edge"
|
||||
icon_state = "[base_icon_state][fire_charges ? fire_charges : ""]"
|
||||
return ..()
|
||||
|
||||
/obj/item/house_edge/proc/reset_charges(on_dash = FALSE)
|
||||
if(!COOLDOWN_FINISHED(src, fire_charge_cooldown) && !on_dash)
|
||||
/**
|
||||
* Proc that handles the house edge's fire_charge mechanic when resetting charges back to zero.
|
||||
* Updates icon, sets count, and updates icon.
|
||||
*/
|
||||
/obj/item/house_edge/proc/reset_charges(on_slash = FALSE)
|
||||
if(!COOLDOWN_FINISHED(src, fire_charge_cooldown) && !on_slash)
|
||||
return
|
||||
if(fire_charges)
|
||||
balloon_alert_to_viewers("charges lost!")
|
||||
fire_charges = 0
|
||||
icon_state = "house_edge[fire_charges]"
|
||||
update_icon()
|
||||
update_icon(UPDATE_OVERLAYS|UPDATE_ICON_STATE)
|
||||
|
||||
/// Kills any of the relevant particles off the wielder, as added during special attacks.
|
||||
/obj/item/house_edge/proc/drop_particles(mob/living/user)
|
||||
user.remove_shared_particles(/particles/bonfire)
|
||||
|
||||
/**
|
||||
* Proc that creates and fires the flaming_slash projectile from the house edge special attack.
|
||||
* Extends off the ranged_interact_with_atom_secondary() behavior.
|
||||
* * upgraded: when juiced up from the second do_after, applies a light explosion radius to the slash.
|
||||
*/
|
||||
/obj/item/house_edge/proc/flaming_slash(atom/interacting_with, mob/living/user, upgraded = FALSE)
|
||||
// Do the cool slash
|
||||
var/obj/projectile/flaming_slash/projectile = new /obj/projectile/flaming_slash(get_turf(src))
|
||||
|
||||
projectile.aim_projectile(interacting_with, src)
|
||||
projectile.firer = user
|
||||
projectile.damage += (10 * fire_charges)
|
||||
if(upgraded)
|
||||
projectile.explosion_power = 1
|
||||
projectile.damage /= 2 // The damage is pretty solid normally, but with the explosion and all the RNG that comes with, it's nearly a 1-shot. This evens a playing field a bit.
|
||||
projectile.fire(null, interacting_with)
|
||||
|
||||
user.visible_message(span_danger("[user] makes a[upgraded ? " devastating" : "" ] blazing slash at [interacting_with]!"),\
|
||||
span_notice("You take a blazing swipe at [interacting_with]!"))
|
||||
playsound(src, 'sound/items/modsuit/flamethrower.ogg', vol = 75, vary = FALSE, extrarange = 3)
|
||||
playsound(src, 'sound/items/weapons/slash.ogg', vol = 50, vary = FALSE, extrarange = 3)
|
||||
|
||||
drop_particles(user)
|
||||
COOLDOWN_START(src, fire_charge_cooldown, SLASH_COOLDOWN)
|
||||
reset_charges(on_slash = TRUE)
|
||||
|
||||
/// Flaming slash for the special attack at max charges.
|
||||
/obj/projectile/flaming_slash
|
||||
name = "flaming slash"
|
||||
desc = "Someone is about to cash out."
|
||||
icon_state = "flaming_slash"
|
||||
damage_type = BURN
|
||||
armor_flag = MELEE //We're operating off of anime remote slash logic here. As such, we can treat this as a hybrid burn/brute this way.
|
||||
damage = 10 // Damage amps based on the number of flame_charges it was created off of.
|
||||
speed = 2
|
||||
light_range = 1
|
||||
light_power = 1
|
||||
light_color = LIGHT_COLOR_FIRE
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
///Applied in on_hit as the light_devastation_range. Defaults to zero unless giving the slash an extra juiced charge.
|
||||
var/explosion_power = 0
|
||||
|
||||
/obj/projectile/flaming_slash/on_hit(atom/target, blocked, pierce_hit)
|
||||
. = ..()
|
||||
explosion(loc,
|
||||
light_impact_range = explosion_power,
|
||||
flame_range = 3,
|
||||
explosion_cause = "[firer] using \the [fired_from]",
|
||||
explosion_arc = 120
|
||||
)
|
||||
|
||||
#undef ENGINE_COOLDOWN
|
||||
#undef DASH_COOLDOWN
|
||||
#undef SLASH_COOLDOWN
|
||||
#undef SLASH_WINDUP
|
||||
#undef CHARGE_DAMAGE_MOD
|
||||
#undef HOUSE_EDGE_ICONS_MAX
|
||||
#undef HOUSE_EDGE_ICONS_MIN
|
||||
|
||||
@@ -363,6 +363,25 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/item/claymore/highlander/robot/process()
|
||||
loc.layer = ABOVE_ALL_MOB_LAYER
|
||||
|
||||
/obj/item/claymore/gladius
|
||||
name = "gladius"
|
||||
desc = "A short but formidable sword, favored by recently-reanimated ancient warriors."
|
||||
icon = 'icons/obj/weapons/sword.dmi'
|
||||
icon_state = "gladius"
|
||||
inhand_icon_state = "gladius"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
|
||||
sharpness = SHARP_POINTY
|
||||
attack_verb_continuous = list("stabs", "cuts")
|
||||
attack_verb_simple = list("stab", "cut")
|
||||
slot_flags = null
|
||||
sound_vary = TRUE
|
||||
block_sound = 'sound/items/weapons/parry.ogg'
|
||||
hitsound = 'sound/items/weapons/bladeslice.ogg'
|
||||
pickup_sound = SFX_KNIFE_PICKUP
|
||||
drop_sound = SFX_KNIFE_DROP
|
||||
|
||||
|
||||
/obj/item/katana
|
||||
name = "katana"
|
||||
desc = "Woefully underpowered in D20."
|
||||
@@ -1023,10 +1042,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
/// Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc.
|
||||
var/static/list/splattable
|
||||
/// Things in this list which take a lot more damage from the fly swatter, but not be necessarily killed by it.
|
||||
var/static/list/strong_against
|
||||
/// How much extra damage the fly swatter does against mobs it is strong against
|
||||
var/extra_strength_damage = 24
|
||||
|
||||
/obj/item/melee/flyswatter/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -1041,11 +1056,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
/obj/effect/decal/cleanable/ants,
|
||||
/obj/item/queen_bee,
|
||||
))
|
||||
if (isnull(strong_against))
|
||||
strong_against = typecacheof(list(
|
||||
/mob/living/basic/spider,
|
||||
))
|
||||
|
||||
AddElement(/datum/element/bane, mob_biotypes = MOB_BUG, target_type = /mob/living/basic, damage_multiplier = 0, added_damage = 24, requires_combat_mode = FALSE)
|
||||
|
||||
/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, list/modifiers, list/attack_modifiers)
|
||||
if(is_type_in_typecache(target, splattable))
|
||||
@@ -1057,10 +1068,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
|
||||
bug.gib(DROP_ALL_REMAINS)
|
||||
else
|
||||
qdel(target)
|
||||
return
|
||||
if(is_type_in_typecache(target, strong_against) && isliving(target))
|
||||
var/mob/living/living_target = target
|
||||
living_target.adjustBruteLoss(extra_strength_damage)
|
||||
|
||||
/obj/item/proc/can_trigger_gun(mob/living/user, akimbo_usage)
|
||||
if(!user.can_use_guns(src))
|
||||
|
||||
Reference in New Issue
Block a user