mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 12:04:48 +01:00
Added mimics! There's the classic crate (chest) mimic which waits until somebody is close before trying to attack them. You can fill him with loot by putting items on him on your map. This was done by changing the base initialize proc to an /atom/movable and then instead of looping through the world for objects, instead loop for atom movables.
The next type of mimic is for the staff of animation! They will copy the icon of the object they're copying and will set themselves stats based on the object too. They will not attack the bearer of the staff which made them animated. Added the option to get the staff on the wizard's spell book. Added a "friends" var to hostile mobs. It will make the simple animal ignore friends when choosing targets. Changed the statues from /obj/effect/showcase to /obj/structure/showcase. Added a new variable to projectiles, "shot_from" is the gun that shot the projectile. It's used to determine what staff animated the mob and it will then add that staff, so it can ignore it when choosing targets. Added a wander var for simple animals, turning it to 0 will stop the simple animal from moving when idle. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@5246 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
var/projectilesound
|
||||
var/casingtype
|
||||
var/move_to_delay = 2 //delay for the automated movement.
|
||||
var/list/friends = list()
|
||||
stop_automated_movement_when_pulled = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()
|
||||
@@ -21,6 +22,8 @@
|
||||
var/mob/living/L = A
|
||||
if(L.faction == src.faction && !attack_same)
|
||||
continue
|
||||
else if(L in friends)
|
||||
continue
|
||||
else
|
||||
if(!L.stat)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
@@ -34,7 +37,7 @@
|
||||
break
|
||||
return T
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget(var/step = 5)
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || SA_attackable(target_mob))
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
@@ -53,12 +56,13 @@
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || SA_attackable(target_mob))
|
||||
LoseTarget()
|
||||
return
|
||||
return 0
|
||||
if(!(target_mob in ListTargets()))
|
||||
LostTarget()
|
||||
return
|
||||
return 0
|
||||
if(get_dist(src, target_mob) <= 1) //Attacking
|
||||
AttackingTarget()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
if(isliving(target_mob))
|
||||
@@ -109,8 +113,6 @@
|
||||
DestroySurroundings()
|
||||
AttackTarget()
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(target_mob)
|
||||
var/target = target_mob
|
||||
visible_message("\red <b>[src]</b> fires at [target]!", 1)
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// Abstract Class
|
||||
//
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic
|
||||
name = "crate"
|
||||
desc = "A rectangular steel crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "crate"
|
||||
icon_living = "crate"
|
||||
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
|
||||
response_help = "touches the"
|
||||
response_disarm = "pushes the"
|
||||
response_harm = "hits the"
|
||||
speed = -1
|
||||
maxHealth = 250
|
||||
health = 250
|
||||
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 8
|
||||
melee_damage_upper = 12
|
||||
attacktext = "attacks"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
|
||||
min_oxy = 0
|
||||
max_oxy = 0
|
||||
min_tox = 0
|
||||
max_tox = 0
|
||||
min_co2 = 0
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
minbodytemp = 0
|
||||
|
||||
faction = "mimic"
|
||||
move_to_delay = 8
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
emote("growls at [.]")
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/Die()
|
||||
..()
|
||||
visible_message("\red <b>[src]</b> stops moving!")
|
||||
del(src)
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Crate Mimic
|
||||
//
|
||||
|
||||
|
||||
// Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies.
|
||||
/mob/living/simple_animal/hostile/mimic/crate
|
||||
|
||||
attacktext = "bites"
|
||||
|
||||
stop_automated_movement = 1
|
||||
wander = 0
|
||||
var/attempt_open = 0
|
||||
|
||||
// Pickup loot
|
||||
/mob/living/simple_animal/hostile/mimic/crate/initialize()
|
||||
..()
|
||||
for(var/obj/item/I in loc)
|
||||
I.loc = src
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/DestroySurroundings()
|
||||
..()
|
||||
if(prob(90))
|
||||
icon_state = "[initial(icon_state)]open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/ListTargets()
|
||||
if(attempt_open)
|
||||
return view(src, 10)
|
||||
return view(src, 1)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
trigger()
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/AttackingTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/proc/trigger()
|
||||
if(!attempt_open)
|
||||
visible_message("<b>[src]</b> starts to move!")
|
||||
attempt_open = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/adjustBruteLoss(var/damage)
|
||||
trigger()
|
||||
..(damage)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/LoseTarget()
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/LostTarget()
|
||||
..()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/Die()
|
||||
|
||||
var/obj/structure/closet/crate/C = new(get_turf(src))
|
||||
// Put loot in crate
|
||||
for(var/obj/O in src)
|
||||
O.loc = C
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/crate/AttackingTarget()
|
||||
. =..()
|
||||
var/mob/living/L = .
|
||||
if(istype(L))
|
||||
if(prob(15))
|
||||
L.Weaken(2)
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
|
||||
//
|
||||
// Copy Mimic
|
||||
//
|
||||
|
||||
var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy
|
||||
|
||||
health = 100
|
||||
maxHealth = 100
|
||||
var/obj/item/staff = null // the staff that changed they, never attack the bearer of this staff
|
||||
var/destroy_objects = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/obj/item/staff)
|
||||
..(loc)
|
||||
CopyObject(copy, staff)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/Die()
|
||||
|
||||
for(var/atom/movable/M in src)
|
||||
M.loc = get_turf(src)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/ListTargets()
|
||||
// Return a list of targets that isn't the holder of our staff
|
||||
return view(src, 7) - get(staff, /mob)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(var/obj/O, var/obj/item/staff)
|
||||
|
||||
if((istype(O, /obj/item) || istype(O, /obj/structure)) && !is_type_in_list(O, protected_objects))
|
||||
|
||||
O.loc = src
|
||||
name = O.name
|
||||
desc = O.desc
|
||||
icon = O.icon
|
||||
icon_state = O.icon_state
|
||||
icon_living = icon_state
|
||||
|
||||
if(istype(O, /obj/structure))
|
||||
health = (anchored * 50) + 50
|
||||
destroy_objects = 1
|
||||
else if(istype(O, /obj/item))
|
||||
var/obj/item/I = O
|
||||
health = 15 * I.w_class
|
||||
melee_damage_lower = 2 + I.force
|
||||
melee_damage_upper = 2 + I.force
|
||||
move_to_delay = 2 * I.w_class
|
||||
|
||||
maxHealth = health
|
||||
if(staff)
|
||||
src.staff = staff
|
||||
return 1
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings()
|
||||
if(destroy_objects)
|
||||
..()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
var/meat_amount = 0
|
||||
var/meat_type
|
||||
var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals.
|
||||
var/wander = 1 // Does the mob wander around when idle?
|
||||
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
|
||||
|
||||
//Interaction
|
||||
@@ -95,7 +96,7 @@
|
||||
AdjustParalysis(-1)
|
||||
|
||||
//Movement
|
||||
if(!client && !stop_automated_movement)
|
||||
if(!client && !stop_automated_movement && wander)
|
||||
if(isturf(src.loc) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
||||
turns_since_move++
|
||||
if(turns_since_move >= turns_per_move)
|
||||
@@ -186,12 +187,12 @@
|
||||
|
||||
//Atmos effect
|
||||
if(bodytemperature < minbodytemp)
|
||||
health -= cold_damage_per_tick
|
||||
adjustBruteLoss(cold_damage_per_tick)
|
||||
else if(bodytemperature > maxbodytemp)
|
||||
health -= heat_damage_per_tick
|
||||
adjustBruteLoss(heat_damage_per_tick)
|
||||
|
||||
if(!atmos_suitable)
|
||||
health -= unsuitable_atoms_damage
|
||||
adjustBruteLoss(unsuitable_atoms_damage)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/Bumped(AM as mob|obj)
|
||||
@@ -241,11 +242,11 @@
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
|
||||
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
health -= damage
|
||||
adjustBruteLoss(damage)
|
||||
|
||||
/mob/living/simple_animal/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(!Proj) return
|
||||
src.health -= Proj.damage
|
||||
adjustBruteLoss(Proj.damage)
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M as mob)
|
||||
@@ -264,6 +265,7 @@
|
||||
return
|
||||
if (!(status_flags & CANPUSH))
|
||||
return
|
||||
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
|
||||
|
||||
M.put_in_active_hand(G)
|
||||
@@ -277,17 +279,12 @@
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
|
||||
|
||||
if("hurt")
|
||||
health -= harm_intent_damage
|
||||
if("hurt", "disarm")
|
||||
adjustBruteLoss(harm_intent_damage)
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\red [M] [response_harm] [src]")
|
||||
|
||||
if("disarm")
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message("\blue [M] [response_disarm] [src]")
|
||||
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
|
||||
@@ -295,6 +292,7 @@
|
||||
switch(M.a_intent)
|
||||
|
||||
if ("help")
|
||||
|
||||
for(var/mob/O in viewers(src, null))
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
|
||||
@@ -303,6 +301,7 @@
|
||||
return
|
||||
if(!(status_flags & CANPUSH))
|
||||
return
|
||||
|
||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src )
|
||||
|
||||
M.put_in_active_hand(G)
|
||||
@@ -316,16 +315,10 @@
|
||||
if ((O.client && !( O.blinded )))
|
||||
O.show_message(text("\red [] has grabbed [] passively!", M, src), 1)
|
||||
|
||||
if("hurt")
|
||||
if("hurt", "disarm")
|
||||
var/damage = rand(15, 30)
|
||||
visible_message("\red <B>[M] has slashed at [src]!</B>")
|
||||
src.health -= damage
|
||||
|
||||
|
||||
if("disarm")
|
||||
var/damage = rand(15, 30)
|
||||
visible_message("\red <B>[M] has slashed at [src]!</B>")
|
||||
src.health -= damage
|
||||
adjustBruteLoss(damage)
|
||||
|
||||
return
|
||||
|
||||
@@ -335,23 +328,25 @@
|
||||
if("help")
|
||||
visible_message("\blue [L] rubs it's head against [src]")
|
||||
|
||||
|
||||
else
|
||||
|
||||
var/damage = rand(5, 10)
|
||||
visible_message("\red <B>[L] bites [src]!</B>")
|
||||
|
||||
if(stat != DEAD)
|
||||
src.health -= damage
|
||||
adjustBruteLoss(damage)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
|
||||
|
||||
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/stack/medical))
|
||||
|
||||
if(stat != DEAD)
|
||||
var/obj/item/stack/medical/MED = O
|
||||
if(health < maxHealth)
|
||||
if(MED.amount >= 1)
|
||||
health = min(maxHealth, health + MED.heal_brute)
|
||||
adjustBruteLoss(-MED.heal_brute)
|
||||
MED.amount -= 1
|
||||
if(MED.amount <= 0)
|
||||
del(MED)
|
||||
@@ -372,7 +367,7 @@
|
||||
var/damage = O.force
|
||||
if (O.damtype == HALLOSS)
|
||||
damage = 0
|
||||
health -= damage
|
||||
adjustBruteLoss(damage)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
|
||||
@@ -383,6 +378,7 @@
|
||||
M.show_message("\red [user] gently taps [src] with the [O]. ")
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/movement_delay()
|
||||
var/tally = 0 //Incase I need to add stuff other than "speed" later
|
||||
|
||||
@@ -409,19 +405,19 @@
|
||||
flick("flash", flash)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
health -= 500
|
||||
adjustBruteLoss(500)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2.0)
|
||||
health -= 60
|
||||
adjustBruteLoss(60)
|
||||
|
||||
|
||||
if(3.0)
|
||||
health -= 30
|
||||
adjustBruteLoss(30)
|
||||
|
||||
/mob/living/simple_animal/adjustBruteLoss(damage)
|
||||
health -= damage
|
||||
health = Clamp(health - damage, 0, maxHealth)
|
||||
|
||||
/mob/living/simple_animal/proc/SA_attackable(target_mob)
|
||||
if (isliving(target_mob))
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
in_chamber.original = target
|
||||
in_chamber.loc = get_turf(user)
|
||||
in_chamber.starting = get_turf(user)
|
||||
in_chamber.shot_from = src
|
||||
user.next_move = world.time + 4
|
||||
in_chamber.silenced = silenced
|
||||
in_chamber.current = curloc
|
||||
|
||||
@@ -64,6 +64,11 @@ obj/item/weapon/gun/energy/staff
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/staff/animate
|
||||
name = "staff of animation"
|
||||
desc = "An artefact that spits bolts of life-force which causes objects which are hit by it to animate and come to life! This magic doesn't affect machines."
|
||||
projectile_type = "/obj/item/projectile/animate"
|
||||
|
||||
/obj/item/weapon/gun/energy/floragun
|
||||
name = "floral somatoray"
|
||||
desc = "A tool that discharges controlled radiation which induces mutation in plant cells."
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
var/yo = null
|
||||
var/xo = null
|
||||
var/current = null
|
||||
var/obj/shot_from = null // the object which shot us
|
||||
var/atom/original = null // the original target clicked
|
||||
var/turf/starting = null // the projectile's starting turf
|
||||
var/list/permutated = list() // we've passed through these atoms, don't try to hit them again
|
||||
@@ -61,9 +62,9 @@
|
||||
Bump(atom/A as mob|obj|turf|area)
|
||||
if(A == firer)
|
||||
loc = A.loc
|
||||
return //cannot shoot yourself
|
||||
return 0 //cannot shoot yourself
|
||||
|
||||
if(bumped) return
|
||||
if(bumped) return 0
|
||||
var/forcedodge = 0 // force the projectile to pass
|
||||
|
||||
bumped = 1
|
||||
@@ -71,7 +72,7 @@
|
||||
var/mob/M = A
|
||||
if(!istype(A, /mob/living))
|
||||
loc = A.loc
|
||||
return // nope.avi
|
||||
return 0// nope.avi
|
||||
|
||||
// check for dodge (i can't place in bullet_act because then things get wonky)
|
||||
if(!M.stat && !M.lying && (REFLEXES in M.augmentations) && prob(85))
|
||||
@@ -104,7 +105,7 @@
|
||||
else
|
||||
loc = A.loc
|
||||
permutated.Add(A)
|
||||
return
|
||||
return 0
|
||||
|
||||
if(istype(A,/turf))
|
||||
for(var/obj/O in A)
|
||||
@@ -115,7 +116,7 @@
|
||||
density = 0
|
||||
invisibility = 101
|
||||
del(src)
|
||||
return
|
||||
return 1
|
||||
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/obj/item/projectile/animate
|
||||
name = "bolt of animation"
|
||||
icon_state = "ice_1"
|
||||
damage = 0
|
||||
damage_type = BURN
|
||||
nodamage = 1
|
||||
flag = "energy"
|
||||
|
||||
/obj/item/projectile/animate/Bump(var/atom/change)
|
||||
. = ..()
|
||||
if(istype(change, /obj/item) || istype(change, /obj/structure) && !is_type_in_list(change, protected_objects))
|
||||
var/obj/O = change
|
||||
new /mob/living/simple_animal/hostile/mimic/copy(O.loc, O, shot_from)
|
||||
Reference in New Issue
Block a user