diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index ca293307099..a05575f575d 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -54,6 +54,13 @@ #define AI_IDLE 2 #define AI_OFF 3 +//Attack types for checking shields/hit reactions + +#define MELEE_ATTACK 1 +#define UNARMED_ATTACK 2 +#define PROJECTILE_ATTACK 3 +#define THROWN_PROJECTILE_ATTACK 4 + //Gun Stuff #define SAWN_INTACT 0 #define SAWN_OFF 1 diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index e79d40f7176..0562d7086ab 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -4,10 +4,9 @@ #define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message with the default handler #define AIRTIGHT 8 // mask allows internals #define HANDSLOW 16 // If an item has this flag, it will slow you to carry it -#define NOSHIELD 32 // weapon not affected by shield -#define CONDUCT 64 // conducts electricity (metal etc.) -#define ABSTRACT 128 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way -#define ON_BORDER 256 // item has priority to check when entering or leaving +#define CONDUCT 32 // conducts electricity (metal etc.) +#define ABSTRACT 64 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way +#define ON_BORDER 128 // item has priority to check when entering or leaving #define GLASSESCOVERSEYES 1024 #define MASKCOVERSEYES 1024 // get rid of some of the other retardation in these flags diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index f4d628deebd..765fbd0a5e1 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -206,6 +206,7 @@ flags = NODROP icon = 'icons/obj/weapons.dmi' icon_state = "ling_shield" + block_chance = 50 var/remaining_uses //Set by the changeling ability. @@ -217,17 +218,17 @@ /obj/item/weapon/shield/changeling/dropped() qdel(src) -/obj/item/weapon/shield/changeling/IsShield() +/obj/item/weapon/shield/changeling/hit_reaction() if(remaining_uses < 1) if(ishuman(loc)) var/mob/living/carbon/human/H = loc - H.visible_message("With a sickening crunch, [H] reforms his shield into an arm!", "We assimilate our shield into our body", "With a sickening crunch, [H] reforms his shield into an arm!", "We assimilate our shield into our body", "[owner] blocks [attack_text] with [src]!") + return 1 + return 0 + /obj/item/proc/talk_into(mob/M as mob, var/text, var/channel=null) return @@ -374,9 +383,6 @@ /obj/item/proc/ui_action_click() attack_self(usr) -/obj/item/proc/IsShield() - return 0 - /obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit return 0 diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 6c0cf78de6e..52fa28f58eb 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -141,7 +141,6 @@ item_state = "sword0" var/active = 0.0 w_class = 2.0 - flags = NOSHIELD attack_verb = list("attacked", "struck", "hit") /obj/item/toy/sword/attack_self(mob/user as mob) @@ -199,7 +198,7 @@ origin_tech = null attack_verb = list("attacked", "struck", "hit") -/obj/item/weapon/twohanded/dualsaber/toy/IsShield() +/obj/item/weapon/twohanded/dualsaber/toy/hit_reaction() return 0 /obj/item/weapon/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles diff --git a/code/game/objects/items/weapons/alien_specific.dm b/code/game/objects/items/weapons/alien_specific.dm index e4f6bcd7a75..c487af03cd6 100644 --- a/code/game/objects/items/weapons/alien_specific.dm +++ b/code/game/objects/items/weapons/alien_specific.dm @@ -14,7 +14,6 @@ throw_range = 5 w_class = 2 w_class_on = 2 - flags = NOSHIELD attack_verb = list("attacked", "slashed", "gored", "sliced", "torn", "ripped", "butchered", "cut") attack_verb_on = list() diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 75c1b030ed4..10394b2e236 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -191,10 +191,10 @@ return -/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target) +/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target, release_amount = 0.05) //TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this... //Transfer 5% of current tank air contents to turf - var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.05) + var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount) air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE target.assume_air(air_transfer) //Burn it based on transfered gas @@ -218,4 +218,12 @@ /obj/item/weapon/flamethrower/full/tank/New(var/loc) ..() ptank = new /obj/item/weapon/tank/plasma/full(src) - update_icon() \ No newline at end of file + update_icon() + +/obj/item/weapon/flamethrower/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(ptank && damage && attack_type == PROJECTILE_ATTACK && prob(15)) + owner.visible_message("[attack_text] hits the fueltank on [owner]'s [src], rupturing it! What a shot!") + var/target_turf = get_turf(owner) + ignite_turf(target_turf, 100) + qdel(ptank) + return 1 //It hit the flamethrower, not them \ No newline at end of file diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index a951f1ade8f..f130f61b7a8 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -102,6 +102,11 @@ spawn(det_time) prime() +/obj/item/weapon/grenade/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(damage && attack_type == PROJECTILE_ATTACK && prob(15)) + owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!") + prime() + return 1 //It hit the grenade, not them /obj/item/weapon/grenade/chem_grenade/attackby(obj/item/I, mob/user, params) if(istype(I,/obj/item/weapon/hand_labeler)) diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index b56e103233e..ada15a3b108 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -76,9 +76,7 @@ w_class = 5 force = 5 slot_flags = SLOT_BACK - -/obj/item/weapon/nullrod/staff/IsShield() - return 1 + block_chance = 50 /obj/item/weapon/nullrod/staff/blue name = "blue holy staff" @@ -92,16 +90,16 @@ desc = "A weapon fit for a crusade!" w_class = 4 slot_flags = SLOT_BACK|SLOT_BELT + block_chance = 30 sharp = 1 edge = 1 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") -/obj/item/weapon/nullrod/claymore/IsShield() - if(prob(30)) - return 1 - else - return 0 +/obj/item/weapon/nullrod/claymore/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(attack_type == PROJECTILE_ATTACK) + final_block_chance = 0 //Don't bring a sword to a gunfight + return ..() /obj/item/weapon/nullrod/claymore/darkblade icon_state = "cultblade" @@ -333,6 +331,7 @@ desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts, now used to harass the clown." w_class = 4 force = 15 + block_chance = 40 slot_flags = SLOT_BACK sharp = 0 edge = 0 @@ -342,12 +341,6 @@ icon_state = "bostaff0" item_state = "bostaff0" -/obj/item/weapon/nullrod/claymore/bostaff/IsShield() - if(prob(40)) - return 1 - else - return 0 - /obj/item/weapon/nullrod/tribal_knife icon_state = "crysknife" item_state = "crysknife" diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 45b2f1f7452..79cad015653 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -62,7 +62,7 @@ w_class = 3 w_class_on = 5 hitsound = "swing_hit" - flags = CONDUCT | NOSHIELD + flags = CONDUCT armour_penetration = 100 origin_tech = "combat=3" attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") @@ -83,9 +83,9 @@ throw_speed = 3 throw_range = 5 hitsound = "swing_hit" - flags = NOSHIELD armour_penetration = 35 origin_tech = "magnets=3;syndicate=4" + block_chance = 50 sharp = 1 edge = 1 var/hacked = 0 @@ -95,9 +95,9 @@ if(item_color == null) item_color = pick("red", "blue", "green", "purple") -/obj/item/weapon/melee/energy/sword/IsShield() +/obj/item/weapon/melee/energy/sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) if(active) - return 1 + return ..() return 0 /obj/item/weapon/melee/energy/sword/cyborg @@ -133,7 +133,7 @@ ..() item_color = null -/obj/item/weapon/melee/energy/sword/cyborg/saw/IsShield() +/obj/item/weapon/melee/energy/sword/cyborg/saw/hit_reaction() return 0 /obj/item/weapon/melee/energy/sword/saber @@ -206,7 +206,6 @@ throw_speed = 3 throw_range = 1 w_class = 4//So you can't hide it in your pocket or some such. - flags = NOSHIELD armour_penetration = 50 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") var/datum/effect/system/spark_spread/spark_system diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm index a161755c285..809bf0d298d 100644 --- a/code/game/objects/items/weapons/shields.dm +++ b/code/game/objects/items/weapons/shields.dm @@ -1,5 +1,6 @@ /obj/item/weapon/shield name = "shield" + block_chance = 50 /obj/item/weapon/shield/riot name = "riot shield" @@ -17,8 +18,10 @@ attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time -/obj/item/weapon/shield/riot/IsShield() - return 1 +/obj/item/weapon/shield/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type) + if(attack_type == THROWN_PROJECTILE_ATTACK) + final_block_chance += 30 + return ..() /obj/item/weapon/shield/riot/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(istype(W, /obj/item/weapon/melee/baton)) @@ -41,12 +44,7 @@ icon_state = "buckler" item_state = "buckler" materials = list() - -/obj/item/weapon/shield/riot/buckler/IsShield() - if(prob(60)) - return 1 - else - return 0 + block_chance = 30 /obj/item/weapon/shield/energy name = "energy combat shield" @@ -62,8 +60,8 @@ attack_verb = list("shoved", "bashed") var/active = 0 -/obj/item/weapon/shield/energy/IsShield() - return (active) +/obj/item/weapon/shield/energy/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) + return 0 /obj/item/weapon/shield/energy/IsReflect() return (active) @@ -109,8 +107,10 @@ w_class = 3 var/active = 0 -/obj/item/weapon/shield/riot/tele/IsShield() - return (active) +/obj/item/weapon/shield/riot/tele/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) + if(active) + return ..() + return 0 /obj/item/weapon/shield/riot/tele/attack_self(mob/living/user) active = !active diff --git a/code/game/objects/items/weapons/staff.dm b/code/game/objects/items/weapons/staff.dm index 049339a1b01..793f384126e 100644 --- a/code/game/objects/items/weapons/staff.dm +++ b/code/game/objects/items/weapons/staff.dm @@ -8,7 +8,6 @@ throw_speed = 1 throw_range = 5 w_class = 2.0 - flags = NOSHIELD armour_penetration = 100 attack_verb = list("bludgeoned", "whacked", "disciplined") @@ -73,5 +72,4 @@ throwforce = 5.0 throw_speed = 1 throw_range = 5 - w_class = 2.0 - flags = NOSHIELD \ No newline at end of file + w_class = 2.0 \ No newline at end of file diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 0f2fd65475e..6ab787e519f 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -134,7 +134,7 @@ /obj/item/weapon/melee/baton/proc/baton_stun(mob/living/L, mob/user) if(ishuman(L)) var/mob/living/carbon/human/H = L - if(H.check_shields(0, "[user]'s [name]")) //No message; check_shields() handles that + if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) //No message; check_shields() handles that playsound(L, 'sound/weapons/Genhit.ogg', 50, 1) return user.lastattacked = L diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 6af34367d75..844a6f68d54 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -53,7 +53,7 @@ if(cooldown <= 0) if(ishuman(target)) var/mob/living/carbon/human/H = target - if(H.check_shields(0, "[user]'s [name]")) + if(H.check_shields(0, "[user]'s [name]", src, MELEE_ATTACK)) return 0 playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1) target.Weaken(3) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 1f808939f17..cf43a0b7bf4 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -120,14 +120,6 @@ /obj/item/weapon/twohanded/offhand/wield() qdel(src) -/obj/item/weapon/twohanded/offhand/IsShield()//if the actual twohanded weapon is a shield, we count as a shield too! - var/mob/user = loc - if(!istype(user)) return 0 - var/obj/item/I = user.get_active_hand() - if(I == src) I = user.get_inactive_hand() - if(!I) return 0 - return I.IsShield() - ///////////Two hand required objects/////////////// //This is for objects that require two hands to even pick up /obj/item/weapon/twohanded/required/ @@ -205,10 +197,10 @@ force_wielded = 34 wieldsound = 'sound/weapons/saberon.ogg' unwieldsound = 'sound/weapons/saberoff.ogg' - flags = NOSHIELD armour_penetration = 35 origin_tech = "magnets=3;syndicate=4" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 75 sharp = 1 edge = 1 no_embed = 1 // Like with the single-handed esword, this shouldn't be embedding in people. @@ -238,11 +230,10 @@ user.dir = i sleep(1) -/obj/item/weapon/twohanded/dualsaber/IsShield() +/obj/item/weapon/twohanded/dualsaber/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) if(wielded) - return 1 - else - return 0 + return ..() + return 0 /obj/item/weapon/twohanded/dualsaber/green/New() blade_color = "green" @@ -296,7 +287,6 @@ throw_speed = 3 armour_penetration = 10 no_spin_thrown = 1 // Thrown spears that spin look dumb. -Fox - flags = NOSHIELD attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") /obj/item/weapon/twohanded/spear/update_icon() @@ -371,7 +361,6 @@ force_wielded = 40 //you'll gouge their eye out! Or a limb...maybe even their entire body! wieldsound = 'sound/weapons/chainsawstart.ogg' hitsound = null - flags = NOSHIELD armour_penetration = 35 origin_tech = "materials=6;syndicate=4" attack_verb = list("sawed", "cut", "hacked", "carved", "cleaved", "butchered", "felled", "timbered") diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 8ff2f931159..908cc1e2d80 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -50,13 +50,11 @@ edge = 1 w_class = 3 attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 50 - IsShield() - return 1 - - suicide_act(mob/user) - to_chat(viewers(user), "[user] is falling on the [src.name]! It looks like \he's trying to commit suicide.") - return(BRUTELOSS) +/obj/item/weapon/claymore/suicide_act(mob/user) + user.visible_message("[user] is falling on the [src.name]! It looks like \he's trying to commit suicide.") + return(BRUTELOSS) /obj/item/weapon/claymore/ceremonial name = "ceremonial claymore" @@ -77,6 +75,7 @@ w_class = 3 hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 50 /obj/item/weapon/katana/cursed slot_flags = null @@ -85,9 +84,6 @@ user.visible_message("[user] is slitting \his stomach open with the [src.name]! It looks like \he's trying to commit seppuku.") return(BRUTELOSS) -/obj/item/weapon/katana/IsShield() - return 1 - /obj/item/weapon/harpoon name = "harpoon" sharp = 1 diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index ea811f68be6..f99837df127 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -222,30 +222,27 @@ //Reactive armor -//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!) /obj/item/clothing/suit/armor/reactive - name = "Reactive Teleport Armor" - desc = "Someone seperated our Research Director from his own head!" - var/active = 0.0 + name = "reactive armor" + desc = "Doesn't seem to do much for some reason." + var/active = 0 icon_state = "reactiveoff" item_state = "reactiveoff" blood_overlay_type = "armor" - action_button_name = "Toggle Reactive Armor" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + action_button_name = "Toggle Reactive Armor" + unacidable = 1 + hit_reaction_chance = 50 -/obj/item/clothing/suit/armor/reactive/IsShield() - if(active) - return 1 - return 0 -/obj/item/clothing/suit/armor/reactive/attack_self(mob/user as mob) +/obj/item/clothing/suit/armor/reactive/attack_self(mob/user) active = !(active) if(active) - to_chat(user, "The reactive armor is now active.") + to_chat(user, "[src] is now active.") icon_state = "reactive" item_state = "reactive" else - to_chat(user, "The reactive armor is now inactive.") + to_chat(user, "[src] is now inactive.") icon_state = "reactiveoff" item_state = "reactiveoff" add_fingerprint(user) @@ -255,11 +252,91 @@ active = 0 icon_state = "reactiveoff" item_state = "reactiveoff" - - var/mob/living/carbon/human/user = usr - user.update_inv_wear_suit() ..() +//When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!) +/obj/item/clothing/suit/armor/reactive/teleport + name = "reactive teleport armor" + desc = "Someone seperated our Research Director from his own head!" + var/tele_range = 6 + +/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) + if(!active) + return 0 + if(prob(hit_reaction_chance)) + var/mob/living/carbon/human/H = owner + owner.visible_message("The reactive teleport system flings [H] clear of [attack_text], shutting itself off in the process!") + var/list/turfs = new/list() + for(var/turf/T in orange(tele_range, H)) + if(istype(T, /turf/space)) + continue + if(T.density) + continue + if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.yThe [src] blocks the [attack_text], sending out jets of flame!") + for(var/mob/living/carbon/C in range(6, owner)) + if(C != owner) + C.fire_stacks += 8 + C.IgniteMob() + owner.fire_stacks = -20 + return 1 + return 0 + + +/obj/item/clothing/suit/armor/reactive/stealth + name = "reactive stealth armor" + +/obj/item/clothing/suit/armor/reactive/stealth/hit_reaction(mob/living/carbon/human/owner, attack_text) + if(!active) + return 0 + if(prob(hit_reaction_chance)) + var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc) + E.Copy_Parent(owner, 50) + E.GiveTarget(owner) //so it starts running right away + E.Goto(owner, E.move_to_delay, E.minimum_distance) + owner.alpha = 0 + owner.visible_message("[owner] is hit by [attack_text] in the chest!") //We pretend to be hit, since blocking it would stop the message otherwise + spawn(40) + owner.alpha = initial(owner.alpha) + return 1 + +/obj/item/clothing/suit/armor/reactive/tesla + name = "reactive tesla armor" + +/obj/item/clothing/suit/armor/reactive/tesla/hit_reaction(mob/living/carbon/human/owner, attack_text) + if(!active) + return 0 + if(prob(hit_reaction_chance)) + owner.visible_message("The [src] blocks the [attack_text], sending out arcs of lightning!") + for(var/mob/living/M in view(6, owner)) + if(M == owner) + continue + owner.Beam(M,icon_state="lightning[rand(1, 12)]",icon='icons/effects/effects.dmi',time=5) + M.adjustFireLoss(25) + playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) + return 1 //All of the armor below is mostly unused diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 5a7017b353a..68307875b1b 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -70,6 +70,9 @@ item_color = "clown" flags_size = ONESIZEFITSALL +/obj/item/clothing/under/rank/clown/hit_reaction() + playsound(loc, 'sound/items/bikehorn.ogg', 50, 1, -1) + return 0 /obj/item/clothing/under/rank/head_of_personnel desc = "It's a jumpsuit worn by someone who works in the position of \"Head of Personnel\"." diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index fd4864b7900..86b3728be3c 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -92,7 +92,7 @@ sharp = 0 edge = 0 -/obj/item/weapon/claymore/fluff/IsShield() +/obj/item/weapon/claymore/fluff/hit_reaction() return 0 /obj/item/weapon/crowbar/fluff/zelda_creedy_1 // Zomgponies: Griffin Rowley diff --git a/code/modules/hydroponics/trays/tray_tools.dm b/code/modules/hydroponics/trays/tray_tools.dm index 9cb59b4f296..3fae45bea2e 100644 --- a/code/modules/hydroponics/trays/tray_tools.dm +++ b/code/modules/hydroponics/trays/tray_tools.dm @@ -313,7 +313,7 @@ throw_range = 3 w_class = 4 var/extend = 1 - flags = NOSHIELD | CONDUCT + flags = CONDUCT armour_penetration = 20 slot_flags = SLOT_BACK origin_tech = "materials=2;combat=2" @@ -339,7 +339,6 @@ throw_range = 3 w_class = 2.0 extend = 0 - flags = NOSHIELD armour_penetration = 20 slot_flags = SLOT_BELT origin_tech = "materials=3;combat=3" diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index d128e22c0f6..0ca98c921d8 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -181,7 +181,7 @@ attack_verb = list("smashed", "slammed", "whacked", "thwacked") icon = 'icons/obj/weapons.dmi' icon_state = "bostaff0" - + block_chance = 50 /obj/item/weapon/twohanded/bostaff/update_icon() icon_state = "bostaff[wielded]" @@ -239,8 +239,7 @@ return ..() return ..() -/obj/item/weapon/twohanded/bostaff/IsShield() +/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) if(wielded) - return 1 - else - return 0 \ No newline at end of file + return ..() + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index a5e72059ab8..aff7b82bd03 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -85,7 +85,7 @@ leaping = 0 update_icons() -/mob/living/carbon/alien/humanoid/hunter/throw_impact(A) +/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A) if(!leaping) return ..() @@ -93,20 +93,26 @@ if(A) if(istype(A, /mob/living)) var/mob/living/L = A - L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") - if(ishuman(L)) - var/mob/living/carbon/human/H = L - H.apply_effect(5, WEAKEN, H.run_armor_check(null, "melee")) - else - L.Weaken(5) - sleep(2)//Runtime prevention (infinite bump() calls on hulks) - step_towards(src,L) + var/blocked = 0 + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(H.check_shields(90, "the [name]", src, attack_type = THROWN_PROJECTILE_ATTACK)) + blocked = 1 + if(!blocked) + L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") + if(ishuman(L)) + var/mob/living/carbon/human/H = L + H.apply_effect(5, WEAKEN, H.run_armor_check(null, "melee")) + else + L.Weaken(5) + sleep(2)//Runtime prevention (infinite bump() calls on hulks) + step_towards(src,L) toggle_leap(0) pounce_cooldown = !pounce_cooldown spawn(pounce_cooldown_time) //3s by default pounce_cooldown = !pounce_cooldown - else + else if(A.density && !A.CanPass(src)) visible_message("[src] smashes into [A]!", "[src] smashes into [A]!") weakened = 2 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1bc79c16242..bbaa9e40da0 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -203,15 +203,14 @@ now_pushing = 0 return - if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return + //anti-riot equipment is also anti-push + if(tmob.r_hand && (prob(tmob.r_hand.block_chance * 2)) && !istype(tmob.r_hand, /obj/item/clothing)) + now_pushing = 0 + return + if(tmob.l_hand && (prob(tmob.l_hand.block_chance * 2)) && !istype(tmob.l_hand, /obj/item/clothing)) + now_pushing = 0 + return if(!(tmob.status_flags & CANPUSH)) now_pushing = 0 @@ -414,16 +413,16 @@ M.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])") src.attack_log += text("\[[time_stamp()]\] was attacked by [M.name] ([M.ckey])") var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) - if(check_shields(damage, "the [M.name]")) + if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration)) return 0 var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot") var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone)) - var/armor = run_armor_check(affecting, "melee") + var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) var/obj/item/organ/external/affected = src.get_organ(dam_zone) if(affected) affected.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data - apply_damage(damage,M.melee_damage_type, affecting, armor, M.name) + apply_damage(damage, M.melee_damage_type, affecting, armor) updatehealth() /mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L as mob) @@ -461,7 +460,7 @@ else damage = rand(5, 25) - if(check_shields(damage, "the [M.name]")) + if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK)) return 0 var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot") diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 33cb567ba4a..f7839568a03 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -18,10 +18,9 @@ ..() - if((M != src) && check_shields(0, M.name)) + if((M != src) && M.a_intent != "help" && check_shields(0, M.name, attack_type = UNARMED_ATTACK)) add_logs(src, M, "attempted to touch") - M.do_attack_animation(src) - visible_message("\red [M] attempted to touch [src]!") + visible_message("[M] attempted to touch [src]!") return 0 if(istype(M.gloves , /obj/item/clothing/gloves/boxing/hologlove)) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 3a935e5e449..c8bc136103c 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -32,7 +32,7 @@ emp_act return -1 // complete projectile permutation //Shields - if(check_shields(P.damage, "the [P.name]", P)) + if(check_shields(P.damage, "the [P.name]", P, PROJECTILE_ATTACK, P.armour_penetration)) P.on_hit(src, 100, def_zone) return 2 @@ -132,40 +132,24 @@ emp_act //End Here -/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack", var/obj/item/O) - if(O) - if(O.flags & NOSHIELD) //weapon ignores shields altogether - return 0 - if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3) - var/obj/item/weapon/I = l_hand - if(I.IsShield() && (prob(50 - round(damage / 3)))) - visible_message("[src] blocks [attack_text] with [l_hand]!", \ - "[src] blocks [attack_text] with [l_hand]!") +/mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", atom/movable/AM, attack_type = MELEE_ATTACK, armour_penetration = 0) + var/block_chance_modifier = round(damage / -3) + + if(l_hand && !istype(l_hand, /obj/item/clothing)) + var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example + if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) return 1 - if(r_hand && istype(r_hand, /obj/item/weapon)) - var/obj/item/weapon/I = r_hand - if(I.IsShield() && (prob(50 - round(damage / 3)))) - visible_message("[src] blocks [attack_text] with [r_hand]!", \ - "[src] blocks [attack_text] with [r_hand]!") + if(r_hand && !istype(r_hand, /obj/item/clothing)) + var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts + if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) return 1 - if(wear_suit && istype(wear_suit, /obj/item/)) - var/obj/item/I = wear_suit - if(I.IsShield() && (prob(50))) - visible_message("The reactive teleport system flings [src] clear of [attack_text]!", \ - "The reactive teleport system flings [src] clear of [attack_text]!") - var/list/turfs = new/list() - for(var/turf/T in orange(6, src)) - if(istype(T,/turf/space)) continue - if(T.density) continue - if(T.x>world.maxx-6 || T.x<6) continue - if(T.y>world.maxy-6 || T.y<6) continue - turfs += T - if(!turfs.len) turfs += pick(/turf in orange(6, src)) - var/turf/picked = pick(turfs) - if(!isturf(picked)) return - if(buckled) - buckled.unbuckle_mob() - src.loc = picked + if(wear_suit) + var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier + if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) + return 1 + if(w_uniform) + var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier + if(w_uniform.hit_reaction(src, attack_text, final_block_chance, damage, attack_type)) return 1 return 0 @@ -221,7 +205,7 @@ emp_act if(user != src) user.do_attack_animation(src) - if(check_shields(I.force, "the [I.name]", I)) + if(check_shields(I.force, "the [I.name]", I, MELEE_ATTACK, I.armour_penetration)) return 0 if(istype(I,/obj/item/weapon/card/emag)) @@ -315,59 +299,52 @@ emp_act //this proc handles being hit by a thrown atom /mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = 5) - if(istype(AM,/obj/)) - var/obj/O = AM + if(istype(AM, /obj/item)) + var/obj/item/I = AM if(in_throw_mode && !get_active_hand() && speed <= 5) //empty active hand and we're in throw mode if(canmove && !restrained()) - if(isturf(O.loc)) - put_in_active_hand(O) - visible_message("[src] catches [O]!") + if(isturf(I.loc)) + put_in_active_hand(I) + visible_message("[src] catches [I]!") throw_mode_off() return var/zone = ran_zone("chest", 65) var/dtype = BRUTE - if(istype(O,/obj/item/weapon)) - var/obj/item/weapon/W = O + if(istype(I, /obj/item/weapon)) + var/obj/item/weapon/W = I dtype = W.damtype - var/throw_damage = O.throwforce*(speed/5) + var/throw_damage = I.throwforce*(speed/5) - /* - if(!zone) - visible_message("\blue \The [O] misses [src] narrowly!") - return - */ - O.throwing = 0 //it hit, so stop moving + I.throwing = 0 //it hit, so stop moving - if ((O.thrower != src) && check_shields(throw_damage, "[O]")) + if((I.thrower != src) && check_shields(throw_damage, "\the [I.name]", I, THROWN_PROJECTILE_ATTACK)) return var/obj/item/organ/external/affecting = get_organ(zone) if(!affecting) - var/missverb = (O.gender == PLURAL) ? "whizz" : "whizzes" - visible_message("\The [O] [missverb] past [src]'s missing [parse_zone(zone)]!", - "\The [O] [missverb] past your missing [parse_zone(zone)]!") + var/missverb = (I.gender == PLURAL) ? "whizz" : "whizzes" + visible_message("\The [I] [missverb] past [src]'s missing [parse_zone(zone)]!", + "\The [I] [missverb] past your missing [parse_zone(zone)]!") return var/hit_area = affecting.name - src.visible_message("\red [src] has been hit in the [hit_area] by [O].") - var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].") //I guess "melee" is the best fit here + src.visible_message("\red [src] has been hit in the [hit_area] by [I].") + var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].", I.armour_penetration) //I guess "melee" is the best fit here + apply_damage(throw_damage, dtype, zone, armor, is_sharp(I), has_edge(I), I) - apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) - - if(ismob(O.thrower)) - var/mob/M = O.thrower + if(ismob(I.thrower)) + var/mob/M = I.thrower if(M) - src.attack_log += text("\[[time_stamp()]\] Has been hit with a [O], thrown by [key_name(M)]") - M.attack_log += text("\[[time_stamp()]\] Hit [key_name(src)] with a thrown [O]") + src.attack_log += text("\[[time_stamp()]\] Has been hit with a [I], thrown by [key_name(M)]") + M.attack_log += text("\[[time_stamp()]\] Hit [key_name(src)] with a thrown [I]") if(!istype(src,/mob/living/simple_animal/mouse)) - msg_admin_attack("[key_name_admin(src)] was hit by a [O], thrown by [key_name_admin(M)]") + msg_admin_attack("[key_name_admin(src)] was hit by a [I], thrown by [key_name_admin(M)]") //thrown weapon embedded object code. - if(dtype == BRUTE && istype(O,/obj/item)) - var/obj/item/I = O + if(dtype == BRUTE && istype(I)) if (!I.is_robot_module()) var/sharp = is_sharp(I) var/damage = throw_damage @@ -384,10 +361,10 @@ emp_act affecting.embed(I) // Begin BS12 momentum-transfer code. - if(O.throw_source && speed >= 15) - var/obj/item/weapon/W = O + if(I.throw_source && speed >= 15) + var/obj/item/weapon/W = I var/momentum = speed/2 - var/dir = get_dir(O.throw_source, src) + var/dir = get_dir(I.throw_source, src) visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!") src.throw_at(get_edge_target_turf(src,dir),1,momentum) @@ -399,9 +376,9 @@ emp_act if(T) src.loc = T - visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!") + visible_message("[src] is pinned to the wall by [I]!","You are pinned to the wall by [I]!") src.anchored = 1 - src.pinned += O + src.pinned += I /mob/living/carbon/human/proc/bloody_hands(var/mob/living/source, var/amount = 2) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index cc50408148e..2df5b32409b 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -62,49 +62,40 @@ //this proc handles being hit by a thrown atom /mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve - if(istype(AM,/obj/)) - var/obj/O = AM + if(istype(AM, /obj/item)) + var/obj/item/I = AM var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest var/dtype = BRUTE - if(istype(O,/obj/item/weapon)) - var/obj/item/weapon/W = O + if(istype(I, /obj/item/weapon)) + var/obj/item/weapon/W = I dtype = W.damtype if (W.hitsound && W.throwforce > 0) playsound(loc, W.hitsound, 30, 1, -1) //run to-hit check here - var/throw_damage = O.throwforce*(speed/5) + var/throw_damage = I.throwforce*(speed/5) - //var/miss_chance = 15 - //if (O.throw_source) - //var/distance = get_dist(O.throw_source, loc) - //miss_chance = min(15*(distance-2), 0) - /* - if (prob(miss_chance)) - visible_message("\blue \The [O] misses [src] narrowly!") - return - */ - src.visible_message("\red [src] has been hit by [O].") - var/armor = run_armor_check(zone, "melee") + src.visible_message("\red [src] has been hit by [I].") + var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", I.armour_penetration) - apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O) + apply_damage(throw_damage, dtype, zone, armor, is_sharp(I), has_edge(I), I) - O.throwing = 0 //it hit, so stop moving + I.throwing = 0 //it hit, so stop moving - if(ismob(O.thrower)) - var/mob/M = O.thrower + if(ismob(I.thrower)) + var/mob/M = I.thrower if(M) - src.attack_log += text("\[[time_stamp()]\] Has been hit with a [O], thrown by [key_name(M)]") - M.attack_log += text("\[[time_stamp()]\] Hit [key_name(src)] with a thrown [O]") + attack_log += text("\[[time_stamp()]\] Has been hit with a [I], thrown by [key_name(M)]") + M.attack_log += text("\[[time_stamp()]\] Hit [key_name(src)] with a thrown [I]") if(!istype(src,/mob/living/simple_animal/mouse)) - msg_admin_attack("[key_name_admin(src)] was hit by a [O], thrown by [key_name_admin(M)]") + msg_admin_attack("[key_name_admin(src)] was hit by a [I], thrown by [key_name_admin(M)]") // Begin BS12 momentum-transfer code. - if(O.throw_source && speed >= 15) - var/obj/item/weapon/W = O + if(I.throw_source && speed >= 15) + var/obj/item/weapon/W = I var/momentum = speed/2 - var/dir = get_dir(O.throw_source, src) + var/dir = get_dir(I.throw_source, src) visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!") src.throw_at(get_edge_target_turf(src,dir),1,momentum) @@ -113,16 +104,16 @@ if(W.sharp) //Projectile is suitable for pinning. //Handles embedding for non-humans and simple_animals. - O.loc = src - src.embedded += O + I.loc = src + embedded += I var/turf/T = near_wall(dir,2) if(T) src.loc = T - visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!") + visible_message("[src] is pinned to the wall by [I]!","You are pinned to the wall by [I]!") src.anchored = 1 - src.pinned += O + src.pinned += I /mob/living/mech_melee_attack(obj/mecha/M) if(M.occupant.a_intent == I_HARM) diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm new file mode 100644 index 00000000000..c4a71cca618 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -0,0 +1,75 @@ +/mob/living/simple_animal/hostile/illusion + name = "illusion" + desc = "It's a fake!" + icon = 'icons/effects/effects.dmi' + icon_state = "static" + icon_living = "static" + icon_dead = "null" + melee_damage_lower = 5 + melee_damage_upper = 5 + a_intent = "harm" + attacktext = "gores" + maxHealth = 100 + health = 100 + speed = 0 + faction = list("illusion") + var/life_span = INFINITY //how long until they despawn + var/mob/living/parent_mob + var/multiply_chance = 0 //if we multiply on hit + + +/mob/living/simple_animal/hostile/illusion/Life() + ..() + if(world.time > life_span) + death() + +/mob/living/simple_animal/hostile/illusion/death(gibbed) + ..() + visible_message("\The [src] vanishes into thin air! It was a fake!") + ghostize() + qdel(src) + +/mob/living/simple_animal/hostile/illusion/proc/Copy_Parent(mob/living/original, life = 50, health = 100, damage = 0, replicate = 0 ) + appearance = original.appearance + parent_mob = original + dir = original.dir + life_span = world.time+life + melee_damage_lower = damage + melee_damage_upper = damage + multiply_chance = replicate + faction -= "neutral" + transform = initial(transform) + pixel_y = initial(pixel_y) + pixel_x = initial(pixel_x) + +/mob/living/simple_animal/hostile/illusion/examine(mob/user) + if(parent_mob) + parent_mob.examine(user) + else + return ..() + + +/mob/living/simple_animal/hostile/illusion/AttackingTarget() + ..() + if(istype(target, /mob/living) && prob(multiply_chance)) + var/mob/living/L = target + if(L.stat == DEAD) + return + var/mob/living/simple_animal/hostile/illusion/M = new(loc) + M.faction = faction.Copy() + M.Copy_Parent(parent_mob, 80, health/2, melee_damage_upper, multiply_chance/2) + M.GiveTarget(L) + +///////Actual Types///////// + +/mob/living/simple_animal/hostile/illusion/escape + retreat_distance = 10 + minimum_distance = 10 + melee_damage_lower = 0 + melee_damage_upper = 0 + speed = -1 + environment_smash = 0 + + +/mob/living/simple_animal/hostile/illusion/escape/AttackingTarget() + return diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 32bdf5fc772..fe04470c60c 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -39,6 +39,7 @@ icon_living = "syndicatemelee" attacktext = "slashes" attack_sound = 'sound/weapons/bladeslice.ogg' + armour_penetration = 28 status_flags = 0 loot = list(/obj/effect/landmark/mobcorpse/syndicatesoldier, /obj/item/weapon/melee/energy/sword/saber/red, /obj/item/weapon/shield/energy) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 93e72a96707..f1818153974 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -49,6 +49,7 @@ //LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly var/melee_damage_lower = 0 var/melee_damage_upper = 0 + var/armour_penetration = 0 //How much armour they ignore, as a flat reduction from the targets armour value var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage. var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source var/attacktext = "attacks" diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 695d701dba3..725d97ce21b 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/paradise.dme b/paradise.dme index 3f06e7152d2..9817e7c4db0 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1628,6 +1628,7 @@ #include "code\modules\mob\living\simple_animal\hostile\headcrab.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" +#include "code\modules\mob\living\simple_animal\hostile\illusion.dm" #include "code\modules\mob\living\simple_animal\hostile\jungle_animals.dm" #include "code\modules\mob\living\simple_animal\hostile\killertomato.dm" #include "code\modules\mob\living\simple_animal\hostile\mimic.dm"