diff --git a/code/game/objects/livestock.dm b/code/game/objects/livestock.dm index 0aa573d0789..01c18c954aa 100644 --- a/code/game/objects/livestock.dm +++ b/code/game/objects/livestock.dm @@ -16,6 +16,7 @@ var/frustration = 0 //How long it's gone without reaching it's target. var/patience = 35 //The maximum time it'll chase a target. var/mob/living/carbon/target //It's combat target. + var/list/mob/living/carbon/flee_from = new/list() var/list/path_target = new/list() //The path to the combat target. var/turf/trg_idle //It's idle target, the one it's following but not attacking. @@ -25,6 +26,7 @@ var/maxhealth = 25 var/health = 25 var/aggressive = 0 + var/cowardly = 0 //PLEASE do not mix with agressive, I have no idea what its behaviour will be then flags = 258.0 var/strength = 10 //The damage done by the creature if it attacks something. var/cycle_pause = 5 @@ -230,62 +232,83 @@ set background = 1 if (!alive) //If it isn't alive, it shouldn't be doing anything. return - if (!target) - if (path_target.len) path_target = new/list() //No target but there's still path data? reset it. - var/last_health = INFINITY //Set as high as possible as an initial value. - var/view = view_range-2 //Actual sight slightly lower then it's total sight. - for (var/mob/living/carbon/C in range(view,src.loc)) //Checks all carbon creatures in range. - if (!aggressive) //Is this animal angry? If not, what the fuck are you doing? - break - if (C.stat == 2 || !can_see(src,C,view_range) || (!can_see(src,C,(view_range / 2)) && C.invisibility >= 1)) - continue - if(C:stunned || C:paralysis || C:weakened) - target = C - break - if(C:health < last_health) //Selects the target but does NOT break the FOR loop. - last_health = C:health // As such, it'll keep going until it finds the one with the - target = C // lowest health. - if(target) //Does it have a target NOW? - if (aggressive) //Double checking if it is aggressive or not. - set_attack() - else if(state != 2) //If it doesn't have a target and it isn't idling already, idle. - set_idle() - idle() - else if(target) //It already has a target? YAY! - var/turf/distance = get_dist(src, target) - if (src.aggressive) //I probably don't need this check, but just in case. - set_attack() - else - set_idle() - idle() - if(can_see(src,target,view_range )) //Can I see it? - if(distance <= 1) //Am I close enough to attack it? - for(var/mob/O in viewers(world.view,src)) - O.show_message("\red [src.target] has been attacked by [src.name]!", 1, "\red You hear someone fall.", 2) - target:bruteloss += strength - special_attack() - src.loc = target.loc - set_null() - step_towards(src,get_step_towards2(src , target)) // Move towards the target. - else - if( !path_target.len ) //Don't have a path yet but do have a target? - path_attack(target) //Find a path! - if(!path_target.len) //Still no path? - set_null() //Fuck this shit. - if( path_target.len ) //Ok, I DO have a path - var/turf/next = path_target[1] //Select the next square to move to. - if(next in range(1,src)) //Is it next to it? - path_attack(target) //Re-find path. - if(!path_target.len) //If can't path to the target, it gets really angry. - src.frustration += 5 + if (cowardly) //cowardly = 1 stuff + if (!flee_from.len) //checking for threats + var/view = view_range-2 //Actual sight slightly lower then it's total sight. + for (var/mob/living/carbon/C in range(view,src.loc)) + if ((get_dir(src,C) & dir) || (C.m_intent=="run" && C.moved_recently)) //if it can see or hear anyone nearby, start fleeing + flee_from += C + if (flee_from.len) //ohgodrun + var/viable_dirs = 0 + for(var/mob/living/carbon/C in flee_from) + if(!(C in view(src,view_range))) //first, see if someone who it has been fleeing from is still there. if not, delete that guy from the list + flee_from -= C else - next = path_target[1] //If it CAN path to the target, select the next move point - path_target -= next - step_towards(src,next) //And move in that direction. - if (get_dist(src, src.target) >= distance) src.frustration++ //If it hasn't reached the target yet, get a little angry. - else src.frustration-- //It reached the target! Get less angry. - if(frustration >= patience) set_null() //If too angry? Fuck this shit. - if(target) + viable_dirs |= get_dir(src,C) + viable_dirs = 15 - viable_dirs //so it runs AWAY from those directions, not TOWARDS them + if(viable_dirs) //if there is somewhere to run, DO IT DAMNIT + var/list/turfs_to_move_to = new/list() + for(var/turf/T in orange(src,1)) + if((get_dir(src,T) & viable_dirs) == get_dir(src,T)) + turfs_to_move_to += T + src.Move(pick(turfs_to_move_to)) + if (aggressive) //aggressive = 1 stuff + if (!target) + if (path_target.len) path_target = new/list() //No target but there's still path data? reset it. + var/last_health = INFINITY //Set as high as possible as an initial value. + var/view = view_range-2 //Actual sight slightly lower then it's total sight. + for (var/mob/living/carbon/C in range(view,src.loc)) //Checks all carbon creatures in range. + if (!aggressive) //Is this animal angry? If not, what the fuck are you doing? + break + if (C.stat == 2 || !can_see(src,C,view_range) || (!can_see(src,C,(view_range / 2)) && C.invisibility >= 1)) + continue + if(C:stunned || C:paralysis || C:weakened) + target = C + break + if(C:health < last_health) //Selects the target but does NOT break the FOR loop. + last_health = C:health // As such, it'll keep going until it finds the one with the + target = C // lowest health. + if(target) //Does it have a target NOW? + if (aggressive) //Double checking if it is aggressive or not. + set_attack() + else if(state != 2) //If it doesn't have a target and it isn't idling already, idle. + set_idle() + idle() + else if(target) //It already has a target? YAY! + var/turf/distance = get_dist(src, target) + if (src.aggressive) //I probably don't need this check, but just in case. + set_attack() + else + set_idle() + idle() + if(can_see(src,target,view_range )) //Can I see it? + if(distance <= 1) //Am I close enough to attack it? + for(var/mob/O in viewers(world.view,src)) + O.show_message("\red [src.target] has been attacked by [src.name]!", 1, "\red You hear someone fall.", 2) + target:bruteloss += strength + special_attack() + src.loc = target.loc + set_null() + step_towards(src,get_step_towards2(src , target)) // Move towards the target. + else + if( !path_target.len ) //Don't have a path yet but do have a target? + path_attack(target) //Find a path! + if(!path_target.len) //Still no path? + set_null() //Fuck this shit. + if( path_target.len ) //Ok, I DO have a path + var/turf/next = path_target[1] //Select the next square to move to. + if(next in range(1,src)) //Is it next to it? + path_attack(target) //Re-find path. + if(!path_target.len) //If can't path to the target, it gets really angry. + src.frustration += 5 + else + next = path_target[1] //If it CAN path to the target, select the next move point + path_target -= next + step_towards(src,next) //And move in that direction. + if (get_dist(src, src.target) >= distance) src.frustration++ //If it hasn't reached the target yet, get a little angry. + else src.frustration-- //It reached the target! Get less angry. + if(frustration >= patience) set_null() //If too angry? Fuck this shit. + if(target || flee_from.len) spawn(cycle_pause / 3) src.process() else @@ -413,6 +436,18 @@ stun_chance = 40 intelligence = "Assistant" +/obj/livestock/lizard + name = "Lizard" + desc = "A cute tiny lizard." + icon_state = "lizard" + cowardly = 1 + health = 10 + maxhealth = 10 + strength = 2 + cycle_pause = 10 + patience = 50 + view_range = 7 + /* Commented out because of filthy xeno-lovers. /obj/livestock/cow name = "Pigmy Cow" diff --git a/icons/mob/livestock.dmi b/icons/mob/livestock.dmi index cedaeaf5066..d833643d5c1 100644 Binary files a/icons/mob/livestock.dmi and b/icons/mob/livestock.dmi differ