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:
giacomand@gmail.com
2012-12-02 04:38:43 +00:00
parent 79f9733f4a
commit 9941bb8587
15 changed files with 276 additions and 51 deletions
@@ -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))
+1
View File
@@ -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."
+6 -5
View File
@@ -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)