About Store Forum Documentation Contact



Post Reply 
Server sided AI
Author Message
Palaxe Offline
Member

Post: #16
RE: Server sided AI
Is this compatible with 2.0?
If so what is the best way to bring it in?[/u]
03-13-2013 05:00 PM
Find all posts by this user Quote this message in a reply
TBJokers Offline
Member

Post: #17
RE: Server sided AI
(03-13-2013 05:00 PM)Palaxe Wrote:  Is this compatible with 2.0?
If so what is the best way to bring it in?[/u]

It should be compatible with the EE 2.0, the server sided code should work to a 100%. However though when it comes to client, I am not sure if the Meshes are handled in the same way, but it shouldn't be a problem converting it over to 2.0. smile

Man, it's always that semicolon...
03-13-2013 07:49 PM
Visit this user's website Find all posts by this user Quote this message in a reply
Palaxe Offline
Member

Post: #18
RE: Server sided AI
Ok Thanks for the reply smile
03-16-2013 06:43 AM
Find all posts by this user Quote this message in a reply
Ozmodian Offline
Member

Post: #19
RE: Server sided AI
Just wanted to throw my 2 cents in here. Thanks so much for posting this. It gives me a really good base to work with. I have been able to incorporate it into my modified version of Ineisis as well.

Here is a video I posted of 1000 bots running pretty well (don't know why the volume is low). Thanks again Fex and TB Joker.



06-09-2013 09:23 PM
Find all posts by this user Quote this message in a reply
Ozmodian Offline
Member

Post: #20
RE: Server sided AI
Some people were asking for 2.0 code. I only made a very small change to use UID instead of file name but thought i should post it:

Client.AI
Code:
class AI : Game::Chr
{
  
   Int ID; //ID so that we can identify which the server wants us to use
   Vec OldLocation; //Old target location
   Str Name; // Name-
   Flt scale =2.0;

   //Memc<AI> ai;
   void AI::spawn(Str name, Game.ObjParamsPtr &obj, Int id, Vec pos)
   {

      super.create(*Game.Objs(obj.id())); //Create the object.
     // Log(S+"Create successful on " + id + "\n");
      
      Name = name; //Add specifics read from server.
      ID   = id;
      Flt y = Game.World.hmHeight(pos.xz(),true)+0.6f;                                                
      T.pos(pos+Vec(0,y,0)); //Add Y so that it doesn't spawn just under the map.
      ctrl.actor.group(AG_AI);//Set actor group to 1 so that we can disable collision (pushing of monsters)
      //Log(S+"Got to end of spawn on " + id + "\n");
  
  
   }
   bool AI::update(){
      if(super::update())
      {
        if( OldLocation!=0 && (T.pos() - OldLocation).length() < 2.0)T.actionBreak();
         return true;
      }
      return false;
   }
   void AI::Move(Vec pos){
      if(OldLocation!=0 && (T.pos() - OldLocation).length() > 3.0/*T.pos() != OldLocation*/)T.pos(OldLocation); // If old location is not already reached, set the position instantly there.
      Flt y = Game::World.hmHeight(pos.xz(),true)+0.6f; //Get height of target location
     T.actionMoveDir(Vec(pos.x, y, pos.z) - T.pos());//Move to locationPlr.pos() - T.pos()
      OldLocation = pos+Vec(0,y,0);//Set previous Location target so that we can check when receiving next time.
     // CM.New(S+"Newoldpos "+OldLocation);
   }
   void AI::drawName(){
      Vec2 NamePos = PosToScreen(pos()+Vec(0,T.ctrl.height(),0)); // Position of monster + it's height.
      if(Dist(pos(), Plr.pos())<D.viewRange()/3){ // if distance of /3
        if(visible())D.text(NamePos, S+Name+ID);
      }
   }
   void AI::Action(Byte b ){
      
      
   }
   bool visible() {return Frustum(mesh->box, Matrix(scale, pos()));}

}
Memc<AI> ai;

Client.Game
Code:
case CS_AI_SPAWN:
      {
        //CM.New("Recieved CS_AI_SPAWN");
        Str name; Game.ObjParamsPtr obj; Int id; Vec Pos;
        Server.data.getStr(name).decIntV(id).decFlt3cm(Pos.x).decFlt3cm(Pos.z); obj = Server.data.getUID();
        ai.New().spawn(name, obj, id, Pos);
        //File f = Server.data;
        //Str name = Server.data.getStr(); Str obj = Server.data.getStr(); Int id = Server.data.decIntV(); Flt x = Server.data.decFlt3cm(); Flt z = Server.data.decFlt3cm();ai.New().spawn(name,obj,id,Vec(x,0,z));
      } break;
        
      case CS_AI_MOVE:
      {
        //CM.New("Recieved CS_AI_MOVE");
        Int id = Server.data.decIntV(); Flt x = Server.data.decFlt3cm(); Flt z = Server.data.decFlt3cm(); Int ith; REPA(ai)if(ai[i].ID == id)ith =i; ai[ith].Move(Vec(x,0,z));
      } break;
      
      case CS_AI_ACTION:
      {
        //CM.New("Recieved CS_AI_ACTION");
      } break;

Server.AI
Code:
class ArtificialIntelligence
{
     /* void createAI(Int, Str, Str, Vec, Flt); //Create
      bool update  (   );                  //Update loop
      void spawn   (Int);
      bool foundtarget(Int);
      void sendMovement();
      void sendAction  (); */
      ArtificialIntelligence(){MovementTimer = RandomF(2,6); ActionTimer = RandomF(10,15);} //Set timers at construction
   //private:
      Memc<Client*> active_clients; //Active list of clients. The clients that has this monster spawned.
      Str Creature_Name;
      Vec Position     ;
      Game.ObjParamsPtr Object       ; //Object path.
      Int Creature_ID  ;
      Flt MovementTimer;
      Flt ActionTimer  ;
      Ball RadiusBall  ;


   ::Client& client(Int i) {return (::Client&)Server.clients.lockedData(i);}
   //Memc<ArtificialIntelligence> ai;
   void ArtificialIntelligence::createAI(Int id, Str name, Vec pos, Flt radius, Game.ObjParamsPtr &object){
      Creature_ID = id; //Set creature ID
      Creature_Name = name; //Set Creature Name
      Object = object; //Object path, example "Obj/Chr/Skeleton/0.obj"
      Position = pos; //Start position
      RadiusBall.r = radius; //Radius it can move in each move command.
   }
   bool ArtificialIntelligence::update()
   {
      REPA(active_clients)
      {
         if(!active_clients[i].inGame())active_clients.remove(i); // need to remove clients that have exited game/went back to login screen
      }
      REPA(Server.clients){
         if(client(i).inGame()/*state == iGame*/)if(Dist(Position,client(i).pos())>50)foundtarget(i); // go to state of processing if you should spawn a monster for this or if it's already spawned
      }
      MovementTimer -= Time.d();
      ActionTimer   -= Time.d();
      if(MovementTimer <= 0)sendMovement();
      //if(ActionTimer   <= 0)sendAction();
      return true;
   }
   void ArtificialIntelligence::spawn(Int i){
      File f;
      f.writeMem().putByte(CS_AI_SPAWN);
      f.putStr(Creature_Name).
        cmpIntV(Creature_ID ).
        cmpFlt3cm(Position.x).
        cmpFlt3cm(Position.z)
        <<Object.id();
      f.pos(0);
      //Log(S+"Server Spawn " + Creature_ID);
      client(i).connection.dataFull(f,f.left());
      active_clients.New() = &client(i); //Directly after spawning the monster set the client into the monsters active list.
   }

   bool ArtificialIntelligence::foundtarget(Int a){
      Int temp = 0;
      REPA(active_clients){
         if(active_clients[i] ==&client(a)){return false;} //If client is in monster list directly return false so that it is not spawned again.
         if(active_clients[i] !=&client(a)){temp++;}
      }
      if(!active_clients.elms()){ //If there are no Active clients, add the first one
         spawn(a);
         return true;
      }
      if((temp-active_clients.elms())==0){ //If the client wasn't found in the active list spawn it.
         spawn(a);
         return true;
      }
      return false;
   }
   void ArtificialIntelligence::sendMovement(){
   //tryagain:;

      Vec test = Position +=Random(RadiusBall,true); //Test,
      /*if(map.checkpos(test))*/{                        //Map checking will be added later on
         MovementTimer = RandomF(2, 10);    //Reset timer
         File f;
         f.writeMem().putByte(CS_AI_MOVE);
         f.cmpIntV(Creature_ID ).
           cmpFlt3cm(Position.x).
           cmpFlt3cm(Position.z);
         REPA(active_clients){f.pos(0); active_clients[i]->connection.dataFull(f,f.left(),true);} //Send movement to all active clients.
      }/*else goto tryagain; */  //If position failed and it's on an invalid place, then start over to try another position
   }
   void ArtificialIntelligence::sendAction(){
      File f;
      f.writeMem().putByte(CS_AI_ACTION);
      f.cmpIntV(Creature_ID ).putByte(Random(0,2)); //Put random action 0-2
      REPA(active_clients){f.pos(0); active_clients[i]->connection.dataFull(f,f.left(),true);} //Send action to all clients.
   }

}
Memc<ArtificialIntelligence> ai;

Server.main
Code:
REP(10)ai.New().createAI(i,"Warrior",Vec(RandomF(0,20),RandomF(0,20),RandomF(0,20)),10, Game.ObjParamsPtr(UID(1789382582, 1118947404, 2757836681, 1453939461)));
[/php]
06-14-2013 08:09 AM
Find all posts by this user Quote this message in a reply
Palaxe Offline
Member

Post: #21
RE: Server sided AI
(06-14-2013 08:09 AM)Ozmodian Wrote:  Some people were asking for 2.0 code. I only made a very small change to use UID instead of file name but thought i should post it:

Client.AI
Code:
class AI : Game::Chr
{
  
   Int ID; //ID so that we can identify which the server wants us to use
   Vec OldLocation; //Old target location
   Str Name; // Name-
   Flt scale =2.0;

   //Memc<AI> ai;
   void AI::spawn(Str name, Game.ObjParamsPtr &obj, Int id, Vec pos)
   {

      super.create(*Game.Objs(obj.id())); //Create the object.
     // Log(S+"Create successful on " + id + "\n");
      
      Name = name; //Add specifics read from server.
      ID   = id;
      Flt y = Game.World.hmHeight(pos.xz(),true)+0.6f;                                                
      T.pos(pos+Vec(0,y,0)); //Add Y so that it doesn't spawn just under the map.
      ctrl.actor.group(AG_AI);//Set actor group to 1 so that we can disable collision (pushing of monsters)
      //Log(S+"Got to end of spawn on " + id + "\n");
  
  
   }
   bool AI::update(){
      if(super::update())
      {
        if( OldLocation!=0 && (T.pos() - OldLocation).length() < 2.0)T.actionBreak();
         return true;
      }
      return false;
   }
   void AI::Move(Vec pos){
      if(OldLocation!=0 && (T.pos() - OldLocation).length() > 3.0/*T.pos() != OldLocation*/)T.pos(OldLocation); // If old location is not already reached, set the position instantly there.
      Flt y = Game::World.hmHeight(pos.xz(),true)+0.6f; //Get height of target location
     T.actionMoveDir(Vec(pos.x, y, pos.z) - T.pos());//Move to locationPlr.pos() - T.pos()
      OldLocation = pos+Vec(0,y,0);//Set previous Location target so that we can check when receiving next time.
     // CM.New(S+"Newoldpos "+OldLocation);
   }
   void AI::drawName(){
      Vec2 NamePos = PosToScreen(pos()+Vec(0,T.ctrl.height(),0)); // Position of monster + it's height.
      if(Dist(pos(), Plr.pos())<D.viewRange()/3){ // if distance of /3
        if(visible())D.text(NamePos, S+Name+ID);
      }
   }
   void AI::Action(Byte b ){
      
      
   }
   bool visible() {return Frustum(mesh->box, Matrix(scale, pos()));}

}
Memc<AI> ai;

Client.Game
Code:
case CS_AI_SPAWN:
      {
        //CM.New("Recieved CS_AI_SPAWN");
        Str name; Game.ObjParamsPtr obj; Int id; Vec Pos;
        Server.data.getStr(name).decIntV(id).decFlt3cm(Pos.x).decFlt3cm(Pos.z); obj = Server.data.getUID();
        ai.New().spawn(name, obj, id, Pos);
        //File f = Server.data;
        //Str name = Server.data.getStr(); Str obj = Server.data.getStr(); Int id = Server.data.decIntV(); Flt x = Server.data.decFlt3cm(); Flt z = Server.data.decFlt3cm();ai.New().spawn(name,obj,id,Vec(x,0,z));
      } break;
        
      case CS_AI_MOVE:
      {
        //CM.New("Recieved CS_AI_MOVE");
        Int id = Server.data.decIntV(); Flt x = Server.data.decFlt3cm(); Flt z = Server.data.decFlt3cm(); Int ith; REPA(ai)if(ai[i].ID == id)ith =i; ai[ith].Move(Vec(x,0,z));
      } break;
      
      case CS_AI_ACTION:
      {
        //CM.New("Recieved CS_AI_ACTION");
      } break;

Server.AI
Code:
class ArtificialIntelligence
{
     /* void createAI(Int, Str, Str, Vec, Flt); //Create
      bool update  (   );                  //Update loop
      void spawn   (Int);
      bool foundtarget(Int);
      void sendMovement();
      void sendAction  (); */
      ArtificialIntelligence(){MovementTimer = RandomF(2,6); ActionTimer = RandomF(10,15);} //Set timers at construction
   //private:
      Memc<Client*> active_clients; //Active list of clients. The clients that has this monster spawned.
      Str Creature_Name;
      Vec Position     ;
      Game.ObjParamsPtr Object       ; //Object path.
      Int Creature_ID  ;
      Flt MovementTimer;
      Flt ActionTimer  ;
      Ball RadiusBall  ;


   ::Client& client(Int i) {return (::Client&)Server.clients.lockedData(i);}
   //Memc<ArtificialIntelligence> ai;
   void ArtificialIntelligence::createAI(Int id, Str name, Vec pos, Flt radius, Game.ObjParamsPtr &object){
      Creature_ID = id; //Set creature ID
      Creature_Name = name; //Set Creature Name
      Object = object; //Object path, example "Obj/Chr/Skeleton/0.obj"
      Position = pos; //Start position
      RadiusBall.r = radius; //Radius it can move in each move command.
   }
   bool ArtificialIntelligence::update()
   {
      REPA(active_clients)
      {
         if(!active_clients[i].inGame())active_clients.remove(i); // need to remove clients that have exited game/went back to login screen
      }
      REPA(Server.clients){
         if(client(i).inGame()/*state == iGame*/)if(Dist(Position,client(i).pos())>50)foundtarget(i); // go to state of processing if you should spawn a monster for this or if it's already spawned
      }
      MovementTimer -= Time.d();
      ActionTimer   -= Time.d();
      if(MovementTimer <= 0)sendMovement();
      //if(ActionTimer   <= 0)sendAction();
      return true;
   }
   void ArtificialIntelligence::spawn(Int i){
      File f;
      f.writeMem().putByte(CS_AI_SPAWN);
      f.putStr(Creature_Name).
        cmpIntV(Creature_ID ).
        cmpFlt3cm(Position.x).
        cmpFlt3cm(Position.z)
        <<Object.id();
      f.pos(0);
      //Log(S+"Server Spawn " + Creature_ID);
      client(i).connection.dataFull(f,f.left());
      active_clients.New() = &client(i); //Directly after spawning the monster set the client into the monsters active list.
   }

   bool ArtificialIntelligence::foundtarget(Int a){
      Int temp = 0;
      REPA(active_clients){
         if(active_clients[i] ==&client(a)){return false;} //If client is in monster list directly return false so that it is not spawned again.
         if(active_clients[i] !=&client(a)){temp++;}
      }
      if(!active_clients.elms()){ //If there are no Active clients, add the first one
         spawn(a);
         return true;
      }
      if((temp-active_clients.elms())==0){ //If the client wasn't found in the active list spawn it.
         spawn(a);
         return true;
      }
      return false;
   }
   void ArtificialIntelligence::sendMovement(){
   //tryagain:;

      Vec test = Position +=Random(RadiusBall,true); //Test,
      /*if(map.checkpos(test))*/{                        //Map checking will be added later on
         MovementTimer = RandomF(2, 10);    //Reset timer
         File f;
         f.writeMem().putByte(CS_AI_MOVE);
         f.cmpIntV(Creature_ID ).
           cmpFlt3cm(Position.x).
           cmpFlt3cm(Position.z);
         REPA(active_clients){f.pos(0); active_clients[i]->connection.dataFull(f,f.left(),true);} //Send movement to all active clients.
      }/*else goto tryagain; */  //If position failed and it's on an invalid place, then start over to try another position
   }
   void ArtificialIntelligence::sendAction(){
      File f;
      f.writeMem().putByte(CS_AI_ACTION);
      f.cmpIntV(Creature_ID ).putByte(Random(0,2)); //Put random action 0-2
      REPA(active_clients){f.pos(0); active_clients[i]->connection.dataFull(f,f.left(),true);} //Send action to all clients.
   }

}
Memc<ArtificialIntelligence> ai;

Server.main
Code:
REP(10)ai.New().createAI(i,"Warrior",Vec(RandomF(0,20),RandomF(0,20),RandomF(0,20)),10, Game.ObjParamsPtr(UID(1789382582, 1118947404, 2757836681, 1453939461)));
[/php]
Thanks for doing this. I stepped away from AI to learn more about the engine and its functions. I think I'm ready to try and tackle this. Thanks for sharing smile
10-21-2013 08:00 PM
Find all posts by this user Quote this message in a reply
Piepants Offline
Member

Post: #22
RE: Server sided AI
Hello, I recently stumbled upon this project and figured I'd give it a shot since I have the Ineisis source purchased. Ozmodian, are those 4 code segments all that is needed to modify a fresh 2.0 Ineisis source to be buildable with this AI? Or should I also be using some of Fex's code snippets on the first page? Thanks! And thanks very much TBJokers for posting this, looks incredible!
11-21-2013 04:46 AM
Find all posts by this user Quote this message in a reply
Ozmodian Offline
Member

Post: #23
RE: Server sided AI
My code snippets are the main pieces. I think there were 1 or 2 one line entries you may have to make, but it should be pretty simple.
11-21-2013 06:28 AM
Find all posts by this user Quote this message in a reply
KraaxLeNain Offline
Member

Post: #24
RE: Server sided AI
For those who intend to reuse the snipet : store object in MemX and not MemC on the client side else you could have some violent crash when casting the object (Game.MemxObj would even be better but ... I don't master that yet - who said noob?).

Apart from that the snipet is a good frame for basic artichecture and quite inspiring. Thx to the contributors wink
(This post was last modified: 12-11-2013 09:13 AM by KraaxLeNain.)
12-11-2013 09:13 AM
Find all posts by this user Quote this message in a reply
TBJokers Offline
Member

Post: #25
RE: Server sided AI
That's good, but i've improved upon our official more complex AI to use Maps. that's probably the best idea.
12-11-2013 02:36 PM
Visit this user's website Find all posts by this user Quote this message in a reply
KraaxLeNain Offline
Member

Post: #26
RE: Server sided AI
Well I intend to do the same in fact. Map is based on Memx and not Memc wich explain why it works too. My remark is just here to prevent some random guy to ask himself "why the hell is it not working" for 14hours like I did grin

Certainly I can't lecture anyone or give lessons at this stage of my knowledge on Esenthel. I'm a noob smile

Would you share eventually your map<,> code part, it would help a lot smile ? I'm still having trouble gathering the pieces of map using, especially when I need to build an object with more params than the create fonction has when you call map (or maybe I just misunderstood and the three input on the map build are minmum requirement and not strict requirement). I always figure something wrong and either object is not created either it can't compile because it find no appropriate constructor.
(This post was last modified: 12-11-2013 04:15 PM by KraaxLeNain.)
12-11-2013 04:13 PM
Find all posts by this user Quote this message in a reply
TBJokers Offline
Member

Post: #27
RE: Server sided AI
What is your problem if i may ask? Elaborate ! smile
12-12-2013 05:08 PM
Visit this user's website Find all posts by this user Quote this message in a reply
KraaxLeNain Offline
Member

Post: #28
RE: Server sided AI
Well I finally sorted it out but thx for the help proposal... It was trouble for creating element in the map. Yeah noob call ;D
12-16-2013 10:59 AM
Find all posts by this user Quote this message in a reply
Zach Offline
Member

Post: #29
RE: Server sided AI
Hello,

Thank you for posting help and tutorials about AI. I am however having one problem that I can't figure out. It is in Client.AI, and these two lines get error:
Code:
if( OldLocation!=0 && (T.pos() - OldLocation).length() < 2.0)T.actionBreak();
if(OldLocation!=0 && (T.pos() - OldLocation).length() > 3.0/*T.pos() != OldLocation*/)T.pos(OldLocation); // If old location is not already reached, set the position instantly there.

in this block of code:
Code:
bool AI::update(){
      if(super::update())
      {
        if( OldLocation!=0 && (T.pos() - OldLocation).length() < 2.0)T.actionBreak();
         return true;
      }
      return false;
   }
   void AI::Move(Vec pos){
      if(OldLocation!=0 && (T.pos() - OldLocation).length() > 3.0/*T.pos() != OldLocation*/)T.pos(OldLocation); // If old location is not already reached, set the position instantly there.
      Flt y = Game::World.hmHeight(pos.xz(),true)+0.6f; //Get height of target location
     T.actionMoveDir(Vec(pos.x, y, pos.z) - T.pos());//Move to locationPlr.pos() - T.pos()
      OldLocation = pos+Vec(0,y,0);//Set previous Location target so that we can check when receiving next time.
     // CM.New(S+"Newoldpos "+OldLocation);
   }

The error is this:
Code:
AI.cpp
c:\program files\esenthel\projects\_build_\ineisis client\source\ai.cpp(25): error C2666: 'EE::Vec::operator !=': 13 overloads have similar conversions [C:\Program Files\Esenthel\Projects\_Build_\Ineisis Client\Project.vcxproj]

Any help appreciated.. thank you!!
04-23-2017 10:02 PM
Visit this user's website Find all posts by this user Quote this message in a reply
RedcrowProd Offline
Bronze Supporter

Post: #30
RE: Server sided AI
this is just saying that it doesnt know how to deal with a vec!=0

you can try this instead Vec(0)
if( OldLocation!=Vec(0) && (T.pos() - OldLocation).length() < 2.0)T.actionBreak();
(This post was last modified: 04-24-2017 12:08 AM by RedcrowProd.)
04-24-2017 12:07 AM
Find all posts by this user Quote this message in a reply
Post Reply