diff --git a/code/__defines/species.dm b/code/__defines/species.dm index 34bc7bea241..60cf982786c 100644 --- a/code/__defines/species.dm +++ b/code/__defines/species.dm @@ -39,6 +39,9 @@ #define SPECIES_SKELETON "Skeleton" #define SPECIES_CULTGHOST "Apparition" #define SPECIES_ZOMBIE "Zombie" +#define SPECIES_ZOMBIE_BULL "Zombie Bull" +#define SPECIES_ZOMBIE_HUNTER "Zombie Hunter" +#define SPECIES_ZOMBIE_RHINO "Zombie Rhino" #define SPECIES_ZOMBIE_TAJARA "Tajara Zombie" #define SPECIES_ZOMBIE_UNATHI "Unathi Zombie" #define SPECIES_ZOMBIE_SKRELL "Skrell Zombie" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index cbca46adbde..701a0694bd1 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -227,7 +227,7 @@ // Its vital that if you make new power tools or new recipies that you include this -/obj/item/Initialize() +/obj/item/Initialize(mapload, ...) . = ..() if(islist(armor)) for(var/type in armor) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 0f79e9c1078..19c9eea958d 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -393,3 +393,31 @@ beakers += B1 beakers += B2 icon_state = initial(icon_state) +"_locked" + +///Zombie-producing grenade +/obj/item/grenade/chem_grenade/trioxin + name = "trioxin grenade" + desc = "Concentrated trioxin. The lab really cooked for this one." + stage = 2 + path = 1 + +/obj/item/grenade/chem_grenade/trioxin/Initialize() + . = ..() + var/obj/item/reagent_containers/glass/beaker/large/B1 = new(src) + var/obj/item/reagent_containers/glass/beaker/large/B2 = new(src) + + B1.reagents.add_reagent(/singleton/reagent/phosphorus, 40) + B1.reagents.add_reagent(/singleton/reagent/potassium, 40) + B1.reagents.add_reagent(/singleton/reagent/toxin/trioxin, 40) + B2.reagents.add_reagent(/singleton/reagent/sugar, 40) + B2.reagents.add_reagent(/singleton/reagent/toxin/trioxin, 80) + + detonator = new/obj/item/device/assembly_holder/timer_igniter(src) + + var/obj/item/device/assembly/timer/tmr = detonator.a_left + tmr.time = 2 + detonator.name = "[initial(detonator.name)] ([tmr.time] secs)" + + beakers += B1 + beakers += B2 + icon_state = initial(icon_state) +"_locked" diff --git a/code/modules/heavy_vehicle/mech_interaction.dm b/code/modules/heavy_vehicle/mech_interaction.dm index cf54f13ed13..3e78de029b5 100644 --- a/code/modules/heavy_vehicle/mech_interaction.dm +++ b/code/modules/heavy_vehicle/mech_interaction.dm @@ -480,7 +480,7 @@ /mob/living/heavy_vehicle/attack_hand(var/mob/user) // Drag the pilot out if possible. - if(user.a_intent == I_HURT || user.a_intent == I_GRAB) + if(user.a_intent == I_GRAB) if(!LAZYLEN(pilots)) to_chat(user, "There is nobody inside \the [src].") else if(!hatch_closed) @@ -489,6 +489,11 @@ if(do_after(user, 30) && user.Adjacent(src) && (pilot in pilots) && !hatch_closed) user.visible_message("\The [user] drags \the [pilot] out of \the [src]!") eject(pilot, silent=1) + + return + + if(user.a_intent == I_HURT) + attack_generic(user) return // Otherwise toggle the hatch. @@ -501,6 +506,20 @@ update_icon() return +/mob/living/heavy_vehicle/attack_generic(var/mob/user, var/damage, var/attack_message, var/armor_penetration, var/attack_flags, var/damage_type = DAMAGE_BRUTE) + if(!(user in pilots)) + . = ..() + + var/mob/living/carbon/human/H = user + + if(!istype(H)) + return + + var/datum/martial_art/attacker_style = H.primary_martial_art + if(attacker_style && attacker_style.harm_act(H, src)) + return TRUE + + /mob/living/heavy_vehicle/proc/attack_self(var/mob/user) return visible_message("\The [src] pokes itself.") diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index b8c16cca7f3..4bac5211572 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -276,7 +276,7 @@ return FALSE var/mob/living/carbon/human/H = user playsound(loc, /singleton/sound_category/wood_break_sound, 50, TRUE) - var/damage = H.default_attack.get_unarmed_damage() ? H.default_attack.get_unarmed_damage() : 1 + var/damage = H.default_attack.get_unarmed_damage(H, src) ? H.default_attack.get_unarmed_damage(H, src) : 1 if(H.default_attack.edge || H.default_attack.sharp) damage *= 2 health -= damage diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index 34e18e7c0cd..f0ea4fa3dc9 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -100,7 +100,7 @@ var/damage_flags = attack.damage_flags() var/armor_penetration = attack.armor_penetration - real_damage += attack.get_unarmed_damage(A) + real_damage += attack.get_unarmed_damage(A, D) real_damage *= D.damage_multiplier rand_damage *= D.damage_multiplier @@ -137,6 +137,33 @@ return 1 +/datum/martial_art/proc/heavy_vehicle_basic_hit(var/mob/living/carbon/human/A, var/mob/living/heavy_vehicle/D) + if(!istype(D)) + crash_with("The target is not an heavy_vehicle") + return + + var/hit_zone = A.zone_sel.selecting + //var/obj/item/mech_component/affecting = D.zoneToComponent(hit_zone) + + var/rand_damage = rand(1, 5) + + var/datum/unarmed_attack/attack = A.get_unarmed_attack(src, hit_zone) + var/hit_dam_type = attack.damage_type + var/damage_flags = attack.damage_flags() + var/armor_penetration = attack.armor_penetration + + var/real_damage = rand_damage + real_damage += attack.get_unarmed_damage(A, D) + + attack.show_attack(A, D, hit_zone, rand_damage) + + var/miss_type = 1 //For now, mechs can't parry + playsound(D.loc, ((miss_type) ? (miss_type == 1 ? attack.miss_sound : 'sound/weapons/thudswoosh.ogg') : attack.attack_sound), 25, 1, -1) + D.apply_damage(real_damage, hit_dam_type, hit_zone, damage_flags = damage_flags, armor_pen = armor_penetration) + + return TRUE + + /datum/martial_art/proc/teach(var/mob/living/carbon/human/H) if(help_verb) add_verb(H, help_verb) diff --git a/code/modules/martial_arts/zombie.dm b/code/modules/martial_arts/zombie.dm index 4a7de62a202..f14177fc07c 100644 --- a/code/modules/martial_arts/zombie.dm +++ b/code/modules/martial_arts/zombie.dm @@ -17,7 +17,13 @@ add_to_streak("H", D) if(check_streak(A, D)) return TRUE - basic_hit(A, D) + + //Apply the hit based on what is being attacked + if(istype(D, /mob/living/heavy_vehicle)) + heavy_vehicle_basic_hit(A, D) + else + basic_hit(A, D) + return TRUE @@ -38,4 +44,4 @@ to_chat(usr, "Strong Bite: Harm Harm Harm. Delivers a strong bite to your foe. This bite does 5 to 10 damage but pierces through all armour.") to_chat(usr, SPAN_NOTICE("Press the Check Attacks verb in the IC tab! Your bite infects, but it is less powerful than your claws.")) -#undef STRONG_BITE \ No newline at end of file +#undef STRONG_BITE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index f395ac07b65..6c60272ebca 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -95,8 +95,6 @@ sync_organ_dna() make_blood() - available_maneuvers = species.maneuvers.Copy() - pixel_x = species.icon_x_offset pixel_y = species.icon_y_offset @@ -1441,6 +1439,11 @@ if(species.holder_type) holder_type = species.holder_type + //Clear out the manouvers of the previous specie and add the one of the current specie + available_maneuvers = null + if(species?.maneuvers) + available_maneuvers = species.maneuvers.Copy() + icon_state = lowertext(species.name) species.create_organs(src) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 612ee50aa91..0d807b501a8 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -257,7 +257,7 @@ var/hit_dam_type = attack.damage_type var/damage_flags = attack.damage_flags() - real_damage += attack.get_unarmed_damage(H) + real_damage += attack.get_unarmed_damage(src, H) real_damage *= damage_multiplier rand_damage *= damage_multiplier diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 26378279bcd..ce1f8d3dee7 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -384,6 +384,8 @@ This function restores all organs. /mob/living/carbon/human/proc/get_organ(var/zone, var/allow_no_result = FALSE) + SHOULD_NOT_SLEEP(TRUE) + RETURN_TYPE(/obj/item/organ) if(!zone) if(allow_no_result) return diff --git a/code/modules/mob/living/carbon/human/species/outsider/undead.dm b/code/modules/mob/living/carbon/human/species/outsider/undead.dm index 8b3b9fed753..086748503e1 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/undead.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/undead.dm @@ -80,7 +80,7 @@ stamina = 500 //Tireless automatons stamina_recovery = 1 sprint_speed_factor = 0.3 - exhaust_threshold = 0 //No oxyloss, so zero threshold + exhaust_threshold = 10 max_nutrition_factor = -1 @@ -164,8 +164,6 @@ unarmed_types = list(/datum/unarmed_attack/bite/infectious, /datum/unarmed_attack/claws/strong/zombie) darksight = 8 - slowdown = 0.5 - has_fine_manipulation = FALSE speech_sounds = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg') @@ -194,11 +192,11 @@ BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/zombie) ) - total_health = 100 + total_health = 80 slowdown = 2 - vision_flags = DEFAULT_SIGHT | SEE_MOBS + vision_flags = DEFAULT_SIGHT reagent_tag = IS_UNDEAD @@ -219,7 +217,7 @@ stamina = 500 //Tireless automatons stamina_recovery = 1 sprint_speed_factor = 0.1 - exhaust_threshold = 0 //No oxyloss, so zero threshold + exhaust_threshold = 10 inherent_verbs = list(/mob/living/carbon/human/proc/darkness_eyes) @@ -235,6 +233,17 @@ H.accent = ACCENT_BLUESPACE return ..() +//Zombies do not have oxygen, so we have to handle the sprint this way +/datum/species/zombie/handle_sprint_cost(var/mob/living/carbon/human/H, var/cost, var/pre_move) + . = ..() + + if(exhaust_threshold && (H.stamina) < (exhaust_threshold * 0.8)) + H.m_intent = M_WALK + H.hud_used.move_intent.update_move_icon(H) + to_chat(H, SPAN_DANGER("You're too exhausted to run anymore!")) + H.flash_pain(H.get_shock()) + return 0 + /datum/species/zombie/tajara name = SPECIES_ZOMBIE_TAJARA name_plural = "Tajara Zombies" @@ -311,3 +320,99 @@ dust_remains_type = /obj/effect/decal/remains/xeno/burned default_h_style = "Skrell Short Tentacles" + + +///A zombie tuned for tankness +/datum/species/zombie/bull + name = SPECIES_ZOMBIE_BULL + name_plural = SPECIES_ZOMBIE_BULL+"s" + icobase = 'icons/mob/human_races/zombie/r_zombie_bull.dmi' + deform = 'icons/mob/human_races/zombie/r_zombie_bull.dmi' + + total_health = 300 + + allowed_eat_types = TYPE_ORGANIC | TYPE_HUMANOID | TYPE_SYNTHETIC | TYPE_WEIRD + gluttonous = GLUT_ANYTHING + stomach_capacity = 10 + + stamina = 50 + sprint_speed_factor = 0.9 + slowdown = 2 + exhaust_threshold = 20 + + bump_flag = HEAVY + species_height = HEIGHT_CLASS_TALL + + natural_armor = list( + ballistic = ARMOR_BALLISTIC_RIFLE, + laser = ARMOR_LASER_MEDIUM, + melee = ARMOR_MELEE_MAJOR, + bomb = null, + energy = ARMOR_ENERGY_RESISTANT + ) + + unarmed_types = list(/datum/unarmed_attack/bite/infectious) + + +///A zombie tuned to hunt preys +/datum/species/zombie/hunter + name = SPECIES_ZOMBIE_HUNTER + name_plural = SPECIES_ZOMBIE_HUNTER+"s" + icobase = 'icons/mob/human_races/zombie/r_zombie_hunter.dmi' + deform = 'icons/mob/human_races/zombie/r_zombie_hunter.dmi' + slowdown = 2 + + total_health = 90 + + stamina = 40 + sprint_speed_factor = 0.9 + slowdown = -2 + standing_jump_range = 5 + natural_climbing = TRUE + + vision_flags = SEE_SELF | SEE_MOBS + hearing_sensitivity = HEARING_VERY_SENSITIVE + + natural_armor = list( + ballistic = ARMOR_BALLISTIC_MEDIUM, + laser = ARMOR_LASER_PISTOL, + melee = ARMOR_MELEE_MAJOR, + bomb = ARMOR_BOMB_PADDED, + energy = ARMOR_ENERGY_SMALL + ) + + unarmed_types = list(/datum/unarmed_attack/shocking) //This zombie cannot infect, it's an harrass type of zombie + +///A zombie tuned for charge attacks +/datum/species/zombie/rhino + name = SPECIES_ZOMBIE_RHINO + name_plural = SPECIES_ZOMBIE_RHINO+"s" + icobase = 'icons/mob/human_races/zombie/r_zombie_rhino.dmi' + deform = 'icons/mob/human_races/zombie/r_zombie_rhino.dmi' + slowdown = 2 + + total_health = 120 + + stamina = 50 + sprint_speed_factor = 0.7 + standing_jump_range = 5 + + vision_flags = SEE_SELF + + bump_flag = HEAVY + push_flags = HEAVY + + mob_size = MOB_LARGE + grab_mod = 5 + + natural_armor = list( + ballistic = ARMOR_BALLISTIC_MEDIUM, + laser = ARMOR_LASER_PISTOL, + melee = ARMOR_MELEE_MAJOR, + bomb = ARMOR_BOMB_PADDED, + energy = ARMOR_ENERGY_SMALL + ) + + maneuvers = list(/singleton/maneuver/leap/areagrab) + + unarmed_types = list(/datum/unarmed_attack/bite/infectious, /datum/unarmed_attack/golem) diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm index 90dc6a43592..52215f30de8 100644 --- a/code/modules/mob/living/carbon/human/species/species_attack.dm +++ b/code/modules/mob/living/carbon/human/species/species_attack.dm @@ -98,7 +98,7 @@ attack_verb = list("jumped on") attack_name = "weak stomp" -/datum/unarmed_attack/stomp/weak/get_unarmed_damage() +/datum/unarmed_attack/stomp/weak/get_unarmed_damage(var/mob/attacker, var/mob/living/carbon/human/target) return damage /datum/unarmed_attack/stomp/weak/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) @@ -212,6 +212,12 @@ var/trioxin_amount = REAGENT_VOLUME(target.reagents, /singleton/reagent/toxin/trioxin) target.reagents.add_reagent(/singleton/reagent/toxin/trioxin, min(10, ZOMBIE_MAX_TRIOXIN - trioxin_amount)) +/datum/unarmed_attack/bite/infectious/get_unarmed_damage(var/mob/attacker, var/target) + if(istype(target, /mob/living/heavy_vehicle)) + return damage * 4 + + . = ..() + /datum/unarmed_attack/golem attack_verb = list("smashed", "crushed", "rammed") attack_noun = list("fist") diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 37ee129a605..6c20c59da4e 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -44,7 +44,16 @@ var/global/list/sparring_attack_cache = list() return FALSE -/datum/unarmed_attack/proc/get_unarmed_damage() +/** + * Returns the unarmed damage of an attack, aka what damage the attack does if there's no objects involved + * + * * attacker - The `/mob` that is performing the attack + * * target - The target of the attack, aka who is being attacked/damaged + */ +/datum/unarmed_attack/proc/get_unarmed_damage(var/mob/attacker, var/target) + SHOULD_BE_PURE(TRUE) + SHOULD_NOT_SLEEP(TRUE) + return damage /datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/attack_damage,var/zone) @@ -104,13 +113,26 @@ var/global/list/sparring_attack_cache = list() target.visible_message("[target] has been weakened!") target.apply_effect(3, WEAKEN, armor*100) -/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/obj/item/organ/external/affecting = target.get_organ(zone) +/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/target, var/zone, var/attack_damage) + SHOULD_NOT_SLEEP(TRUE) + + var/affecting = null + + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/human = target + var/obj/item/organ/organ = human.get_organ(zone) + affecting = organ?.name + + else if(istype(target, /mob/living/heavy_vehicle)) + var/mob/living/heavy_vehicle/mech = target + var/obj/item/mech_component/component = mech.zoneToComponent(zone) + affecting = component?.name + if(!affecting) return - user.visible_message(SPAN_WARNING("[user] [pick(attack_verb)] [target] in the [affecting.name]!")) + user.visible_message(SPAN_WARNING("[user] [pick(attack_verb)] [target] in the [affecting]!")) playsound(user.loc, attack_sound, 25, 1, -1) /datum/unarmed_attack/proc/show_attack_simple(var/mob/living/carbon/human/user, var/mob/living/target, var/zone) @@ -246,8 +268,8 @@ var/global/list/sparring_attack_cache = list() return FALSE -/datum/unarmed_attack/kick/get_unarmed_damage(var/mob/living/carbon/human/user) - var/obj/item/clothing/shoes = user.shoes +/datum/unarmed_attack/kick/get_unarmed_damage(var/mob/attacker, var/mob/living/carbon/human/target) + var/obj/item/clothing/shoes = target.shoes if(!istype(shoes)) return damage return damage + (shoes ? shoes.force : 0) @@ -294,8 +316,8 @@ var/global/list/sparring_attack_cache = list() return FALSE -/datum/unarmed_attack/stomp/get_unarmed_damage(var/mob/living/carbon/human/user) - var/obj/item/clothing/shoes = user.shoes +/datum/unarmed_attack/stomp/get_unarmed_damage(var/mob/attacker, var/mob/living/carbon/human/target) + var/obj/item/clothing/shoes = target.shoes return damage + (shoes ? shoes.force : 0) /datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) @@ -332,4 +354,4 @@ var/global/list/sparring_attack_cache = list() desc = "Sparring: A heavy strike to your opponent. With poise and precision, no evidence will be left behind! They WILL ABSOLUTELY feel this, but will suffer no dangerous side effect, unless you punch them into cardiac arrest! Show off your might!" damage = 4 attack_name = "heavy hit" - attack_sound = /singleton/sound_category/punch_bassy_sound \ No newline at end of file + attack_sound = /singleton/sound_category/punch_bassy_sound diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 0aa072bbe3e..0edec859743 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -1476,6 +1476,8 @@ There are several things that need to be remembered: //Drawcheck functions //These functions check if an item should be drawn, or if its covered up by something else /mob/living/carbon/human/proc/check_draw_gloves() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!gloves) return FALSE else if (gloves.flags_inv & ALWAYSDRAW) @@ -1486,6 +1488,8 @@ There are several things that need to be remembered: return TRUE /mob/living/carbon/human/proc/check_draw_right_ear() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!r_ear) return FALSE else if (r_ear.flags_inv & ALWAYSDRAW) @@ -1496,6 +1500,8 @@ There are several things that need to be remembered: /mob/living/carbon/human/proc/check_draw_left_ear() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!l_ear) return FALSE else if (l_ear.flags_inv & ALWAYSDRAW) @@ -1505,6 +1511,8 @@ There are several things that need to be remembered: return TRUE /mob/living/carbon/human/proc/check_draw_glasses() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!glasses) return FALSE else if (glasses.flags_inv & ALWAYSDRAW) @@ -1516,6 +1524,8 @@ There are several things that need to be remembered: /mob/living/carbon/human/proc/check_draw_mask() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!wear_mask) return FALSE else if (wear_mask.flags_inv & ALWAYSDRAW) @@ -1526,6 +1536,8 @@ There are several things that need to be remembered: return TRUE /mob/living/carbon/human/proc/check_draw_shoes() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!shoes) return FALSE else if (shoes.flags_inv & ALWAYSDRAW) @@ -1536,6 +1548,8 @@ There are several things that need to be remembered: return TRUE /mob/living/carbon/human/proc/check_draw_underclothing() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!w_uniform) return FALSE else if (w_uniform.flags_inv & ALWAYSDRAW) @@ -1546,6 +1560,8 @@ There are several things that need to be remembered: return TRUE /mob/living/carbon/human/proc/check_draw_wrists() + SHOULD_NOT_SLEEP(TRUE) + SHOULD_BE_PURE(TRUE) if (!wrists) return FALSE else if (wrists.flags_inv & ALWAYSDRAW) diff --git a/code/modules/mob/living/maneuvers/maneuver_leap.dm b/code/modules/mob/living/maneuvers/maneuver_leap.dm index 26b754ad1b7..9ece179602f 100644 --- a/code/modules/mob/living/maneuvers/maneuver_leap.dm +++ b/code/modules/mob/living/maneuvers/maneuver_leap.dm @@ -19,6 +19,7 @@ end_leap(user, target, old_pass_flags) /singleton/maneuver/leap/proc/end_leap(var/mob/living/user, var/atom/target, var/pass_flag) + SHOULD_NOT_SLEEP(TRUE) user.pass_flags = pass_flag if(ishuman(user)) var/mob/living/carbon/human/H = user @@ -114,4 +115,50 @@ /singleton/maneuver/leap/tesla_body cooldown = 20 SECONDS delay = 4 SECONDS - stamina_cost = 30 \ No newline at end of file + stamina_cost = 30 + +/singleton/maneuver/leap/areagrab + cooldown = 5 MINUTES + delay = 3 SECONDS + stamina_cost = 50 + +/singleton/maneuver/leap/areagrab/show_initial_message(mob/living/user, atom/target) + . = ..() + user.balloon_alert_to_viewers("OUUGUGUUUUUUUUUUUGBHGH", "OUUGUGUUUUUUUUUUUGBHGH") + + //Let them hear, let them fear + for(var/mob/living/carbon/human/person_in_range in get_hearers_in_LOS(world.view+5)) + to_chat(person_in_range, + SPAN_HIGHDANGER("OUUGUGUUUUUUUUUUUGBHGH!!!") + ) + +/singleton/maneuver/leap/areagrab/end_leap(var/mob/living/user, var/atom/target, pass_flag) + . = ..() + + var/list/mob/living/affected_mobs = list() + + for(var/mob/living/subject in range(1)) + affected_mobs += subject + + affected_mobs -= user //Exclude ourself from it + + if(length(affected_mobs)) + var/mob/living/very_unlucky_guy = pick(affected_mobs) + + for(var/mob/living/subject as anything in (affected_mobs - very_unlucky_guy)) + INVOKE_ASYNC(subject, TYPE_PROC_REF(/atom/movable, throw_at_random), FALSE, 3, THROWNOBJ_KNOCKBACK_SPEED) + INVOKE_ASYNC(subject, TYPE_PROC_REF(/mob/living, Weaken), 5) + + if(ismob(very_unlucky_guy) && user.Adjacent(very_unlucky_guy)) + + var/obj/item/grab/G = new(user, user, very_unlucky_guy) + + user.put_in_active_hand(G) + + G.state = GRAB_NECK + G.icon_state = "grabbed+1" + G.synch() + G.update_icon() + G.hud.icon_state = "kill" + G.hud.name = "kill" + diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 901440d7873..5b690feb6eb 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -534,7 +534,7 @@ simple_harm_attack(user) return attack.show_attack_simple(user, src, pick(organ_names)) - var/actual_damage = attack.get_unarmed_damage(user) //Punch and kick no longer have get_unarmed_damage due to how humanmob combat works. If we have none, we'll apply a small random amount. + var/actual_damage = attack.get_unarmed_damage(src, user) //Punch and kick no longer have get_unarmed_damage due to how humanmob combat works. If we have none, we'll apply a small random amount. if(!actual_damage) actual_damage = harm_intent_damage ? rand(1, harm_intent_damage) : 0 apply_damage(actual_damage, attack.damage_type) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 2c6bf870a7b..96f1e24d3ba 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -154,15 +154,12 @@ /proc/iszombie(A) if(ishuman(A)) var/mob/living/carbon/human/H = A - switch(H.get_species()) - if(SPECIES_ZOMBIE) - return TRUE - if(SPECIES_ZOMBIE_TAJARA) - return TRUE - if(SPECIES_ZOMBIE_UNATHI) - return TRUE - if(SPECIES_ZOMBIE_SKRELL) - return TRUE + + if(istype(H.get_species(TRUE), /datum/species/zombie)) + return TRUE + else + return FALSE + return FALSE /proc/isundead(A) diff --git a/code/modules/organs/subtypes/parasite.dm b/code/modules/organs/subtypes/parasite.dm index 3a4ce27c83b..cacc08d6fdd 100644 --- a/code/modules/organs/subtypes/parasite.dm +++ b/code/modules/organs/subtypes/parasite.dm @@ -6,13 +6,27 @@ var/max_stage = 4 var/stage_ticker = 0 var/recession = 0 - var/infection_speed = 2 //Will be determined by get_infect_speed() - var/infect_speed_high = 35 //The fastest this parasite will advance stages - var/infect_speed_low = 15 //The slowest this parasite will advance stages - var/stage_interval = 300 //time between stages, in seconds. interval of 300 allows convenient treating with antiparasitics, higher will require spaced dosing of medications. - var/subtle = 0 //will the body reject the parasite naturally? - var/egg = null //does the parasite have a reagent which seeds an infection? - var/drug_resistance = 0 //is the parasite resistant to antiparasitic medications? + + ///Infection progress speed, will be determined by get_infect_speed() + var/infection_speed = 2 + + ///The fastest the parasite will advance its stage + var/infect_speed_high = 35 + + ///The fastest the parasite will advance its stage + var/infect_speed_low = 15 + + ///Time between stages, in seconds. interval of 300 allows convenient treating with antiparasitics, higher will require spaced dosing of medications. + var/stage_interval = 300 + + ///Boolean, if the body should reject the parasite naturally + var/subtle = FALSE + + ///Does the parasite have a reagent which seeds an infection? + var/egg = null + + //Boolean, if the parasite is resistant to antiparasitic medications + var/drug_resistance = FALSE /obj/item/organ/internal/parasite/Initialize() . = ..() @@ -307,8 +321,8 @@ organ_tag = BP_ZOMBIE_PARASITE parent_organ = BP_HEAD - stage_interval = 150 - drug_resistance = 1 + stage_interval = 110 + drug_resistance = TRUE relative_size = 0 egg = /singleton/reagent/toxin/trioxin diff --git a/html/changelogs/fluffyghost-zombieupgrade.yml b/html/changelogs/fluffyghost-zombieupgrade.yml new file mode 100644 index 00000000000..f580100a20c --- /dev/null +++ b/html/changelogs/fluffyghost-zombieupgrade.yml @@ -0,0 +1,52 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: FluffyGhost + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added 3 subtypes of zombie." + - rscadd: "Subtype of zombie: bull, very tanky, slow moving, short sprint and low stamina." + - rscadd: "Subtype of zombie: hunter, very fast and sensitive to sounds, can see through walls other mobs, can leap far and often, natural climber, relatively squishy, cannot infect, attacks have a chance to electric shock, good against IPCs." + - rscadd: "Subtype of zombie: rhino, relatively slow, can leap after a small delay and land sending people in a radius of 1 to fly except one, that gets red grabbed, punches relatively hard." + - rscadd: "Zombie producing chemical grenade added." + - tweak: "Turning into zombie is now ~40% faster than before." + - tweak: "Zombies now have a limited stamina." + - balance: "Normal zombies no longer see through walls; only the hunter does." + - backend: "Some dmdoc and spacemandmm constrains added." + - bugfix: "Fixed some issues with mechs on destruction, that were runtiming" + - refactor: "Small refactor of unarmed attacks, now zombies can attack and destroy mechs" + - balance: "Normal zombies are now weaker and die a little more easily." diff --git a/icons/mob/human_races/zombie/r_zombie_bull.dmi b/icons/mob/human_races/zombie/r_zombie_bull.dmi new file mode 100644 index 00000000000..9cbb45472fd Binary files /dev/null and b/icons/mob/human_races/zombie/r_zombie_bull.dmi differ diff --git a/icons/mob/human_races/zombie/r_zombie_hunter.dmi b/icons/mob/human_races/zombie/r_zombie_hunter.dmi new file mode 100644 index 00000000000..ae286b8bd21 Binary files /dev/null and b/icons/mob/human_races/zombie/r_zombie_hunter.dmi differ diff --git a/icons/mob/human_races/zombie/r_zombie_rhino.dmi b/icons/mob/human_races/zombie/r_zombie_rhino.dmi new file mode 100644 index 00000000000..eb7ffd78cae Binary files /dev/null and b/icons/mob/human_races/zombie/r_zombie_rhino.dmi differ