// AI (i.e. game AI, not the AI player) controlled bots /obj/machinery/bot icon = 'aibots.dmi' layer = MOB_LAYER var/obj/item/weapon/card/id/botcard // the ID card that the bot "holds" var/on = 1 var/health = 0 //do not forget to set health for your bot! var/maxhealth = 0 var/fire_dam_coeff = 1.0 var/brute_dam_coeff = 1.0 var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots /obj/machinery/bot/proc/turn_on() if (stat) return 0 src.on = 1 return 1 /obj/machinery/bot/proc/turn_off() src.on = 0 /obj/machinery/bot/proc/explode() del(src) /obj/machinery/bot/proc/healthcheck() if (src.health <= 0) src.explode() /obj/machinery/bot/proc/Emag(mob/user as mob) if(!emagged) emagged = 1 /obj/machinery/bot/examine() set src in view() ..() if (src.health < maxhealth) if (src.health > maxhealth/3) usr << text("\red [src]'s parts look loose.") else usr << text("\red [src]'s parts look very loose!") return /obj/machinery/bot/attack_alien(var/mob/living/carbon/alien/user as mob) /* Well, aliums dislike machines and do not want to caress them. if (user.a_intent == "help") for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) O.show_message(text("\blue [user] caresses [src.name] with its scythe like arm."), 1) else */ src.health -= rand(15,30)*brute_dam_coeff src.visible_message("\red [user] has slashed [src]!") playsound(src.loc, 'slice.ogg', 25, 1, -1) if(prob(10)) new /obj/effect/decal/cleanable/oil(src.loc) healthcheck() /obj/machinery/bot/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/screwdriver)) if (src.health < maxhealth) src.health = min(maxhealth, src.health+25) user.visible_message( "\red [user] repairs [src]!", "\blue You repair [src]!" ) else user << "\blue [src] does not need a repair!" else if (istype(W, /obj/item/weapon/card/emag) && !emagged) Emag(user) else switch(W.damtype) if("fire") src.health -= W.force * fire_dam_coeff if("brute") src.health -= W.force * brute_dam_coeff ..() healthcheck() /obj/machinery/bot/bullet_act(var/obj/item/projectile/Proj) health -= Proj.damage ..() healthcheck() /obj/machinery/bot/meteorhit() src.explode() return /obj/machinery/bot/blob_act() src.health -= rand(20,40)*fire_dam_coeff healthcheck() return /obj/machinery/bot/ex_act(severity) switch(severity) if(1.0) src.explode() return if(2.0) src.health -= rand(5,10)*fire_dam_coeff src.health -= rand(10,20)*brute_dam_coeff healthcheck() return if(3.0) if (prob(50)) src.health -= rand(1,5)*fire_dam_coeff src.health -= rand(1,5)*brute_dam_coeff healthcheck() return return /obj/machinery/bot/emp_act(severity) var/was_on = on stat |= EMPED var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc ) pulse2.icon = 'effects.dmi' pulse2.icon_state = "empdisable" pulse2.name = "emp sparks" pulse2.anchored = 1 pulse2.dir = pick(cardinal) spawn(10) del(pulse2) if (on) turn_off() spawn(severity*300) stat &= ~EMPED if (was_on) turn_on() /obj/machinery/bot/attack_ai(mob/user as mob) if (src.on) turn_off() else turn_on() /******************************************************************/ // Navigation procs // Used for A-star pathfinding // Returns the surrounding cardinal turfs with open links // Including through doors openable with the ID /turf/proc/CardinalTurfsWithAccess(var/obj/item/weapon/card/id/ID) var/L[] = new() // for(var/turf/simulated/t in oview(src,1)) for(var/d in cardinal) var/turf/simulated/T = get_step(src, d) if(istype(T) && !T.density) if(!LinkBlockedWithAccess(src, T, ID)) L.Add(T) return L // Returns true if a link between A and B is blocked // Movement through doors allowed if ID has access /proc/LinkBlockedWithAccess(turf/A, turf/B, obj/item/weapon/card/id/ID) if(A == null || B == null) return 1 var/adir = get_dir(A,B) var/rdir = get_dir(B,A) if((adir & (NORTH|SOUTH)) && (adir & (EAST|WEST))) // diagonal var/iStep = get_step(A,adir&(NORTH|SOUTH)) if(!LinkBlockedWithAccess(A,iStep, ID) && !LinkBlockedWithAccess(iStep,B,ID)) return 0 var/pStep = get_step(A,adir&(EAST|WEST)) if(!LinkBlockedWithAccess(A,pStep,ID) && !LinkBlockedWithAccess(pStep,B,ID)) return 0 return 1 if(DirBlockedWithAccess(A,adir, ID)) return 1 if(DirBlockedWithAccess(B,rdir, ID)) return 1 for(var/obj/O in B) if(O.density && !istype(O, /obj/machinery/door) && !(O.flags & ON_BORDER)) return 1 return 0 // Returns true if direction is blocked from loc // Checks doors against access with given ID /proc/DirBlockedWithAccess(turf/loc,var/dir,var/obj/item/weapon/card/id/ID) for(var/obj/structure/window/D in loc) if(!D.density) continue if(D.dir == SOUTHWEST) return 1 if(D.dir == dir) return 1 for(var/obj/machinery/door/D in loc) if(!D.density) continue if(istype(D, /obj/machinery/door/window)) if( dir & D.dir ) return !D.check_access(ID) //if((dir & SOUTH) && (D.dir & (EAST|WEST))) return !D.check_access(ID) //if((dir & EAST ) && (D.dir & (NORTH|SOUTH))) return !D.check_access(ID) else return !D.check_access(ID) // it's a real, air blocking door return 0