Advertisement
Guest User

Roamer ant v1.3

a guest
Jan 22nd, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.86 KB | None | 0 0
  1. // ROAMER SCRIPT FOR ANTS, VER. 1.3
  2. extern void object::Roam( )
  3. {
  4.     int     list[], i;
  5.     object  target;
  6.     object  targets[];
  7.     point       center[];
  8.     point       lastPos = position, lastSafePos = position, lastUnsafePos, probSafePoint;
  9.     int         part = 0, apart = 0;
  10.     int         approach = 0;
  11.     int         cgo[];
  12.     float       safeDir;
  13.     float       roamDist[];
  14.     float       guardDist[];
  15.     float       attackDist[];
  16.     float       absDetectRange = 10000;
  17.     float       r;
  18.     float       mp = 1, tp = 1;
  19.     float       wc = 8;
  20.     float       wcd0, wcd1, wcd2, wcd3, wcd4; // directions of primary water check for checking around
  21.     float       sfsmin = 8, sfsmax = 12; // distance of search for safe point, in case if current one is not as safe
  22.     float       frange[];
  23.     float       ci = 0, cli = 0, icli = 0; // center counter, cmdline counter, internal cmdline counter
  24.     float       waiter[];
  25.     float       ftime = abstime();
  26.     float       lastOri = orientation;
  27.  
  28.     errmode(0);
  29.     while ( ismovie() != 0 )  wait(1);
  30.    
  31.     float       stime = abstime();
  32.  
  33.     i = 0;
  34.     list[i++] = WingedGrabber;
  35.     list[i++] = TrackedGrabber;
  36.     list[i++] = WheeledGrabber;
  37.     list[i++] = LeggedGrabber;
  38.     list[i++] = WingedShooter;
  39.     list[i++] = TrackedShooter;
  40.     list[i++] = WheeledShooter;
  41.     list[i++] = LeggedShooter;
  42.     list[i++] = WingedOrgaShooter;
  43.     list[i++] = TrackedOrgaShooter;
  44.     list[i++] = WheeledOrgaShooter;
  45.     list[i++] = LeggedOrgaShooter;
  46.     list[i++] = WingedSniffer;
  47.     list[i++] = TrackedSniffer;
  48.     list[i++] = WheeledSniffer;
  49.     list[i++] = LeggedSniffer;
  50.     list[i++] = Thumper;
  51.     list[i++] = PhazerShooter;
  52.     list[i++] = Recycler;
  53.     list[i++] = Shielder;
  54.     list[i++] = Subber;
  55.     list[i++] = Me;
  56.     list[i++] = Derrick;
  57.     list[i++] = BotFactory;
  58.     list[i++] = PowerStation;
  59.     list[i++] = Converter;
  60.     list[i++] = RepairCenter;
  61.     list[i++] = DefenseTower;
  62.     list[i++] = ResearchCenter;
  63.     list[i++] = RadarStation;
  64.     list[i++] = ExchangePost;
  65.     list[i++] = PowerPlant;
  66.     list[i++] = AutoLab;
  67.     list[i++] = NuclearPlant;
  68.    
  69.    
  70.     // BEGIN OF COMMAND LINE VALUES PROCESSING
  71.     // EXAMINE FOR BETTER UNDERSTANDING
  72.     // These are five simple values but with them you can create very, very different behaviors.
  73.    
  74.     center[ci] = position;
  75.     roamDist[ci] = 0;
  76.     guardDist[ci] = 0;
  77.     attackDist[ci] = 40;
  78.     waiter[ci] = 0;
  79.     frange[ci] = 40;
  80.     cgo[ci] = 0;
  81.     while(cmdline(cli) != 0)
  82.     {
  83.         if(cmdline(cli) < 1000)
  84.         {
  85.             ci++;
  86.            
  87.             // These are default values. They will be replaced with specified values or values based on other specified values if there will be any.
  88.             // Central point.
  89.             center[ci] = position;
  90.             // Range within which insect will roam around central point.
  91.             // If 0 then there is no range and insect will roam everywhere.
  92.             roamDist[ci] = 0;
  93.             // Timer after expiration of which central point changes to next one. Timer is absolute, not relative.
  94.             // By default there is no need in timer.
  95.             waiter[ci] = 0;
  96.             // If there is any enemy closer to central point than that value then insect will go and attack this enemy.
  97.             guardDist[ci] = 0;
  98.             // If there is any enemy closer to insect itself than that value then insect will go and attack this enemy.
  99.             // But insect will NOT go towards enemy in these cases:
  100.             // 1) both roam range and guard range are greater than 0 and insect is about to get out of both.
  101.             // 2) only roam range is greater than 0 and insect is about to get out of it.
  102.             attackDist[ci] = 40;
  103.             // If there is enemy then insect will start shooting at this enemy from this distance.
  104.             frange[ci] = 40;
  105.             // If insect is allowed to get out of both roam and guard ranges while moving towards enemy. 0 - now allowed, 1 - allowed.
  106.             cgo[ci] = 0;
  107.            
  108.             center[ci].x = cmdline(cli);
  109.             center[ci].y = 0;
  110.             icli = 0;
  111.             if(cmdline(cli+1) < 1000)
  112.             {
  113.                 center[ci].y = cmdline(cli+1);
  114.                 cli++;
  115.             }
  116.         }
  117.         if(cmdline(cli) >= 1000)
  118.         {
  119.             if(icli == 0)
  120.             {
  121.                 roamDist[ci] = cmdline(cli) - 1000;
  122.                 guardDist[ci] = cmdline(cli) - 1000;
  123.             }
  124.             else if(icli == 1)
  125.             {
  126.                 waiter[ci] = cmdline(cli) - 1000;
  127.             }
  128.             else if(icli == 2)
  129.             {
  130.                 guardDist[ci] = cmdline(cli) - 1000;
  131.             }
  132.             else if(icli == 3)
  133.             {
  134.                 attackDist[ci] = cmdline(cli) - 1000;
  135.             }
  136.             else if(icli == 4)
  137.             {
  138.                 if(cmdline(cli-icli+3) == 0 and attackDist[ci] > 0)
  139.                 {
  140.                     // DEFAULT: if attack dist was not specified and thus was by default equaled to default fire range... Equal it to specified fire range instead.
  141.                     attackDist[ci] = attackDist[ci] - frange[ci];
  142.                     attackDist[ci] = attackDist[ci] + cmdline(cli) - 1000;
  143.                 }
  144.                 frange[ci] = cmdline(cli) - 1000;
  145.             }
  146.             else if(icli == 5)
  147.             {
  148.                 cgo[ci] = cmdline(cli) - 1000;
  149.             }
  150.             icli++;
  151.         }
  152.         cli++;
  153.     }
  154.     // END OF COMMAND LINE VALUES PROCESSING
  155.    
  156.     ci = 0;
  157.     cli = 0;
  158.     icli = 0;
  159.    
  160.     lastPos = position;
  161.     lastSafePos = position;
  162.     lastUnsafePos.x = 9999;
  163.     lastUnsafePos.y = 9999;
  164.     lastUnsafePos.z = 0;
  165.     motor(1,1);
  166.     ftime = abstime();
  167.     while ( true )
  168.     {
  169.         if(distance2d(lastUnsafePos,position) > wc)
  170.         {
  171.             wcd0 = orientation;
  172.             wcd1 = orientation + 65;
  173.             wcd2 = orientation - 65;
  174.             wcd3 = orientation + 130;
  175.             wcd4 = orientation - 130;
  176.             if(wcd1 > 360){ wcd1 = wcd1 - 360; }
  177.             if(wcd2 < 0){ wcd2 = wcd2 + 360; }
  178.             if(wcd3 > 360){ wcd3 = wcd3 - 360; }
  179.             if(wcd4 < 0){ wcd4 = wcd4 + 360; }
  180.             if(CheckWater(position,wcd0,wc,0.5) > -1 or CheckWater(position,wcd1,wc,0.5) > -1 or CheckWater(position,wcd2,wc,0.5) > -1 or CheckWater(position,wcd3,wc,0.5) > -1 or CheckWater(position,wcd4,wc,0.5) > -1)
  181.             {
  182.                 lastUnsafePos = position;
  183.             }
  184.             else
  185.             {
  186.                 lastSafePos = position;
  187.             }
  188.         }
  189.         if(ftime > abstime()) // because before 0.1.11 Colobot was losing abstime() and lifetime()
  190.         {
  191.             i = 0;
  192.             while(i < sizeof(waiter))
  193.             {
  194.                 waiter[i] = waiter[i] - (ftime - abstime());
  195.                 if(waiter[i] < 0)
  196.                 {
  197.                     waiter[i] = 0;
  198.                 }
  199.                 i++;
  200.             }
  201.             ftime = abstime();
  202.         }
  203.         else
  204.         {
  205.             ftime = abstime();
  206.         }
  207.         if(ci < sizeof(center) - 1 and abstime() > waiter[ci] + stime and ((roamDist[ci] != 0 and distance2d(position,center[ci]) <= roamDist[ci]) or distance2d(position,center[ci]) <= 5 or (roamDist[ci] == 0 and waiter[ci] != 0)))
  208.         {
  209.             ci++;
  210.             if(roamDist[ci] - 1 > 1.5)
  211.             {
  212.                 turn(rand()*360-180);
  213.                 motor(1,1);
  214.                 wait(1);
  215.             }
  216.         }
  217.         target = null;
  218.         targets = radarall(list);
  219.         i = 0;
  220.         approach = 0;
  221.         while(i < sizeof(targets))
  222.         {
  223.             // Detect enemy only if it is not underwater
  224.             if(targets[i].altitude + topo(targets[i].position) > -2.0)
  225.             {
  226.                 if(guardDist[ci] != 0 and distance(targets[i].position,center[ci]) <= guardDist[ci] + frange[ci] and distance(position,center[ci]) <= guardDist[ci])
  227.                 {
  228.                     target = targets[i];
  229.                     approach = 1;
  230.                 }
  231.                 else if(distance(targets[i].position,position) <= attackDist[ci])
  232.                 {
  233.                     if(guardDist[ci] <= 0 and roamDist[ci] > 0)
  234.                     {
  235.                         if(cgo[ci] > 0 or distance(targets[i].position,position) <= frange[ci] or distance(targets[i].position,center[ci]) <= roamDist[ci] + frange[ci] or (distance(targets[i].position,position) > frange[ci] and distance(targets[i].position,position) <= attackDist[ci]))
  236.                         {
  237.                             approach = 2;
  238.                             if(cgo[ci] > 0 or (distance(targets[i].position,position) > frange[ci] and distance(targets[i].position,position) <= attackDist[ci]))
  239.                             {
  240.                                 approach = 1;
  241.                             }
  242.                             target = targets[i];
  243.                         }
  244.                     }
  245.                     else if(guardDist[ci] > 0 and roamDist[ci] > 0)
  246.                     {
  247.                         if(cgo[ci] > 0 or distance(targets[i].position,center[ci]) <= guardDist[ci] + frange[ci] or distance(targets[i].position,center[ci]) <= roamDist[ci] + frange[ci] or (distance(targets[i].position,position) > frange[ci] and distance(targets[i].position,position) <= attackDist[ci]))
  248.                         {
  249.                             approach = 2;
  250.                             if(cgo[ci] > 0 or (distance(targets[i].position,position) > frange[ci] and distance(targets[i].position,position) <= attackDist[ci]))
  251.                             {
  252.                                 approach = 1;
  253.                             }
  254.                             target = targets[i];
  255.                         }
  256.                     }
  257.                     else
  258.                     {
  259.                         approach = 1;
  260.                         target = targets[i];
  261.                     }
  262.                 }
  263.                 if(approach == 1 and (guardDist[ci] != 0 and guardDist[ci] < 1.5) and (roamDist[ci] != 0 and roamDist[ci] < 1.5))
  264.                 {
  265.                     approach = 2;
  266.                 }
  267.             }
  268.             if(approach > 0)
  269.             {
  270.                 break;
  271.             }
  272.             i++;
  273.         }
  274.         // if there is no enemy or (we are in danger of submersion and safe point isn't nearby already)
  275.         if (target == null or topo(position)<=-0.05 or (distance2d(lastUnsafePos,position) <= 2 and distance2d(lastSafePos,position) > 2))
  276.         {
  277.             apart = 0;
  278.             // if we are in danger of submersion
  279.             if(topo(position)<-0.05 or (distance2d(lastUnsafePos,position) <= 2 and distance2d(lastSafePos,position) > 2))
  280.             {
  281.                 if(distance(position,lastSafePos) > 1)
  282.                 {
  283.                     turn(direction(lastSafePos));
  284.                 }
  285.                 while(distance(position,lastSafePos) > 1)
  286.                 {
  287.                     motor (1, 1);
  288.                     wait(0.1);
  289.                 }
  290.                 if(target != null and distance(target.position,position) <= frange[ci])
  291.                 {
  292.                     motor (0, 0);
  293.                     turn(direction(target.position));
  294.                     fire(target.position);
  295.                 }
  296.             }
  297.             // or if we have a home and we are outside of it
  298.             else if ((roamDist[ci] > 0 and distance2d(position, center[ci]) > roamDist[ci]) or (((roamDist[ci] == 0 and waiter[ci] == 0) or roamDist[ci] < 0) and ci < sizeof(center) - 1 and distance2d(position, center[ci]) > 5))
  299.             {
  300.                 mp = 1;
  301.                 if(roamDist[ci] > 0 and roamDist[ci] <= 5 and distance2d(position, center[ci]) < 9)
  302.                 {
  303.                     mp = roamDist[ci] / 4;
  304.                 }
  305.                 if(direction(center[ci]) > 2)
  306.                 {
  307.                     tp = direction(center[ci]) / 60;
  308.                     motor (mp-0.2*tp, mp+0.2*tp);
  309.                 }
  310.                 else if(direction(center[ci]) < -2)
  311.                 {
  312.                     tp = -direction(center[ci]) / 60;
  313.                     motor (mp+0.2*tp, mp-0.2*tp);
  314.                 }
  315.                 else
  316.                 {
  317.                     motor (mp, mp);
  318.                 }
  319.                 while(target != null and distance(target.position,position) <= frange[ci])
  320.                 {
  321.                     motor (0, 0);
  322.                     fire(target.position);
  323.                 }
  324.                 // try to walk around if we got stuck
  325.                 lastPos = position;
  326.                 wait(0.5);
  327.                 if (distance2d(lastPos, position) < 0.2)
  328.                 {
  329.                     turn(rand()*360-180);
  330.                     motor(mp,mp);
  331.                     wait(1);
  332.                     if(direction(center[ci]) > 2 or direction(center[ci]) < -2)
  333.                     {
  334.                         turn(direction(center[ci]));
  335.                     }
  336.                 }
  337.             }
  338.             // if either we are homeless or we are at home already then we roam around
  339.             else if((roamDist[ci] >= 1.5 or roamDist[ci] == 0) and CheckWater(position,orientation,wc,0.5) == -1)
  340.             {
  341.                 mp = 1;
  342.                 if(roamDist[ci] > 0 and roamDist[ci] <= 9)
  343.                 {
  344.                     mp = roamDist[ci] / 6;
  345.                 }
  346.                 if((roamDist[ci] <= 5 and roamDist[ci] != 0) or distance2d(position,lastUnsafePos) <= 2)
  347.                 {
  348.                     if(roamDist[ci] > 5 or roamDist[ci] == 0)
  349.                     {
  350.                         mp = 0.45;
  351.                     }
  352.                     if(part <= 5)
  353.                     {
  354.                         mp = mp / 5 * part;
  355.                         if(rand()<0.1)
  356.                         {
  357.                             r = rand();
  358.                             if (r > 0.6)
  359.                             {
  360.                                 motor(mp*(rand()/4),mp);
  361.                             }
  362.                             else if (r < 0.4)
  363.                             {
  364.                                 motor(mp,mp*(rand()/4));
  365.                             }
  366.                             else
  367.                             {
  368.                                 r = 10;
  369.                                 while(r > 0)
  370.                                 {
  371.                                     motor(mp/10*r,mp/10*r);
  372.                                     wait(0.1);
  373.                                     r = r - 1;
  374.                                 }
  375.                                 motor(0,0);
  376.                                 wait(0.1);
  377.                                 part = 6;
  378.                             }
  379.                             lastPos = position;
  380.                         }
  381.                         else
  382.                         {
  383.                             if(direction(center[ci]) < -20)
  384.                             {
  385.                                 motor(mp,mp*rand());
  386.                             }
  387.                             else if(direction(center[ci]) > 20)
  388.                             {
  389.                                 motor(mp*rand(),mp);
  390.                             }
  391.                             else
  392.                             {
  393.                                 motor(mp,mp);
  394.                             }
  395.                             wait(0.25);
  396.                             lastPos = position;
  397.                         }
  398.                         if(part < 5)
  399.                         {
  400.                             part++;
  401.                         }
  402.                     }
  403.                     else if(part > 5)
  404.                     {
  405.                         motor(0,0);
  406.                         wait(0.3+rand()/3);
  407.                         part++;
  408.                         if(part > 13 or (part > 9 and rand() <= 0.1))
  409.                         {
  410.                             part = 0;
  411.                         }
  412.                     }
  413.                     if(part > 13)
  414.                     {
  415.                         part = 0;
  416.                     }
  417.                 }
  418.                 else
  419.                 {
  420.                     if(part == 0)
  421.                     {
  422.                         if (distance2d(lastPos, position) < 0.2)
  423.                         {
  424.                             turn(rand()*360-180);
  425.                         }
  426.                         lastPos = position;
  427.                     }
  428.                     if(part == 1)
  429.                     {
  430.                         motor(mp,mp);
  431.                         wait(0.3);
  432.                         lastPos = position;
  433.                     }
  434.                     if(part == 2)
  435.                     {
  436.                         r = rand();
  437.                         if (r > 0.6)
  438.                         {
  439.                             motor (mp, mp*0.7);
  440.                             wait(rand()*1);
  441.                             motor (mp, mp);
  442.                         }
  443.                         if (r < 0.4)
  444.                         {
  445.                             motor (mp*0.7, mp);
  446.                             wait(rand()*1);
  447.                             motor (mp, mp);
  448.                         }
  449.                         wait(0.45);
  450.                         lastPos = position;
  451.                     }
  452.                     part++;
  453.                     if(part > 2)
  454.                     {
  455.                         part = 0;
  456.                     }
  457.                 }
  458.             }
  459.             else
  460.             {
  461.                 // I don't like to call CheckWater too often, so this is fine too
  462.                 if(roamDist[ci] >= 1.5 or roamDist[ci] == 0)
  463.                 {
  464.                     r = rand();
  465.                     if(rand() < 0.3)
  466.                     {
  467.                         motor(r,-r);
  468.                     }
  469.                     else if(rand() < 0.3)
  470.                     {
  471.                         motor(-r,r);
  472.                     }
  473.                     wait(0.45);
  474.                 }
  475.                 else
  476.                 {
  477.                     r = rand() * 0.2;
  478.                     if(rand() < 0.2 and rand() < 0.2)
  479.                     {
  480.                         motor(r,-r);
  481.                     }
  482.                     else if(rand() < 0.2 and rand() < 0.2)
  483.                     {
  484.                         motor(-r,r);
  485.                     }
  486.                     else
  487.                     {
  488.                         motor(0,0);
  489.                     }
  490.                     wait(0.45);
  491.                 }
  492.             }
  493.         }
  494.         // we have a target
  495.         else if(target != null)
  496.         {
  497.             part = 0;
  498.             if(false and apart == 0)
  499.             {
  500.                 if(direction(target.position) > 2 or direction(target.position) < -2)
  501.                 {
  502.                     turn(direction(target.position));
  503.                 }
  504.                 apart++;
  505.             }
  506.             else if(true or apart == 1)
  507.             {
  508.                 if(target != null and distance(target.position,position) <= frange[ci])
  509.                 {
  510.                     fire(target.position);
  511.                 }
  512.                 // come closer to target if it is farther than 10 meters
  513.                 if(ismovie() == 0 and approach == 1 and target != null and distance(target.position,position) > 10 and topo(position)>=-0.5 and distance2d(position,lastUnsafePos) > 2 and CheckWater(position,orientation,wc,0.5) == -1)
  514.                 {
  515.                     mp = 1;
  516.                     if(direction(target.position) > 2)
  517.                     {
  518.                         tp = direction(target.position) / 60;
  519.                         motor (mp-0.2*tp, mp+0.2*tp);
  520.                     }
  521.                     else if(direction(target.position) < -2)
  522.                     {
  523.                         tp = -direction(target.position) / 60;
  524.                         motor (mp+0.2*tp, mp-0.2*tp);
  525.                     }
  526.                     else
  527.                     {
  528.                         motor (mp, mp);
  529.                     }
  530.                     // try to walk around if we got stuck
  531.                     lastPos = position;
  532.                     wait(0.5);
  533.                     if (distance2d(lastPos, position) < 0.2)
  534.                     {
  535.                         turn(rand()*360-180);
  536.                         motor(1,1);
  537.                         wait(1);
  538.                         turn(direction(center[ci]));
  539.                     }
  540.                 }
  541.                 else
  542.                 {
  543.                     motor(0,0);
  544.                 }
  545.                 apart = 0;
  546.             }
  547.         }
  548.     }
  549. }
  550.  
  551. float CheckWater(point pos, float ori, float i, float start)
  552. {
  553.     float orix,oriy,c;
  554.     point p;
  555.     if(ori < 180)
  556.     {
  557.         if(ori < 90)
  558.         {
  559.             orix = 1-(ori/90);
  560.             oriy = ori/90;
  561.         }
  562.         else
  563.         {
  564.             orix = -((ori-90)/90);
  565.             oriy = 1-(ori-90)/90;
  566.         }
  567.     }
  568.     else
  569.     {
  570.         if(ori < 270)
  571.         {
  572.             orix = -1+((ori-180)/90);
  573.             oriy = -((ori-180)/90);
  574.         }
  575.         else
  576.         {
  577.             orix = (ori-270)/90;
  578.             oriy = -1+(ori-270)/90;
  579.         }
  580.     }
  581.     c = start;
  582.     while(c <= i)
  583.     {
  584.         p.x = pos.x+(c*orix);
  585.         p.y = pos.y+(c*oriy);
  586.         if(topo(p) <= -0.05)
  587.         {
  588.             return c;
  589.         }
  590.         c = c + 2.5;
  591.     }
  592.     return -1;
  593. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement