Refactors bottle smashing, apply_hit_effect() now returns the blocked status.

Conflicts:
	code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
	code/modules/mob/living/simple_animal/simple_animal.dm
	code/modules/reagents/reagent_containers/food/drinks/bottle.dm
This commit is contained in:
mwerezak
2015-09-09 13:39:18 -04:00
committed by HarpyEagle
parent 9ef3df66e3
commit deb215d262
9 changed files with 280 additions and 94 deletions

View File

@@ -74,7 +74,7 @@ avoid code duplication. This includes items that may sometimes act as a standard
return 1
//Called when a weapon is used to make a successful melee attack on a mob.
//Called when a weapon is used to make a successful melee attack on a mob. Returns the blocked result
/obj/item/proc/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
if(hitsound)
playsound(loc, hitsound, 50, 1, -1)

View File

@@ -19,11 +19,11 @@
qdel(src)
return
user.visible_message("<span class='danger'>\The [user] has prodded \the [M] with \a [src]!</span>")
if(!user.cell || !user.cell.checked_use(1250)) //Slightly more than a baton.
user.visible_message("<span class='danger'>\The [user] has prodded \the [M] with its arm!</span>")
return
user.visible_message("<span class='danger'>\The [user] has prodded \the [M] with \a [src]!</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
M.apply_effect(5, STUTTER)

View File

@@ -112,8 +112,7 @@
/obj/item/weapon/melee/baton/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
if(isrobot(target))
..()
return
return ..()
var/agony = agonyforce
var/stun = stunforce
@@ -123,7 +122,7 @@
affecting = H.get_organ(hit_zone)
if(user.a_intent == I_HURT)
..()
. = ..()
//whacking someone causes a much poorer electrical contact than deliberately prodding them.
agony *= 0.5
stun *= 0.5

View File

@@ -237,7 +237,7 @@
..()
/obj/item/weapon/reagent_containers/food/snacks/grown/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
..()
. = ..()
if(seed && seed.get_trait(TRAIT_STINGS))
if(!reagents || reagents.total_volume <= 0)

View File

@@ -178,7 +178,7 @@ emp_act
var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].")
standard_weapon_hit_effects(I, user, effective_force, blocked, hit_zone)
return 1
return blocked
/mob/living/carbon/human/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
var/obj/item/organ/external/affecting = get_organ(hit_zone)

View File

