mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-23 03:57:13 +01:00
@@ -0,0 +1,254 @@
|
||||
|
||||
#define BEEBOX_MAX_FRAMES 3 //Max frames per box
|
||||
#define BEES_RATIO 0.5 //Multiplied by the max number of honeycombs to find the max number of bees
|
||||
#define BEE_PROB_NEW_BEE 20 //The chance for spare bee_resources to be turned into new bees
|
||||
#define BEE_RESOURCE_HONEYCOMB_COST 100 //The amount of bee_resources for a new honeycomb to be produced, percentage cost 1-100
|
||||
#define BEE_RESOURCE_NEW_BEE_COST 50 //The amount of bee_resources for a new bee to be produced, percentage cost 1-100
|
||||
|
||||
|
||||
|
||||
/mob/proc/bee_friendly()
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/bee_friendly()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/bot/bee_friendly()
|
||||
if(paicard)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/diona/bee_friendly()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/bee_friendly()
|
||||
if(get_species() == "Diona") //bees pollinate plants, duh.
|
||||
return 1
|
||||
if((wear_suit && (wear_suit.flags & THICKMATERIAL)) && (head && (head.flags & THICKMATERIAL)))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/structure/beebox
|
||||
name = "apiary"
|
||||
desc = "Dr Miles Manners is just your average Wasp themed super hero by day, but by night he becomes DR BEES!"
|
||||
icon = 'icons/obj/apiary_bees.dmi'
|
||||
icon_state = "beebox"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/mob/living/simple_animal/hostile/poison/bees/queen/queen_bee = null
|
||||
var/list/bees = list() //bees owned by the box, not those inside it
|
||||
var/list/honeycombs = list()
|
||||
var/list/honey_frames = list()
|
||||
var/bee_resources = 0
|
||||
|
||||
|
||||
/obj/structure/beebox/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
|
||||
|
||||
/obj/structure/beebox/Destroy()
|
||||
processing_objects.Remove(src)
|
||||
bees.Cut()
|
||||
bees = null
|
||||
honeycombs.Cut()
|
||||
honeycombs = null
|
||||
queen_bee = null
|
||||
return ..()
|
||||
|
||||
|
||||
//Premade apiaries can spawn with a random reagent
|
||||
/obj/structure/beebox/premade
|
||||
var/random_reagent = FALSE
|
||||
|
||||
|
||||
/obj/structure/beebox/premade/New()
|
||||
..()
|
||||
|
||||
var/datum/reagent/R = null
|
||||
if(random_reagent)
|
||||
R = pick(subtypesof(/datum/reagent))
|
||||
R = chemical_reagents_list[initial(R.id)]
|
||||
|
||||
queen_bee = new(src)
|
||||
queen_bee.beehome = src
|
||||
bees += queen_bee
|
||||
queen_bee.assign_reagent(R)
|
||||
|
||||
for(var/i in 1 to BEEBOX_MAX_FRAMES)
|
||||
var/obj/item/honey_frame/HF = new(src)
|
||||
honey_frames += HF
|
||||
|
||||
for(var/i in 1 to get_max_bees())
|
||||
var/mob/living/simple_animal/hostile/poison/bees/B = new(src)
|
||||
bees += B
|
||||
B.beehome = src
|
||||
B.assign_reagent(R)
|
||||
|
||||
|
||||
/obj/structure/beebox/premade/random
|
||||
random_reagent = TRUE
|
||||
|
||||
|
||||
/obj/structure/beebox/process()
|
||||
if(queen_bee)
|
||||
if(bee_resources >= BEE_RESOURCE_HONEYCOMB_COST)
|
||||
if(honeycombs.len < get_max_honeycomb())
|
||||
bee_resources = max(bee_resources-BEE_RESOURCE_HONEYCOMB_COST, 0)
|
||||
var/obj/item/weapon/reagent_containers/honeycomb/HC = new(src)
|
||||
if(queen_bee.beegent)
|
||||
HC.set_reagent(queen_bee.beegent.id)
|
||||
honeycombs += HC
|
||||
|
||||
if(bees.len < get_max_bees())
|
||||
var/freebee = FALSE //a freebee, geddit?, hahaha HAHAHAHA
|
||||
if(bees.len <= 1) //there's always one set of worker bees, this isn't colony collapse disorder its 2d spessmen
|
||||
freebee = TRUE
|
||||
if((bee_resources >= BEE_RESOURCE_NEW_BEE_COST && prob(BEE_PROB_NEW_BEE)) || freebee)
|
||||
if(!freebee)
|
||||
bee_resources = max(bee_resources - BEE_RESOURCE_NEW_BEE_COST, 0)
|
||||
var/mob/living/simple_animal/hostile/poison/bees/B = new(src)
|
||||
B.beehome = src
|
||||
B.assign_reagent(queen_bee.beegent)
|
||||
bees += B
|
||||
|
||||
|
||||
/obj/structure/beebox/proc/get_max_honeycomb()
|
||||
. = 0
|
||||
for(var/hf in honey_frames)
|
||||
var/obj/item/honey_frame/HF = hf
|
||||
. += HF.honeycomb_capacity
|
||||
|
||||
|
||||
/obj/structure/beebox/proc/get_max_bees()
|
||||
. = get_max_honeycomb() * BEES_RATIO
|
||||
|
||||
|
||||
/obj/structure/beebox/examine(mob/user)
|
||||
..()
|
||||
|
||||
if(!queen_bee)
|
||||
to_chat(user, "<span class='warning'>There is no queen bee! There won't bee any honeycomb without a queen!</span>")
|
||||
|
||||
var/half_bee = get_max_bees()*0.5
|
||||
if(half_bee && (bees.len >= half_bee))
|
||||
to_chat(user, "<span class='notice'>This place is a BUZZ with activity... there are lots of bees!</span>")
|
||||
|
||||
to_chat(user, "<span class='notice'>[bee_resources]/100 resource supply.</span>")
|
||||
to_chat(user, "<span class='notice'>[bee_resources]% towards a new honeycomb.</span>")
|
||||
to_chat(user, "<span class='notice'>[bee_resources*2]% towards a new bee.</span>")
|
||||
|
||||
if(honeycombs.len)
|
||||
var/plural = honeycombs.len > 1
|
||||
to_chat(user, "<span class='notice'>There [plural? "are" : "is"] [honeycombs.len] uncollected honeycomb[plural ? "s":""] in the apiary.</span>")
|
||||
|
||||
if(honeycombs.len >= get_max_honeycomb())
|
||||
to_chat(user, "<span class='warning'>there's no room for more honeycomb!</span>")
|
||||
|
||||
|
||||
/obj/structure/beebox/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/honey_frame))
|
||||
var/obj/item/honey_frame/HF = I
|
||||
if(honey_frames.len < BEEBOX_MAX_FRAMES)
|
||||
visible_message("<span class='notice'>[user] adds a frame to the apiary.</span>")
|
||||
user.unEquip(HF)
|
||||
HF.forceMove(src)
|
||||
honey_frames += HF
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There's no room for anymore frames in the apiary!</span>")
|
||||
|
||||
if(istype(I, /obj/item/weapon/wrench))
|
||||
if(default_unfasten_wrench(user, I, time = 20))
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/queen_bee))
|
||||
if(queen_bee)
|
||||
to_chat(user, "<span class='warning'>This hive already has a queen!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/queen_bee/qb = I
|
||||
user.unEquip(qb)
|
||||
|
||||
qb.queen.forceMove(src)
|
||||
bees += qb.queen
|
||||
queen_bee = qb.queen
|
||||
qb.queen = null
|
||||
|
||||
if(queen_bee)
|
||||
visible_message("<span class='notice'>[user] sets [qb] down inside the apiary, making it their new home.</span>")
|
||||
var/relocated = 0
|
||||
for(var/b in bees)
|
||||
var/mob/living/simple_animal/hostile/poison/bees/B = b
|
||||
if(B.reagent_incompatible(queen_bee))
|
||||
bees -= B
|
||||
B.beehome = null
|
||||
if(B.loc == src)
|
||||
B.forceMove(get_turf(src))
|
||||
relocated++
|
||||
if(relocated)
|
||||
to_chat(user, "<span class='warning'>This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!</span>")
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The queen bee disappeared! bees disappearing has been in the news lately...</span>")
|
||||
|
||||
qdel(qb)
|
||||
|
||||
|
||||
/obj/structure/beebox/attack_hand(mob/user)
|
||||
if(ishuman(user))
|
||||
if(!user.bee_friendly())
|
||||
//Time to get stung!
|
||||
var/bees = FALSE
|
||||
for(var/b in bees) //everyone who's ever lived here now instantly hates you, suck it assistant!
|
||||
var/mob/living/simple_animal/hostile/poison/bees/B = b
|
||||
if(B.isqueen)
|
||||
continue
|
||||
if(B.loc == src)
|
||||
B.forceMove(get_turf(src))
|
||||
B.target = user
|
||||
bees = TRUE
|
||||
if(bees)
|
||||
visible_message("<span class='danger'>[user] disturbs the bees!</span>")
|
||||
else
|
||||
var/option = input(user, "What Action do you wish to perform?", "Apiary") as null|anything in list("Remove a Honey Frame","Remove the Queen Bee")
|
||||
if(!Adjacent(user) || !option)
|
||||
return
|
||||
switch(option)
|
||||
if("Remove a Honey Frame")
|
||||
if(!honey_frames.len)
|
||||
to_chat(user, "<span class='warning'>There are no honey frames to remove!</span>")
|
||||
return
|
||||
|
||||
var/obj/item/honey_frame/HF = pick_n_take(honey_frames)
|
||||
if(HF)
|
||||
if(!user.put_in_active_hand(HF))
|
||||
HF.forceMove(get_turf(src))
|
||||
visible_message("<span class='notice'>[user] removes a frame from the apiary.</span>")
|
||||
|
||||
var/amtH = HF.honeycomb_capacity
|
||||
var/fallen = 0
|
||||
while(honeycombs.len && amtH) //let's pretend you always grab the frame with the most honeycomb on it
|
||||
var/obj/item/weapon/reagent_containers/honeycomb/HC = pick_n_take(honeycombs)
|
||||
if(HC)
|
||||
HC.forceMove(get_turf(src))
|
||||
amtH--
|
||||
fallen++
|
||||
if(fallen)
|
||||
var/multiple = fallen > 1
|
||||
visible_message("<span class='notice'>[user] scrapes [multiple ? "[fallen]" : "a"] honeycomb[multiple ? "s" : ""] off of the frame.</span>")
|
||||
|
||||
if("Remove the Queen Bee")
|
||||
if(!queen_bee || queen_bee.loc != src)
|
||||
to_chat(user, "<span class='warning'>There is no queen bee to remove!</span>")
|
||||
return
|
||||
var/obj/item/queen_bee/QB = new()
|
||||
queen_bee.forceMove(QB)
|
||||
bees -= queen_bee
|
||||
QB.queen = queen_bee
|
||||
QB.name = queen_bee.name
|
||||
if(!user.put_in_active_hand(QB))
|
||||
QB.forceMove(get_turf(src))
|
||||
visible_message("<span class='notice'>[user] removes the queen from the apiary.</span>")
|
||||
queen_bee = null
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
/obj/item/clothing/head/beekeeper_head
|
||||
name = "beekeeper hat"
|
||||
desc = "keeps the lil buzzing buggers out of your eyes"
|
||||
icon_state = "beekeeper"
|
||||
item_state = "beekeeper"
|
||||
flags = THICKMATERIAL
|
||||
|
||||
|
||||
/obj/item/clothing/suit/beekeeper_suit
|
||||
name = "beekeeper suit"
|
||||
desc = "keeps the lil buzzing buggers away from your squishy bits"
|
||||
icon_state = "beekeeper"
|
||||
item_state = "beekeeper"
|
||||
flags = THICKMATERIAL
|
||||
allowed = list (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/fertilizer,/obj/item/weapon/minihoe)
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
/obj/item/honey_frame
|
||||
name = "honey frame"
|
||||
desc = "a scaffold for bees to build honeycomb on"
|
||||
icon = 'icons/obj/apiary_bees.dmi'
|
||||
icon_state = "honey_frame"
|
||||
var/honeycomb_capacity = 10 //10 Honeycomb per frame by default, researchable frames perhaps?
|
||||
|
||||
|
||||
/obj/item/honey_frame/New()
|
||||
pixel_x = rand(8,-8)
|
||||
pixel_y = rand(8,-8)
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/honeycomb
|
||||
name = "honeycomb"
|
||||
desc = "a hexagonal mesh of honeycomb"
|
||||
icon = 'icons/obj/apiary_bees.dmi'
|
||||
icon_state = "honeycomb"
|
||||
possible_transfer_amounts = list()
|
||||
disease_amount = 0
|
||||
volume = 10
|
||||
amount_per_transfer_from_this = 0
|
||||
list_reagents = list("honey" = 5)
|
||||
var/honey_color = ""
|
||||
|
||||
/obj/item/weapon/reagent_containers/honeycomb/New()
|
||||
..()
|
||||
pixel_x = rand(8,-8)
|
||||
pixel_y = rand(8,-8)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/honeycomb/update_icon()
|
||||
overlays.Cut()
|
||||
var/image/honey
|
||||
if(honey_color)
|
||||
honey = image(icon = 'icons/obj/apiary_bees.dmi', icon_state = "greyscale_honey")
|
||||
honey.color = honey_color
|
||||
else
|
||||
honey = image(icon = 'icons/obj/apiary_bees.dmi', icon_state = "honey")
|
||||
overlays += honey
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/honeycomb/proc/set_reagent(reagent)
|
||||
var/datum/reagent/R = chemical_reagents_list[reagent]
|
||||
if(istype(R))
|
||||
name = "honeycomb ([R.name])"
|
||||
honey_color = R.color
|
||||
reagents.add_reagent(R.id,5)
|
||||
else
|
||||
honey_color = ""
|
||||
update_icon()
|
||||
@@ -49,6 +49,8 @@
|
||||
|
||||
var/last_plant_ikey //This is for debugging reference, and is otherwise useless. --FalseIncarnate
|
||||
|
||||
var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpolinate one plant
|
||||
|
||||
/*
|
||||
* process() can be found in \code\modules\hydroponics\tray\tray_process.dm
|
||||
* reagent handling can be found in \code\modules\hydroponics\tray\tray_reagents.dm
|
||||
@@ -586,19 +588,6 @@
|
||||
anchored = !anchored
|
||||
to_chat(user, "You [anchored ? "wrench" : "unwrench"] \the [src].")
|
||||
|
||||
else if(istype(O, /obj/item/apiary))
|
||||
|
||||
if(seed)
|
||||
to_chat(user, "<span class='danger'>[src] is already occupied!</span>")
|
||||
else
|
||||
user.drop_item()
|
||||
qdel(O)
|
||||
|
||||
var/obj/machinery/apiary/A = new(src.loc)
|
||||
A.icon = src.icon
|
||||
A.icon_state = src.icon_state
|
||||
A.hydrotray_type = src.type
|
||||
qdel(src)
|
||||
else if ((istype(O, /obj/item/weapon/tank) && !( src.destroyed )))
|
||||
if (src.holding)
|
||||
to_chat(user, "\blue There is alreadu a tank loaded into the [src].")
|
||||
@@ -715,4 +704,4 @@
|
||||
if(istype(holding, /obj/item/weapon/tank))
|
||||
to_chat(usr, "\blue You eject [holding.name] from [src].")
|
||||
holding.loc = loc
|
||||
holding = null
|
||||
holding = null
|
||||
|
||||
@@ -730,7 +730,7 @@
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/W = I
|
||||
if(W.welding && !stat)
|
||||
if(stance != HOSTILE_STANCE_IDLE)
|
||||
if(AIStatus == AI_ON)
|
||||
to_chat(user, "<span class='info'>[src] is moving around too much to repair!</span>")
|
||||
return
|
||||
if(maxHealth == health)
|
||||
@@ -1061,4 +1061,4 @@
|
||||
return ..()
|
||||
C.preserved = 1
|
||||
to_chat(user, "<span class='notice'>You inject the hivelord core with the stabilizer. It will no longer go inert.</span>")
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
|
||||
/mob/living/simple_animal/bee
|
||||
name = "bees"
|
||||
icon = 'icons/obj/apiary_bees_etc.dmi'
|
||||
icon_state = "bees1"
|
||||
icon_living = "bees1"
|
||||
icon_dead = "bees1"
|
||||
var/strength = 1
|
||||
var/feral = 0
|
||||
var/mut = 0
|
||||
var/toxic = 0
|
||||
var/turf/target_turf
|
||||
var/mob/target_mob
|
||||
var/obj/machinery/apiary/parent
|
||||
pass_flags = PASSTABLE
|
||||
turns_per_move = 6
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray
|
||||
|
||||
// Allow final solutions.
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 360
|
||||
|
||||
/mob/living/simple_animal/bee/New(loc, var/obj/machinery/apiary/new_parent)
|
||||
..()
|
||||
parent = new_parent
|
||||
|
||||
/mob/living/simple_animal/bee/Destroy()
|
||||
if(parent)
|
||||
parent.owned_bee_swarms.Remove(src)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/bee/process_ai()
|
||||
//if we're strong enough, sting some people
|
||||
var/mob/living/carbon/human/M = target_mob
|
||||
var/sting_prob = 100 // 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!
|
||||
to_chat(M, "\red You have been stung!")
|
||||
|
||||
//if we're chasing someone, get a little bit angry
|
||||
if(target_mob && prob(10))
|
||||
feral++
|
||||
|
||||
//calm down a little bit
|
||||
if(feral > 0)
|
||||
if(prob(feral * 10))
|
||||
feral -= 1
|
||||
else
|
||||
//if feral is less than 0, we're becalmed by smoke or steam
|
||||
if(feral < 0)
|
||||
feral += 1
|
||||
|
||||
if(target_mob)
|
||||
target_mob = null
|
||||
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))))
|
||||
B.strength = rand(1,5)
|
||||
src.strength -= B.strength
|
||||
if(src.strength <= 5)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.parent)
|
||||
B.parent = src.parent
|
||||
src.parent.owned_bee_swarms.Add(B)
|
||||
|
||||
//make some noise
|
||||
if(prob(0.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/chem_smoke, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
/obj/effect/mist)
|
||||
|
||||
for(var/obj/effect/check_effect in src.loc)
|
||||
if(check_effect.type in calmers)
|
||||
calming = 1
|
||||
break
|
||||
|
||||
if(calming)
|
||||
if(feral > 0)
|
||||
src.visible_message("\blue The bees calm down!")
|
||||
feral = -10
|
||||
target_mob = null
|
||||
target_turf = null
|
||||
wander = 1
|
||||
|
||||
for(var/mob/living/simple_animal/bee/B in src.loc)
|
||||
if(B == src)
|
||||
continue
|
||||
|
||||
if(feral > 0)
|
||||
src.strength += B.strength
|
||||
qdel(B)
|
||||
src.icon_living = "bees[src.strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "bees_swarm"
|
||||
else if(prob(10))
|
||||
//make the other swarm of bees stronger, then move away
|
||||
var/total_bees = B.strength + src.strength
|
||||
if(total_bees < 10)
|
||||
B.strength = min(5, total_bees)
|
||||
src.strength = total_bees - B.strength
|
||||
|
||||
B.icon_living = "bees[B.strength]"
|
||||
if(src.strength <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
src.icon_living = "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)))
|
||||
src.loc = T
|
||||
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_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))
|
||||
src.visible_message("\blue The bees swarm after [target_mob]!")
|
||||
if(src.loc == target_turf)
|
||||
target_turf = null
|
||||
wander = 1
|
||||
else
|
||||
//find some flowers, harvest
|
||||
//angry bee swarms don't hang around
|
||||
if(feral > 0)
|
||||
turns_per_move = rand(1,3)
|
||||
else if(feral < 0)
|
||||
turns_since_move = 0
|
||||
else if(!my_hydrotray || my_hydrotray.loc != src.loc || my_hydrotray.dead || !my_hydrotray.seed)
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/my_hydrotray = locate() in src.loc
|
||||
if(my_hydrotray)
|
||||
if(!my_hydrotray.dead && my_hydrotray.seed)
|
||||
turns_per_move = rand(20,50)
|
||||
else
|
||||
my_hydrotray = null
|
||||
|
||||
pixel_x = rand(-12,12)
|
||||
pixel_y = rand(-12,12)
|
||||
|
||||
/mob/living/simple_animal/bee/handle_state_icons()
|
||||
if(!parent && prob(10))
|
||||
strength -= 1
|
||||
if(strength <= 0)
|
||||
qdel(src)
|
||||
else if(strength <= 5)
|
||||
icon_living = "bees[strength]"
|
||||
|
||||
//debugging
|
||||
/*icon_living = "[strength]"
|
||||
if(strength > 5)
|
||||
icon_living = "unknown"*/
|
||||
|
||||
..()
|
||||
@@ -43,13 +43,12 @@
|
||||
var/plant_cooldown = 30
|
||||
var/plants_off = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/drone/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
/mob/living/simple_animal/hostile/alien/drone/handle_automated_action()
|
||||
if(!..()) //AIStatus is off
|
||||
return
|
||||
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(AIStatus == AI_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
@@ -90,12 +89,12 @@
|
||||
var/egg_cooldown = 30
|
||||
var/plant_cooldown = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/queen/process_ai()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/queen/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
egg_cooldown--
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(AIStatus == AI_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 30
|
||||
attacktext = "mauls"
|
||||
friendly = "bear hugs"
|
||||
attack_sound = 'sound/weapons/genhit3.ogg'
|
||||
|
||||
//Space bears aren't affected by atmos.
|
||||
atmos_requirements = list("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
|
||||
var/stance_step = 0
|
||||
|
||||
faction = list("russian")
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
@@ -36,10 +36,12 @@
|
||||
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
|
||||
/mob/living/simple_animal/hostile/bear/Hudson
|
||||
name = "Hudson"
|
||||
desc = ""
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
desc = "Feared outlaw, this guy is one bad news bear." //I'm sorry...
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Hudson/New()
|
||||
..()
|
||||
var/unbearable_pun = pick("He's unbearably cute.", "It looks like he is a bearer of bad news.", "Sadly, he is bearly able to comprehend puns.")
|
||||
desc = "That's Hudson. " + unbearable_pun// I am not sorry for this.
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Move()
|
||||
..()
|
||||
@@ -49,121 +51,5 @@
|
||||
else
|
||||
icon_state = "bearfloor"
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
switch(stance)
|
||||
|
||||
if(HOSTILE_STANCE_TIRED)
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(stance_step >= 10) //rests for 10 ticks
|
||||
if(target && target in ListTargets())
|
||||
stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
|
||||
else
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
|
||||
if(HOSTILE_STANCE_ALERT)
|
||||
stop_automated_movement = 1
|
||||
var/found_mob = 0
|
||||
if(target && target in ListTargets())
|
||||
if(CanAttack(target))
|
||||
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
|
||||
stance_step++
|
||||
found_mob = 1
|
||||
src.dir = get_dir(src,target) //Keep staring at the mob
|
||||
|
||||
if(stance_step in list(1,4,7)) //every 3 ticks
|
||||
var/action = pick( list( "growls at [target]", "stares angrily at [target]", "prepares to attack [target]", "closely watches [target]" ) )
|
||||
if(action)
|
||||
custom_emote(1, action)
|
||||
if(!found_mob)
|
||||
stance_step--
|
||||
|
||||
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
|
||||
custom_emote(1, "is worn out and needs to rest" )
|
||||
stance = HOSTILE_STANCE_TIRED
|
||||
stance_step = 0
|
||||
walk(src, 0) //This stops the bear's walking
|
||||
return
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target = user
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/attack_hand(mob/living/carbon/human/M as mob)
|
||||
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target = M
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/movement_dir = 0)
|
||||
return 1 //No drifting in space for space bears!
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
custom_emote(1, "stares alertly at [.]")
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/LoseTarget()
|
||||
..(5)
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/AttackingTarget()
|
||||
custom_emote(1, pick( list("slashes at [target]", "bites [target]") ) )
|
||||
|
||||
var/damage = rand(20,30)
|
||||
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
|
||||
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
|
||||
return H
|
||||
else if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.adjustBruteLoss(damage)
|
||||
return L
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.attack_animal(src)
|
||||
return M
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
#define BEE_IDLE_ROAMING 70 //The value of idle at which a bee in a beebox will try to wander
|
||||
#define BEE_IDLE_GOHOME 0 //The value of idle at which a bee will try to go home
|
||||
#define BEE_PROB_GOHOME 35 //Probability to go home when idle is below BEE_IDLE_GOHOME
|
||||
#define BEE_PROB_GOROAM 5 //Probability to go roaming when idle is above BEE_IDLE_ROAMING
|
||||
#define BEE_TRAY_RECENT_VISIT 200 //How long in deciseconds until a tray can be visited by a bee again
|
||||
#define BEE_DEFAULT_COLOUR "#e5e500" //the colour we make the stripes of the bee if our reagent has no colour (or we have no reagent)
|
||||
|
||||
#define BEE_POLLINATE_YIELD_CHANCE 10
|
||||
#define BEE_POLLINATE_PEST_CHANCE 33
|
||||
#define BEE_POLLINATE_POTENTCY_CHANCE 50
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees
|
||||
name = "bee"
|
||||
desc = "buzzy buzzy bee, stingy sti- Ouch!"
|
||||
icon_state = ""
|
||||
icon_living = ""
|
||||
icon = 'icons/mob/bees.dmi'
|
||||
speak_emote = list("buzzes")
|
||||
emote_hear = list("buzzes")
|
||||
turns_per_move = 0
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 1
|
||||
attacktext = "stings"
|
||||
response_help = "shoos"
|
||||
response_disarm = "swats away"
|
||||
response_harm = "squashes"
|
||||
maxHealth = 10
|
||||
health = 10
|
||||
faction = list("hostile")
|
||||
move_to_delay = 0
|
||||
environment_smash = 0
|
||||
mouse_opacity = 2
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
flying = 1
|
||||
search_objects = 1 //have to find those plant trays!
|
||||
density = 0
|
||||
small = 1
|
||||
|
||||
//Spaceborn beings don't get hurt by space
|
||||
atmos_requirements = list("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
|
||||
|
||||
var/datum/reagent/beegent = null //hehe, beegent
|
||||
var/obj/structure/beebox/beehome = null
|
||||
var/idle = 0
|
||||
var/isqueen = FALSE
|
||||
var/icon_base = "bee"
|
||||
var/static/list/bee_icons = list()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(movement_dir = 0)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/New()
|
||||
..()
|
||||
generate_bee_visuals()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Destroy()
|
||||
if(beehome)
|
||||
beehome.bees.Remove(src)
|
||||
beehome = null
|
||||
beegent = null
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/death(gibbed)
|
||||
if(beehome)
|
||||
beehome.bees.Remove(src)
|
||||
beehome = null
|
||||
beegent = null
|
||||
..()
|
||||
ghostize()
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/examine(mob/user)
|
||||
..()
|
||||
|
||||
if(!beehome)
|
||||
to_chat(user, "<span class='warning'>This bee is homeless!</span>")
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals()
|
||||
overlays.Cut()
|
||||
|
||||
var/col = BEE_DEFAULT_COLOUR
|
||||
if(beegent && beegent.color)
|
||||
col = beegent.color
|
||||
|
||||
var/image/base
|
||||
if(!bee_icons["[icon_base]_base"])
|
||||
bee_icons["[icon_base]_base"] = image(icon = 'icons/mob/bees.dmi', icon_state = "[icon_base]_base")
|
||||
base = bee_icons["[icon_base]_base"]
|
||||
overlays += base
|
||||
|
||||
var/image/greyscale
|
||||
if(!bee_icons["[icon_base]_grey_[col]"])
|
||||
bee_icons["[icon_base]_grey_[col]"] = image(icon = 'icons/mob/bees.dmi', icon_state = "[icon_base]_grey")
|
||||
greyscale = bee_icons["[icon_base]_grey_[col]"]
|
||||
greyscale.color = col
|
||||
overlays += greyscale
|
||||
|
||||
var/image/wings
|
||||
if(!bee_icons["[icon_base]_wings"])
|
||||
bee_icons["[icon_base]_wings"] = image(icon = 'icons/mob/bees.dmi', icon_state = "[icon_base]_wings")
|
||||
wings = bee_icons["[icon_base]_wings"]
|
||||
overlays += wings
|
||||
|
||||
|
||||
//We don't attack beekeepers/people dressed as bees//Todo: bee costume
|
||||
/mob/living/simple_animal/hostile/poison/bees/CanAttack(atom/the_target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return 0
|
||||
if(ishuman(the_target))
|
||||
var/mob/living/carbon/human/H = the_target
|
||||
return !H.bee_friendly()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Found(atom/A)
|
||||
if(istype(A, /obj/machinery/portable_atmospherics/hydroponics))
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/Hydro = A
|
||||
if(Hydro.seed && !Hydro.dead && !Hydro.recent_bee_visit)
|
||||
wanted_objects |= /obj/machinery/portable_atmospherics/hydroponics //so we only hunt them while they're alive/seeded/not visisted
|
||||
return 1
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
return !H.bee_friendly()
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/AttackingTarget()
|
||||
//Pollinate
|
||||
if(istype(target, /obj/machinery/portable_atmospherics/hydroponics))
|
||||
var/obj/machinery/portable_atmospherics/hydroponics/Hydro = target
|
||||
pollinate(Hydro)
|
||||
else if(target == beehome)
|
||||
var/obj/structure/beebox/BB = target
|
||||
forceMove(BB)
|
||||
target = null
|
||||
wanted_objects.Remove(/obj/structure/beebox) //so we don't attack beeboxes when not going home
|
||||
else
|
||||
if(beegent && isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!isnull(target.reagents))
|
||||
beegent.reaction_mob(L, TOUCH)
|
||||
L.reagents.add_reagent(beegent.id, rand(1,5))
|
||||
target.attack_animal(src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/assign_reagent(datum/reagent/R)
|
||||
if(istype(R))
|
||||
beegent = R
|
||||
name = "[initial(name)] ([R.name])"
|
||||
generate_bee_visuals()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/pollinate(obj/machinery/portable_atmospherics/hydroponics/Hydro)
|
||||
if(!istype(Hydro) || !Hydro.seed || Hydro.dead || Hydro.recent_bee_visit)
|
||||
target = null
|
||||
return
|
||||
|
||||
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
|
||||
wanted_objects.Remove(/obj/machinery/portable_atmospherics/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
|
||||
Hydro.recent_bee_visit = TRUE
|
||||
spawn(BEE_TRAY_RECENT_VISIT)
|
||||
if(Hydro)
|
||||
Hydro.recent_bee_visit = FALSE
|
||||
|
||||
var/growth = health //Health also means how many bees are in the swarm, roughly.
|
||||
//better healthier plants!
|
||||
Hydro.health += round(growth*0.5)
|
||||
if(prob(BEE_POLLINATE_PEST_CHANCE))
|
||||
Hydro.pestlevel = max(0, --Hydro.pestlevel)
|
||||
if(prob(BEE_POLLINATE_YIELD_CHANCE)) //Yield mod is HELLA powerful, but quite rare
|
||||
if(!isnull(plant_controller.seeds[Hydro.seed.name]))
|
||||
Hydro.seed = Hydro.seed.diverge()
|
||||
var/seed_yield = Hydro.seed.get_trait(TRAIT_YIELD)
|
||||
Hydro.seed.set_trait(TRAIT_YIELD, seed_yield + 1, 10, 0)
|
||||
if(prob(BEE_POLLINATE_POTENTCY_CHANCE))
|
||||
if(!isnull(plant_controller.seeds[Hydro.seed.name]))
|
||||
Hydro.seed = Hydro.seed.diverge()
|
||||
var/seed_potency = Hydro.seed.get_trait(TRAIT_POTENCY)
|
||||
Hydro.seed.set_trait(TRAIT_POTENCY, seed_potency + 1, 200, 0)
|
||||
|
||||
if(beehome)
|
||||
beehome.bee_resources = min(beehome.bee_resources + growth, 100)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/handle_automated_action()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
if(!isqueen)
|
||||
if(loc == beehome)
|
||||
idle = min(100, ++idle)
|
||||
if(idle >= BEE_IDLE_ROAMING && prob(BEE_PROB_GOROAM))
|
||||
forceMove(get_turf(beehome))
|
||||
else
|
||||
idle = max(0, --idle)
|
||||
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
|
||||
if(!FindTarget())
|
||||
wanted_objects.Add(/obj/structure/beebox) //so we don't attack beeboxes when not going home
|
||||
target = beehome
|
||||
if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home
|
||||
for(var/obj/structure/beebox/BB in view(vision_range, src))
|
||||
if(reagent_incompatible(BB.queen_bee) || BB.bees.len >= BB.get_max_bees())
|
||||
continue
|
||||
BB.bees |= src
|
||||
beehome = BB
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/queen
|
||||
name = "queen bee"
|
||||
desc = "she's the queen of bees, BZZ BZZ"
|
||||
icon_base = "queen"
|
||||
isqueen = TRUE
|
||||
|
||||
|
||||
//the Queen doesn't leave the box on her own, and she CERTAINLY doesn't pollinate by herself
|
||||
/mob/living/simple_animal/hostile/poison/bees/queen/Found(atom/A)
|
||||
return 0
|
||||
|
||||
|
||||
//leave pollination for the peasent bees
|
||||
/mob/living/simple_animal/hostile/poison/bees/queen/AttackingTarget()
|
||||
if(beegent && isliving(target))
|
||||
var/mob/living/L = target
|
||||
beegent.reaction_mob(L, TOUCH)
|
||||
L.reagents.add_reagent(beegent.id, rand(1,5))
|
||||
target.attack_animal(src)
|
||||
|
||||
|
||||
//PEASENT BEES
|
||||
/mob/living/simple_animal/hostile/poison/bees/queen/pollinate()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/reagent_incompatible(mob/living/simple_animal/hostile/poison/bees/B)
|
||||
if(!B)
|
||||
return 0
|
||||
if(B.beegent && beegent && B.beegent.id != beegent.id || B.beegent && !beegent || !B.beegent && beegent)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/queen_bee
|
||||
name = "queen bee"
|
||||
desc = "she's the queen of bees, BZZ BZZ"
|
||||
icon_state = "queen_item"
|
||||
item_state = ""
|
||||
icon = 'icons/mob/bees.dmi'
|
||||
var/mob/living/simple_animal/hostile/poison/bees/queen/queen
|
||||
|
||||
|
||||
/obj/item/queen_bee/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I,/obj/item/weapon/reagent_containers/syringe))
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = I
|
||||
if(S.reagents.has_reagent("royal_bee_jelly")) //checked twice, because I really don't want royal bee jelly to be duped
|
||||
if(S.reagents.has_reagent("royal_bee_jelly",5))
|
||||
S.reagents.remove_reagent("royal_bee_jelly", 5)
|
||||
var/obj/item/queen_bee/qb = new(get_turf(user))
|
||||
qb.queen = new(qb)
|
||||
if(queen && queen.beegent)
|
||||
qb.queen.assign_reagent(queen.beegent) //Bees use the global singleton instances of reagents, so we don't need to worry about one bee being deleted and her copies losing their reagents.
|
||||
user.put_in_active_hand(qb)
|
||||
user.visible_message("<span class='notice'>[user] injects [src] with royal bee jelly, causing it to split into two bees, MORE BEES!</span>","<span class ='warning'>You inject [src] with royal bee jelly, causing it to split into two bees, MORE BEES!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You don't have enough royal bee jelly to split a bee in two!</span>")
|
||||
else
|
||||
var/datum/reagent/R = chemical_reagents_list[S.reagents.get_master_reagent_id()]
|
||||
if(R && S.reagents.has_reagent(R.id, 5))
|
||||
S.reagents.remove_reagent(R.id,5)
|
||||
queen.assign_reagent(R)
|
||||
user.visible_message("<span class='warning'>[user] injects [src]'s genome with [R.name], mutating it's DNA!</span>","<span class='warning'>You inject [src]'s genome with [R.name], mutating it's DNA!</span>")
|
||||
name = queen.name
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You don't have enough units of that chemical to modify the bee's DNA!</span>")
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/queen_bee/bought/New()
|
||||
..()
|
||||
queen = new(src)
|
||||
|
||||
/obj/item/queen_bee/Destroy()
|
||||
qdel(queen)
|
||||
return ..()
|
||||
@@ -82,18 +82,17 @@
|
||||
move_to_delay = 5
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/hunter/handle_automated_action()
|
||||
if(!stat)
|
||||
if(stance == HOSTILE_STANCE_IDLE)
|
||||
//1% chance to skitter madly away
|
||||
if(!busy && prob(1))
|
||||
/*var/list/move_targets = list()
|
||||
for(var/turf/T in orange(20, src))
|
||||
move_targets.Add(T)*/
|
||||
stop_automated_movement = 1
|
||||
Goto(pick(orange(20, src)), move_to_delay)
|
||||
spawn(50)
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
if(!..()) //AIStatus is off
|
||||
return
|
||||
if(AIStatus == AI_IDLE)
|
||||
//1% chance to skitter madly away
|
||||
if(!busy && prob(1))
|
||||
stop_automated_movement = 1
|
||||
Goto(pick(orange(20, src)), move_to_delay)
|
||||
spawn(50)
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/GiveUp(var/C)
|
||||
spawn(100)
|
||||
@@ -104,36 +103,31 @@
|
||||
stop_automated_movement = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/handle_automated_action()
|
||||
if(!stat && !ckey)
|
||||
if(stance == HOSTILE_STANCE_IDLE)
|
||||
var/list/can_see = view(src, 10)
|
||||
//30% chance to stop wandering and do something
|
||||
if(!busy && prob(30))
|
||||
//first, check for potential food nearby to cocoon
|
||||
for(var/mob/living/C in can_see)
|
||||
if(C.stat && !istype(C,/mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
cocoon_target = C
|
||||
busy = MOVING_TO_TARGET
|
||||
Goto(C, move_to_delay)
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(C)
|
||||
return
|
||||
|
||||
//second, spin a sticky spiderweb on this tile
|
||||
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
|
||||
if(!W)
|
||||
Web()
|
||||
if(..())
|
||||
var/list/can_see = view(src, 10)
|
||||
if(!busy && prob(30)) //30% chance to stop wandering and do something
|
||||
//first, check for potential food nearby to cocoon
|
||||
for(var/mob/living/C in can_see)
|
||||
if(C.stat && !istype(C,/mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
cocoon_target = C
|
||||
busy = MOVING_TO_TARGET
|
||||
Goto(C, move_to_delay)
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(C)
|
||||
return
|
||||
//second, spin a sticky spiderweb on this tile
|
||||
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
|
||||
if(!W)
|
||||
Web()
|
||||
else
|
||||
//third, lay an egg cluster there
|
||||
if(fed)
|
||||
LayEggs()
|
||||
else
|
||||
//third, lay an egg cluster there
|
||||
if(fed)
|
||||
LayEggs()
|
||||
else
|
||||
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
|
||||
for(var/obj/O in can_see)
|
||||
|
||||
if(O.anchored)
|
||||
continue
|
||||
|
||||
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
|
||||
for(var/obj/O in can_see)
|
||||
if(O.anchored)
|
||||
continue
|
||||
if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
|
||||
cocoon_target = O
|
||||
busy = MOVING_TO_TARGET
|
||||
@@ -142,13 +136,13 @@
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(O)
|
||||
|
||||
else if(busy == MOVING_TO_TARGET && cocoon_target)
|
||||
if(get_dist(src, cocoon_target) <= 1)
|
||||
Wrap()
|
||||
else if(busy == MOVING_TO_TARGET && cocoon_target)
|
||||
if(get_dist(src, cocoon_target) <= 1)
|
||||
Wrap()
|
||||
|
||||
else
|
||||
busy = 0
|
||||
stop_automated_movement = 0
|
||||
else
|
||||
busy = 0
|
||||
stop_automated_movement = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/verb/Web()
|
||||
set name = "Lay Web"
|
||||
@@ -254,4 +248,4 @@
|
||||
#undef SPINNING_WEB
|
||||
#undef LAYING_EGGS
|
||||
#undef MOVING_TO_TARGET
|
||||
#undef SPINNING_COCOON
|
||||
#undef SPINNING_COCOON
|
||||
|
||||
@@ -101,9 +101,8 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
if(prob(2))//Might be a bit low, will mess with it likely
|
||||
warpbots()
|
||||
warpbots()
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
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
|
||||
stop_automated_movement_when_pulled = 0
|
||||
environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
|
||||
var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior
|
||||
var/atom/target
|
||||
var/ranged = 0
|
||||
var/rapid = 0
|
||||
@@ -30,39 +29,35 @@
|
||||
var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
|
||||
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
|
||||
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_SLEEP (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
|
||||
/mob/living/simple_animal/hostile/Life()
|
||||
. = ..()
|
||||
if(!.)
|
||||
walk(src, 0)
|
||||
return 0
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
|
||||
/mob/living/simple_animal/hostile/process_ai()
|
||||
..()
|
||||
if(!AICanContinue())
|
||||
return 0
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
MoveToTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/handle_automated_action()
|
||||
if(AIStatus == AI_OFF)
|
||||
return 0
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
var/list/possible_targets = ListTargets() //we look around for potential targets and make it a list for later use.
|
||||
if(environment_smash)
|
||||
EscapeConfinement()
|
||||
|
||||
if(AICanContinue(possible_targets))
|
||||
DestroySurroundings()
|
||||
if(!MoveToTarget(possible_targets)) //if we lose our target
|
||||
if(AIShouldSleep(possible_targets)) // we try to acquire a new one
|
||||
AIStatus = AI_IDLE // otherwise we go idle
|
||||
return 1
|
||||
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
|
||||
@@ -82,19 +77,18 @@
|
||||
L += Objects
|
||||
return L
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()//Step 2, filter down possible targets to things we actually care about
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
|
||||
var/list/Targets = list()
|
||||
var/Target
|
||||
for(var/atom/A in ListTargets())
|
||||
if(!HasTargetsList)
|
||||
possible_targets = ListTargets()
|
||||
for(var/atom/A in possible_targets)
|
||||
if(Found(A))//Just in case people want to override targetting
|
||||
var/list/FoundTarget = list()
|
||||
FoundTarget += A
|
||||
Targets = FoundTarget
|
||||
Targets = list(A)
|
||||
break
|
||||
if(CanAttack(A))//Can we attack it?
|
||||
Targets += A
|
||||
continue
|
||||
Target = PickTarget(Targets)
|
||||
var/Target = PickTarget(Targets)
|
||||
GiveTarget(Target)
|
||||
return Target //We now have a target
|
||||
|
||||
@@ -102,14 +96,14 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/PickTarget(var/list/Targets)//Step 3, pick amongst the possible, attackable targets
|
||||
if(!Targets.len)//We didnt find nothin!
|
||||
return
|
||||
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
|
||||
|
||||
@@ -148,23 +142,21 @@
|
||||
return 0
|
||||
return 1
|
||||
if(isobj(the_target))
|
||||
if(the_target.type in wanted_objects)
|
||||
if(is_type_in_list(the_target, wanted_objects))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our selected target
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()//Step 5, handle movement between us and our target
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget(var/list/possible_targets)//Step 5, handle movement between us and our target
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return
|
||||
if(target in ListTargets())
|
||||
return 0
|
||||
if(target in possible_targets)
|
||||
var/target_distance = get_dist(src,target)
|
||||
if(ranged)//We ranged? Shoot at em
|
||||
if(target_distance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
|
||||
@@ -178,17 +170,18 @@
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack
|
||||
AttackingTarget()
|
||||
return
|
||||
return 1
|
||||
if(environment_smash)
|
||||
if(target.loc != null && get_dist(src, target.loc) <= vision_range)//We can't see our target, but he's in our vision range still
|
||||
if(environment_smash >= 2)//If we're capable of smashing through walls, forget about vision completely after finding our target
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
FindHidden()
|
||||
return
|
||||
return 1
|
||||
else
|
||||
if(FindHidden())
|
||||
return
|
||||
return 1
|
||||
LostTarget()
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay, var/minimum_distance)
|
||||
walk_to(src, target, minimum_distance, delay)
|
||||
@@ -199,27 +192,11 @@
|
||||
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
|
||||
search_objects = 0
|
||||
target = null
|
||||
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
|
||||
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()
|
||||
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return 0
|
||||
if(!(target in ListTargets()))
|
||||
LostTarget()
|
||||
return 0
|
||||
if(isturf(loc) && target.Adjacent(src))
|
||||
AttackingTarget()
|
||||
return 1
|
||||
if(AIStatus == AI_IDLE)
|
||||
AIStatus = AI_ON
|
||||
FindTarget()
|
||||
else if(target != null && prob(40))//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
|
||||
FindTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
target.attack_animal(src)
|
||||
@@ -232,13 +209,11 @@
|
||||
vision_range = idle_vision_range
|
||||
|
||||
/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()
|
||||
|
||||
@@ -340,28 +315,16 @@
|
||||
|
||||
|
||||
////// AI Status ///////
|
||||
/mob/living/simple_animal/hostile/proc/AICanContinue()
|
||||
/mob/living/simple_animal/hostile/proc/AICanContinue(var/list/possible_targets)
|
||||
switch(AIStatus)
|
||||
if(AI_ON)
|
||||
. = 1
|
||||
if(AI_SLEEP)
|
||||
if(AIShouldWake())
|
||||
if(AI_IDLE)
|
||||
if(FindTarget(possible_targets, 1))
|
||||
. = 1
|
||||
AIStatus = AI_ON //Wake up for more than one Life() cycle.
|
||||
else
|
||||
. = 0
|
||||
if(AI_OFF)
|
||||
. = 0
|
||||
|
||||
|
||||
//Returns 1 if the AI should wake up
|
||||
//Returns 0 if the AI should remain asleep
|
||||
/mob/living/simple_animal/hostile/proc/AIShouldWake()
|
||||
. = 0
|
||||
if(FindTarget())
|
||||
. = 1
|
||||
|
||||
|
||||
//Convenience
|
||||
/mob/living/simple_animal/hostile/proc/AIShouldSleep()
|
||||
. = !(AIShouldWake())
|
||||
/mob/living/simple_animal/hostile/proc/AIShouldSleep(var/list/possible_targets)
|
||||
return !FindTarget(possible_targets, 1)
|
||||
|
||||
@@ -32,13 +32,7 @@
|
||||
var/stalk_tick_delay = 3
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
|
||||
/mob/living/simple_animal/hostile/panther/ListTargets()
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/carbon/human/H in view(src, 10))
|
||||
targets += H
|
||||
return targets
|
||||
|
||||
/mob/living/simple_animal/hostile/panther/FindTarget()
|
||||
/mob/living/simple_animal/hostile/panther/FindTarget(var/list/possible_targets)
|
||||
. = ..()
|
||||
if(.)
|
||||
emote("nashes at [.]")
|
||||
@@ -51,14 +45,6 @@
|
||||
L.Weaken(3)
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/panther/AttackTarget()
|
||||
..()
|
||||
if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target))
|
||||
stalk_tick_delay -= 1
|
||||
if(stalk_tick_delay <= 0)
|
||||
src.loc = get_step_towards(src, target)
|
||||
stalk_tick_delay = 3
|
||||
|
||||
//*******//
|
||||
// Snake //
|
||||
//*******//
|
||||
@@ -90,12 +76,6 @@
|
||||
var/stalk_tick_delay = 3
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
|
||||
/mob/living/simple_animal/hostile/snake/ListTargets()
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/carbon/human/H in view(src, 10))
|
||||
targets += H
|
||||
return targets
|
||||
|
||||
/mob/living/simple_animal/hostile/snake/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -106,11 +86,3 @@
|
||||
var/mob/living/L = .
|
||||
if(istype(L))
|
||||
L.apply_damage(rand(3,12), TOX)
|
||||
|
||||
/mob/living/simple_animal/hostile/snake/AttackTarget()
|
||||
..()
|
||||
if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target))
|
||||
stalk_tick_delay -= 1
|
||||
if(stalk_tick_delay <= 0)
|
||||
src.loc = get_step_towards(src, target)
|
||||
stalk_tick_delay = 3
|
||||
|
||||
@@ -84,16 +84,12 @@
|
||||
temperature = 50
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(var/new_target)
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
if(..()) //we have a target
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.bodytemperature > 261)
|
||||
L.bodytemperature = 261
|
||||
visible_message("<span class='danger'>The [src.name]'s stare chills [L.name] to the bone!</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity)
|
||||
switch(severity)
|
||||
@@ -156,17 +152,12 @@
|
||||
if(target != null)
|
||||
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
|
||||
return
|
||||
if(isliving(target))
|
||||
else if(isliving(target))
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
visible_message("<span class='danger'>The [src.name] tries to flee from [target.name]!</span>")
|
||||
retreat_distance = 10
|
||||
minimum_distance = 10
|
||||
Burrow()
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/AttackingTarget()
|
||||
if(istype(target, /obj/item/weapon/ore))
|
||||
@@ -387,7 +378,7 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/proc/handle_preattack()
|
||||
if(ranged_cooldown <= 2 && !pre_attack)
|
||||
pre_attack++
|
||||
if(!pre_attack || stat || stance == HOSTILE_STANCE_IDLE)
|
||||
if(!pre_attack || stat || AIStatus == AI_IDLE)
|
||||
return
|
||||
icon_state = "Goliath_preattack"
|
||||
|
||||
@@ -511,4 +502,4 @@
|
||||
to_chat(user, "<span class='warning'>You can't add armour onto the mech while someone is inside!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
return
|
||||
return
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/mob/living/simple_animal/hostile/poison/bees
|
||||
name = "space bee swarm"
|
||||
desc = ""
|
||||
icon_state = "bee_1"
|
||||
icon_living = "bee"
|
||||
speak_emote = list("buzzes")
|
||||
emote_hear = list("buzzes")
|
||||
turns_per_move = 0
|
||||
melee_damage_lower = 1
|
||||
melee_damage_upper = 1
|
||||
attacktext = "stings"
|
||||
response_help = "shoos"
|
||||
response_disarm = "swats away"
|
||||
response_harm = "squashes"
|
||||
maxHealth = 10
|
||||
health = 10
|
||||
faction = list("hostile")
|
||||
move_to_delay = 0
|
||||
environment_smash = 0
|
||||
mouse_opacity = 2
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
flying = 1
|
||||
|
||||
//Spaceborn beings don't get hurt by space
|
||||
atmos_requirements = list("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
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Process_Spacemove(var/check_drift = 0)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/New()
|
||||
..()
|
||||
var/bees = rand(2, 10)
|
||||
for(var/i, i <= bees, i++)
|
||||
var/N = rand(1, 4)
|
||||
var/image/I = image(icon='icons/mob/animal.dmi',icon_state="bee_[N]", pixel_x = rand(-8, 8), pixel_y = rand(-8, 8))
|
||||
overlays += I
|
||||
|
||||
//update_bees()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/death()
|
||||
..()
|
||||
ghostize()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/*/mob/living/simple_animal/hostile/poison/bees/Life()
|
||||
..()
|
||||
|
||||
update_bees()
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/proc/update_bees()
|
||||
while(overlays.len != health-1) //how many bees do we have in the swarm?
|
||||
var/N = rand(1, 4)
|
||||
var/image/I = image(icon='icons/mob/animal.dmi',icon_state="bee_[N]", pixel_x = rand(-8, 8), pixel_y = rand(-8, 8))
|
||||
if(overlays.len < health-1)
|
||||
overlays.Add(I)
|
||||
if(overlays.len > health-1)
|
||||
overlays.Remove(I) //REMOVING A RANDOM IMAGE FROM AN OVERLAYS LIST THAT DOES NOT CONTAIN THAT IMAGE
|
||||
poison_per_bite = health * 0.5 //each bee is half a toxin reagent //WHAT A GREAT FUCKING PLAN
|
||||
if(health > 1)
|
||||
desc = "A buzzy swarm of [health] poisonous space bees, renowned for their aggressiveness"
|
||||
else
|
||||
desc = "Although now lonely, this single space bee is still poisonous and very angry at you."*///NOVEL IDEA: INFINITE LOOP IMPLEMENTATION
|
||||
@@ -5,19 +5,16 @@
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(!L.stat)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return L
|
||||
else
|
||||
enemies -= L
|
||||
else if(istype(A, /obj/mecha))
|
||||
var/obj/mecha/M = A
|
||||
if(M.occupant)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return A
|
||||
else if(istype(A, /obj/spacepod))
|
||||
var/obj/spacepod/M = A
|
||||
if(M.occupant || M.occupant2)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return A
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/ListTargets()
|
||||
@@ -72,4 +69,4 @@
|
||||
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/closet) || istype(obstacle, /obj/structure/table))
|
||||
obstacle.attack_animal(src)
|
||||
obstacle.attack_animal(src)
|
||||
|
||||
@@ -70,9 +70,9 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/process_ai()
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/statue/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
if(target) // If we have a target and we're AI controlled
|
||||
var/mob/watching = can_be_seen()
|
||||
// If they're not our target
|
||||
@@ -211,11 +211,10 @@
|
||||
name = "Toggle Nightvision \[OFF\]"
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/sentience_act()
|
||||
faction -= "neutral"
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/restrained()
|
||||
. = ..()
|
||||
if(can_be_seen(loc))
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -831,7 +831,8 @@
|
||||
|
||||
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
|
||||
/obj/item/weapon/reagent_containers/food/pill = list(),
|
||||
/obj/item/weapon/reagent_containers/food = list()
|
||||
/obj/item/weapon/reagent_containers/food = list(),
|
||||
/obj/item/weapon/reagent_containers/honeycomb = list()
|
||||
)
|
||||
|
||||
var/list/blend_tags = list (
|
||||
|
||||
@@ -116,20 +116,17 @@ datum/reagent/vhfcs/on_mob_life(var/mob/living/M as mob)
|
||||
id = "honey"
|
||||
description = "A sweet substance produced by bees through partial digestion. Bee barf."
|
||||
reagent_state = LIQUID
|
||||
color = "#CFCF1F"
|
||||
color = "#d3a308"
|
||||
|
||||
datum/reagent/honey/on_mob_life(var/mob/living/M as mob)
|
||||
if(!M) M = holder.my_atom
|
||||
if(!M)
|
||||
M = holder.my_atom
|
||||
M.reagents.add_reagent("sugar", 0.4)
|
||||
if(prob(20))
|
||||
M.heal_organ_damage(3,1)
|
||||
..()
|
||||
return
|
||||
|
||||
datum/reagent/honey/reaction_turf(var/turf/T, var/volume)
|
||||
src = null
|
||||
if(volume >= 5)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/honeycomb(T)
|
||||
return
|
||||
|
||||
/datum/reagent/chocolate
|
||||
name = "Chocolate"
|
||||
id = "chocolate"
|
||||
@@ -605,4 +602,4 @@ datum/reagent/pepperoni/reaction_mob(var/mob/living/M, var/method=TOUCH, var/vol
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.heart_attack)
|
||||
H.heart_attack = 1
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -386,4 +386,22 @@ datum/reagent/triplepiss
|
||||
id = "triplepiss"
|
||||
description = "Ewwwwwwwww."
|
||||
reagent_state = LIQUID
|
||||
color = "#857400"
|
||||
color = "#857400"
|
||||
|
||||
/datum/reagent/royal_bee_jelly
|
||||
name = "royal bee jelly"
|
||||
id = "royal_bee_jelly"
|
||||
description = "Royal Bee Jelly, if injected into a Queen Space Bee said bee will split into two bees."
|
||||
color = "#00ff80"
|
||||
|
||||
/datum/reagent/royal_bee_jelly/on_mob_life(mob/living/M)
|
||||
if(prob(2))
|
||||
M.say(pick("Bzzz...","BZZ BZZ","Bzzzzzzzzzzz..."))
|
||||
..()
|
||||
|
||||
/datum/chemical_reaction/royal_bee_jelly
|
||||
name = "royal bee jelly"
|
||||
id = "royal_bee_jelly"
|
||||
result = "royal_bee_jelly"
|
||||
required_reagents = list("mutagen" = 10, "honey" = 40)
|
||||
result_amount = 5
|
||||
@@ -33,7 +33,6 @@
|
||||
/obj/machinery/iv_drip,
|
||||
/obj/machinery/computer/pandemic,
|
||||
/obj/machinery/disposal,
|
||||
/obj/machinery/apiary,
|
||||
/mob/living/simple_animal/cow,
|
||||
/mob/living/simple_animal/hostile/retaliate/goat,
|
||||
/obj/machinery/sleeper,
|
||||
|
||||
Reference in New Issue
Block a user