Merge pull request #6930 from Novacat/nova-shuttle

Earlyport Fixes
This commit is contained in:
Novacat
2020-03-20 14:00:51 -04:00
committed by GitHub
12 changed files with 43 additions and 27 deletions

View File

@@ -20,6 +20,11 @@
#define MOVEMENT_FAILED 0 // Move() returned false for whatever reason and the mob didn't move. #define MOVEMENT_FAILED 0 // Move() returned false for whatever reason and the mob didn't move.
#define MOVEMENT_SUCCESSFUL 1 // Move() returned true and the mob hopefully moved. #define MOVEMENT_SUCCESSFUL 1 // Move() returned true and the mob hopefully moved.
// Results of pre-attack checks
#define ATTACK_ON_COOLDOWN -1 // Recently attacked and needs to try again soon.
#define ATTACK_FAILED 0 // Something else went wrong! Maybe they moved away!
#define ATTACK_SUCCESSFUL 1 // We attacked (or tried to, misses count too)
// Reasons for targets to not be valid. Based on why, the AI responds differently. // Reasons for targets to not be valid. Based on why, the AI responds differently.
#define AI_TARGET_VALID 0 // We can fight them. #define AI_TARGET_VALID 0 // We can fight them.
#define AI_TARGET_INVIS 1 // They were in field of view but became invisible. Switch to STANCE_BLINDFIGHT if no other viable targets exist. #define AI_TARGET_INVIS 1 // They were in field of view but became invisible. Switch to STANCE_BLINDFIGHT if no other viable targets exist.

View File

@@ -70,21 +70,21 @@
/datum/ai_holder/proc/melee_attack(atom/A) /datum/ai_holder/proc/melee_attack(atom/A)
pre_melee_attack(A) pre_melee_attack(A)
. = holder.IAttack(A) . = holder.IAttack(A)
if(.) if(. == ATTACK_SUCCESSFUL)
post_melee_attack(A) post_melee_attack(A)
// Ditto. // Ditto.
/datum/ai_holder/proc/ranged_attack(atom/A) /datum/ai_holder/proc/ranged_attack(atom/A)
pre_ranged_attack(A) pre_ranged_attack(A)
. = holder.IRangedAttack(A) . = holder.IRangedAttack(A)
if(.) if(. == ATTACK_SUCCESSFUL)
post_ranged_attack(A) post_ranged_attack(A)
// Most mobs probably won't have this defined but we don't care. // Most mobs probably won't have this defined but we don't care.
/datum/ai_holder/proc/special_attack(atom/movable/AM) /datum/ai_holder/proc/special_attack(atom/movable/AM)
pre_special_attack(AM) pre_special_attack(AM)
. = holder.ISpecialAttack(AM) . = holder.ISpecialAttack(AM)
if(.) if(. == ATTACK_SUCCESSFUL)
post_special_attack(AM) post_special_attack(AM)
// Called when within striking/shooting distance, however cooldown is not considered. // Called when within striking/shooting distance, however cooldown is not considered.
@@ -218,7 +218,6 @@
var/dir_to_target = get_dir(holder, target_atom) var/dir_to_target = get_dir(holder, target_atom)
holder.face_atom(target_atom) holder.face_atom(target_atom)
ai_log("breakthrough() : Exiting", AI_LOG_DEBUG)
// Sometimes the mob will try to hit something diagonally, and generally this fails. // Sometimes the mob will try to hit something diagonally, and generally this fails.
// So instead we will try two more times with some adjustments if the attack fails. // So instead we will try two more times with some adjustments if the attack fails.
@@ -274,31 +273,31 @@
for(var/obj/structure/window/W in problem_turf) for(var/obj/structure/window/W in problem_turf)
if(W.dir == reverse_dir[holder.dir]) // So that windows get smashed in the right order if(W.dir == reverse_dir[holder.dir]) // So that windows get smashed in the right order
ai_log("destroy_surroundings() : Attacking side window.", AI_LOG_INFO) ai_log("destroy_surroundings() : Attacking side window.", AI_LOG_INFO)
return holder.IAttack(W) return melee_attack(W)
else if(W.is_fulltile()) else if(W.is_fulltile())
ai_log("destroy_surroundings() : Attacking full tile window.", AI_LOG_INFO) ai_log("destroy_surroundings() : Attacking full tile window.", AI_LOG_INFO)
return holder.IAttack(W) return melee_attack(W)
// Kill hull shields in the way. // Kill hull shields in the way.
for(var/obj/effect/energy_field/shield in problem_turf) for(var/obj/effect/energy_field/shield in problem_turf)
if(shield.density) // Don't attack shields that are already down. if(shield.density) // Don't attack shields that are already down.
ai_log("destroy_surroundings() : Attacking hull shield.", AI_LOG_INFO) ai_log("destroy_surroundings() : Attacking hull shield.", AI_LOG_INFO)
return holder.IAttack(shield) return melee_attack(shield)
// Kill common obstacle in the way like tables. // Kill common obstacle in the way like tables.
var/obj/structure/obstacle = locate(/obj/structure, problem_turf) var/obj/structure/obstacle = locate(/obj/structure, problem_turf)
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille)) if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
ai_log("destroy_surroundings() : Attacking generic structure.", AI_LOG_INFO) ai_log("destroy_surroundings() : Attacking generic structure.", AI_LOG_INFO)
return holder.IAttack(obstacle) return melee_attack(obstacle)
for(var/obj/machinery/door/D in problem_turf) // Required since firelocks take up the same turf. for(var/obj/machinery/door/D in problem_turf) // Required since firelocks take up the same turf.
if(D.density) if(D.density)
ai_log("destroy_surroundings() : Attacking closed door.", AI_LOG_INFO) ai_log("destroy_surroundings() : Attacking closed door.", AI_LOG_INFO)
return holder.IAttack(D) return melee_attack(D)
ai_log("destroy_surroundings() : Exiting due to nothing to attack.", AI_LOG_INFO) ai_log("destroy_surroundings() : Exiting due to nothing to attack.", AI_LOG_INFO)
return FALSE // Nothing to attack. return ATTACK_FAILED // Nothing to attack.
// Override for special behaviour. // Override for special behaviour.
/datum/ai_holder/proc/can_violently_breakthrough() /datum/ai_holder/proc/can_violently_breakthrough()