@@ -0,0 +1,232 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
//TODO: Make these simple_animals
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
var/const/MAX_IMPREGNATION_TIME = 150
var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger
name = "alien"
desc = "It has some sort of a tube at the end of its tail."
icon = 'icons/mob/alien.dmi'
icon_state = "facehugger"
item_state = "facehugger"
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
flags = PROXMOVE
body_parts_covered = FACE|EYES
throw_range = 5
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
var/sterile = 0
var/strength = 5
var/attached = 0
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile))
if(Attach(user))
return
..()
/obj/item/clothing/mask/facehugger/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
. = ..()
user.drop_from_inventory(src)
if(hit_zone == "head")
Attach(target)
/obj/item/clothing/mask/facehugger/New()
if(config.aliens_allowed)
..()
else
qdel(src)
/obj/item/clothing/mask/facehugger/examine(mob/user)
..(user)
switch(stat)
if(DEAD,UNCONSCIOUS)
user << "\red \b [src] is not moving."
if(CONSCIOUS)
user << "\red \b [src] seems to be active."
if (sterile)
user << "\red \b It looks like the proboscis has been removed."
return
/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user)
if(I.force)
user.do_attack_animation(src)
Die()
return
/obj/item/clothing/mask/facehugger/bullet_act()
Die()
return
/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C+80)
Die()
return
/obj/item/clothing/mask/facehugger/equipped(mob/M)
Attach(M)
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
HasProximity(target)
return
/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
if(stat == CONSCIOUS)
HasProximity(finder)
return 1
return
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
if(CanHug(AM))
Attach(AM)
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
spawn(15)
if(icon_state == "[initial(icon_state)]_thrown")
icon_state = "[initial(icon_state)]"
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]"
throwing = 0
GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap)
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
if((!iscorgi(M) && !iscarbon(M)))
return
if(attached)
return
var/mob/living/carbon/C = M
if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
return
attached++
spawn(MAX_IMPREGNATION_TIME)
attached = 0
var/mob/living/L = M //just so I don't need to use :
if(loc == L) return
if(stat != CONSCIOUS) return
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
L.visible_message("\red \b [src] leaps at [L]'s face!")
if(iscarbon(M))
var/mob/living/carbon/target = L
if(target.wear_mask)
if(prob(20)) return
var/obj/item/clothing/W = target.wear_mask
if(!W.canremove) return
target.drop_from_inventory(W)
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
target.equip_to_slot(src, slot_wear_mask)
target.contents += src // Monkey sanity check - Snapshot
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
else if (iscorgi(M))
var/mob/living/simple_animal/corgi/corgi = M
src.loc = corgi
corgi.facehugger = src
corgi.wear_mask = src
//C.regenerate_icons()
GoIdle() //so it doesn't jump the people that tear it off
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
Impregnate(L)
return
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
return
if(!sterile)
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
new /obj/item/alien_embryo(target)
target.status_flags |= XENO_HOST
target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
Die()
icon_state = "[initial(icon_state)]_impregnated"
if(iscorgi(target))
var/mob/living/simple_animal/corgi/C = target
src.loc = get_turf(C)
C.facehugger = null
else
target.visible_message("\red \b [src] violates [target]'s face!")
return
/obj/item/clothing/mask/facehugger/proc/GoActive()
if(stat == DEAD || stat == CONSCIOUS)
return
stat = CONSCIOUS
icon_state = "[initial(icon_state)]"
return
/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME)
if(stat == DEAD || stat == UNCONSCIOUS)
return
/* RemoveActiveIndicators() */
stat = UNCONSCIOUS
icon_state = "[initial(icon_state)]_inactive"
spawn(rand(min_time,max_time))
GoActive()
return
/obj/item/clothing/mask/facehugger/proc/Die()
if(stat == DEAD)
return
/* RemoveActiveIndicators() */
icon_state = "[initial(icon_state)]_dead"
stat = DEAD
src.visible_message("\red \b[src] curls up into a ball!")
return
/proc/CanHug(var/mob/M)
if(iscorgi(M))
return 1
if(!iscarbon(M))
return 0
var/mob/living/carbon/C = M
if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
return 0
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL))
return 0
return 1

View File

@@ -144,35 +144,10 @@
O.emp_act(severity)
..()
/*
//Whereas attackby() handles the general case of using items on mobs, this handles the specific case of attacking a mob with an item as a weapon.
/mob/living/proc/attacked_with_item(obj/item/I, mob/living/user, var/target_zone)
if(!istype(user))
return 0
/////////////////////////
user.lastattacked = M
M.lastattacker = user
if(!no_attack_log)
user.attack_log += "\[[time_stamp()]\]<font color='red'> Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])</font>"
msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" )
/////////////////////////
user.do_attack_animation(M)
var/hit_zone = resolve_hit_zone(I, user, target_zone)
if(hit_zone)
I.apply_hit_effect(src, user, hit_zone)
return 1
*/
/mob/living/proc/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone)
return target_zone
//Called when the mob is hit with an item in combat.
//Called when the mob is hit with an item in combat. Returns the blocked result
/mob/living/proc/hit_with_weapon(obj/item/I, mob/living/user, var/effective_force, var/hit_zone)
visible_message("<span class='danger'>[src] has been [I.attack_verb.len? pick(I.attack_verb) : "attacked"] with [I.name] by [user]!</span>")
@@ -183,6 +158,8 @@
var/turf/simulated/location = get_turf(src)
if(istype(location)) location.add_blood_floor(src)
return blocked
//returns 0 if the effects failed to apply for some reason, 1 otherwise.
/mob/living/proc/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
if(!effective_force || blocked >= 2)

View File

@@ -294,19 +294,22 @@
/mob/living/simple_animal/hit_with_weapon(obj/item/O, mob/living/user, var/effective_force, var/hit_zone)
if(O.force > resistance)
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
if(supernatural && istype(O,/obj/item/weapon/nullrod))
damage *= 2
purge = 3
adjustBruteLoss(damage)
else
user << "<span class='danger'>This weapon is ineffective, it does no damage.</span>"
visible_message("<span class='danger'>\The [src] has been attacked with \the [O] by [user].</span>")
if(O.force <= resistance)
user << "<span class='danger'>This weapon is ineffective, it does no damage.</span>"
return 2
var/damage = O.force
if (O.damtype == HALLOSS)
damage = 0
if(supernatural && istype(O,/obj/item/weapon/nullrod))
damage *= 2
purge = 3
adjustBruteLoss(damage)
return 0
/mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later

