This commit is contained in:
shadowlord13
2008-06-07 02:35:42 +00:00
parent af58259444
commit 1ccf694a72
68 changed files with 3373 additions and 1901 deletions
+699
View File
@@ -0,0 +1,699 @@
//This is a drone controllable by the AI.
//Todo:
/*
Add throw button, intent buttons to drone GUI, button for releasing pull
Drone needs meteor damage, explosion damage, and laser damage
Drone pull/grab should only work if gripper is empty
Take-off dialog for taking things off others should work, except humans controlling a drone should have a high chance of failure and harming the person instead.
should lose drone control upon going unconscious (it's already lost upon death), and also if the user is pulled/moves away from the control station
re-test: can drone push canisters now?
test: hit monkey as drone, as person
test: hit drone as monkey
more testing: drone vs drone fight, and another human vs drone fight.
Try out the grip/heal/disarm/harm intents from drone to human and from human to drone. (Once the intent buttons are added for drones.)
Held jetpack with flight system turned on doesn't work for drone - appears to be due to lack of internal air
Implement AI-controlled drone precision attacks:
screwdriver to heart? protected by armor (may break screwdriver tool permanently), reduced damage from other suits.
lit welder to eyes? protected by helmets?
crowbar to whack items out of opponents' hands, when there's anything in them, and send them flying. If not, does damage normally to the normal area.
wrench targets kneecaps for bonus damage, knocking down, etc.
wirecutters don't have a precision attack or even work well for attacking at all (one would think), and are likely to break if used.
If drone gets ahold of a laser gun or loaded revolver, an AI controller will be able to precision aim it as well.
Note to be very clear: If a human is controlling the drone, they do not get any of those precision bonus attacks. Those are only applied if the AI is controlling the drone.
*/
/mob/drone
name = "Drone"
icon = 'drone.dmi'
icon_state = "generic"
gender = MALE
flags = 320.0 //64: fireable by mass driver, 256: fprint
var/mob/controlledBy = null
var/list/savedDroneIcons = null
var/obj/screen/screenIcons = null
var/obj/screen/gripperIcon
var/obj/screen/wirecuttersIcon
var/obj/screen/crowbarIcon
var/obj/screen/screwdriverIcon
var/obj/screen/welderIcon
var/obj/screen/wrenchIcon
var/obj/screen/aiIcon
var/obj/screen/selector
var/obj/screen/dropButton
var/obj/screen/throwButton
var/obj/item/weapon/grippers
var/obj/item/weapon/wirecutters
var/obj/item/weapon/crowbar
var/obj/item/weapon/screwdriver
var/obj/item/weapon/welder
var/image/welderUnlit = null
var/image/welderLit = null
var/obj/item/weapon/wrench
var/obj/item/weapon/aiInterface
var/image/grippedItemImage = null
var/list/tools
var/obj/item/weapon/selectedTool = null
New()
spawn(10)
while (!config)
sleep(10)
if (!config.enable_drones)
del(src)
src.gripperIcon = new /obj/screen( null )
src.wirecuttersIcon = new /obj/screen( null )
src.crowbarIcon = new /obj/screen( null )
src.screwdriverIcon = new /obj/screen( null )
src.welderIcon = new /obj/screen( null )
src.wrenchIcon = new /obj/screen( null )
src.aiIcon = new /obj/screen( null )
src.selector = new /obj/screen( null )
src.dropButton = new /obj/screen( null )
src.throwButton = new /obj/screen( null )
var/inventorySlotImageName = "inv"
src.gripperIcon.icon_state = inventorySlotImageName
src.wirecuttersIcon.icon_state = inventorySlotImageName
src.crowbarIcon.icon_state = inventorySlotImageName
src.screwdriverIcon.icon_state = inventorySlotImageName
src.welderIcon.icon_state = inventorySlotImageName
src.wrenchIcon.icon_state = inventorySlotImageName
src.aiIcon.icon_state = inventorySlotImageName
src.selector.icon_state = "selector"
src.dropButton.icon_state = "act_drop"
src.throwButton.icon_state = "act_throw"
src.gripperIcon.name = "Gripper"
src.wirecuttersIcon.name = "Wirecutters"
src.crowbarIcon.name = "Crowbar"
src.screwdriverIcon.name = "Screwdriver"
src.welderIcon.name = "Welder"
src.wrenchIcon.name = "Wrench"
src.aiIcon.name = "AI"
src.selector.name = "Selected Tool"
src.dropButton.name = "drop"
src.throwButton.name = "throw"
src.gripperIcon.screen_loc = "1,1"
src.wirecuttersIcon.screen_loc = "2,1"
src.crowbarIcon.screen_loc = "3,1"
src.screwdriverIcon.screen_loc = "4,1"
src.welderIcon.screen_loc = "5,1"
src.wrenchIcon.screen_loc = "6,1"
src.wrenchIcon.pixel_x = 10
src.aiIcon.screen_loc = "7,1"
src.selector.screen_loc = "1,1"
src.dropButton.screen_loc = "8,1"
src.throwButton.screen_loc = "9,1"
src.grippers = new /obj/item/weapon/drone/grippers(src)
src.wirecutters = new /obj/item/weapon/wirecutters(src)
src.crowbar = new /obj/item/weapon/crowbar(src)
src.screwdriver = new /obj/item/weapon/screwdriver(src)
src.welder = new /obj/item/weapon/weldingtool(src)
src.wrench = new /obj/item/weapon/wrench(src)
src.aiInterface = new /obj/item/weapon/drone/aiInterface(src)
src.grippers.layer = FLOAT_LAYER
src.wirecutters.layer = FLOAT_LAYER
src.crowbar.layer = FLOAT_LAYER
src.screwdriver.layer = FLOAT_LAYER
src.welder.layer = FLOAT_LAYER
src.wrench.layer = FLOAT_LAYER
src.aiInterface.layer = FLOAT_LAYER
src.grippers.screen_loc = "1,1"
src.wirecutters.screen_loc = "2,1"
src.crowbar.screen_loc = "3,1"
src.screwdriver.screen_loc = "4,1"
src.welder.screen_loc = "5,1"
src.wrench.screen_loc = "6,1"
src.aiInterface.screen_loc = "7,1"
src.screenIcons = list(src.gripperIcon, src.wirecuttersIcon, src.crowbarIcon, src.screwdriverIcon, src.welderIcon, src.wrenchIcon, src.aiIcon, src.selector, src.dropButton, src.throwButton)
src.gripperIcon.overlays += src.grippers
src.wirecuttersIcon.overlays += src.wirecutters
src.crowbarIcon.overlays += src.crowbar
src.screwdriverIcon.overlays += src.screwdriver
src.welderLit = image('items.dmi', icon_state="welder1")
src.welderUnlit = image('items.dmi', icon_state="welder")
if (src.welder:welding)
src.welderIcon.overlays += src.welderLit
else
src.welderIcon.overlays += src.welderUnlit
src.wrenchIcon.overlays += src.wrench
src.aiIcon.overlays += src.aiInterface
src.tools = list(src.grippers, src.wirecutters, src.crowbar, src.screwdriver, src.welder, src.wrench, src.aiInterface)
src.contents += src.tools
src.selectTool(src.grippers)
src.l_hand = null
src.hand = 0
//src.grippedItemImage = null
Del()
src.drop_item()
src.releaseControl()
..()
proc/nameDrone(num)
var/list/droneIDs = list("Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda", "Mu", "Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi", "Chi", "Psi", "Omega")
var/counter = 1
while (num >= droneIDs.len)
num -= droneIDs.len
counter ++
name = "Maintenance Drone "+droneIDs[num+1]
if (counter>1)
name = name + " [num]"
proc/updateToolIcon(var/obj/item/weapon/W)
for (var/obj/screen/SI in src.screenIcons)
if (SI.screen_loc == W.screen_loc)
if (SI != src.dropButton && SI != src.selector)
if (W == src.welder)
SI.overlays -= src.welderUnlit
SI.overlays -= src.welderLit
if (W:welding)
src.icon_state = "welder-lit"
SI.overlays += src.welderLit
else
src.icon_state = "welder"
SI.overlays += src.welderUnlit
else if (W in src.tools)
SI.overlays -= W
spawn(0)
SI.overlays += W
else
var/mob/clientMob = src.client_mob()
var/client/client = clientMob.client
if (client!=null)
W.screen_loc = "1,1"
W.layer = 20
client.screen -= W
spawn(0)
client.screen += W
proc/pressIfDroneButton(var/obj/screen/S)
if (S.name=="drop")
if (src.l_hand!=null)
src.drop_item()
Topic(href, href_list)
..()
if (href_list["mach_close"])
var/t1 = text("window=[]", href_list["mach_close"])
src.machine = null
src.client_mob() << browse(null, t1)
return
equipped()
var/obj/retval
if (src.selectedTool!=null)
retval = src.selectedTool
else
retval = src.grippers
if (retval==src.grippers)
retval = src.l_hand
return retval
proc/grip(var/obj/item)
if (item!=src.l_hand)
src.ungrip()
src.l_hand = item
src.l_hand.loc = src
src.l_hand = item
item.layer = 20
item.screen_loc = "1,1"
var/mob/clientMob = src.client_mob()
var/client/client = clientMob.client
if (client!=null)
client.screen -= item
client.screen += item
//src.gripperIcon.overlays -= src.grippers
//src.grippedItemImage = image(item.icon, item.icon_state)
//src.gripperIcon.overlays += src.grippedItemImage
proc/ungrip()
if (src.l_hand!=null)
if (src.l_hand.loc==src)
src.l_hand.loc = src.loc
if (src.l_hand.layer == 20)
src.l_hand.layer = initial(src.l_hand.layer)
if (src.l_hand.screen_loc == "1,1")
src.l_hand.screen_loc = initial(src.l_hand.screen_loc)
var/mob/clientMob = src.client_mob()
var/client/client = clientMob.client
if (client!=null)
client.screen -= src.l_hand
src.l_hand = null
//if (src.grippedItemImage!=null)
// src.gripperIcon.overlays -= src.grippedItemImage
// src.grippedItemImage = null
//src.gripperIcon.overlays -= src.grippers
//src.gripperIcon.overlays += src.grippers
proc/selectTool(var/obj/item/weapon/W)
if (W in src.tools)
src.selectedTool = W
if (W==src.grippers)
src.selector.screen_loc = "1,1"
src.icon_state = "gripper"
else if (W==src.wirecutters)
src.selector.screen_loc = "2,1"
src.icon_state = "wirecutters"
else if (W==src.crowbar)
src.selector.screen_loc = "3,1"
src.icon_state = "crowbar"
else if (W==src.screwdriver)
src.selector.screen_loc = "4,1"
src.icon_state = "screwdriver"
else if (W==src.welder)
src.selector.screen_loc = "5,1"
src.updateToolIcon(W)
else if (W==src.wrench)
src.selector.screen_loc = "6,1"
src.icon_state = "wrench"
else if (W==src.aiInterface)
src.selector.screen_loc = "7,1"
src.icon_state = "generic"
proc/checkIsOurTool(var/obj/W)
if (W in src.tools)
return W
else if (W in src.screenIcons)
var/screen_loc = W:screen_loc
for (var/W2 in src.tools)
if (W2:screen_loc == screen_loc)
return W2
return null
else
return null
proc/use_via_drone_control(var/mob/user)
if (user.currentDrone)
return
if (istype(user, /mob/drone))
return
if (user.client)
if (user.stat==0)
if (src.stat==0)
if (src.controlledBy == null)
if (user:cameraFollow!=null)
user:cancel_camera()
src.takeControl(user)
else if (src == user)
src.releaseControl(1)
else
if (istype(user, /mob/ai))
user << text("Someone else is already controlling that drone! The station's drone control system reports that it is [].", src.controlledBy)
else
user << "Someone is already controlling this drone!"
else if (src.stat==2)
user.client_mob() << "That drone is a wreck. It's mostly destroyed."
else
user << "That drone is not responding to signals at this time."
attack_ai(var/mob/user)
if (user.client)
use_via_drone_control(user)
attack_paw(var/mob/user)
user.client_mob() << "You can't figure it out, and slapping the shiny metal with your paws doesn't seem to harm it."
attack_hand(var/mob/user)
if (src == user)
src.releaseControl(1)
return
if (user.client && (!istype(user, /mob/drone) || !(user:controlledBy)) && !(user.currentDrone))
if (user.stat < 1)
if (user.a_intent == "help")
if (src.health < 0)
user.client_mob() << "It looks critically damaged."
else if (src.health < 25)
user.client_mob() << "It looks severely damaged."
else if (src.health < 50)
user.client_mob() << "It looks badly damaged."
else if (src.health < 75)
user.client_mob() << "It looks moderately damaged."
else if (src.health < 100)
user.client_mob() << "It looks slightly damaged."
user.client_mob() << "There isn't anything you can do right now to repair any damage to its circuitry or mechanics."
else if (user.a_intent == "grab")
if (config.walkable_not_pullable_drones)
user.client_mob() << "That is entirely too heavy to grab and drag anywhere."
else
user.pulling = src
user.client_mob() << "You can pull it, but it doesn't have hands or a neck and it is very heavy, so you can't really do better than that."
else if (user.a_intent == "disarm")
user.client_mob() << "Its weight is too low to the ground to be knocked over, and it certainly can't be disarmed either."
else if (user.a_intent == "hurt")
if (istype(user, /mob/human) || istype(user, /mob/monkey))
var/damage = rand(1, 9)
var/obj/item/weapon/organ/external/affecting = null
var/def_zone
if (user.hand)
def_zone = "l_hand"
else
def_zone = "r_hand"
if (user.organs[text("[]", def_zone)])
affecting = user.organs[text("[]", def_zone)]
if (affecting!=null && (istype(affecting, /obj/item/weapon/organ/external) && prob(90)))
for(var/mob/O in viewers(src, null))
O.show_message(text("\red <B>[] has punched [], and it looked painful!</B>", user, src), 1)
affecting.take_damage(damage)
if (istype(user, /mob/human))
user:UpdateDamageIcon()
user.health = 100 - user.oxyloss - user.toxloss - user.fireloss - user.bruteloss
user.client_mob() << "\red<font size=3>OUCH!</font>"
else
for(var/mob/O in viewers(src, null))
O.show_message(text("\red <B>[] has attempted to punch []!</B>", user, src), 1)
//Foreach goto(1419)
return
else if (istype(user, /mob/drone))
for(var/mob/O in viewers(src, null))
O.show_message(text("[] just whacked []!", user, src), 1)
for(var/mob/M in hearers(src, null))
var/msg = text("<FONT size=[]>KLANG!</FONT>", max(0, 5 - get_dist(src, M)))
M.client_mob() << msg
abiotic()
return 1
proc/takeControl(var/mob/user)
if (user.client)
if (istype(user, /mob/human) || istype(user, /mob/ai))
if (src.stat==0)
user << "You have taken control of the drone. <b>To release control later, use/attack (click or double click) the drone with your empty gripper-hand</b>."
src.controlledBy = user
user.currentDrone = src
user:reset_view(src)
//world.log << text("takeControl begin. src.savedDroneIcons are [], src.screenIcons are [], user.client.screen is []", listToString(src.savedDroneIcons), listToString(src.screenIcons), listToString(user.client.screen))
src.savedDroneIcons = list()
src.savedDroneIcons += user.client.screen
var/screenFile
if (user.hud_used == main_hud)
screenFile = 'screen1.dmi'
else
screenFile = 'screen.dmi'
for (var/atom/item in src.screenIcons)
item.icon = screenFile
user.client.screen -= user.client.screen
user.droneTransitioning = 1
src.droneTransitioning = 1
src.client = user.client
user.droneTransitioning = 0
src.droneTransitioning = 0
src.client.screen += src.screenIcons
if (!istype(user, /mob/ai))
src.client.screen -= src.aiIcon
src.client.screen -= src.aiInterface
//world.log << text("takeControl end. src.savedDroneIcons are [], src.screenIcons are [], user.client.screen is []", listToString(src.savedDroneIcons), listToString(src.screenIcons), listToString(user.client.screen))
else
user << "That drone is too damaged to control."
proc/releaseControl(voluntary)
var/mob/user = src.controlledBy
if (user!=null)
if (istype(user, /mob/human) || istype(user, /mob/ai))
user.currentDrone = null
src.controlledBy = null
//world.log << text("releaseControl begin. src.savedDroneIcons are [], src.screenIcons are [], user.client.screen is []", listToString(src.savedDroneIcons), listToString(src.screenIcons), listToString(user.client.screen))
src.client.screen -= src.client.screen
user.droneTransitioning = 1
src.droneTransitioning = 1
user.client = src.client
user.droneTransitioning = 0
src.droneTransitioning = 0
user.client.screen += src.savedDroneIcons
user:cancel_camera()
src.savedDroneIcons = list()
///world.log << text("releaseControl end. src.savedDroneIcons are [], src.screenIcons are [], user.client.screen is []", listToString(src.savedDroneIcons), listToString(src.screenIcons), listToString(user.client.screen))
user.UpdateClothing()
if (voluntary)
user << "You have released control of the drone."
else
user << "You have lost control of the drone!"
drop_item_v()
src.drop_item()
switch_hud()
var/file = null
var/mob/user = src.controlledBy
if (user.hud_used == main_hud)
user.favorite_hud = 1
user.hud_used = main_hud2
file = 'screen.dmi'
else
user.favorite_hud = 0
user.hud_used = main_hud
file = 'screen1.dmi'
var/client/client = src.alwaysClient()
for (var/obj/screenIcon in src.screenIcons)
client.screen -= screenIcon
screenIcon.icon = file
client.screen += screenIcon
can_drop()
if (src.l_hand!=null)
return 1
return 0
drop_item()
usr.client_mob() << "drop_item() usr is [usr] src is [src]"
if (src.can_drop())
src.ungrip()
//return ..()
Life()
if (src.stat != 2)
if (src.stat!=0)
//lose control!
if (src.controlledBy!=null)
src.releaseControl(0)
src.health = 100 - src.fireloss - src.bruteloss - src.oxyloss
var/turf/T = src.loc
if (istype(T, /turf))
var/ficheck = src.firecheck(T)
if (ficheck)
src.fireloss += ficheck * 10
src.health = 100 - src.fireloss - src.bruteloss - src.oxyloss
if (src.fire)
src.fire.icon_state = "fire1"
else if (src.fire)
src.fire.icon_state = "fire0"
if (src.l_hand!=null && src.l_hand.screen_loc != "1,1") //something changed our gripped item
src.grip(src.l_hand)
if (src.health <= -100.0)
death()
return
else if (src.health < 0)
src.oxyloss++
..()
death()
if (src.healths)
src.healths.icon_state = "health5"
if (src.stat == 2)
CRASH("/mob/drone/death called when stat is already 2")
if (src.controlledBy!=null)
src.releaseControl(0)
src.drop_item()
src.stat = 2
src.canmove = 0
src.rname = "[src.rname] (Destroyed)"
src.icon_state = "broken"
return ..()
Stat()
..()
statpanel("Status")
if (src.client.statpanel == "Status")
if (ticker)
var/timel = ticker.timeleft
stat(null, text("ETA-[]:[][]", timel / 600 % 60, timel / 100 % 6, timel / 10 % 10))
return
proc/firecheck(turf/T as turf)
if (T.firelevel < config.min_gas_for_fire)
return 0
var/total = 0
total += 0.25
return total
u_equip(obj/item)
if (src.equipped()==item && src.can_drop())
src.drop_item()
UpdateClothing()
var/freeSlot = 0
if (src.equipped()==null)
freeSlot = 1
if (l_hand!=null)
src.updateClothingProcessHandItem(l_hand, freeSlot)
freeSlot = 0
l_hand = null
if (r_hand!=null)
src.updateClothingProcessHandItem(r_hand, freeSlot)
freeSlot = 0
r_hand = null
proc/updateClothingProcessHandItem(obj/item/weapon/item, freeSlot)
if (!freeSlot)
item.loc = src.loc
item.dropped(src)
if (item)
item.layer = initial(item.layer)
else
item.layer = initial(item.layer)
grip(item)
client_mob()
if (src.client!=null)
return src
else
var/mob/owner = src.controlledBy
if (owner!=null)
return owner
else
return src
hasClient()
if (src.client!=null)
return 1
else if (src.controlledBy!=null && src.controlledBy.client!=null)
return 1
else
return 0
/* IMPORTANT NOTE: Both humans and drones have a copy of this code. If the code is modified to fix a bug or whatever, it will need to be modified in BOTH of them. Monkeys also have some of this code, but not all of it. (Moving the code into a shared method or two wasn't feasible because of where the ..() calls are and such) --shadowlord13 */
Move(a, b, flag)
if (src.buckled)
return
if (src.restrained())
src.pulling = null
var/t7 = 1
if (src.restrained())
for(var/mob/M in range(src, 1))
if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
t7 = null
//Foreach goto(62)
if ((t7 && (src.pulling && ((get_dist(src, src.pulling) <= 1 || src.pulling.loc == src.loc) && (src.client && src.client.moving)))))
var/turf/T = src.loc
. = ..()
if (!( isturf(src.pulling.loc) ))
src.pulling = null
return
//////
if (src.pulling.anchored)
src.pulling = null
return
//////
if (!( src.restrained() ))
var/diag = get_dir(src, src.pulling)
if ((diag - 1) & diag)
else
diag = null
if ((get_dist(src, src.pulling) > 1 || diag))
if (ismob(src.pulling))
var/mob/M = src.pulling
var/ok = 1
if (locate(/obj/item/weapon/grab, M.grabbed_by.len))
if (prob(75))
var/obj/item/weapon/grab/G = pick(M.grabbed_by)
if (istype(G, /obj/item/weapon/grab))
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [] has been pulled from []'s grip by []", G.affecting, G.assailant, src), 1)
//Foreach goto(354)
//G = null
del(G)
else
ok = 0
if (locate(/obj/item/weapon/grab, M.grabbed_by.len))
ok = 0
if (ok)
var/t = M.pulling
M.pulling = null
step(src.pulling, get_dir(src.pulling.loc, T))
M.pulling = t
else
step(src.pulling, get_dir(src.pulling.loc, T))
else
src.pulling = null
. = ..()
if ((src.s_active && !( s_active in src.contents ) ))
src.s_active.close(src)
return
Bump(atom/movable/AM as mob|obj, yes)
spawn( 0 )
if ((!( yes ) || src.now_pushing))
return
..()
src.PushingBump(AM, yes)
return
//block the take-off/put-on dialog
show_inv(mob/user as mob)
return
/obj/item/weapon/drone/aiInterface
name = "AI Interface"
icon = 'drone.dmi'
icon_state = "tool-aiInterface"
flags = 322.0
/obj/item/weapon/drone/grippers
name = "Grippers"
icon = 'drone.dmi'
icon_state = "tool-grippers"
flags = 322.0
/proc/listToString(var/list/L)
var/output = "{"
for (var/entry in L)
if (lentext(output)==1)
output += "[entry]"
else
output += ", [entry]"
output += "}"
return output