mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Adds miss chance and shield checks to thrown atoms
Also makes setting a thrown atom's throwing var the responsibility of the handler, so that impact handling code can decide if the thrown atom should keep on going.
This commit is contained in:
@@ -22,27 +22,6 @@
|
|||||||
//Detective Work, used for the duplicate data points kept in the scanners
|
//Detective Work, used for the duplicate data points kept in the scanners
|
||||||
var/list/original_atom
|
var/list/original_atom
|
||||||
|
|
||||||
/atom/proc/throw_impact(atom/hit_atom, var/speed)
|
|
||||||
if(istype(hit_atom,/mob/living))
|
|
||||||
var/mob/living/M = hit_atom
|
|
||||||
M.hitby(src,speed)
|
|
||||||
|
|
||||||
else if(isobj(hit_atom))
|
|
||||||
var/obj/O = hit_atom
|
|
||||||
if(!O.anchored)
|
|
||||||
step(O, src.dir)
|
|
||||||
O.hitby(src,speed)
|
|
||||||
|
|
||||||
else if(isturf(hit_atom))
|
|
||||||
var/turf/T = hit_atom
|
|
||||||
if(T.density)
|
|
||||||
spawn(2)
|
|
||||||
step(src, turn(src.dir, 180))
|
|
||||||
if(istype(src,/mob/living))
|
|
||||||
var/mob/living/M = src
|
|
||||||
M.turf_collision(T, speed)
|
|
||||||
|
|
||||||
|
|
||||||
/atom/proc/assume_air(datum/gas_mixture/giver)
|
/atom/proc/assume_air(datum/gas_mixture/giver)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
@@ -237,6 +216,8 @@ its easier to just keep the beam vertical.
|
|||||||
return
|
return
|
||||||
|
|
||||||
/atom/proc/hitby(atom/movable/AM as mob|obj)
|
/atom/proc/hitby(atom/movable/AM as mob|obj)
|
||||||
|
if (density)
|
||||||
|
AM.throwing = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
/atom/proc/add_hiddenprint(mob/living/M as mob)
|
/atom/proc/add_hiddenprint(mob/living/M as mob)
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
/atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes)
|
/atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes)
|
||||||
if(src.throwing)
|
if(src.throwing)
|
||||||
src.throw_impact(A)
|
src.throw_impact(A)
|
||||||
src.throwing = 0
|
|
||||||
|
|
||||||
spawn( 0 )
|
spawn( 0 )
|
||||||
if ((A && yes))
|
if ((A && yes))
|
||||||
@@ -44,6 +43,29 @@
|
|||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
//called when src is thrown into hit_atom
|
||||||
|
/atom/movable/proc/throw_impact(atom/hit_atom, var/speed)
|
||||||
|
if(istype(hit_atom,/mob/living))
|
||||||
|
var/mob/living/M = hit_atom
|
||||||
|
M.hitby(src,speed)
|
||||||
|
|
||||||
|
else if(isobj(hit_atom))
|
||||||
|
var/obj/O = hit_atom
|
||||||
|
if(!O.anchored)
|
||||||
|
step(O, src.dir)
|
||||||
|
O.hitby(src,speed)
|
||||||
|
|
||||||
|
else if(isturf(hit_atom))
|
||||||
|
src.throwing = 0
|
||||||
|
var/turf/T = hit_atom
|
||||||
|
if(T.density)
|
||||||
|
spawn(2)
|
||||||
|
step(src, turn(src.dir, 180))
|
||||||
|
if(istype(src,/mob/living))
|
||||||
|
var/mob/living/M = src
|
||||||
|
M.turf_collision(T, speed)
|
||||||
|
|
||||||
|
//decided whether a movable atom being thrown can pass through the turf it is in.
|
||||||
/atom/movable/proc/hit_check(var/speed)
|
/atom/movable/proc/hit_check(var/speed)
|
||||||
if(src.throwing)
|
if(src.throwing)
|
||||||
for(var/atom/A in get_turf(src))
|
for(var/atom/A in get_turf(src))
|
||||||
@@ -51,12 +73,9 @@
|
|||||||
if(istype(A,/mob/living))
|
if(istype(A,/mob/living))
|
||||||
if(A:lying) continue
|
if(A:lying) continue
|
||||||
src.throw_impact(A,speed)
|
src.throw_impact(A,speed)
|
||||||
if(src.throwing == 1)
|
|
||||||
src.throwing = 0
|
|
||||||
if(isobj(A))
|
if(isobj(A))
|
||||||
if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement
|
if(A.density && !A.throwpass) // **TODO: Better behaviour for windows which are dense, but shouldn't always stop movement
|
||||||
src.throw_impact(A,speed)
|
src.throw_impact(A,speed)
|
||||||
src.throwing = 0
|
|
||||||
|
|
||||||
/atom/movable/proc/throw_at(atom/target, range, speed)
|
/atom/movable/proc/throw_at(atom/target, range, speed)
|
||||||
if(!target || !src) return 0
|
if(!target || !src) return 0
|
||||||
@@ -149,8 +168,8 @@
|
|||||||
a = get_area(src.loc)
|
a = get_area(src.loc)
|
||||||
|
|
||||||
//done throwing, either because it hit something or it finished moving
|
//done throwing, either because it hit something or it finished moving
|
||||||
src.throwing = 0
|
|
||||||
if(isobj(src)) src.throw_impact(get_turf(src),speed)
|
if(isobj(src)) src.throw_impact(get_turf(src),speed)
|
||||||
|
src.throwing = 0
|
||||||
|
|
||||||
|
|
||||||
//Overlays
|
//Overlays
|
||||||
|
|||||||
@@ -469,6 +469,7 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
|
/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
|
||||||
|
..()
|
||||||
src.log_message("Hit by [A].",1)
|
src.log_message("Hit by [A].",1)
|
||||||
call((proc_res["dynhitby"]||src), "dynhitby")(A)
|
call((proc_res["dynhitby"]||src), "dynhitby")(A)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
|||||||
if(stat == CONSCIOUS)
|
if(stat == CONSCIOUS)
|
||||||
icon_state = "[initial(icon_state)]"
|
icon_state = "[initial(icon_state)]"
|
||||||
Attach(hit_atom)
|
Attach(hit_atom)
|
||||||
|
throwing = 0
|
||||||
|
|
||||||
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
|
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
|
||||||
if( (!iscorgi(M) && !iscarbon(M)) || isalien(M))
|
if( (!iscorgi(M) && !iscarbon(M)) || isalien(M))
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
P.on_hit(src, absorb, def_zone)
|
P.on_hit(src, absorb, def_zone)
|
||||||
return absorb
|
return absorb
|
||||||
|
|
||||||
|
//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
|
/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
|
||||||
if(istype(AM,/obj/))
|
if(istype(AM,/obj/))
|
||||||
var/obj/O = AM
|
var/obj/O = AM
|
||||||
@@ -73,14 +74,27 @@
|
|||||||
if(istype(O,/obj/item/weapon))
|
if(istype(O,/obj/item/weapon))
|
||||||
var/obj/item/weapon/W = O
|
var/obj/item/weapon/W = O
|
||||||
dtype = W.damtype
|
dtype = W.damtype
|
||||||
|
var/throw_damage = O.throwforce*(speed/5)
|
||||||
|
|
||||||
//run to-hit check here
|
//def_zone = get_zone_with_miss_chance(zone, src, 15*AM.throwing_dist_travelled)
|
||||||
|
zone = get_zone_with_miss_chance(zone, src) //TODO: store the location of the thrower and adjust miss chance with distance
|
||||||
|
|
||||||
|
if(!zone)
|
||||||
|
visible_message("\blue \The [AM] misses [src] narrowly!")
|
||||||
|
return
|
||||||
|
|
||||||
|
AM.throwing = 0 //it hit, so stop moving
|
||||||
|
|
||||||
|
if (istype(src, /mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = src
|
||||||
|
if (H.check_shields(throw_damage, "[O]"))
|
||||||
|
return
|
||||||
|
|
||||||
src.visible_message("\red [src] has been hit by [O].")
|
src.visible_message("\red [src] has been hit by [O].")
|
||||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened hit to your [zone].")
|
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened the hit to your [zone].")
|
||||||
|
|
||||||
if(armor < 2)
|
if(armor < 2)
|
||||||
apply_damage(O.throwforce*(speed/5), dtype, zone, armor, is_sharp(O), has_edge(O), O)
|
apply_damage(throw_damage, dtype, zone, armor, is_sharp(O), has_edge(O), O)
|
||||||
|
|
||||||
if(!O.fingerprintslast)
|
if(!O.fingerprintslast)
|
||||||
return
|
return
|
||||||
@@ -99,7 +113,7 @@
|
|||||||
if(speed >= 15)
|
if(speed >= 15)
|
||||||
var/obj/item/weapon/W = O
|
var/obj/item/weapon/W = O
|
||||||
var/momentum = speed/2
|
var/momentum = speed/2
|
||||||
var/dir = get_dir(M,src)
|
var/dir = get_dir(M,src) //TODO: store the location of the thrower and move this out of the fingerprintslast block
|
||||||
|
|
||||||
visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
|
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)
|
src.throw_at(get_edge_target_turf(src,dir),1,momentum)
|
||||||
|
|||||||
@@ -147,7 +147,11 @@ proc/hasorgans(A)
|
|||||||
*/
|
*/
|
||||||
return zone
|
return zone
|
||||||
|
|
||||||
|
// Returns zone with a certain probability.
|
||||||
|
// If the probability misses, returns "chest" instead.
|
||||||
|
// If "chest" was passed in as zone, then on a "miss" will return "head", "l_arm", or "r_arm"
|
||||||
|
// Do not use this if someone is intentionally trying to hit a specific body part.
|
||||||
|
// Use get_zone_with_miss_chance() for that.
|
||||||
/proc/ran_zone(zone, probability)
|
/proc/ran_zone(zone, probability)
|
||||||
zone = check_zone(zone)
|
zone = check_zone(zone)
|
||||||
if(!probability) probability = 90
|
if(!probability) probability = 90
|
||||||
|
|||||||
Reference in New Issue
Block a user