View File

@@ -136,59 +136,34 @@
else
set_light(0)
/obj/item/weapon/reagent_containers/food/drinks/bottle/attack(mob/living/target as mob, mob/living/user as mob)
if(!target)
/obj/item/weapon/reagent_containers/food/drinks/bottle/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
var/blocked = ..()
if(user.a_intent != I_HURT)
return
if(user.a_intent != I_HURT || !isGlass)
return ..()
var/affecting = user.zone_sel.selecting //Find what the player is aiming at
var/armor_block = 0 //Get the target's armour values for normal attack damage.
var/armor_duration = 0 //The more force the bottle has, the longer the duration.
//Calculating duration and calculating damage.
armor_block = target.run_armor_check(affecting, "melee")
//force will counteract armour, but will never increase duration
armor_duration = smash_duration + min(0, force - target.getarmor(affecting, "melee") + 10)
//Apply the damage!
target.apply_damage(force, BRUTE, affecting, armor_block, sharp=0)
if(!smash_check(1))
return //won't always break on the first hit
// You are going to knock someone out for longer if they are not wearing a helmet.
var/do_smash = smash_check(1) //won't always break on the first hit
var/mob/living/carbon/human/H = target
if(do_smash && istype(H) && H.headcheck(affecting))
//Display an attack message.
var/obj/item/organ/O = H.get_organ(affecting)
user.visible_message("<span class='danger'>[user] smashes [src] into [H]'s [O.name]!</span>")
//Weaken the target for the duration that we calculated and divide it by 5.
if(armor_duration)
target.apply_effect(min(armor_duration, 5) , WEAKEN, armor_block) // Never weaken more than a flash!
var/weaken_duration = 0
if(blocked < 2)
weaken_duration = smash_duration + min(0, force - target.getarmor(hit_zone, "melee") + 10)
if(hit_zone == "head" && istype(target, /mob/living/carbon/))
user.visible_message("<span class='danger'>\The [user] smashes [src] over [target]'s head!</span>")
if(weaken_duration)
target.apply_effect(min(weaken_duration, 5), WEAKEN, blocked) // Never weaken more than a flash!
else
//Default attack message and don't weaken the target.
for(var/mob/O in viewers(user, null))
if(target != user) O.show_message(text("\red <B>[target] has been attacked with a bottle of [src.name], by [user]!</B>"), 1)
else O.show_message(text("\red <B>[target] has attacked \himself with a bottle of [src.name]!</B>"), 1)
user.visible_message("<span class='danger'>\The [user] smashes [src] into [target]!</span>")
//Attack logs
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has attacked [target.name] ([target.ckey]) with a bottle!</font>")
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been smashed with a bottle by [user.name] ([user.ckey])</font>")
msg_admin_attack("[user.name] ([user.ckey]) attacked [target.name] ([target.ckey]) with a bottle. (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
//The reagents in the bottle splash all over the target, thanks for the idea Nodrak
if(reagents)
user.visible_message("<span class='notice'>The contents of the [src] splash all over [target]!</span>")
reagents.splash(target, reagents.total_volume)
if(do_smash)
//The reagents in the bottle splash all over the target, thanks for the idea Nodrak
if(reagents)
user.visible_message("<span class='notice'>The contents of the [src] splash all over [target]!</span>")
reagents.splash(target, reagents.total_volume)
//Finally, smash the bottle. This kills (qdel) the bottle.
var/obj/item/weapon/broken_bottle/B = src.smash(target.loc, target)
user.put_in_active_hand(B)
return
//Finally, smash the bottle. This kills (qdel) the bottle.
var/obj/item/weapon/broken_bottle/B = smash(target.loc, target)
user.put_in_active_hand(B)
//Keeping this here for now, I'll ask if I should keep it here.
/obj/item/weapon/broken_bottle
@@ -480,4 +455,4 @@
center_of_mass = list("x"=16, "y"=10)
New()
..()
reagents.add_reagent("ale", 30)
reagents.add_reagent("ale", 30)