mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-17 18:13:34 +01:00
Mining Mobs - More mob behavior overhaul, kinetic gun tweaks, etc
Conflicts: code/modules/mob/living/simple_animal/hostile/hostile.dm code/modules/projectiles/ammunition/energy.dm code/modules/projectiles/guns/energy/special.dm code/modules/projectiles/projectile.dm code/modules/projectiles/projectile/special.dm icons/mob/animal.dmi icons/obj/projectiles.dmi
This commit is contained in:
@@ -104,7 +104,7 @@
|
||||
return src.attack_hand(user)
|
||||
|
||||
|
||||
/turf/simulated/wall/attack_animal(mob/living/simple_animal/M as mob)
|
||||
/*/turf/simulated/wall/attack_animal(mob/living/simple_animal/M as mob)
|
||||
if(M.wall_smash)
|
||||
if (istype(src, /turf/simulated/wall/r_wall) && !rotting)
|
||||
M << text("\blue This wall is far too strong for you to destroy.")
|
||||
@@ -119,7 +119,17 @@
|
||||
return
|
||||
|
||||
M << "\blue You push the wall but nothing happens!"
|
||||
return
|
||||
return*/
|
||||
|
||||
/turf/simulated/wall/attack_animal(var/mob/living/simple_animal/M)
|
||||
if(M.wall_smash)
|
||||
if (istype(src, /turf/simulated/wall/r_wall))
|
||||
M << text("\blue This wall is far too strong for you to destroy.")
|
||||
return
|
||||
else
|
||||
M << text("\blue You smash through the wall.")
|
||||
dismantle_wall(1)
|
||||
return
|
||||
|
||||
/turf/simulated/wall/attack_hand(mob/user as mob)
|
||||
if (M_HULK in user.mutations)
|
||||
@@ -394,4 +404,4 @@
|
||||
|
||||
/turf/simulated/wall/ChangeTurf(var/newtype)
|
||||
for(var/obj/effect/E in src) if(E.name == "Wallrot") del E
|
||||
..(newtype)
|
||||
..(newtype)
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
ranged = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
projectiletype = /obj/item/projectile/neurotox
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
@@ -67,6 +69,8 @@
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
ranged = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
move_to_delay = 3
|
||||
projectiletype = /obj/item/projectile/neurotox
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
|
||||
@@ -32,10 +32,14 @@
|
||||
name = "Hivebot"
|
||||
desc = "A smallish robot, this one is armed!"
|
||||
ranged = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/rapid
|
||||
ranged = 1
|
||||
rapid = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/strong
|
||||
name = "Strong Hivebot"
|
||||
@@ -43,7 +47,6 @@
|
||||
health = 80
|
||||
ranged = 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/Die()
|
||||
..()
|
||||
visible_message("<b>[src]</b> blows apart!")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/mob/living/simple_animal/hostile
|
||||
faction = "hostile"
|
||||
mouse_opacity = 2 //This makes it easier to hit hostile mobs, you only need to click on their tile, and is set back to 1 when they die
|
||||
var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior
|
||||
var/atom/target
|
||||
var/attack_same = 0
|
||||
@@ -10,65 +11,140 @@
|
||||
var/casingtype
|
||||
var/move_to_delay = 2 //delay for the automated movement.
|
||||
var/list/friends = list()
|
||||
var/vision_range = 10
|
||||
var/vision_range = 9 //How big of an area to search for targets in, a vision of 9 attempts to find targets as soon as they walk into screen view
|
||||
var/idle_env_destroyer = 0
|
||||
stop_automated_movement_when_pulled = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()
|
||||
var/icon_aggro = null // If we swap our icon to something else when we're aggressive, put it here
|
||||
var/aggro_vision_range = 9 //If a mob is aggro, it's searching for targets in a much wider range than normal
|
||||
var/idle_vision_range = 9 //If a mob is just idling around, it's vision range is limited to this. Defaults to 9 for legacy purposes.
|
||||
var/ranged_message = "fires" //Fluff text for ranged mobs
|
||||
var/ranged_cooldown = 2 //What the starting cooldown is on ranged attacks
|
||||
var/ranged_cooldown_cap = 3 //What ranged attacks, after being used are set to, to go back on cooldown, defaults to 3 life() ticks
|
||||
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
|
||||
var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
|
||||
var/search_objects = 0 //If we want to consider objects when searching around, set this to 1. If you want to search for objects while also ignoring mobs, set it to 2.
|
||||
var/list/wanted_objects = list() //A list of objects that will be checked against to attack, should we have search_objects enabled
|
||||
|
||||
var/atom/T = null
|
||||
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets(var/override = -1)
|
||||
if(override == -1)
|
||||
override = vision_range
|
||||
var/list/L = hearers(src, override)
|
||||
if(search_objects)
|
||||
var/list/Objects = oview(vision_range, src)
|
||||
for(var/obj/O in Objects)
|
||||
L.Add(O)
|
||||
else
|
||||
for(var/obj/mecha/M in mechas_list)
|
||||
if(get_dist(M, src) <= override && can_see(src, M, override))
|
||||
L += M
|
||||
return L
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()//Step 2, filter down possible targets to things we actually care about
|
||||
var/list/Targets = list()
|
||||
var/Target
|
||||
stop_automated_movement = 0
|
||||
for(var/atom/A in ListTargets())
|
||||
|
||||
var/atom/F = Found(A)
|
||||
if(F)
|
||||
T = F
|
||||
if(Found(A))//Just in case people want to override targetting IE: Dire rat sees cheese
|
||||
var/list/FoundTarget = list()
|
||||
FoundTarget.Add(A)
|
||||
Targets = FoundTarget
|
||||
break
|
||||
if(CanAttack(A))//Can we attack it?
|
||||
Targets.Add(A)
|
||||
continue
|
||||
Target = PickTarget(Targets)
|
||||
return Target //We now have a target
|
||||
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(istype(src, /mob/living/simple_animal/hostile/scarybat))
|
||||
if(src:owner == L) continue
|
||||
if(L.faction == src.faction && !attack_same)
|
||||
continue
|
||||
else if(L in friends)
|
||||
continue
|
||||
else
|
||||
if(!L.stat)
|
||||
T = L
|
||||
break
|
||||
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)//This is here as a potential override to pick a specific target if available
|
||||
return
|
||||
|
||||
else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets().
|
||||
var/obj/mecha/M = A
|
||||
if (M.occupant)
|
||||
T = M
|
||||
break
|
||||
/mob/living/simple_animal/hostile/proc/PickTarget(var/list/Targets)//Step 3, pick amongst the possible, attackable targets
|
||||
if(target != null)//If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets
|
||||
for(var/atom/A in Targets)
|
||||
var/target_dist = get_dist(src, target)
|
||||
var/possible_target_distance = get_dist(src, A)
|
||||
if(target_dist < possible_target_distance)
|
||||
Targets -= A
|
||||
if(!Targets.len)//We didnt find nothin!
|
||||
return
|
||||
var/chosen_target = pick(Targets)//Pick the remaining targets (if any) at random
|
||||
return chosen_target
|
||||
|
||||
return T
|
||||
/mob/living/simple_animal/hostile/CanAttack(var/atom/the_target)//Can we actually attack a possible target?
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
return 0
|
||||
if(isobj(the_target) && search_objects >= 1)//If search for objects, check it against the items we actually care about
|
||||
if(the_target.type in wanted_objects)
|
||||
return 1
|
||||
if(isliving(the_target) && search_objects < 2)
|
||||
var/mob/living/L = the_target
|
||||
if(L.stat != CONSCIOUS || L.faction == src.faction && !attack_same)//If they're unconscious, or in our faction, forget it
|
||||
return 0
|
||||
if(L in friends)
|
||||
return 0
|
||||
return 1
|
||||
if(istype(the_target, /obj/mecha) && search_objects < 2)
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)//Just so we don't attack empty mechs
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/*/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our chosen target, and set us to aggressive
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return*/
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)
|
||||
target = new_target
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
if(target != null)
|
||||
if(isobj(target))
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
if(isliving(target) && search_objects < 2)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay)
|
||||
walk_to(src, target, 1, delay)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()//Step 5, handle movement between us and our target
|
||||
stop_automated_movement = 1
|
||||
if(!target || SA_attackable(target))
|
||||
LoseTarget()
|
||||
world << "Our target was null, or we didnt consider that we were able to attack it"
|
||||
if(target in ListTargets())
|
||||
if(ranged)
|
||||
if(get_dist(src, target) <= 6)
|
||||
var/TargetDistance = get_dist(src,target)
|
||||
if(ranged)//We ranged? Shoot at em
|
||||
if(TargetDistance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
|
||||
OpenFire(target)
|
||||
else
|
||||
Goto(target, move_to_delay)
|
||||
else
|
||||
stance = HOSTILE_STANCE_ATTACKING
|
||||
Goto(target, move_to_delay)
|
||||
if(retreat_distance != null)//If we have a retreat distance, check if we need to run from our target
|
||||
if(TargetDistance <= retreat_distance)//If target's closer than our retreat distance, run
|
||||
walk_away(src,target,retreat_distance,move_to_delay)
|
||||
else Goto(target,move_to_delay,minimum_distance)//Otherwise, get to our minimum distance to shoot at them, so we chase them
|
||||
else Goto(target,move_to_delay,minimum_distance)
|
||||
if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack
|
||||
AttackingTarget()
|
||||
return
|
||||
LostTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay, var/minimum_distance)
|
||||
walk_to(src, target, minimum_distance, delay)
|
||||
|
||||
/mob/living/simple_animal/hostile/adjustBruteLoss(var/damage)
|
||||
..(damage)
|
||||
if(!stat)
|
||||
if(stance == HOSTILE_STANCE_IDLE)//If we took damage while idle, immediately attempt to find the source of it so we find a living target
|
||||
if(search_objects)//Turn off item searching, we're more concerned with fight or flight
|
||||
search_objects = 0
|
||||
Aggro()
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
if(stance == HOSTILE_STANCE_ATTACK)//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
|
||||
if(target != null && prob(25))
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackTarget()
|
||||
|
||||
@@ -79,44 +155,39 @@
|
||||
if(!(target in ListTargets()))
|
||||
LostTarget()
|
||||
return 0
|
||||
if(get_dist(src, target) <= 1) //Attacking
|
||||
if(isturf(loc) && target.Adjacent(src))
|
||||
AttackingTarget()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.attack_animal(src)
|
||||
return L
|
||||
if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.attack_animal(src)
|
||||
return M
|
||||
target.attack_animal(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Aggro()
|
||||
vision_range = aggro_vision_range
|
||||
if(icon_aggro != null)
|
||||
icon_state = icon_aggro
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LoseAggro()
|
||||
vision_range = idle_vision_range
|
||||
if(icon_state != icon_living)
|
||||
icon_state = icon_living
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LoseTarget()
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target = null
|
||||
walk(src, 0)
|
||||
LoseAggro()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LostTarget()
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
walk(src, 0)
|
||||
LoseAggro()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets(var/override = -1)
|
||||
|
||||
// Allows you to override how much the mob can see. Defaults to vision_range if none is entered.
|
||||
if(override == -1)
|
||||
override = vision_range
|
||||
|
||||
var/list/L = hearers(src, override)
|
||||
for(var/obj/mecha/M in mechas_list)
|
||||
// Will check the distance before checking the line of sight, if the distance is small enough.
|
||||
if(get_dist(M, src) <= override && can_see(src, M, override))
|
||||
L += M
|
||||
return L
|
||||
//////////////END HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
/mob/living/simple_animal/hostile/Die()
|
||||
LoseAggro()
|
||||
mouse_opacity = 1
|
||||
..()
|
||||
walk(src, 0)
|
||||
|
||||
@@ -134,6 +205,8 @@
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
if(idle_env_destroyer)
|
||||
DestroySurroundings()
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
DestroySurroundings()
|
||||
@@ -142,10 +215,12 @@
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
DestroySurroundings()
|
||||
AttackTarget()
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target)
|
||||
var/target = the_target
|
||||
visible_message("\red <b>[src]</b> fires at [target]!", 1)
|
||||
visible_message("\red <b>[src]</b> [ranged_message] at [target]!", 1)
|
||||
|
||||
var/tturf = get_turf(target)
|
||||
if(rapid)
|
||||
@@ -168,9 +243,9 @@
|
||||
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target = null
|
||||
ranged_cooldown = ranged_cooldown_cap
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Shoot(var/target, var/start, var/user, var/bullet = 0)
|
||||
if(target == start)
|
||||
return
|
||||
@@ -190,7 +265,27 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/DestroySurroundings()
|
||||
for(var/dir in cardinal) // North, South, East, West
|
||||
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
|
||||
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
|
||||
obstacle.attack_animal(src)
|
||||
var/list/directions = cardinal.Copy()
|
||||
for(var/dir in directions)
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(istype(T, /turf/simulated/wall) || istype(T, /turf/simulated/mineral))
|
||||
T.attack_animal(src)
|
||||
for(var/atom/A in T)
|
||||
if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille))
|
||||
A.attack_animal(src)
|
||||
|
||||
/*/mob/living/simple_animal/hostile/proc/DestroySurroundings()
|
||||
for(var/dir in cardinal) // North, South, East, West
|
||||
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
|
||||
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
|
||||
obstacle.attack_animal(src)
|
||||
|
||||
/obj/effect/goliath_tentacle/original/New()
|
||||
var/list/directions = cardinal.Copy()
|
||||
var/counter
|
||||
for(counter = 1, counter <= 3, counter++)
|
||||
var/spawndir = pick(directions)
|
||||
directions -= spawndir
|
||||
var/turf/T = get_step(src,spawndir)
|
||||
new /obj/effect/goliath_tentacle(T)
|
||||
..()*/
|
||||
|
||||
@@ -16,156 +16,20 @@
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoves"
|
||||
response_harm = "strikes"
|
||||
var/aggro_vision_range = 8
|
||||
var/idle_vision_range = null
|
||||
var/icon_aggro = null
|
||||
var/ranged_message = "fires"
|
||||
status_flags = 0
|
||||
a_intent = "harm"
|
||||
var/throw_message = "bounces off of"
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/New()
|
||||
idle_vision_range = vision_range
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/GiveTarget(var/new_target)
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/LoseTarget()
|
||||
..()
|
||||
LoseAggro()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/LostTarget()
|
||||
..()
|
||||
LoseAggro()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/proc/Aggro()
|
||||
vision_range = aggro_vision_range
|
||||
icon_state = icon_aggro
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/proc/LoseAggro()
|
||||
vision_range = idle_vision_range
|
||||
icon_state = icon_living
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/adjustBruteLoss(var/damage)
|
||||
..(damage)
|
||||
if(stance == HOSTILE_STANCE_IDLE)
|
||||
Aggro()
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
if(stance == HOSTILE_STANCE_ATTACK)//No more pulling a mob forever and having a second player attack it, it can switch targets now
|
||||
if(target != null && prob(25))
|
||||
world << "We're calling FindTarget due to being damaged"
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/bullet_act(var/obj/item/projectile/P)
|
||||
/mob/living/simple_animal/hostile/asteroid/bullet_act(var/obj/item/projectile/P)//Limits the weapons available to kill them at range
|
||||
if(P.damage < 30)
|
||||
visible_message("<span class='danger'>The [P.name] had no effect on [src.name]!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
//ALL THIS SHIT IS FOR TRACKING PEOPLE AND TARGETTING//
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/FindTarget()
|
||||
var/list/Targets = list()
|
||||
var/Target
|
||||
world << "We're about to run FindTarget"
|
||||
stop_automated_movement = 0
|
||||
for(var/atom/A in ListTargets())
|
||||
if(Found(A))//Just in case people want to override targetting IE: Mouse sees cheese
|
||||
Target = A
|
||||
break
|
||||
if(CanAttack(A))//Can we attack it?
|
||||
Targets.Add(A)
|
||||
continue
|
||||
world << "We're about to run PickTarget"
|
||||
Target = PickTarget(Targets)
|
||||
return Target //We now have a target
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/proc/PickTarget(var/list/Targets)
|
||||
if(target != null)
|
||||
world << "There IS a target in PickTarget"
|
||||
for(var/atom/A in Targets)
|
||||
var/target_dist = get_dist(src, target)
|
||||
var/possible_target_distance = get_dist(src, A)
|
||||
world << "Distance to current target [target.name] [target_dist], Distance to possible target [A.name] [possible_target_distance]"
|
||||
if(target_dist < possible_target_distance)
|
||||
Targets -= A
|
||||
for(var/A in Targets)
|
||||
world << "[A]"
|
||||
if(!Targets.len)
|
||||
return
|
||||
var/chosen_target = pick(Targets)
|
||||
world << "IIIII We chose [chosen_target]"
|
||||
return chosen_target
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/CanAttack(var/atom/the_target)
|
||||
if(see_invisible < the_target.invisibility)
|
||||
return 0
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
if(L.stat != CONSCIOUS || L.faction == src.faction && !attack_same)
|
||||
return 0
|
||||
if(L in friends)
|
||||
return 0
|
||||
return 1
|
||||
if(istype(the_target, /obj/mecha))
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//END SHIT FOR TRACKING PEOPLE AND TARGETTING//
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Die()
|
||||
LoseAggro()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/MoveToTarget()
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
if(target in ListTargets())
|
||||
if(get_dist(src, target) >= 2 && ranged)
|
||||
OpenFire(target)
|
||||
Goto(target, move_to_delay)
|
||||
if(isturf(loc) && target.Adjacent(src)) //Attacking
|
||||
AttackingTarget()
|
||||
return
|
||||
LostTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/OpenFire(var/the_target)
|
||||
|
||||
var/target = the_target
|
||||
visible_message("\red <b>[src]</b> [ranged_message] at [target]!", 1)
|
||||
|
||||
var/tturf = get_turf(target)
|
||||
if(rapid)
|
||||
spawn(1)
|
||||
Shoot(tturf, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
spawn(4)
|
||||
Shoot(tturf, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
spawn(6)
|
||||
Shoot(tturf, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
else
|
||||
Shoot(tturf, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM)
|
||||
/mob/living/simple_animal/hostile/asteroid/hitby(atom/movable/AM)//No floor tiling them to death, wiseguy
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/T = AM
|
||||
if(T.throwforce <= 15)//No floor tiling them to death, wiseguy
|
||||
if(T.throwforce <= 15)
|
||||
visible_message("<span class='notice'>The [T.name] [src.throw_message] [src.name]!</span>")
|
||||
Aggro()
|
||||
return
|
||||
@@ -185,11 +49,12 @@
|
||||
projectilesound = 'sound/weapons/pierce.ogg'
|
||||
ranged = 1
|
||||
ranged_message = "stares"
|
||||
throw_message = "rebounds off its hard shell to no effect"
|
||||
ranged_cooldown_cap = 8
|
||||
throw_message = "does nothing against the hard shell of"
|
||||
vision_range = 2
|
||||
speed = 3
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
@@ -197,6 +62,8 @@
|
||||
a_intent = "harm"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
ranged_cooldown_cap = 4
|
||||
|
||||
/obj/item/projectile/temp/basilisk
|
||||
name = "freezing blast"
|
||||
icon_state = "ice_2"
|
||||
@@ -227,9 +94,8 @@
|
||||
icon_aggro = "Goldgrub_alert"
|
||||
icon_dead = "Goldgrub_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
move_to_delay = 0
|
||||
move_to_delay = 3
|
||||
friendly = "harmlessly rolls into"
|
||||
vision_range = 2
|
||||
maxHealth = 45
|
||||
health = 45
|
||||
harm_intent_damage = 5
|
||||
@@ -237,30 +103,39 @@
|
||||
melee_damage_upper = 0
|
||||
attacktext = "barrels into"
|
||||
a_intent = "help"
|
||||
throw_message = "hits, but just bounces off its fat"
|
||||
throw_message = "sinks in slowly, before being pushed out of "
|
||||
status_flags = CANPUSH
|
||||
search_objects = 2
|
||||
wanted_objects = list(/obj/item/weapon/ore/diamond, /obj/item/weapon/ore/gold, /obj/item/weapon/ore/silver, /obj/item/weapon/ore/plasma,
|
||||
/obj/item/weapon/ore/uranium, /obj/item/weapon/ore/iron, /obj/item/weapon/ore/clown)
|
||||
var/alerted = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/MoveToTarget()
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
if(target in ListTargets())
|
||||
walk_away(src,target,10)
|
||||
if(isturf(loc) && target.Adjacent(src)) //Attacking
|
||||
AttackingTarget()
|
||||
return
|
||||
LostTarget()
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/Found(var/new_target)
|
||||
if(istype(new_target, /obj/item/weapon/ore) && stance == HOSTILE_STANCE_IDLE)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/GiveTarget(var/new_target)
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
visible_message("<span class='danger'>The [src.name] tries to flee from [target.name]!</span>")
|
||||
Burrow()
|
||||
if(istype(target, /obj/item/weapon/ore))
|
||||
visible_message("<span class='notice'>The [src.name] looks at [target.name] with hungry eyes.</span>")
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
if(isliving(target) && !search_objects)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
visible_message("<span class='danger'>The [src.name] tries to flee from [target.name]!</span>")
|
||||
retreat_distance = 10
|
||||
Burrow()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/proc/Burrow()
|
||||
/obj/item/weapon/ore/attack_animal(var/mob/living/L)
|
||||
if(istype(L, /mob/living/simple_animal/hostile/asteroid/Goldgrub))
|
||||
L.visible_message("<span class='notice'>The [src.name] was swallowed whole!</span>")
|
||||
del(src)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/proc/Burrow()//Begin the chase to kill the goldgrub in time
|
||||
if(!alerted)
|
||||
alerted = 1
|
||||
spawn(100)
|
||||
@@ -268,6 +143,10 @@
|
||||
visible_message("<span class='danger'>The [src.name] buries into the ground, vanishing from sight!</span>")
|
||||
del(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/adjustBruteLoss(var/damage)
|
||||
search_objects = 0 //Stop looking for items if we've been hurt by someone, so we can run!
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goldgrub/bullet_act(var/obj/item/projectile/P)
|
||||
visible_message("<span class='danger'>The [P.name] was repelled by [src.name]'s girth!</span>")
|
||||
return
|
||||
@@ -286,7 +165,7 @@
|
||||
icon_dead = "Hivelord_dead"
|
||||
icon_gib = "syndicate_gib"
|
||||
mouse_opacity = 2
|
||||
move_to_delay = 0
|
||||
move_to_delay = 12
|
||||
ranged = 1
|
||||
vision_range = 4
|
||||
speed = 3
|
||||
@@ -295,32 +174,26 @@
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 2
|
||||
attacktext = "lashes out"
|
||||
throw_message = "seems to have no effect on"
|
||||
attacktext = "lashes out at"
|
||||
throw_message = "falls right through the strange body of the "
|
||||
ranged_cooldown = 0
|
||||
ranged_cooldown_cap = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Hivelord/MoveToTarget()
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
if(target in ListTargets())
|
||||
OpenFire(target)
|
||||
var/mob/living/simple_animal/hostile/asteroid/Hivelord/D = get_dist(src, target)
|
||||
if(D <= 5)
|
||||
step_away(src, target)
|
||||
return
|
||||
LostTarget()
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Hivelord/OpenFire(var/the_target)
|
||||
var/target = the_target
|
||||
var/tturf = get_turf(target)
|
||||
var/mob/living/simple_animal/hostile/asteroid/Hivelordbrood/A = new /mob/living/simple_animal/hostile/asteroid/Hivelordbrood(tturf)
|
||||
var/mob/living/simple_animal/hostile/asteroid/Hivelordbrood/A = new /mob/living/simple_animal/hostile/asteroid/Hivelordbrood(src.loc)
|
||||
A.GiveTarget(target)
|
||||
step_away(A, target)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Hivelord/AttackingTarget()
|
||||
OpenFire()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Hivelordbrood
|
||||
name = "Hivelord brood"
|
||||
desc = "A small hivelord brood, called to rally behind its parent. One isn't much of a threat, but..."
|
||||
desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..."
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
icon_state = "Hivelordbrood"
|
||||
icon_living = "Hivelordbrood"
|
||||
@@ -338,6 +211,7 @@
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 2
|
||||
attacktext = "slashes"
|
||||
throw_message = "falls right through the strange body of the "
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Hivelordbrood/New()
|
||||
..()
|
||||
@@ -359,22 +233,30 @@
|
||||
mouse_opacity = 2
|
||||
move_to_delay = 40
|
||||
ranged = 1
|
||||
ranged_cooldown_cap = 8
|
||||
friendly = "wails at"
|
||||
vision_range = 5
|
||||
speed = 3
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
maxHealth = 300
|
||||
health = 300
|
||||
harm_intent_damage = 0
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "pulverizes"
|
||||
var/tentacle_recharge = 0
|
||||
throw_message = "does nothing to the rocky hide of the "
|
||||
|
||||
/obj/effect/goliath_tentacle/
|
||||
name = "Goliath tentacle"
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
icon_state = "Goliath_tentacle"
|
||||
|
||||
/obj/effect/goliath_tentacle/New()
|
||||
var/turftype = get_turf(src)
|
||||
if(istype(turftype, /turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = turftype
|
||||
M.GetDrilled()
|
||||
..()
|
||||
|
||||
/obj/effect/goliath_tentacle/original
|
||||
|
||||
/obj/effect/goliath_tentacle/original/New()
|
||||
@@ -404,14 +286,12 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goliath/OpenFire()
|
||||
tentacle_recharge--
|
||||
if(tentacle_recharge <= 0)
|
||||
visible_message("<span class='warning'>The [src.name] digs its tentacles under [target.name]!</span>")
|
||||
var/tturf = get_turf(target)
|
||||
new /obj/effect/goliath_tentacle/original(tturf)
|
||||
tentacle_recharge = 6
|
||||
return
|
||||
visible_message("<span class='warning'>The [src.name] digs its tentacles under [target.name]!</span>")
|
||||
var/tturf = get_turf(target)
|
||||
new /obj/effect/goliath_tentacle/original(tturf)
|
||||
ranged_cooldown = ranged_cooldown_cap
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Goliath/adjustBruteLoss(var/damage)
|
||||
tentacle_recharge--
|
||||
ranged_cooldown--
|
||||
..()
|
||||
@@ -42,6 +42,8 @@
|
||||
projectilesound = 'sound/weapons/laser.ogg'
|
||||
ranged = 1
|
||||
rapid = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
projectiletype = /obj/item/projectile/beam
|
||||
corpse = /obj/effect/landmark/mobcorpse/pirate/ranged
|
||||
weapon1 = /obj/item/weapon/gun/energy/laser
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
corpse = /obj/effect/landmark/mobcorpse/russian/ranged
|
||||
weapon1 = /obj/item/weapon/gun/projectile/revolver/mateba
|
||||
ranged = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
projectiletype = /obj/item/projectile/bullet
|
||||
projectilesound = 'sound/weapons/Gunshot.ogg'
|
||||
casingtype = /obj/item/ammo_casing/a357
|
||||
|
||||
@@ -104,6 +104,8 @@
|
||||
/mob/living/simple_animal/hostile/syndicate/ranged
|
||||
ranged = 1
|
||||
rapid = 1
|
||||
retreat_distance = 5
|
||||
minimum_distance = 5
|
||||
icon_state = "syndicateranged"
|
||||
icon_living = "syndicateranged"
|
||||
casingtype = /obj/item/ammo_casing/a12mm
|
||||
|
||||
@@ -182,7 +182,7 @@ obj/item/weapon/gun/energy/staff/focus
|
||||
zoom = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/sniperrifle/verb/zoom()
|
||||
set category = "Special Verbs"
|
||||
set category = "Object"
|
||||
set name = "Zoom"
|
||||
set popup_menu = 0
|
||||
if(usr.stat || !(istype(usr,/mob/living/carbon/human)))
|
||||
@@ -196,4 +196,20 @@ obj/item/weapon/gun/energy/staff/focus
|
||||
usr << sound('sound/mecha/imag_enh.ogg',volume=50)
|
||||
else
|
||||
usr.client.view = world.view//world.view - default mob view size
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator
|
||||
name = "proto-kinetic accelerator"
|
||||
desc = "According to Nanotrasen accounting, this is mining equipment. It's been modified to the legal limit on power output, and often serves as a miner's first defense against hostile alien life; it's not very powerful unless used in a low pressure environment."
|
||||
icon_state = "freezegun"
|
||||
item_state = "shotgun"
|
||||
projectile_type = "/obj/item/projectile/kinetic"
|
||||
cell_type = "/obj/item/weapon/cell/crap"
|
||||
charge_cost = 500
|
||||
fire_delay = 20
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/attack_self(var/mob/living/user/L)
|
||||
power_supply.give(500)
|
||||
playsound(src.loc, 'sound/weapons/shotgunpump.ogg', 60, 1)
|
||||
return
|
||||
|
||||
@@ -179,8 +179,10 @@
|
||||
if(!(original in permutated))
|
||||
Bump(original)
|
||||
sleep(1)
|
||||
Range()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/projectile/test //Used to see if you can hit them.
|
||||
invisibility = 101 //Nope! Can't see me!
|
||||
yo = null
|
||||
@@ -221,3 +223,7 @@
|
||||
M = locate() in get_step(src,target)
|
||||
if(istype(M))
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/proc/Range()
|
||||
return
|
||||
|
||||
|
||||
@@ -152,3 +152,44 @@
|
||||
src.visible_message("\red The [src.name] explodes!","\red You hear a snap!")
|
||||
playsound(src, 'sound/effects/snap.ogg', 50, 1)
|
||||
del(src)
|
||||
|
||||
/obj/item/projectile/kinetic
|
||||
name = "kinetic force"
|
||||
icon_state = null
|
||||
damage = 15
|
||||
damage_type = BRUTE
|
||||
flag = "bomb"
|
||||
var/range = 2
|
||||
|
||||
obj/item/projectile/kinetic/New()
|
||||
var/turf/proj_turf = get_turf(src)
|
||||
if(!istype(proj_turf, /turf))
|
||||
return
|
||||
var/datum/gas_mixture/environment = proj_turf.return_air()
|
||||
var/pressure = environment.return_pressure()
|
||||
if(pressure < 50)
|
||||
name = "full strength kinetic force"
|
||||
damage = 30
|
||||
..()
|
||||
|
||||
/obj/item/projectile/kinetic/Range()
|
||||
range--
|
||||
if(range <= 0)
|
||||
new /obj/item/effect/kinetic_blast(src.loc)
|
||||
delete()
|
||||
|
||||
/obj/item/projectile/kinetic/on_hit(var/atom/target)
|
||||
var/turf/target_turf= get_turf(target)
|
||||
new /obj/item/effect/kinetic_blast(target_turf)
|
||||
..()
|
||||
|
||||
/obj/item/effect/kinetic_blast
|
||||
name = "kinetic explosion"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "kinetic_blast"
|
||||
layer = 4.1
|
||||
|
||||
/obj/item/effect/kinetic_blast/New()
|
||||
spawn(4)
|
||||
del(src)
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 32 KiB |
Reference in New Issue
Block a user