Looks very well though out and drawn... I guess one has to substitute the loss of one thing for another![]()
So looks like my computer is going to be out of comission a little longer, despite the best efforts to get Gmod working on my laptop. So, once again, my brain comes up with an idea, extrapolates, extrapolates, and here I am with another drone idea.
In keeping with the Greek pantheon of my Hephaestus drone, this is the Hermes drone.
Background
The Hermes drone is something of a mail carrier, but I'm intending to up the ante by adding a way for it to carry cargo as well. It's currently designed with the capacity in mind that you enter a message into the E2 using a Wired Keyboard (Affixed to the rear of the screen) and then enter a target's name.
Then, the E2 checks if it can find that target in the range of it's Target Finder, and if it can it nabs the vector co-ordinates and feeds them into the hoverdrive (Minus a little extrapolation so it doesn't materialise in the ground or the target). If not, it roams around a bit until it can find them.
Upon reaching its target, the screen's hydraulic extends, pushing the screen to a vertical position. The E2 then reads through the message into the screen, then flips the screen around to present the keyboard, presuming that the target will want to reply or send a message of their own.
Now of course, I can see there being questions here, "Why not use the chat?" being chief among them. My primary idea with that is privacy, post things to the chat and everyone can see them (Which is partially why the Hephaestus' inter-drone messages are pure gibberish to anyone who doesn't know the code, and includes a security passcode). The Hermes drone allows you to send messages in private, but if you're sneaky, Hermes can also be a bloodhound.
And given a cargo capacity, Hermes can also be a package delivery system, or a homing missile.
Presently, the left and right wings are used predominantly to keep the drone in the air, whilst the tail can aid them or be used to forward motion. Increasing thrust in one side and decreasing in the other would cause the drone to tilt and consequently turn. With cargo, it would need to be able to compensate for the weight of its cargo.
Because the design incorporates a (shielded) hoverdrive, Hermes drones are conceivably repairable by the Hephaestus unless the hoverdrive is destroyed/removed, because right now SEnts can't be Prop Spawners.
Current Body Iteration: Version 1.6
Current known code:[highlight=E2]@name Hermes drone operating system
@inputs Key, Rand:wirelink, Ran1:wirelink, Ran2:wirelink,Ran3:wirelink
@inputs Vec1:wirelink, Vec2:wirelink, Vec3:wirelink
@inputs LefWing:wirelink, RigWing:wirelink,TaiWing:wirelink, ScrHyd:wirelink
@outputs BotNum, LastMes
@outputs Vector, Launch, ScrText, ScrClk
@persist BotNum, LastMes
@persist Dir, Nsix, Status:array, Quo:array, DonorMode
@persist Name:string, Target:entity, Vector, Index, Num, Keyboard, Message:array, Chunk:table
@persist LLW, LRW, LTW, LS, Vec1, Vec2, Vec3
#STARTUP
if(first()|dupe()){
timer("ghost_fill",1000)
gSetGroup("Hermes")
BotCount = gGetNum(1)
BotNum = BotCount + 1
gSetNum(1,BotNum)
Quo = entity():getConstraints()
Repo = 1
stoptimer("ghost_fill")}
interval(10)
DirCode = gGetStr(3)
Passcode = gGetStr(2)
#BOOTING SCREEN CLOCK
Rand:setNumber("A") = 0
Rand:setNumber("B") = 1
if(first()){ScrClk = 1}
if(!Rand:number("A")){ScrClk = ScrClk * -1}
#COMMUNICATION RECEPTION
runOnChat(1)
Message = lastSaid()
if(Message:left(5) == Passcode){
ExMes = S:explode(" ",Message)
Code = ExMes:remove(1)
if(Code(1) == DirCode & Code(2) == 2|Code(1) == DirCode & Code(2) == 10){
Dir = Code(3)
DirRec = 1}
elseif(Code(1) == 1 & Code(8) == 2){
DonorMode = 1
GPSCheck = S:explode("+",Code(3))
#MOTION CONTROL
#POSITIONAL RESET
if(Repo){
Length1 = [X]
Length2 = [X]
Length3 = [X]
Length4 = [X]
HoverAlt = 140
Repo = 0}
#INTER-DRONE AVOIDANCE
if(Avoidance){
interval(500)
findClearBlackList()
findClearWhiteList()
findInSphere(entity()os(),400)
findClipToClass("gmod_wire_locator")
findSortByDistance(entity()os())
DroneDist = findResult(1):distance(findResult(2))
if(DroneDist < 100){
VecBase = -(findResult(2)os())}}
#LOCATING VECTOR THRUSTERS
V1 = Torsoos() - Vec1
os()
V1toV2 = Vec1os() - Vec2
os()
V1toV3 = Vec1os() - Vec3
os()
#HOVER CONTROL
Alt = min(Ran1:number("Range"),Ran2:number("Range"),Ran3 :number("Range"))
THoverZ = Alt - HoverAlt
if(Alt != HoverAlt){
interval(125)
HovAlt = Alt + (THoverZ/8)}}
#HYDRAULICS
#Hydraulic control for left wing
Lef = LefWing:number("Length")
TLenLW = Lef - LengthLW
if(Lef != LengthLW){
interval(125)
LefWing:setNumber("Length") = Lef + (TLenLW/8)}
#Hydraulic control for right wing
Rig = RigWing:number("Length")
TLenRW = Rig - LengthRW
if(Rig != LengthRW){
interval(125)
RigWing:setNumber("Length") = Rig + (TLenRW/8)}
#Hydraulic control for tail wing
Tai = TaiWing:number("Length")
TLenTW = Tai - LengthTW
if(Tai != LengthTW){
interval(125)
TaiWing:setNumber("Length") = Tai + (TLenTW/8)}
#Hydraulic control for screen
Scr = ScrHyd:number("Length")
TLenS = Scr - LengthS
if(Scr != LengthS){
interval(125)
ScrHyd:setNumber("Length") = Scr + (TLenS/8)}
#MESSAGE DELIVERY SYSTEM
if(Key){
#Entering the message
if(~Key & Key){
ScrText = "Please enter your message</br>Press the backslash key to finish"
timer("messageentry",10)
MessF = Message:concat("</br>")
NChunk = S:Implode("",Chunk)
ScrText = S:Implode("</br>",{MessF,NChunk})
if(Key == 13 & Cmark >= 40){
ChunkB = S.Implode("",Chunk)
Message:setString(Mmark, ChunkB)
MMark += 1
Chunk = table()}
Cmark = 1
elseif(!Key == 92){
Chunk:setString(Cmark,toChar(Key))
ScrText: S:Implode("",Chunk)
Cmark += 1}
else{
TarSet = 1
stoptimer("messageentry")}
#Setting the target of the message
if(TarSet){
ScrText = "Press T to name your target or V to enter target co-ordinates")
#Target co-ordinates
if(Key == 118|Key == 86){
Vekta = table()
Values = array()
ScrText = "Press enter to change to the next co-ordinate, from X, to Y, and Z</br>If you make a mistake, press E to re-enter the co-ordinates"
interval(10)
if(!Key == 13 & Key == 45){
InVal = "-"
Vekta:setString(InVal,Index)
Index += 1}
elseif(!Key == 13 & Key >= 48 & Key <= 57){
InVal = Key - 48
Vekta:setString(InVal,Index)
Index += 1}
elseif(Key == 13){
Index = 1
NewVec = S.Implode("",Vekta)
Values:setString(Num,NewVec)
if(Num == 3){Num = 1}
else{Num += 1}}
Xvec = Xvec:toNumber()
Yvec = Yvec:toNumber()
Zvec = Zvec:toNumber()
Vector = vec(Xvec,Yvec,Zvec)
if(Vector){
ScrText = "Thank you for your custom</br>Press the Alt key to initiate delivery"
if(!Keyboard){
#Target name
if(Key == 116|Key == 84){
ScrText = "Please remember that target names are cAsE SeNsItIvE!"}}
#DIRECTOR ACTIONS
#ACTION ALLOCATION
if(Dir == 1|Dir == 13 & NoSix == 1){Ramble = 1}
else{Ramble = 0}
if(Dir == 3|Dir == 13 & NoSix == 3){DefSelf = 1}
else{DefSelf = 0}
if(Dir == 4|Dir == 13 & NoSix == 4){DefDir = 1}
else{DefDir = 0}
if(Dir == 5|Dir == 13 & NoSix == 5){Attack = 1}
else{Attack = 0}
if(Dir == 6|Dir == 13 & NoSix == 6){Sleep = 1}
else{Sleep = 0}
if(Dir == 8|Dir == 13 & NoSix == 8){Follow = 1}
else{Follow = 0}
if(Dir == 9|Dir == 13 & NoSix == 9){Stop = 1}
else{Stop = 0}
if(Dir == 10|Dir == 13 & NoSix == 10){Conga = 1}
else{Conga = 0}
if(Dir == 11|Dir == 13 & NoSix == 11){Radar = 1}
else{Radar = 0}
if(Dir == 12|Dir == 13 & NoSix == 12){Guard = 1}
else{Guard = 0}
if(Dir == 13){Nsix = 1}
else{Nsix = 0}}}
if(!MessageMode & !DonorMode){
#D05 - Attack protocol
if(Attack){
findExcludePlayer(owner())
findIncludeClass("player")
findIncludeClass("npc_*")
interval(500)
findInSphere(entity()os(),1000)
Target = findClosest(entity()os())
Tvec = Targetos()
HovAlt = Tvec:z() + Target:height()/2
Vector = vec(Tvec:x(), Tvec:y(), HovAlt)
VecBase = Tvec
if(Target:isAlive()){Launch = 1}
else{Launch = 0}}
#D06 - Sleep protocol
if(Sleep){
HoverAlt = 5
Self = entity()
interval(250)
Shake = Self:velL():length()
if($Shake < 15){
Motion = 0
if(Dir = 13){Nsix = 6}
else{Dir = 6}}
else{Repo = 1}
if{MessageMode){
Repo = 1}}
#D09 - Stop protocol
if(Stop){
Motion = 0
HoverAlt = 0
timer("bystander",10)
MessageMode = 0
Dmgd = 0}
else{stoptimer("bystander")}
#D13 - Number Six protocol
if(first()){
Pref = array()
if(R:count(Pref) < 12){
interval(50)
NewPoi = (R:count(Pref) + 1)
Pref:setNumber(NewPoi,NewPoi)}}
if(Nsix){
#I am not a number, I am a FREE MAN!
interval(60000)
Index = round(random(1,R:count(Pref)))
NoSix = Pref:number(Index)
NewPoi = Index + 1
NewEnt = round(random(1,[X]))
Pref:setNumber(NewEnt,NewPoi)}[/highlight][highlight=E2]@name Hermes Shoe
@inputs Vector Launch
@outputs WingVec SetWing Launch Weld
interval(10)
WingVec = Vector
if(Launch()){
SetWing = 1
Weld = 1
timer("flight",20)
Launch = 1
stopTimer("flight")}
else{
Launch = 0
Weld = 0}[/highlight][highlight=E2]@name Hermes memory chip
@inputs BotNum, LastMes, GPS
@outputs DroneID, MesRec:array, GPS
@persist BotNum, MesRec:array, GPS:vector, GPSCo:string, Torso:entity, Age, TOD
#STARTUP
if(first()){
TorCol = vec(180,218,255)
Bod = entity():getConstraints()
Body = Bod:entity(Mark)
gSetGroup("Hermes")
MesRec = array()
if(!Body){
interval(10)
if(Body:getColor():toString() == TorCol){Torso = Body}
else{Mark += 1}}
#DRONE ID
if(Body)
interval(1000)
Age += 1}
DroneID = "Herm-"+toString(BotNum)+"-"+toString(Age)+"-"+toString(TOD)
#DRONE DEATH
#Dead census
if(!Body & !$Body){
gGetNum(4)
gSetNum(4) += 1
#Time Of Death
TOD = curtime()}
GPSCo = toString(GPS:x())+"+"+toString(GPS:y())+"+"+toStri ng(GPS:z())
#Death alert
timer("alert",random(10,40))
DeathLen = 14 + toString(BotNum):length()
DeathMes = "Deceased-"+DroneID:left(DeathLen-9)
if(!lastSaid():left(DeathLen) == DeathMes){
print("Deceased-"+DroneID+GPSCo)
stoptimer("alert")}
else{stoptimer("alert")}
#Last 10 messages
if($LastMes){
if(MesRec:count() = 10){
MesRec:shiftString()
MesRecushString(LastMes)}
else{MesRecushString(LastMes)}}[/highlight]Global variable group: Hermes
Global variables: BotCount, Passcode, DirCode
Last edited by Lyinginbedmon; 05-28-2009 at 02:59 PM. Reason: Converted over to wirelinks
The Olympus Technologies drones, totally not SkyNet in Gmod form.
Cronus: The Ultimate Drone, definitely SkyNet in Gmod form.
The gBrain Project, the drone controls system that thinks it's better than you
Looks very well though out and drawn... I guess one has to substitute the loss of one thing for another![]()
Last edited by Syranide; 04-01-2009 at 12:59 PM.
Nice design work, might i inquire as to what program you used ?
Apologies if its simply paint, just looks nice is all..
Regarding the thrusters, i personally would also consider an expression 2 chip to do the it all without the meither of thruster power ratios and angling.
Anyways epic ideas mate.
I don't usually like replacing thrusters with E2, but I have to agree here. If you have a lot of these floating around, you need to keep ents to a minimum.
Otherwise there's a very efficient system of four vector thrusters that can control pitch, yaw, roll, and position.
I'll elaborate if need be, but it's fairly complicated if you're not used to working with vectors.
I'd go with E:applyForce() and E:applyAngForce() in this case.
I'm confident with E2 so no worries about explaining. (To me anyway)
Also I agree if at all possible using E2 seems to be much better than thrusters, the math becomes much more clear when your dealing with variables you have direct control over and the stability increases with no whop-off thrusters hanging off of the side..
It's the same program I do all my art with, InkScape.
I can certainly see the use of replacing thrusters with applyForce(), though I like the fluttering wing effect the thrusters vs the hydraulics would give (That could also probably be effected with a slight waver in the applyForce() values). I'm not familiar enough with using either in expressions really to determine which route to go. Any arguments to present?
The two biggest chunks of code by importance with this drone are the message code and the seeking code, which is essentially to either replace or assist the target finder in locating targets.
There's a bunch of different approaches that could be taken in implementing it, such as achieving high altitude and then spiralling lower and lower so the target finder gets a good look over a much larger area, or simply having the drone wander the map using trial and error to find them.
The Olympus Technologies drones, totally not SkyNet in Gmod form.
Cronus: The Ultimate Drone, definitely SkyNet in Gmod form.
The gBrain Project, the drone controls system that thinks it's better than you
Cheers the info, ill look up ink scape in a second.
As a matter of fact its strange that you should mention:
I'm currently working on a project I've deemed "Platey", which is basically a square PHX plate which follows me around and responds to chat functions, so far its all done however the path finding is simply rangers (E2 Rangers) on the sides, top and bottom which when broken stop movement on the relevant axis. This frequently results in failure, and as such my friends and i at college have been experimenting with different methods, our collective knowledge managed to spawn a system where by "Platey" plots his course using rangers simulating himself moving, when they are broken a blockage is detected and using a Fibonacci like spiral he finds a opening then plots the points which are added to an array, finally when he has finished virtually planning his route "Platey" executes it, continually checking along the route and altering as needed.having the drone wander the map using trial and error to find them
This system has not been coded or implemented as of yet, im too tired, however when the holidays hit consider it done.. I'll be sure to make a post showing and describing the finished product when I'm done.
Any questions and hang around the wiremod team speak, i drop in from time to time.
You could use Target = findPlayerByName(Name), which gives you one less target finder. Target finders are actually fairly "expensive" in that they use findInSphere repeatedly.
Example:
Code:@inputs Key @persist Name:string Target:entity if(~Key & Key) #if Key input triggers the expression (if it changes), and if Key != 0 { Name += toChar(Key) } if(Key == 13) #13 is the ASCII value for enter I think. { Target = findPlayerByName(Name) Name = "" #Clear the name string }
Last edited by Bobsymalone; 04-01-2009 at 11:36 AM.
Nice Idea Bob, I'm having some trouble with redefining the build in E2 entity discovery parameters, i managed to get a script error,. That takes skill, but its probably just me doing it wrong, ill retry.
Well, meanwhile I've also had an idea.
A lot of the impetus for making repairing drones was things like Gcombat and, especially, the LUA cinderblock (Featured originally in War of the Servers, there's now a functioning one on gmod.org).
Defense against such methods is why the hoverdrive is currently inside a tube, so that Gcombat rounds hit the casing before the tube, but a cinderblock would still de-weld it from the casing.
So I had a lightbulb: What if the hoverdrive wasn't welded to the casing?
So here we have, the hoverdrive core.
Inside the casing, a wired transferrer feeds the two necessary values into the core's transferrer, operating the expression chip.Code:@name Hermes Shoe @inputs Vector Launch @outputs WingVec SetWing Launch Weld interval(10) WingVec = Vector if(Launch()){ SetWing = 1 Weld = 1 timer("flight",20) Launch = 1 stopTimer("flight")} else{ Launch = 0 Weld = 0}
This way, the hoverdrive is only connected to the drone itself when it's going to launch. So if the casing is hit by a LUA cinderblock, the odds of it hitting while the hoverdrive core is welded (By the grabbers) are so minute as to be considered impossible.
The drone itself would still fall apart if hit by the cinderblock, but if nothing else this makes rebuilding it easier. Hades will be happy![]()
Bookmarks