View File

@@ -16,6 +16,8 @@
var/base_wander_delay = 2 // What the above var gets set to when it wanders. Note that a tick happens every half a second. var/base_wander_delay = 2 // What the above var gets set to when it wanders. Note that a tick happens every half a second.
var/wander_when_pulled = FALSE // If the mob will refrain from wandering if someone is pulling it. var/wander_when_pulled = FALSE // If the mob will refrain from wandering if someone is pulling it.
// Breakthrough
var/failed_breakthroughs = 0 // How many times we've failed to breakthrough something lately
/datum/ai_holder/proc/walk_to_destination() /datum/ai_holder/proc/walk_to_destination()
ai_log("walk_to_destination() : Entering.",AI_LOG_TRACE) ai_log("walk_to_destination() : Entering.",AI_LOG_TRACE)
@@ -90,7 +92,9 @@
// step_to(holder, A) // step_to(holder, A)
if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED) if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED)
ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO) ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO)
breakthrough(A) // We failed to move, time to smash things. if(!breakthrough(A) && failed_breakthroughs++ >= 5) // We failed to move, time to smash things.
give_up_movement()
failed_breakthroughs = 0
return return
if(move_once() == FALSE) // Start walking the path. if(move_once() == FALSE) // Start walking the path.
@@ -106,7 +110,9 @@
ai_log("walk_path() : Going to IMove().", AI_LOG_TRACE) ai_log("walk_path() : Going to IMove().", AI_LOG_TRACE)
if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED ) if(holder.IMove(get_step_to(holder, A)) == MOVEMENT_FAILED )
ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO) ai_log("walk_path() : Failed to move, attempting breakthrough.", AI_LOG_INFO)
breakthrough(A) // We failed to move, time to smash things. if(!breakthrough(A) && failed_breakthroughs++ >= 5) // We failed to move, time to smash things.
give_up_movement()
failed_breakthroughs = 0
ai_log("walk_path() : Exited.", AI_LOG_TRACE) ai_log("walk_path() : Exited.", AI_LOG_TRACE)

View File

@@ -8,7 +8,7 @@
/mob/living/simple_mob/IAttack(atom/A) /mob/living/simple_mob/IAttack(atom/A)
if(!canClick()) // Still on cooldown from a "click". if(!canClick()) // Still on cooldown from a "click".
return FALSE return ATTACK_ON_COOLDOWN
return attack_target(A) // This will set click cooldown. return attack_target(A) // This will set click cooldown.
/mob/living/proc/IRangedAttack(atom/A) /mob/living/proc/IRangedAttack(atom/A)
@@ -16,7 +16,7 @@
/mob/living/simple_mob/IRangedAttack(atom/A) /mob/living/simple_mob/IRangedAttack(atom/A)
if(!canClick()) // Still on cooldown from a "click". if(!canClick()) // Still on cooldown from a "click".
return FALSE return ATTACK_ON_COOLDOWN
return shoot_target(A) return shoot_target(A)
// Test if the AI is allowed to attempt a ranged attack. // Test if the AI is allowed to attempt a ranged attack.

View File

@@ -32,8 +32,11 @@
expire() expire()
else if(holder.fire_stacks > 0) else if(holder.fire_stacks > 0)
holder.fire_stacks -= 1 holder.fire_stacks -= 0.5
/datum/modifier/fire/stack_managed/intense /datum/modifier/fire/stack_managed/intense
mob_overlay_state = "on_fire_intense" mob_overlay_state = "on_fire_intense"
damage_per_tick = 10 damage_per_tick = 10
/datum/modifier/fire/stack_managed/weak
damage_per_tick = 1

View File

