Bee Fixes (#859)

Fixes #526 
Fixes #202 

bugfix: "Attempting to grab or pull bee swarms no longer works"
bugfix: "Fixed bee swarms still flying around when dead and appearing to be unkillable."
tweak: "Bees now take double damage from fire."
tweak: "Thick material clothing now protects against beestings."
tweak: "Beekeeping crate is no longer contraband in cargo."
This commit is contained in:
NanakoAC
2016-09-10 22:37:38 +03:00
committed by skull132
parent 1668df7f9c
commit 967cb1ece7
7 changed files with 193 additions and 69 deletions
@@ -131,6 +131,11 @@
if(G.assailant == M)
M << "<span class='notice'>You already grabbed [src].</span>"
return
if (!attempt_grab(M))
return
if(w_uniform)
w_uniform.add_fingerprint(M)
+102 -47
View File
@@ -1,10 +1,13 @@
//Bees are spawned from an apiary, and will slowly die if it is destroyed.
/mob/living/simple_animal/bee
name = "bees"
icon = 'icons/obj/apiary_bees_etc.dmi'
icon_state = "bees1"
icon_dead = "bees1"
mob_size = 1
mob_size = 0.5
unsuitable_atoms_damage = 2.5
maxHealth = 20
density = 0
var/strength = 1
var/feral = 0
var/mut = 0
@@ -25,6 +28,25 @@
parent.owned_bee_swarms.Remove(src)
..()
//Special death behaviour. When bees accumulate enough damage to 'die', they don't outright die. Thus no call to parent
//Instead the swarm strength (ie, size, or quantity of bees) drops and their health is refilled
//Repeat until strength hits zero. only THEN do they die, and they qdel and leave no corpse in doing so
//Because we don't have sprites for a carpet made of bee corpses.
/mob/living/simple_animal/bee/death()
strength -= 1
if (strength <= 0)
if (prob(35))//probability to reduce spam
src.visible_message("\red The bee swarm completely dissipates.")
qdel(src)
return
else
health = maxHealth
if (prob(35))//probability to reduce spam
src.visible_message("\red The bee swarm starts to thin out a little.")
update_icons()
/mob/living/simple_animal/bee/Life()
..()
@@ -32,26 +54,30 @@
//if we're strong enough, sting some people
var/mob/living/carbon/human/M = target_mob
var/sting_prob = 40 // Bees will always try to sting.
if(M in view(src,1)) // Can I see my target?
if(prob(max(feral * 10, 0))) // Am I mad enough to want to sting? And yes, when I initially appear, I AM mad enough
var/obj/item/clothing/worn_suit = M.wear_suit
var/obj/item/clothing/worn_helmet = M.head
if(worn_suit) // Are you wearing clothes?
sting_prob -= min(worn_suit.armor["bio"],70) // Is it sealed? I can't get to 70% of your body.
if(worn_helmet)
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
M << "\red You have been stung!"
M.flash_pain()
var/prob_mult = 1
if(M && M in view(src,1)) // Can I see my target?
var/obj/item/clothing/worn_suit = M.wear_suit
var/obj/item/clothing/worn_helmet = M.head
if(worn_suit) // Are you wearing clothes?
if ((worn_suit.flags & THICKMATERIAL))
prob_mult -= 0.7
else
prob_mult -= 0.01 * (min(worn_suit.armor["bio"],70)) // Is it sealed? I can't get to 70% of your body.
if(worn_helmet)
if ((worn_helmet.flags & THICKMATERIAL))
prob_mult -= 0.3
else
prob_mult -= 0.01 *(min(worn_helmet.armor["bio"],30))// Is your helmet sealed? I can't get to 30% of your body.
if( prob(sting_prob*prob_mult) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25*prob_mult))) ) // Try to sting! If you're not moving, think about stinging.
M.apply_damage(min(strength,2)+mut, BURN, sharp=1) // Stinging. The more mutated I am, the harder I sting.
M.apply_damage(max(strength*2,(round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic), TOX) // Bee venom based on how angry I am and how many there are of me!
M << "\red You have been stung!"
M.flash_pain()
//if we're chasing someone, get a little bit angry
if(target_mob && prob(5))
feral++
//calm down a little bit
if(feral > 0)
if(feral > 0 && !target_mob)
if(prob(feral * 20))
feral -= 1
else
@@ -64,23 +90,22 @@
target_turf = null
if(strength > 5)
//calm down and spread out a little
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
var/mob/living/simple_animal/bee/B = new(get_turf(src))
B.strength = rand(1,5)
src.strength -= B.strength
if(src.strength <= 5)
src.icon_state = "bees[src.strength]"
B.icon_state = "bees[B.strength]"
update_icons()
B.update_icons()
if(src.parent)
B.parent = src.parent
src.parent.owned_bee_swarms.Add(B)
//make some noise
if(prob(0.5))
if(prob(5))
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
//smoke, water and steam calms us down
var/calming = 0
var/list/calmers = list(/obj/effect/effect/smoke/chem, \
var/list/calmers = list(/obj/effect/effect/smoke, \
/obj/effect/effect/water, \
/obj/effect/effect/foam, \
/obj/effect/effect/steam, \
@@ -108,9 +133,7 @@
if(feral > 0)
src.strength += B.strength
qdel(B)
src.icon_state = "bees[src.strength]"
if(strength > 5)
icon_state = "bees_swarm"
update_icons()
else if(prob(10))
//make the other swarm of bees stronger, then move away
var/total_bees = B.strength + src.strength
@@ -118,11 +141,11 @@
B.strength = min(5, total_bees)
src.strength = total_bees - B.strength
B.icon_state = "bees[B.strength]"
update_icons()
B.update_icons()
if(src.strength <= 0)
qdel(src)
return
src.icon_state = "bees[B.strength]"
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
density = 1
if(T.Enter(src, get_turf(src)))
@@ -130,20 +153,30 @@
density = 0
break
if(target_mob)
if(target_mob in view(src,7))
target_turf = get_turf(target_mob)
wander = 0
else // My target's gone! But I might still be pissed! You there. You look like a good stinging target!
for(var/mob/living/carbon/G in view(src,7))
target_mob = G
break
if(target_mob)//If we have a target
if(target_mob in view(src,7))//Check that we can still see them
target_turf = get_turf(target_mob)//If so, update the location
wander = 0
else//Otherwise, if our target is out of view, we clear them so we can pick a new one in the next step
target_mob = null
target_turf = null
wander = 1
//If we're angry but have no target, lets search for one
if (!target_mob && feral)
for(var/mob/living/carbon/G in view(src,7))
target_mob = G
break
//if we're chasing someone, get a little bit angry
if(target_mob && prob(5))
feral++
if(target_turf)
if (!(DirBlocked(get_step(src, get_dir(src,target_turf)),get_dir(src,target_turf)))) // Check for windows and doors!
Move(get_step(src, get_dir(src,target_turf)))
if (prob(0.1))
if (prob(10))
src.visible_message("\blue The bees swarm after [target_mob]!")
if(src.loc == target_turf)
target_turf = null
@@ -166,14 +199,36 @@
pixel_x = rand(-12,12)
pixel_y = rand(-12,12)
if(!parent && prob(10))
if(!parent && prob(8-strength))
strength -= 1
if(strength <= 0)
qdel(src)
else if(strength <= 5)
icon_state = "bees[strength]"
death()
else
update_icons()
//debugging
/*icon_state = "[strength]"
if(strength > 5)
icon_state = "unknown"*/
/mob/living/simple_animal/bee/update_icons()
if(strength <= 5)
icon_state = "bees[strength]"
else
icon_state = "bees_swarm"
//Kill it with fire!
/mob/living/simple_animal/bee/adjustFireLoss(damage)
damage *= 2
..()
//No more grabbing bee swarms
/mob/living/simple_animal/bee/attempt_grab(var/mob/living/grabber)
if (prob(strength*5))//if the swarm is big you might grab a few bees, you won't make a serious dent
grabber << "<span class = 'warning'>You attempt to grab the swarm, but only manage to snatch a scant handful of crushed bees.</span>"
adjustBruteLoss(strength*0.5)
else
grabber << "<span class = 'warning'>For some bizarre reason known only to yourself, you attempt to grab ahold of the swarm of bees. You come away with nothing but empty, slightly stung hands.</span>"
grabber.apply_damage(strength*0.5, BURN)
return 0
/mob/living/simple_animal/bee/attempt_pull(var/mob/living/grabber)
return attempt_grab(grabber)
@@ -100,9 +100,6 @@
src.client.screen = null
..()
/mob/living/simple_animal/updatehealth()
return
/mob/living/simple_animal/examine(mob/user)
..()
@@ -318,6 +315,9 @@
if (!(status_flags & CANPUSH))
return
if (!attempt_grab(M))
return
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
M.put_in_active_hand(G)
@@ -375,7 +375,9 @@
if(supernatural && istype(O,/obj/item/weapon/nullrod))
damage *= 2
purge = 3
adjustBruteLoss(damage)
apply_damage(damage, O.damtype)
//adjustBruteLoss(damage)
else
usr << "<span class='danger>This weapon is ineffective, it does no damage.</span>"
@@ -402,6 +404,11 @@
if(statpanel("Status") && show_stat_health)
stat(null, "Health: [round((health / maxHealth) * 100)]%")
/mob/living/updatehealth()
..()
if (health <= 0)
death()
/mob/living/simple_animal/death(gibbed, deathmessage = "dies!")
icon_state = icon_dead
density = 0
+7 -3
View File
@@ -605,8 +605,12 @@
usr << "<span class='notice'>It won't budge!</span>"
return
var/mob/M = AM
if(ismob(AM))
var/mob/living/M
if(istype(AM, /mob/living))
M = AM
if (!M.attempt_pull(src))
return
if(!iscarbon(src))
M.LAssailant = null
else
@@ -631,7 +635,7 @@
src << "\red <B>Pulling \the [H] in their current condition would probably be a bad idea.</B>"
//Attempted fix for people flying away through space when cuffed and dragged.
if(ismob(AM))
if(M)
var/mob/pulled = AM
pulled.inertia_dir = 0
+23 -10
View File
@@ -1,6 +1,19 @@
#define UPGRADE_COOLDOWN 40
#define UPGRADE_KILL_TIMER 100
//This is called from human_attackhand.dm before grabbing happens.
//IT is called when grabber tries to grab this mob
//Override this for special grab behaviour.
//Returning 0 will make grab fail, returning 1 will suceed
/mob/living/proc/attempt_grab(var/mob/living/grabber)
return 1
//As above, but called when someone tries to pull this mob
/mob/living/proc/attempt_pull(var/mob/living/grabber)
return 1
///Process_Grab()
///Called by client/Move()
///Checks to see if you are grabbing anything and if moving will affect your grab.
@@ -124,7 +137,7 @@
if(iscarbon(affecting))
handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting)
if(force_down)
if(affecting.loc != assailant.loc)
force_down = 0
@@ -148,7 +161,7 @@
/obj/item/weapon/grab/proc/handle_eye_mouth_covering(mob/living/carbon/target, mob/user, var/target_zone)
var/announce = (target_zone != last_hit_zone) //only display messages when switching between different target zones
last_hit_zone = target_zone
switch(target_zone)
if("mouth")
if(announce)
@@ -232,7 +245,7 @@
else
assailant.visible_message("<span class='warning'>[assailant] pins [affecting] down to the ground (now hands)!</span>")
apply_pinning(affecting, assailant)
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
hud.icon_state = "reinforce1"
@@ -284,10 +297,10 @@
return
if(world.time < (last_action + 20))
return
last_action = world.time
reset_kill_state() //using special grab moves will interrupt choking them
//clicking on the victim while grabbing them
if(M == affecting)
if(ishuman(affecting))
@@ -300,10 +313,10 @@
force_down = 0
return
inspect_organ(affecting, assailant, hit_zone)
if(I_GRAB)
jointlock(affecting, assailant, hit_zone)
if(I_HURT)
if(hit_zone == "eyes")
attack_eye(affecting, assailant)
@@ -311,10 +324,10 @@
headbut(affecting, assailant)
else
dislocate(affecting, assailant, hit_zone)
if(I_DISARM)
pin_down(affecting, assailant)
//clicking on yourself while grabbing them
if(M == assailant && state >= GRAB_AGGRESSIVE)
devour(affecting, assailant)
@@ -325,7 +338,7 @@
qdel(src)
/obj/item/weapon/grab/proc/reset_kill_state()
if(state == GRAB_KILL)
if(state == GRAB_KILL)
assailant.visible_message("<span class='warning'>[assailant] lost \his tight grip on [affecting]'s neck!</span>")
hud.icon_state = "kill"
state = GRAB_NECK