@@ -1,6 +1,6 @@
/mob/living/carbon/human/process_resist() /mob/living/carbon/human/process_resist()
//drop && roll //drop && roll
if(on_fire && !buckled) if((on_fire || has_modifier_of_type(/datum/modifier/fire)) && !buckled)
adjust_fire_stacks(-1.2) adjust_fire_stacks(-1.2)
Weaken(3) Weaken(3)
spin(32,2) spin(32,2)
@@ -9,7 +9,7 @@
"<span class='notice'>You stop, drop, and roll!</span>" "<span class='notice'>You stop, drop, and roll!</span>"
) )
sleep(30) sleep(30)
if(fire_stacks <= 0) if(fire_stacks <= 0 && !(has_modifier_of_type(/datum/modifier/fire)))
visible_message( visible_message(
"<span class='danger'>[src] has successfully extinguished themselves!</span>", "<span class='danger'>[src] has successfully extinguished themselves!</span>",
"<span class='notice'>You extinguish yourself.</span>" "<span class='notice'>You extinguish yourself.</span>"

View File

@@ -363,6 +363,9 @@
handle_light() handle_light()
update_fire() update_fire()
if(has_modifier_of_type(/datum/modifier/fire))
remove_modifiers_of_type(/datum/modifier/fire)
/mob/living/proc/update_fire() /mob/living/proc/update_fire()
return return

View File

@@ -3,26 +3,24 @@
set waitfor = FALSE // For attack animations. Don't want the AI processor to get held up. set waitfor = FALSE // For attack animations. Don't want the AI processor to get held up.
if(!A.Adjacent(src)) if(!A.Adjacent(src))
return FALSE return ATTACK_FAILED
var/turf/their_T = get_turf(A) var/turf/their_T = get_turf(A)
face_atom(A) face_atom(A)
if(melee_attack_delay) if(melee_attack_delay)
// their_T.color = "#FF0000"
melee_pre_animation(A) melee_pre_animation(A)
. = ATTACK_SUCCESSFUL //Shoving this in here as a 'best guess' since this proc is about to sleep and return and we won't be able to know the real value
handle_attack_delay(A, melee_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false. handle_attack_delay(A, melee_attack_delay) // This will sleep this proc for a bit, which is why waitfor is false.
// Cooldown testing is done at click code (for players) and interface code (for AI). // Cooldown testing is done at click code (for players) and interface code (for AI).
setClickCooldown(get_attack_speed()) setClickCooldown(get_attack_speed())
// Returns a value, but will be lost if
. = do_attack(A, their_T) . = do_attack(A, their_T)
if(melee_attack_delay) if(melee_attack_delay)
melee_post_animation(A) melee_post_animation(A)
// their_T.color = "#FFFFFF"
// This does the actual attack. // This does the actual attack.
// This is a seperate proc for the purposes of attack animations. // This is a seperate proc for the purposes of attack animations.

View File

@@ -9,6 +9,7 @@
one_handed_penalty = 20 one_handed_penalty = 20
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_ILLEGAL = 2, TECH_PHORON = 4) origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_ILLEGAL = 2, TECH_PHORON = 4)
w_class = ITEMSIZE_LARGE w_class = ITEMSIZE_LARGE
slowdown = 1
burst = 3 burst = 3
burst_delay = 1 burst_delay = 1

View File

@@ -271,10 +271,11 @@
/obj/item/projectile/bullet/incendiary/flamethrower/tiny /obj/item/projectile/bullet/incendiary/flamethrower/tiny
damage = 2 damage = 2
incendiary = 0 incendiary = 0
modifier_type_to_apply = /datum/modifier/fire/weak flammability = 2
modifier_type_to_apply = /datum/modifier/fire/stack_managed/weak
modifier_duration = 20 SECONDS modifier_duration = 20 SECONDS
range = 7 range = 6
agony = 3 agony = 0
/* Practice rounds and blanks */ /* Practice rounds and blanks */

View File

@@ -175,10 +175,10 @@
S.visible_message("<span class='warning'>[S]'s flesh sizzles where the water touches it!</span>", "<span class='danger'>Your flesh burns in the water!</span>") S.visible_message("<span class='warning'>[S]'s flesh sizzles where the water touches it!</span>", "<span class='danger'>Your flesh burns in the water!</span>")
// Then extinguish people on fire. // Then extinguish people on fire.
var/needed = L.fire_stacks * 5 var/needed = max(0,L.fire_stacks) * 5
if(amount > needed) if(amount > needed)
L.ExtinguishMob() L.ExtinguishMob()
L.adjust_fire_stacks(-(amount / 5)) L.water_act(amount / 25) // Div by 25, as water_act multiplies it by 5 in order to calculate firestack modification.
remove_self(needed) remove_self(needed)
/* //VOREStation Edit Start. Stops slimes from dying from water. Fixes fuel affect_ingest, too. /* //VOREStation Edit Start. Stops slimes from dying from water. Fixes fuel affect_ingest, too.
/datum/reagent/water/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) /datum/reagent/water/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB