Последнее время с поисковых систем стабильно приходят пользователи, пытающиеся найти у меня готовые программы для игр Colobot и Ceebot.
Поэтому я решил срочно исправляться. В этом посте я собрал некоторые программы, которые позволят Вам сэкономить время или посмотреть, как программируют в Colobot другие игроки.
Кстати, я написал отличный обзор этой игре у себя в блоге. Можете также почитать мои другие обзоры игр для программистов.
Пост получился очень большим из-за того что я привел исходные коды многих программ. Но, в любом случае, это будет удобно тем, кто ищет готовые программы — все в одном месте.
Аккуратно! Ваш скролл может умереть мучительной и жестокой смертью.
Программа для PhazerShooter
Поместите робота на местность (желательно повыше), активируйте и наблюдайте за его работой. Он уничтожит все цели, которые летят не выше 80 метров.
extern void object::Phazer() { float scanRange = 150; // scan for targets within this radius // Platform specific parameters float minAngle = -20; // minimum gun elevation relative to platform float maxAngle = 45; // maximum gun elevation relative to platform float weaponHeight = 2; // height of weapon above platform float weaponOffset = 2; // weapon is this amount in front of platform float maxTurnRate = 54; // maximum turn rate // Ballistic parameters float v0 = 50; // muzzle velocity (m / s) float g = 50; // gravitation (m / s^2) float bc = v0 * v0 / g; // ballistic constant (max range at equal height) object target; // target while (true) { target = ScanForTarget(scanRange); // do a target scan while (target == null) // wait until target becomes available { motor(0,0); // engines idle wait(1); // wait a little to relieve CPU target = ScanForTarget(scanRange); // scan again } // Variables to track target (cylindrcal coцrdinates) float bearing, range, height, time; float deltaBearing, deltaRange, deltaHeight, deltaTime; // Initialize the 'old' variables float oldBearing = orientation + direction(target.position); float oldRange = distance2d(position, target.position); float oldHeight = target.position.z - position.z; float oldTime = abstime(); // Variables needed for target solution float rt, zt; float t; float D; float it = sqrt(2) * oldRange / v0; // initial estimate for intercept time float azimuth; float elevation; float turnRate; float motorOutput; // Variables needed for slope correction float pitchAz; float rollAz; float a; float b; float c; float d; float corr; float fireTime = abstime() + 0.2; // don't fire for 0.5 seconds (first track target) while (target == ScanForTarget(scanRange)) // As long as target is the most critical target { // Collect data bearing = orientation + direction(target.position); range = distance2d(position, target.position); height = target.position.z - position.z; time = abstime(); // Calculate differences deltaBearing = bearing - oldBearing; deltaRange = range - oldRange; deltaHeight = height - oldHeight; deltaTime = time - oldTime; // Save data for next pass oldBearing = bearing; oldRange = range; oldHeight = height; oldTime = time; // Extrapolate target motion to interception point t = it / deltaTime; // time factor azimuth = bearing + t * deltaBearing - orientation; // intercept azimuth if (azimuth < -180) azimuth += 360; // azimuth correction (pole passage) if (azimuth > 180) azimuth -= 360; zt = height + t * deltaHeight - cos(pitch) * cos(roll) * weaponHeight; // intercept height rt = range + t * deltaRange - weaponOffset * cos(azimuth) * cos(pitch); // intercept range // Calculate weapon elevation D = bc * (bc - 2 * zt) / (rt * rt) - 1; // discriminant if (D < 0) elevation = atan(bc / rt); // target out of range else elevation = atan(bc / rt - sqrt(D)); // target in range it = rt / (v0 * cos(elevation)); // intercept time (estimate for next pass) // Slope-correction pitchAz = pitch * cos(azimuth) - roll * sin(azimuth); // pitch at target azimuth rollAz = roll * cos(azimuth) + pitch * sin(azimuth); // roll at target azimuth // Solve slope-target spherical triangle b = elevation - pitchAz; // relative elevation at target azimuth a = asin(sin(b) * cos(rollAz)); // new gun elevation c = acos(cos(b) / cos(a)); if (b < 0) c = -c; // intermediate variable d = asin(sin(c) * sin(rollAz)); // intermediate variable corr = -acos(cos(c) / cos(d)); if (d < 0) corr = -corr; // azimuth correction azimuth += corr; // apply azimuthal correction // Point the weapon in the right direction aim(a); // weapon elevation turnRate = (deltaBearing + azimuth / 5) / deltaTime; // rotate with target motorOutput = 0.5 * turnRate / maxTurnRate; // calculate motor output motor(-motorOutput, motorOutput); // apply turn rate // Fire if target is within weapon envelope if (D >= 0 && a > minAngle - 2 && a < maxAngle + 2 && azimuth > -2 && azimuth < 2 && fireTime < abstime()) { fire(0.2); // fire fireTime = abstime() + it + 0.1; // wait until round hit (or not) message("Firing at range " + distance(position, target.position) + " m."); // show off performance } } } } object object::ScanForTarget(float range) // does one scan sweep for targets within certain range { object target = null; // search for nearest target for (int i = AlienAnt; i <= AlienWorm; i++) { object item = radar(i, 0, 360, 0, range); // scan for specific target type if (item != null) // if one found { target = item; // it becomes the target range = distance2d(position, target.position); // only pick up new targets closer than this one } } return target; }
Дозаправщик (FieldRefuel)
Цель этой программы — увеличить длительность атаки ботами. Очень большое количество энергии тратится на перемещения с поля боя на базу, подзарядку и возвращение обратно. Эта программа позволяет создавать бота, который будет заниматься исключительно дозаправкой всех остальных роботов.
// FieldRefuel -- The purpose of this program is to extend the // range of attack bots. It takes them too much energy to get // out in the field to have to go back and refuel, so I just // let them run as they will and have this program running on // a dedicated bot all the time. // // It runs in conjunction with a public function I have on all // my bots called FlatGround - when their energy level gets below // 1/4, they look for the nearest flat spot at least 50 meters // away from all enemies and goes to sit there to wait for // refuelling. This prevents the refuel bot from sliding off a // hillside and botching the switch. // // The bot that runs this sits at the power station, and when a // bot gets to 1/4 energy it goes out to its position. The 2nd // goto(bot.position) is to compensate for movement between the // time that it hit the low power mark and found flat ground. // // It goes out to the downed bot, swaps cells (it assumes the // fuel bot is holding 1 full cell at all times), and refuels. // When it's done, it pulls back off the pad to make room for // others. extern void object::FieldRefuel() { object power=radar(PowerStation); object bot=radar(TrackedShooter); //only watches 1 bot errmode(0); //don't exit on errors while(true) //infinite loop { while(bot.energyCell.energyLevel < 0.26) //1/4 energy { goto(bot.position); wait(1); goto(bot.position); //movement correction drop(Behind); //switch cells grab(); turn(90); drop(); turn(-90); grab(Behind); drop(); turn(90); grab(); goto(power.position); //refuel wait(7); move(-5); } } }
Муравьеубийца!
Улучшенная программа для убийства муравьев. Присутствуют баги, так что пользуйтесь аккуратно.
Предназначена для ботов WingedShooters.
extern void object::KillAnts() { //preparation object ant; float angle; float sin1; object repair; object power; object ship; ant=radar(AlienAnt); //co kdyby tu uz zadnej ant nebyl? //rise 30metres while(altitude<30){ jet(1); } ant=radar(AlienAnt); //main loop while(radar(AlienAnt)!=null){ if(ant==null){ break; } if(temperature>0.8){ while(altitude!=0){ jet(-1); } wait(2); } if(shieldLevel<0.5){ repair=radar(RepairCenter); goto(repair.position); while(shieldLevel<1){ wait(1); } } if(energyCell.energyLevel<0.25){ power=radar(PowerStation); goto(power.position); while(energyCell.energyLevel<1){ wait(1); } while(altitude<30){ jet(1); } } while(altitude<20){ jet(1); } //move 20 metres ?before? ant ant=radar(AlienAnt); turn(direction(ant.position)); move(distance(position,ant.position)-20); //descent //5 metres above ant if(altitude>ant.altitude){ while(altitude>ant.altitude){ jet(-1); } } if(altitude<ant.altitude){ while(altitude<ant.altitude){ jet(1); } } turn(direction(ant.position)); //aim! angle=(altitude*altitude)+(distance2d(position,ant.position)*distance2d(position,ant.position)); angle=sqrt(angle); sin1=distance2d(position,ant.position)/angle; angle=acos(sin1); ant=radar(AlienAnt); turn(direction(ant.position)); aim(angle); fire(0.5); } ship=radar(SpaceShip); goto(ship.position); }
Список item`ов
Это не совсем программа. Это — список каждой (!) вещи в colobot, включая такие параметры, как высота и радиус. Включает хорошо написанную документацию, но на английском. Также приведены полезные функции, которые можно использовать при программировании.
num - [Tallest Point][Radi-Clearance] Name ie. ### - [Heigh][Radi-] Name 502 - [02.00][02.25] Alien Ant If you use the tallest point and radi-clearance numbers i suggest that you add a few meters to them, these are the absolute minimum(of the maximum) clearances to the next 1/4 of a meter. I used a Winged Flyer to get these measurements so if your using a shilder(or other large bot) you may have to add an additional 1 or 2 meters. Also if the object is larger in the air than on the ground, the air measurement is taken at the widest part. How do you use this information, just like you would use the name of an object i.e. Radar(5,0,360,0,800); // is the same as: Radar(BotFactory,0,360,0,800); // this means you now have a list of EVRYTHING detectable by the Radar // And all the clearance stats you need to avoid them :P 0 - [--.--][--.--] <-- This is your new best friend! Using 0 in a radar command will return the closest(or farthest depending what you have your radar command set for) ITEM OF ANY CATEGORY! The following example isn’t very practical(and my not even work), it's just a little something to get your mind going. You could use this and simply check for lets say any Alien like this: /---------------------------------------------------------------\ |object Item; | |Item = radar(0,0,360,0,45); | |//501 to 505 is Aliens | |if((abs(Item.category)>=501)&&(abs(Item.category)<=505)) | |{ | | //Aim the cannon | | fire(0.25); //Kill it | |} | \---------------------------------------------------------------/ Now I don’t know how practical of an implementation this is but you get the idea of some uses, i would say that the use of this "0" would be better suited for avoiding objects rather than trying to kill something, because if a bush or tree is closer than the Ant its going to detect the bush or tree instead. Now I’m sure with some thought you can come up with a way to avoid this problem but hey i have to leave you something to think about :P i use "abs(Item.category)" to return the numeric category value if you just used "Item.category" it would return the name of the object if it has one, and frankly the Name of the object may work, i believe that Colobot sees the name as a numeric value. I just haven’t bothered to test that yet. ============================ Full Listing ============================ ### - [Heigh][Radi-] Name; Levels found on and/or more definitions. ====================================================================== 0 - [--.--][--.--] Wild Card, it is anything and everything! 2 - [19.50][32.25] Gantry Crane 3 - [22.50][20.00] Space Ship; Top Width of 8.25 4 - [08.00][03.00] Derrick 5 - [06.50][06.00] Bot Factory 6 - [03.50][06.00] Power Station 7 - [04.00][05.00] Ore Converter 8 - [05.00][05.25] Repair Center 9 - [07.75][02.75] Defense Tower 10 - [00.00][00.00] Alien Nest; Organic Material/hatchery?, however it is probably holding Orga mater 11 - [05.75][03.75] Research Center 12 - [04.75][02.75] Radar Station 13 - [05.25][04.00] Power Plant; Power Cell Factory 14 - [04.25][05.25] Auto Lab 15 - [10.25][07.00] Nuclear Power Station 16 - [00.00][00.00] Start Area; platform 17 - [00.00][00.00] Goal Area; platform 18 - [04.75][02.75] Information exchange post 19 - [17.25][06.50] Power Captor 20 - [25.25][07.75] Target "the target stand" (+)==< looking thing; 03.25 at bace 21 - [00.00][00.00] Target2 "the actual Brass + Target" 22 - [03.75][04.50] Vault 23 - [06.25][18.75] Huston Mission Control 31 - [01.00][01.50] Titanium Ore 32 - [01.00][01.50] Uranium Ore 33 - [01.00][01.50] Titanium 34 - [01.00][01.50] Power Cell 35 - [01.00][01.50] Nuclear Power Cell 36 - [01.00][01.50] Orga Mater 37 - [01.00][01.50] Black Box 38 - [01.00][01.50] TNT Brick 50 - [00.00][00.00] green cross -> energy deposit. 51 - [00.00][00.00] red cross -> titanium ore. 52 - [00.00][00.00] yellow circle -> uranium ore. ### - [Heigh][Radi-] Name 60 - [01.25][02.00] Mine 61 - [01.00][01.75] Firework 63 - [01.00][02.00] Rocket Back Pack 70 - [01.25][01.75] Plant; Earth, Tropica, Centaury 71 - [01.25][01.75] Plant; Earth, Tropica, Centaury 72 - [01.25][01.75] Plant; Earth, Tropica, Centaury 73 - [01.25][01.75] Plant; Earth, Tropica, Centaury 74 - [01.25][01.75] Plant; Earth, Tropica, Centaury 75 - [00.00][00.00] Small Plant; Tropica 76 - [00.00][00.00] Small Plant; Tropica 77 - [00.00][00.00] Small Plant; Tropica 80 - [05.25][02.75] Large Plant; Tropica 81 - [04.75][02.50] Large Plant; Tropica 82 - [05.25][02.50] Large Plant; Tropica 83 - [05.25][03.00] Large Plant; Tropica 84 - [04.25][02.50] Large Plant; Tropica 85 - [01.25][01.75] Plant; Volcano 86 - [01.25][01.75] Plant; Volcano 87 - [01.25][01.75] Plant, Tall; Volcano 88 - [01.25][01.75] Plant; Volcano 89 - [01.25][01.75] Plant; Volcano 90 - [07.75][01.75] Tree; Earth 91 - [10.00][02.50] Tree; Earth 92 - [09.50][02.75] Tree; Earth 93 - [08.25][03.75] Tree; Earth ### - [Heigh][Radi-] Name 100 - [02.25][02.50] Practice Bot 110 - [02.50][02.50] Wheeled Grabber 111 - [02.50][02.50] Tracked Grabber 112 - [02.50][02.50] Winged Grabber 113 - [02.50][02.50] Legged Grabber 120 - [02.50][02.50] Wheeled Shooter 121 - [02.50][02.50] Tracked Shooter 122 - [02.50][02.50] Winged Shooter 123 - [02.50][02.50] Legged Shooter 130 - [02.50][02.50] Wheeled Orga Shooter 131 - [02.50][02.50] Tracked Orga Shooter 132 - [02.50][02.50] Winged Orga Shooter 133 - [02.50][02.50] Legged Orga Shooter 140 - [02.50][02.50] Wheeled Sniffer 141 - [02.50][02.50] Tracked Sniffer 142 - [02.50][02.50] Winged Sniffer 143 - [02.50][02.50] Legged Sniffer 200 - [03.00][03.00] Thumper 201 - [03.25][03.00] Phazer Shooter35 202 - [03.50][03.00] Recycler 203 - [04.50][03.00] Shielder; Height 3.00 when not active 210 - [02.50][02.50] Subber 211 - [02.25][02.50] Target Bot 250 - [00.00][00.00] Way Point ### - [Heigh][Radi-] Name 260 - [00.00][00.00] Blue Flag 261 - [00.00][00.00] Red Flag 262 - [00.00][00.00] Green Flag 263 - [00.00][00.00] Yellow Flag 264 - [00.00][00.00] Purple Flag 270 - [01.00][01.50] KeyA - Blue 271 - [01.00][01.50] KeyB - Red 272 - [01.00][01.50] KeyC - Green 273 - [01.00][01.50] KeyD - Yellow 300 - [02.00][01.75] Me 302 - [02.00][01.75] Tech (looks a lot like "Me" in some levels) 400 - [01.50][02.25] Barrier-Short; 1.5 width (about radi-of bot) 401 - [01.50][03.50] Barrier-Long; 1.5 width (about radi-of bot) 500 - [07.25][06.25] Alien Queen 501 - [02.00][02.25] Alien Egg 502 - [02.00][02.25] Alien Ant 503 - [01.25][02.00] Alien Spider 504 - [02.25][02.25] Alien Wasp 505 - [00.00][00.00] Alien Worm 600 - [02.50][03.00] A Wreckage wild card! for Recyclables /* All Wreckage's are all 600, the 60_ is the .category 600 - [01.75][02.00] Wreckage; Whelled Grabber, Recyclable 601 - [01.50][02.00] Wreckage; Sunken Whelled Grabber, Recyclable 602 - [02.00][03.00] Wreckage; Tracked Shooter, Recyclable 603 - [02.00][03.00] Wreckage; Sunken Tracked Shooter, Recyclable 603 - [02.25][02.50] Wreckage; Sunken Recyceler, Recyclable 605 - [02.50][02.50] Wreckage; Recyceler, Recyclable */ 606 - [04.00][06.00] Ruin; Bot Factory 607 - [01.50][02.25] Ruin; Ore Converter Door 608 - [01.25][02.00] Ruin; Support, C shaped hunk of mettel 609 - [01.50][02.25] Ruin; Brick like, Radar Station Base 610 - [01.25][05.00] Ruin; Ore Converter 611 - [08.75][13.25] Ruin; Space Ship Bace 612 - [09.50][08.50] Ruin; Space Ship Top 700 - [02.00][02.00] Crystal; Crystalium 701 - [02.50][02.50] Crystal; Crystalium 702 - [03.50][02.75] Crystal; Crystalium 703 - [06.00][04.50] Crystal; Crystalium 710 - [06.00][04.25] Green Mega Stalk; Stranve Plant, Small 711 - [07.50][03.50] Green Mega Stalk; Stranve Plant, Small 712 - [06.25][03.25] Green Mega Stalk; Stranve Plant, Small 713 - [08.75][05.25] Green Mega Stalk; Stranve Plant, Med 714 - [12.50][07.25] Green Mega Stalk; Stranve Plant, Large 715 - [12.50][07.25] Green Mega Stalk; Stranve Plant, Large with Green Shield like apperatice 715 - [--.--][22.00] #715's Green Shield (affects flyers ability to fly); you cannot fly over it 731 - [02.50][02.00] Mushroom; non corrosive 732 - [02.50][02.00] Mushroom; corrosive 900 - [04.00][05.02] Lunar Lander; Derelict of Apollo Mission 901 - [02.05][03.25] Lunar Roving Vehicle 902 - [00.00][00.00] American flag; Derelict of Apollo Mission 903 - [01.75][01.75] Inverted Satelite Dish; Derelict of Apollo Mission 904 - [02.75][02.00] Satelite Dish; Derelict of Apollo Mission 910 - [04.50][03.75] Home ### - [Heigh][Radi-] Name -If you have any additions to this list please let me know at RossK_WC2@hotmail.com Aim: Ens1747 ICQ: 1747522 ==================================================== And incase if your wondering how i extracted this data, here you go: ----------------------------------------------------------------------------------- //Outputs all objects on the map to a file //Note: Wrecks are all 600 no mater what .category extern void object::FindNewItems() // This prossess takes some time { file filSearch(); object Named; //File is output to "...\Colobot\files\Search.txt" filSearch.open("Search.txt", "w"); for(int I=1; I<=1000; I++) { Named = radar(I); if(Named!=null) { filSearch.writeln("" + I + " - " + Named.category); } } filSearch.close(); } ----------------------------------------------------------------------------------- // just pull your bot up to an object and run this app, search for the largest // result by circling the Object and probing from difrent directions extern void object::ObjectLookUp() { object Named; Named = radar(0,0,90,0,10); //useing radar(0,..) for wildcard, it'll detect anything if(Named != null) { message("Dist From (" + Named.category + ", " + abs(Named.category) + "): " + (distance2d(position, Named.position))); } } ----------------------------------------------------------------------------------- extern void object::ObjectLookAllUp() { object Named; float fltGole[]; int j=0; for(int i=0;i<=1000;i++) { Named = radar(i,0,90,0,5); if(Named != null) { fltGole[j++] = i; message("Dist From (" + Named.category + ", " + abs(Named.category) + "): " + (distance2d(position, Named.position))); } } message("All that worked: " + fltGole); } ----------------------------------------------------------------------------------- //If you dont understand this i have nothing to say :P //Fly above the object so you can just move freely extern void object::HowHigh() { object Named; Named = radar(0,0,360,0,3); //useing radar(0,..) for wildcard, it'll detect anything message("Elevation: " + (position.z-topo(Named.position))); } ----------------------------------------------------------------------------------- //Marks closest object of type ### with a waypoint to make it easy to find. extern void object::MarkUnknows() { object objWhat; objWhat=radar(###); //Put In Desired Object Number produce(objWhat.position, 0, WayPoint, ""); }
Новый радар!
Улучшенная версия процедуры radar (). Позволяет находить все на карте. Не нужно строительство отдельного здания для этого.
extern void object::main() { object item; int i=0; item = retobject(i); //item =newradar(PhazerShooter,0,360,0,1000,1); //goto(space(item.position)); while(true) { //goto(space(item.position)); message(item.category); wait(0.2); i++; item = retobject(i); }; } public object object::newradar(int category, float angle, float focus, float min, float max,float way) { ipf(1800); object currect=retobject(0); object itemx=null; int i=0; int needdistance; bool checkfornomtems = false; //1 to check for no possition items //else don't if (way == -1) { needdistance = min - 0.01; } else needdistance = max + 0.01; do { i++; if(currect.category == category) { if((position.x != nan) or (checkfornomtems == true)) { float dis = direction(currect.position) - angle; if (dis < 0) { dis = -dis; } if (dis > 180) { dis = 360 - dis; } if((distance(this.position,currect.position) >= min) && (distance(this.position,currect.position) <= max) && ( (distance(this.position,currect.position) * way) < (needdistance * way)) && (dis <= focus /2) ) { itemx=currect; needdistance = distance(this.position,currect.position); } } } currect=retobject(i); } while(currect != null); ipf(200); return itemx; }
Автоперезарядка башен
Для роботов WeeledGrabber (или TrackedGrabber). Отличная программа, решающая проблему перезарядки башен. Роботы будут стоять и сканировать уровень заряда всех башен. Как только уровень падает до 1/3 бот приедит к башне, перезарядит батарейку, а пустую отвезет на станцию перезарядки. Программа протестирована на 3 башнях. ;-)
extern void object::advChargeTowers() { object tower, battery; object power; int a; float dist; errmode(0); if (load!=null) { drop(); } dist=0; while (true) { if (energyCell.energyLevel<0.3) { power=radar(PowerStation); a=goto(power.position); if (a!=0) { message("please free way to the Power Station!"); return; } while (energyCell.energyLevel!=1) { wait(1); } } tower=radar(DefenseTower,0,360,dist); if (tower==null) { dist=0; tower=radar(DefenseTower,0,360,dist); } if (tower.energyCell.energyLevel<0.3) { battery=radar(PowerCell,0,360); if (battery==null) { message("No batteries :-(",DisplayWarning); break; } goto(battery.position); grab(); if (load.energyLevel!=1) { power=radar(PowerStation); a=goto(power.position); if (a!=0) { message("please free way to the Power Station!"); return; } while (load.energyLevel!=1) { wait(1); } } goto(tower.position); drop(Behind); grab(); turn(90); drop(); turn(-90); grab(Behind); drop(); //SwitchCell1(); //break; turn(90); grab(); power=radar(PowerStation); a=goto(power.position); if (a!=0) { message("please free way to the Power Station!"); return; } while (load.energyLevel!=1) { wait(1); } goto(space(position,5,25)); drop(); } else { dist=distance(tower.position,position)+1; } } }
Радароупроститель!
Класс, упрощающий работу с радаром. Теперь нет необходимости в запоминании множества кодов, а можно использовать красивые константы.
Пример использования:
object item; otherCategories otherCats(); // Создаем экземпляр класса. item = radar(otherCats.Mushroom1); // Ищем ближайший объект (Mushroom)
public class otherCategories { static int Firework = 61; static int Bag = 63; static int Greenery0 = 70; static int Greenery1 = 71; static int Greenery2 = 72; static int Greenery3 = 73; static int Greenery4 = 74; static int Greenery5 = 75; static int Greenery6 = 76; static int Greenery7 = 77; static int Greenery10 = 80; static int Greenery11 = 81; static int Greenery12 = 82; static int Greenery13 = 83; static int Greenery14 = 84; static int Greenery15 = 85; static int Greenery16 = 86; static int Greenery17 = 87; static int Greenery18 = 88; static int Greenery19 = 89; static int Tree0 = 90; static int Tree1 = 91; static int Tree2 = 92; static int Tree3 = 93; static int RuinBotFactory = 606; static int RuinDoor = 607; static int RuinSupport = 608; static int RuinRadar = 609; static int RuinConvert = 610; static int RuinBaseCamp = 611; static int RuinHeadCamp = 612; static int Quartz0 = 700; static int Quartz1 = 701; static int Quartz2 = 702; static int Quartz3 = 703; static int Mushroom1 = 731; static int Mushroom2 = 732; static int MegaStalk0 = 710; static int MegaStalk1 = 711; static int MegaStalk2 = 712; static int MegaStalk3 = 713; static int MegaStalk4 = 714; static int MegaStalk5 = 715; static int ApolloLEM = 900; static int ApolloJeep = 901; static int ApolloFlag = 902; static int ApolloModule = 903; static int ApolloAntenna = 904; static int Home = 910; }
Робот-гувернантка
Для робота Winged (желательно). Робот занимается тем, что мониторит других ботов, и заменяет им батарейки, если у них заряд упал ниже определенной величины(настраивается в константах). Разряженные батарейки автоматически доставляет в центр перезарядки.
// (c) Minhiriath Condravox 2002 // Harvests a number of categories of objects and stores them at // predetermined storage sites. // Automatically restores energy if drops below fENERGYLOW. // Automatically repairs shields if drops below fSHIELDLOW. extern void object::Harvest() { float fSHIELDLOW=0.50, fENERGYLOW=0.25; int iDROPTURN = 4, iMAXHARVESTPRG = 4; int iHarvestPRG[iMAXHARVESTPRG][3], i=0; iHarvestPRG[i][0] = Titanium; iHarvestPRG[i][1] = SpaceShip; iHarvestPRG[i++][2] = 15; iHarvestPRG[i][0] = PowerCell; iHarvestPRG[i][1] = PowerStation; iHarvestPRG[i++][2] = 5; iHarvestPRG[i][0] = NuclearCell; iHarvestPRG[i][1] = PowerStation; iHarvestPRG[i++][2] = 5; iHarvestPRG[i][0] = TitaniumOre; iHarvestPRG[i][1] = Converter; iHarvestPRG[i++][2] = 5; int iHarvestPRGNr = 1; object oHarvestItem; int iErrCode, iCount, iNrHarvests = 0; boolean bPaused = false; while (true) { // Check energy and shields if ( CheckAndRepowerEnergy(fENERGYLOW) > 0) { break; } if ( CheckAndRepowerShields(fSHIELDLOW) > 0) { break; } // Find closest harvest item at at least range x from store site and get it oHarvestItem = FindHarvestObject(iHarvestPRG[iHarvestPRGNr][0], iHarvestPRG[iHarvestPRGNr][1], iHarvestPRG[iHarvestPRGNr][2]); if ( oHarvestItem!=null ) { // Go to harvest item errmode(0); if ( goto(oHarvestItem.position, 10)<1 ) { // Grab if (grab(InFront)==0) { iNrHarvests++; } else { message("Harvester bot couldn't get object!", DisplayError); } errmode(1); // Recheck if there is a object held if (load != null) { if ( CheckAndRepowerEnergy(fENERGYLOW) > 0) { break; } if ( CheckAndRepowerShields(fSHIELDLOW) > 0) { break; } // find store site and return to it with object if ( FindAndMoveToObject(iHarvestPRG[iHarvestPRGNr][1], 0, iHarvestPRG[iHarvestPRGNr][2])>0 ) { message("Harvester bot unable to reach store site!", DisplayError); break; } // Wait for power or nuclear cell to reload if ((iHarvestPRG[iHarvestPRGNr][1]==PowerStation) && ((load.category==PowerCell) || (load.category==NuclearCell))) { while (load.energyLevel < 1.0); } // Try to drop object or rotate until empty spot found DropItem(); // Take distance while converting TitaniumOre and get Titanium out if ( (iHarvestPRG[iHarvestPRGNr][0]==TitaniumOre) && (iHarvestPRG[iHarvestPRGNr][1]==Converter) ) { move(-3); wait(15); move(3); grab(); turn(180); move(6); DropItem(); } } } else { message(oHarvestItem.position+" from "+position+"!", DisplayError); break; } errmode(1); } else { // Display amount of type harvested. if (iNrHarvests > 0) { message("Harvested total of "+iNrHarvests+" "+iHarvestPRG[iHarvestPRGNr][0]+"."); wait(2); } // Start harvesting next type iHarvestPRGNr++; if (iHarvestPRGNr >= iMAXHARVESTPRG) { iHarvestPRGNr = 0; } message("Switched to harvesting "+iHarvestPRG[iHarvestPRGNr][0]+"."); iNrHarvests = 0; } } message("Harvester bot stopped harvesting!", DisplayError); } // Find nearest object of category iDestCat and move towards object if found. // Doesn't move if destination is less than iMinRange away. // Returns error codes : // 0 object found and reached // 1 object found but not reached // 2 object not found int object::FindAndMoveToObject(int iDestCat, int iMinRange, int iMinDist) { int iErrCode = -1; object oDest; errmode(0); if ( (oDest = radar(iDestCat, 0, 360, iMinRange)) != null) { if ( distance2d(position, oDest.position)>iMinDist ) { if ( goto(oDest.position, 10) == 0) { iErrCode = 0; } else { iErrCode = 1; } } else { iErrCode = 0; } } else { iErrCode = 2; } errmode(1); return(iErrCode); } // Checks bot energy cell power level and repowers at nearest PowerStation if // dropped below fEnergyLow. // Returns error codes: // -1 energy above fEnergyLow // 0 energy restored successfully // 1 energy needs restoring but couldn't reach PowerStation // 2 energy needs restoring but no PowerStation found int object::CheckAndRepowerEnergy(float fEnergyLow) { object oPowerStation; int iErrCode=-1; // Automatically repower energy if low if (energyCell.energyLevel < fEnergyLow) { message("Harvester bot recharging."); iErrCode = FindAndMoveToObject(PowerStation, 0, 0); switch (iErrCode) { case 0 : while (energyCell.energyLevel < 1.0); break; case 1 : message("Harvester bot en route to PowerStation - can't get there!", DisplayWarning); FindAndMoveToObject(SpaceShip, 0, 5); break; case 2 : message("Harvester bot recharging - can't find PowerStation!", DisplayWarning); FindAndMoveToObject(SpaceShip, 0, 5); break; } } return (iErrCode); } // Checks bot shields and repowers at nearest RepairCenter if dropped below fShieldLow. int object::CheckAndRepowerShields(float fShieldLow) { object oRepairCenter; int iErrCode=-1; // Auto repair if shield low if (shieldLevel < fShieldLow) { message("Harvester bot repairing!", DisplayWarning); iErrCode = FindAndMoveToObject(RepairCenter, 0, 0); switch (iErrCode) { case 0 : while (shieldLevel < 1.0); break; case 1 : message("Harvester bot en route to RepairCenter - can't get there!", DisplayWarning); FindAndMoveToObject(SpaceShip, 0, 5); break; case 2 : message("Harvester bot recharging - can't find RepairCenter!", DisplayWarning); FindAndMoveToObject(SpaceShip, 0, 5); break; } } return (iErrCode); } // Find nearest harvestable iFindCat object at least fStoreSize away from iStoreSiteCat object object::FindHarvestObject(int iFindCat, int iStoreSiteCat, float fStoreSize) { object oStoreSite=radar(iStoreSiteCat), oFind; int iMinDist = 0; if (oStoreSite!=null) { do { oFind = radar(iFindCat, 0, 360, iMinDist); if (oFind!=null) { if ( distance2d(oStoreSite.position, oFind.position)<fStoreSize ) { oFind=null; iMinDist++; } } else { break; } } while ( (oFind==null) && (iMinDist < 1000) ); } else { message("Can't store at "+iStoreSiteCat+" - not present."); oFind=null; } return (oFind); } // Try to drop object or rotate until empty spot found void object::DropItem() { int iDROPTURN = 1; int iCount = 0, iErrCode = -1; errmode(0); while ( (drop(InFront) > 0) & (iCount <360) ) { turn(iDROPTURN); iCount += iDROPTURN; if (iCount >= 360) { message("Harvester bot unable to drop object!", DisplayError); iCount = 0; } } errmode(1); }
Авто-создание роботов
Продвинутая программа для роботов-грабберов для создания других ботов. Она находит Титаниум, перемещает его на станцию создания роботов, ждет 25 секунд, берет заряженную батарейку, помещает его в бота и отьезжает, чтобы новосозданный робот мог оттуда выехать. Также, если необходимо, она подождет, пока батарейка зарядится на станции подзарядки.
extern void object::BotCreate() { object metal; object factory; object power; object recharge; metal=radar(Titanium); factory=radar(BotFactory); power=radar(PowerCell); recharge=radar(PowerStation); goto(metal.position); grab(); goto(factory.position); move(1); drop(InFront); move(-3); wait(25); goto(power.position); grab(); if(power.energyLevel!=1){ if(PowerStation==1){ goto(recharge.position); while(power.energyLevel!=1){ wait(0.1); } } else{ turn(-90); move(15); drop(); turn(180); move(15); } } goto(factory.position); drop(); move(-2); turn(90); move(10); }
Автоогонь
Интересная программа для стреляющих роботов. Позволяет Вам сконцентрироваться на управлении, когда как огонь по вражеским целям будет вести программа.
// Redesinged script copied from AlienKiller by Yenz // This code almost entirely copied from the AlienKiller script // made by Yenz. I wanted to make a simple cyborg script where // a bot is manually piloted, but has precision aiming. Just run // this script instead of hitting the fire button and the bot // will aim and fire once at the closest alien in front of it. // // Now rewritten to include both pitch and roll correction // Reports warnings for temperature, shield and energy levels // in percentages. extern void object::RoboAim2() { object alien; float angle; int alienList[], nr; nr = 0; alienList[nr++] = AlienWasp; alienList[nr++] = AlienAnt; alienList[nr++] = AlienSpider; alienList[nr++] = AlienWorm; alienList[nr++] = AlienEgg; alien = radar(alienList,0,90,0,45); if(alien != null) //if there still is a alien left { if(distance(position, alien.position) < 45) { turn(direction(alien.position)); //coarse turn adjustment; angle = atan(((topo(alien.position)+alien.altitude)-(topo(position)+altitude))/distance2d(position, alien.position)); //determine absolute aiming angle // calulate and turn to adjust for roll angle if(roll < 0) turn((angle-pitch)*cos(roll)*cos(90-roll)); else turn(-((angle-pitch)*cos(roll)*cos(90-roll))); aim(angle-pitch); //aim at the target fire(0.1); //kill it } } else message("No target"); if(temperature > 0.8) message("Engines at " + (temperature * 100) + "%"); if(shieldLevel < 0.2) message("Warning-Shield at " + (shieldLevel * 100) + "%"); if(energyCell.energyLevel < 0.2) message("Warning-Energy at " + (energyCell.energyLevel * 100) + "%"); }
Младший научный работник
Программа для исследовательских центров. Робот автоматически меняет разряженные батарейки. Он ищет другие заряженные батарейки и помещает их в исследовательский центр.
extern void object::Research() { object power; object research; power=radar(PowerCell); research=radar(ResearchCenter); goto(power.position); if(power.energyLevel!=1){ turn(-90); move(10); } grab(); goto(research.position); drop(); }
Вася-ремонтник
Программа для бота Shielder, которая позволяет в автоматическом режиме ремонтировать поврежденные здания. Он также может ремонтировать и других поврежденных роботов
// This program was designed for the Shielder // to repair stationary objects (i.e. buildings). // If you want to include (damaged) bots, they // must remain still during the repair. extern void object::RepairBase() { bool includeBots = false; // You decide. object allies[]; allies = findAllies(includeBots); for(int i = 0; i < sizeof(allies); i++) { if(distance2d(position,allies[i].position) > 26) { turn(direction(allies[i].position)); for(int d = 24; d >= 5; d--) { point dest = triangulate2d(allies[i].position,d); errmode(0); if( goto(dest) == 0 ) break; errmode(1); } if(distance2d(position,allies[i].position) > 26) { message("Could not goto " + allies[i].category + ".", DisplayError); return; } } while(allies[i].shieldLevel < 1) shield(1,distance2d(position,allies[i].position)); message(allies[i].category + " repaired. (" + (i+1) + "/" + sizeof(allies) + ")", DisplayInfo); shield(0,0); } message("All repaired.", DisplayInfo); } object[] object::findAllies(bool repairAll) { int allyList[]; int i = 0; allyList[i++] = Derrick; allyList[i++] = BotFactory; allyList[i++] = PowerStation; allyList[i++] = PowerCaptor; allyList[i++] = Converter; allyList[i++] = RepairCenter; allyList[i++] = DefenseTower; allyList[i++] = ResearchCenter; allyList[i++] = RadarStation; allyList[i++] = ExchangePost; allyList[i++] = PowerPlant; allyList[i++] = AutoLab; allyList[i++] = NuclearPlant; if(repairAll) { allyList[i++] = WingedGrabber; allyList[i++] = TrackedGrabber; allyList[i++] = WheeledGrabber; allyList[i++] = LeggedGrabber; allyList[i++] = WingedShooter; allyList[i++] = TrackedShooter; allyList[i++] = WheeledShooter; allyList[i++] = LeggedShooter; allyList[i++] = WingedOrgaShooter; allyList[i++] = TrackedOrgaShooter; allyList[i++] = WheeledOrgaShooter; allyList[i++] = LeggedOrgaShooter; allyList[i++] = WingedSniffer; allyList[i++] = TrackedSniffer; allyList[i++] = WheeledSniffer; allyList[i++] = LeggedSniffer; allyList[i++] = Thumper; allyList[i++] = PhazerShooter; allyList[i++] = Recycler; allyList[i++] = Shielder; allyList[i++] = Subber; } object allies[]; object tempObject; i = 0; int j = 0; int k = 0; while( (tempObject = retobject(i++)) != null ) { for(j = 0; j < sizeof(allyList); j++) { if(tempObject.category == allyList[j] and tempObject.shieldLevel < 1) { message(tempObject.category + " needs repair."); allies[k++] = tempObject; break; } } } for(i = sizeof(allies)-1; i > 0; i--) { for(j = 0; j < i; j++) { if(distance2d(position,allies[j].position) > distance2d(position,allies[j+1].position)) { tempObject = allies[j]; allies[j] = allies[j+1]; allies[j+1] = tempObject; } } } return allies; } point object::triangulate2d(point p,int dist) { point dest = p; float angl = orientation+180; if(angl > 360) angl -= 360; dest.x += cos(angl) * dist; dest.y += sin(angl) * dist; return dest; }
Джеки Чан
Продвинутая программа для атаки. Применяет некоторые трюки, позволяя достичь превосходства в борьбе с другими роботами.
extern void object::Attack2() { ipf(800); int cat[]; cat[0] = AlienAnt; cat[1] = AlienWorm; cat[2] = AlienWasp; cat[3] = AlienSpider; cat[4] = AlienEgg; object target; float dir; float dis; float dif; float ang; boolean hot = false; while((target = radar(cat)) != null) { if(temperature > 0.8) hot = true; if(temperature < 0.2) hot = false; if(hot and topo(position) > 1) jet(-1); else { dis = distance2d(position,target.position); dif = target.position.z-position.z; ang = atan(dif/(dis-5)); jet(1-ang/-15); } dis = distance2d(position,target.position); dif = target.position.z-position.z; ang = atan(dif/dis); if(altitude == 0) ang -= pitch; dir = direction(target.position); if(dis < 40 and abs(ang) < 20 and abs(dir) < 112.5) turn(dir); else motor(1-dir/45,1+dir/45); dis = distance2d(position,target.position); dif = target.position.z-position.z; ang = atan(dif/dis)-pitch; aim(ang); dir = direction(target.position); if(dis < 40 and abs(ang) < 20 and abs(dir) < 5) fire(0.1); if(dis > 40) maint(); } } void object::maint() { if(energyCell.energyLevel < 0.35) { object pwr = radar(PowerStation); if(pwr != null) { goto(pwr.position,5); while(energyCell.energyLevel < 1) wait(1); } } if(shieldLevel < 0.45) { object rep = radar(RepairCenter); if(rep != null) { goto(rep.position,5); while(shieldLevel < 1) wait(1); } } }
Брюс Ли
Еще одна программа для атаки. Эффективно против всех типов врагов (кроме AlienQueen, конечно ;-) ). Автоматически себе перезаряжает, если необходимо.
// Air Superiority Fighter // Version 1.00 // by Black Eagle // blackeagle@gamebox.net // For WingedShooter and WingedOrgaShooter // Features : // - Effective against all types of enemies (except AlienQueen, of course! :) ) // - Low energy usage for firing // - Recharges and repairs itself when needed // - Avoids water while cooling down (if it can) // // Notes : // * Don't use first person camera while using this program // because of the pitch bug. It will drop the accuracy // severely. // // * This bot can take the following commands via an // information exchange post : // - wsguardrange : change the guard range // - wsfirerate : change the firing rate // - wsfiredelay : change the firing delay // - wsguardpoint : change the guard point with the // wsguardpointx as the x value and // wsguardpointy as the y value // ( This bot DOESN'T check if the guard // point is covered with water or not, // so be careful when using this command ) extern void object::AirSuperiority() { object item; int err1; int err2; int temp1; int temp2; int tempdir; int tempdis; float curdir; float nexttopo; float turnmotor; float firerate; float enemydir; float enemylife; float fired; object enemy; object enemy1; point guardpoint; point togo; errmode(0); ipf(800); guardpoint = position; int list[], i; float maxsearch; float maxsearchorig; int firedelay; int firedelaytime; enemylife = 0; fired = 0.15; temp1 = 0; firedelay = 0; firedelaytime = 12; // Firing delay before another fire firerate = 0.25; // Firing Rate maxsearch = 300; // Max. search area. maxsearchorig = maxsearch; i = 0; list[i++] = AlienAnt; list[i++] = AlienWasp; list[i++] = AlienSpider; list[i++] = AlienEgg; list[i++] = AlienWorm; while(true){ if (radar(PowerStation) == null) { message("No Power Station Found. Aborting...",DisplayError); break; } if (energyCell.energyLevel < (0.4+fired) | shieldLevel < 0.4) { // if so: item = radar(PowerStation); if ( item != null & distance2d(item.position,position) <= 50) { if ( item != null ) // station found ? { err1 = goto(item.position); // go there if (err1 != 0) { err2 = goto(space(item.position,8,120,4)); if (err2 != 0) { while(err2 != 0){ wait(1); err2 = goto(space(item.position,8,120,4)); } } message("Power Station occupied, waiting...",DisplayInfo); while (err1 != 0) { wait(1); err1 = goto(item.position); } } while ( energyCell.energyLevel < 1 ) { // until recharged: wait(1); // wait fired = 0.15; } } if (shieldLevel < 1){ item = radar(RepairCenter); if ( item != null ) // repairstation found ? { err1 = goto(item.position); // go there if (err1 != 0) { err2 = goto(space(item.position,8,120,4)); if (err2 != 0) { while(err2 != 0){ wait(1); err2 = goto(space(item.position,8,120,4)); } } message("Repair Center occupied, waiting...",DisplayInfo); while (err1 != 0) { wait(1); err1 = goto(item.position); } } while ( shieldLevel < 1 ) { // until recharged: wait(1); // wait } } } } else { enemy = radar(PowerStation); } } if (energyCell.energyLevel >= (0.4+fired) & shieldLevel >= 0.4) enemy = radar(list,0,360,0,maxsearch,1); if (testinfo("wsguardrange",1000)) { maxsearch = receive("wsguardrange",1000); deleteinfo("wsguardrange",1000); } if (testinfo("wsfirerate",1000)) { firerate = receive("wsfirerate",1000); deleteinfo("wsfirerate",1000); } if (testinfo("wsfiredelay",1000)) { firedelaytime = receive("wsfiredelay",1000); deleteinfo("wsfiredelaytime",1000); } if (testinfo("wsguardpoint",1000)) { guardpoint.x = receive("wsguardpointx",1000); guardpoint.y = receive("wsguardpointy",1000); deleteinfo("wsguardpoint",1000); } if (enemy != null & temperature < 0.75) { togo.x = (2*cos(orientation))+position.x; togo.y = (2*sin(orientation))+position.y; togo.z = position.z; if(position.z - topo(position) < 2 | position.z - topo(togo) < 2 | position.z < 1) jet(1); else { if(position.z - topo(position) > 10) jet(-0.2); if(enemy.category != AlienWasp and enemy.category != PowerStation) { if(atan(((position.z-enemy.position.z)/distance2d(position,enemy.position))) > 20) jet(-0.8); if(atan(((position.z-enemy.position.z)/distance2d(position,enemy.position))) < 15) jet(0.8); } else { if( enemy.category != PowerStation ) { if(position.z < enemy.position.z) jet(0.4); if(position.z > enemy.position.z) jet(-0.4); } } } turnmotor = distance(position,enemy.position)/150; if(turnmotor < 0) turnmotor = 0; if(turnmotor > 1) turnmotor = 0.5; enemydir = direction(enemy.position); while(enemydir < -180 | enemydir > 180) { if(enemydir < -180) enemydir = enemydir + 360; if(enemydir > 180) enemydir = enemydir - 360; } if(enemy.lifeTime > enemylife & enemy.lifeTime < (enemylife + 5)) { } else firedelay = 0; enemylife = enemy.lifeTime; if(firedelay > 0) firedelay = firedelay - 1; if (distance(enemy.position,position) > 45) { if(enemydir > 0) motor(turnmotor,1); if(enemydir < 0) motor(1,turnmotor); if(enemydir == 0) motor(1,1); } else { if(enemydir > -60 & enemydir < 60) { if(enemydir > 0) motor(turnmotor,1); if(enemydir < 0) motor(1,turnmotor); if(enemydir == 0) motor(1,1); } else motor(1,1); } aim((atan((position.z+1.5-enemy.position.z)/(distance2d(enemy.position,position)))*-1)-pitch); if(direction(enemy.position) < 5 & direction(enemy.position) > -5 & distance(enemy.position,position) < 45 & firedelay < 1){ fire(firerate); if(fired > 0) fired = fired - 0.02; firedelay = firedelaytime; } } if (enemy != null & temperature > 0.75) { temp1 = 0; enemy1 = radar(list,temp1,45,30,150,1); while(enemy1 != null) { temp1 = temp1 + 45; enemy1 = radar(list,temp1,45,30,150,1); } turn(temp1); togo.x = (4*cos(orientation))+position.x; togo.y = (4*sin(orientation))+position.y; togo.z = position.z; while(temperature > 0) { curdir = orientation; if (topo(position) > 0) { motor(1,1); jet(-0.1); togo.x = (8*cos(curdir))+position.x; togo.y = (8*sin(curdir))+position.y; togo.z = position.z; if (topo(togo) <= 0) { temp1 = 0; while (topo(togo) <= 0) { temp1 = temp1 + 15; enemy1 = radar(list,temp1,10,30,150,1); while(enemy1 != null) { temp1 = temp1 + 15; enemy1 = radar(list,temp1,10,30,150,1); } togo.x = (8*cos(curdir+temp1))+position.x; togo.y = (8*sin(curdir+temp1))+position.y; togo.z = position.z; } togo.x = (8*cos(curdir))+position.x; togo.y = (8*sin(curdir))+position.y; togo.z = position.z; temp2 = 0; while (topo(togo) <= 0) { temp2 = temp2 - 15; enemy1 = radar(list,temp2,10,30,150,1); while(enemy1 != null) { temp2 = temp2 - 15; enemy1 = radar(list,temp2,10,30,150,1); } togo.x = (8*cos(curdir+temp2))+position.x; togo.y = (8*sin(curdir+temp2))+position.y; togo.z = position.z; } if(-temp2 > temp1) tempdir = temp1; if(-temp2 <= temp1) tempdir = temp2; turn(tempdir); } } if (topo(position) <= 0) { motor(1,1); jet(-0.05); if(topo(togo) < 0) { temp1 = 0; tempdis = 10; while(topo(togo) < 0) { temp1 = temp1 + 45; togo.x = (tempdis*cos(curdir+temp1))+position.x; togo.y = (tempdis*sin(curdir+temp1))+position.y; togo.z = position.z; if(temp1 >= 360) { temp1 = 0; tempdis = tempdis + 15; } } turn(temp1); } } } } if (enemy == null & distance(position,guardpoint) > 3) { goto(guardpoint); } } }
TowerService
Программа для обслуживания множества башен и ботов. Для более эффективного использования Вы можете построить здание ExchangePost.
extern void object::ServiceTower2() { //resetExChgPst(); while(true) { if(load == null) getCell(); else { if(load.energyLevel < 1) maint(); loadTower(); } } } void object::resetExChgPst() { object towers[]; towers = findAndSortTowers(); for(int i = 0; i < sizeof(towers)-1; i++) finishService(towers[i]); } object object::getTower() { object towers[]; towers = findAndSortTowers(); for(int i = 0; i < sizeof(towers)-1; i++) { if(towers[i] != null and not currentlyBeingServiced(towers[i])) return towers[i]; } return null; } void object::getCell() { object bestCell = findBestCell(); if(bestCell == null) getCellFromTower(); else { myGoto(bestCell.position); errmode(0); grab(); errmode(1); } } object object::findBestCell() { object cell = radar(PowerCell); object bestCell = cell; float min = 0; while( (cell = radar(PowerCell,0,360,min)) != null ) { if(cell.energyLevel == 1) return cell; if(bestCell.energyLevel < cell.energyLevel) bestCell = cell; min = distance2d(position,cell.position) + 0.5; } return bestCell; } object[] object::findAndSortTowers() { object towers[]; int i = 0; float min = 0; while((towers[i] = radar(DefenseTower,0,360,min)) != null) min = distance2d(position,towers[i++].position) + 0.5; for(int j = i-1; j > 0; j--) { for(int k = 0; k < j; k++) { float energyLevel1 = -1; float energyLevel2 = -1; if(towers[k].energyCell != null) energyLevel1 = towers[k].energyCell.energyLevel; if(towers[k+1].energyCell != null) energyLevel2 = towers[k+1].energyCell.energyLevel; if(energyLevel1 > energyLevel2) { object temp = towers[k]; towers[k] = towers[k+1]; towers[k+1] = temp; } } } return towers; } void object::getCellFromTower() { object tower = getTower(); if(tower == null) return; if(tower.energyCell != null) { int cat[]; cat[0] = PowerStation; cat[1] = PowerCaptor; if(tower.energyCell.energyLevel < 0.5 and radar(cat) != null) { startService(tower); myGoto(tower.position); while(enemyIsNear() and tower.energyCell.energyLevel >= 0.125) wait(1); grab(); finishService(tower); } } } void object::loadTower() { object tower = getTower(); if(tower == null) return; if(tower.energyCell != null) { if(tower.energyCell.energyLevel < load.energyLevel) { startService(tower); myGoto(tower.position); while(enemyIsNear() and tower.energyCell.energyLevel >= 0.125) wait(1); swapCell(); finishService(tower); } } else { startService(tower); myGoto(tower.position); drop(); finishService(tower); } } void object::startService(object o) { if(radar(ExchangePost) == null) return; send(o.position.x + "/" + o.position.y,1,1000); } bool object::currentlyBeingServiced(object o) { return testinfo(o.position.x + "/" + o.position.y,1000); } void object::finishService(object o) { deleteinfo(o.position.x + "/" + o.position.y,1000); } void object::swapCell() { drop(Behind); grab(); turn(90); drop(); turn(-90); grab(Behind); drop(); turn(90); grab(); } void object::maint() { message("PowerCell needs recharge. Searching for energy sources..."); if(rechargePlanA() == false and rechargePlanB() == false) { message("Warning. No energy sources found!"); wait(5); return; } message("Recharge completed. Resuming job duties...", DisplayInfo); } bool object::rechargePlanA() { int cat[]; cat[0] = PowerStation; cat[1] = PowerCaptor; object pwrSource = radar(cat); if(pwrSource == null) return false; myGoto(triangulate2d(pwrSource)); myGoto(pwrSource.position); message("Recharging at " + pwrSource.category + "...",DisplayInfo); while(load.energyLevel < 1) wait(1); goto(space()); return true; } bool object::rechargePlanB() { object bestCell = findBestCell(); if(bestCell == null) return false; if(load.energyLevel < bestCell.energyLevel) { goto(bestCell.position); message("Swapping with better PowerCell...",DisplayInfo); drop(Behind); grab(); return true; } return false; } bool object::enemyIsNear() { int cat[]; cat[0] = AlienAnt; cat[1] = AlienWorm; cat[2] = AlienWasp; cat[3] = AlienSpider; object enemy = radar(cat,0,360,0,75); if(enemy == null) return false; return true; } void object::myGoto(point p) { errmode(0); while(goto(p) != 0) wait(2); errmode(1); } point object::triangulate2d(object o) { point dest = o.position; dest.x += cos(o.orientation) * 10; dest.y += sin(o.orientation) * 10; return dest; }
Сборщик урана
Программа для сбора UraniumOre (урановой руды). Поддерживает до двух одновременно работающих ботов, позволяя избегать пробок :-)
extern void object::CollectUranOre() { while(true) { if(energyCell.energyLevel <= 0.4) maint(); if(load == null) retrieveResource(UraniumOre); else { processResource(NuclearPlant); deliverResource(BotFactory); } } } void object::retrieveResource(int category) { object resource; while( (resource = radar(category)) == null ) { message("No UraniumOre found. Standing by..."); wait(10); } myGoto(resource.position); errmode(0); grab(); errmode(1); } void object::processResource(int category) { object building; while( (building = radar(category)) == null ) { message("No NuclearPlant found. Standing by..."); wait(10); } myGoto(triangulate2d(building)); myGoto(building.position); drop(); move(-3); wait(35); move(1.5); grab(); } void object::deliverResource(int category) { object dest = radar(category); if(dest == null) goto(space()); else { errmode(0); if(goto(space(dest.position)) != 0) goto(space()); errmode(1); } drop(); message("NuclearCell delivered.",DisplayInfo); } void object::maint() { message("Energy level low. Searching for energy sources..."); while(rechargePlanA() == false and rechargePlanB() == false) { message("Warning. No energy sources found!"); wait(25); } message("Recharge completed. Resuming job duties...", DisplayInfo); } bool object::rechargePlanA() { int cat[]; cat[0] = PowerStation; cat[1] = PowerCaptor; object pwrSource = radar(cat); if(pwrSource != null) { myGoto(triangulate2d(pwrSource)); myGoto(pwrSource.position); message("Recharging at " + pwrSource.category + "...",DisplayInfo); while(energyCell.energyLevel < 1) wait(1); return true; } return false; } bool object::rechargePlanB() { object cell; float min = 0; while( (cell = radar(PowerCell,0,360,min)) != null ) { min = distance2d(position,cell.position) + 0.5; if(cell.energyLevel >= 0.5) { goto(cell.position); message("Swapping with better PowerCell...",DisplayInfo); grab(); drop(Behind); grab(EnergyCell); drop(); grab(Behind); drop(EnergyCell); return true; } } return false; } void object::myGoto(point p) { errmode(0); while(goto(p) != 0) wait(2); errmode(1); } point object::triangulate2d(object o) { point dest = o.position; dest.x += cos(o.orientation) * 15; dest.y += sin(o.orientation) * 15; return dest; }
Сборщик титаниума
Программа для сбора TitaniumOre. Также поддерживает до двух одновременно работающих ботов, позволяя избегать пробок.
extern void object::CollectTitanOre() { while(true) { if(energyCell.energyLevel <= 0.4) maint(); if(load == null) retrieveResource(TitaniumOre); else { processResource(Converter); deliverResource(-1); } } } void object::retrieveResource(int category) { object resource; while( (resource = radar(category)) == null ) { message("No TitaniumOre found. Standing by..."); wait(10); } myGoto(resource.position); errmode(0); grab(); errmode(1); } void object::processResource(int category) { object building; while( (building = radar(category)) == null ) { message("No Converter found. Standing by..."); wait(10); } myGoto(triangulate2d(building)); myGoto(building.position); drop(); move(-3); wait(15); move(1.5); grab(); } void object::deliverResource(int category) { object dest = radar(category); if(dest == null) goto(space()); else { errmode(0); if(goto(space(dest.position)) != 0) goto(space()); errmode(1); } drop(); message("TitaniumCube delivered.",DisplayInfo); } void object::maint() { message("Energy level low. Searching for energy sources..."); while(rechargePlanA() == false and rechargePlanB() == false) { message("Warning. No energy sources found!"); wait(25); } message("Recharge completed. Resuming job duties...", DisplayInfo); } bool object::rechargePlanA() { int cat[]; cat[0] = PowerStation; cat[1] = PowerCaptor; object pwrSource = radar(cat); if(pwrSource != null) { myGoto(triangulate2d(pwrSource)); myGoto(pwrSource.position); message("Recharging at " + pwrSource.category + "...",DisplayInfo); while(energyCell.energyLevel < 1) wait(1); return true; } return false; } bool object::rechargePlanB() { object cell; float min = 0; while( (cell = radar(PowerCell,0,360,min)) != null ) { min = distance2d(position,cell.position) + 0.5; if(cell.energyLevel >= 0.5) { goto(cell.position); message("Swapping with better PowerCell...",DisplayInfo); grab(); drop(Behind); grab(EnergyCell); drop(); grab(Behind); drop(EnergyCell); return true; } } return false; } void object::myGoto(point p) { errmode(0); while(goto(p) != 0) wait(2); errmode(1); } point object::triangulate2d(object o) { point dest = o.position; dest.x += cos(o.orientation) * 10; dest.y += sin(o.orientation) * 10; return dest; }
Титаниум-граббер
Еще одна программа для сборки/переработки титаниума. Роботы автоматически подзаряжаются при необходимости.
extern void object::MakeTitanium( ) { errmode ( 0 ); for ( int i=0 ; i<10 ; i=i+1 ) { object obj, item; point dest,scrap, storage; int j=0, err=0, h=0; float dist, pl, xt,yt,x,y; do { obj = radar(TitaniumOre); } while ( obj == null ); message("TitaniumOre found at X=" + obj.position.x +" Y="+obj.position.y,DisplayInfo); dist=distance(position,obj.position); if(category == LeggedGrabber) { pl = (0.05 + 2.1*(dist*0.0008)); } if(category == WheeledGrabber) { pl = (0.10 + 2.5*(dist*0.0016)); } if(category == TrackedGrabber) { pl = (0.10 + 2.5*(dist*0.0025)); } if(category == Subber) { pl = (0.20 + 2.5*(dist*0.0025));} if(energyCell.category == NuclearCell) { pl = pl * 0.1;} message("Estimated Safe power needed is :"+(pl*100)+"% Current Cell level is:"+ (energyCell.energyLevel*100)+"%",DisplayInfo); if(pl > 1) { message("The nearest Titanium ore is out of the safe power range of a full charge"); return; } if(energyCell.energyLevel < pl and energyCell.category != NuclearCell and (radar(PowerStation)) != null) { j=5; do { item = radar(PowerStation,0,360,j-5,j); j+=5; if (item != null) { err = goto(item.position); if(err != 0){item = radar(WayPoint,0,1,0,1);} } if (j >= 600){ j=5; message("PowerStation(s) are blocked!",DisplayWarning); wait(30); } } while (item == null); if (item != null){ message("The Bot is recharging its power cells.",DisplayInfo); while ( energyCell.energyLevel < 1 ) { wait(1); } } } else { if (category != Subber) { if(energyCell.energyLevel < pl ) { message("The Bot is changing power cells.",DisplayInfo); j= 5; do{ item = radar(PowerCell,0,360,j-5,j); if (item == null) {item = radar(NuclearCell,0,360,j-5,j);} j+=5; if (item != null) {if (item.energyLevel <= 0.8) { item = radar(WayPoint,0,1,0,1);} } if (j >= 400){ j=5; message("Bot Cannot find any energy cells.",DisplayInfo); wait(30); } } while ( item == null ); do{ err = goto(item.position); if (err != 0) { message("powercell get error.. trying again.",DisplayInfo); turn(120); move(15); } } while(err !=0 ); grab(InFront); // take the new cell in front drop(Behind); // and drop it behind grab(EnergyCell); // take the cell from the bot drop(InFront); // and drop it in front grab(Behind); // take the new cell drop(EnergyCell); // and drop it on the bot } else{ if(energyCell.energyLevel < pl ) { item = radar(SpaceShip); goto(item.position); message("Subber needs a Cell change at SpaceShip.",DisplayError);} } } } do { obj = radar(TitaniumOre); } while ( obj == null ); do{ err = goto(obj.position); if (err != 0) {message("T.ore Get error, Trying again.",DisplayInfo); turn(120); move(15); } } while(err !=0 ); grab(); // grab the titanium ore obj = radar(Converter); if ( obj == null ) return; do{ err = goto(obj.position); if (err != 0) {message("T.ore delivery error, Trying again.",DisplayInfo); turn(120); move(15); } } while(err !=0 ); drop(); move(-2.5); do { obj = radar(Titanium, 0, 360, 0, 5); } while ( obj == null ); goto(obj.position); grab(); if ( i > 2 ){ i=0; h=h+1; } x=i*2+5; y=-(h)*2+10; scrap=position; xt = (x * cos(orientation)) + (y * sin(orientation)); yt = (y * cos(orientation)) - (x * sin(orientation)); //message("X="+xt+"Y="+yt); scrap.x = position.x + xt; scrap.y = position.y + yt; //message("X="+scrap.x+"Y="+scrap.y); storage = space(scrap,0,100,2); if (storage.x == nan) { message("bad."); } message("Titanium being stored tenitivly at: X="+storage.x+" Y="+storage.y,DisplayInfo); err = goto(storage); if (err != 0) { message("T storage errorin moving to space",DisplayInfo); goto(space(storage,4,100,2));drop(); } err = drop(); if (err != 0) { message("T storage error. finding open spot",DisplayInfo); goto(space(position,0,100,2));drop(); } move(-2.5); } }
Недокументированные возможности
Приведены описание хитростей и готовые процедуры, которые можно использовать в игре.
...On my latest mission to a previously explored planet i ran across a race of abandoned robots, in return of being left alone they gave me information about undocumented instructions and mechanism of the bots. --------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------- Syntax : -- float/int abs(float/int variable) Returns absolute value of variable. e.a. always positive. example x = -1; abs(x); message(x); --------------------------------------------------------------------------------------------------------- Syntax : -- boolean Same as bool. If you want a function to return a boolean only the latter is recognized. example :: boolean object::energyLow() { if (energyCell.energyLevel < 0.1) { return true; } return false; } --------------------------------------------------------------------------------------------------------- Syntax : -- boolean && boolean Returns true if both bools are true, else false. -- boolean || boolean Returns false when both bools are false, else true. e.a. inversion of &&. -- !boolean Returns the inversion of the bool. e.a. !true = false, !false = true. example :: object target; target = radar(PowerStation); if (energyCell.energyLevel < 0.1 && energyCell.category == PowerCell) { goto(target.position); } --------------------------------------------------------------------------------------------------------- Syntax : -- variable++ Increases variable by one after instruction. -- variable-- Decreases variable by one after instruction. Use x++ instead of x = x + 1 and x-- instead of x = x - 1. This works on both int and float variables. note -- If the variable is read in the same instruction, the variable will return the old value. example: int x = 0; message(x++); This will prompt 0 instead of 1. example :: for (int x = 0, y = 10; x < y; x++) --------------------------------------------------------------------------------------------------------- Syntax : -- ipf(int) Changes linespeed to int; You can increase the speed the bot interprets your code with this instruction, ideal for ultra intensive routines. :) ipf(200) is more or less the normal setting... --------------------------------------------------------------------------------------------------------- Syntax : -- boolean/float/int/object/string variableA, variableB, variableC; You can declare multiple variables of the same type on the same line by defining them with a ','. example :: int varX, varY, varZ; --------------------------------------------------------------------------------------------------------- Syntax : -- boolean/float/int/object/string[] Defines a array. You can create a array from any type of variable with [], members are addressed with a int index. e.a. variable[12] or array[3] Arrays of arrays of the same type is possible. example :: float array[]; array[0] = 1.23; array[1] = -4.32; --- int[] array, anotherArray, arrays[]; array[0] = 1; array[1] = 2; anotherArray[0] = -1; anotherArray[5] = 1; arrays[0] = array; arrays[1] = anotherArray; Use sizeof to get the size or maximum index of a array, ofcourse functions can also accept and return arrays. Syntax : -- int sizeof(array[]) Returns the size of a array or index-1. -- type[] functionName(type variable[]) Creates a function accepting and returning a array. note -- ( this example can best be used with ipf(10000) or similar ) example :: int[] getCategories() { object Object; int typesFound[], indexFound = 0, searchIndex = 0; while (true) { Object = retobject(searchIndex); if (Object == null) { return typesFound; } if (!intExist(typesFound, Object.category)) { typesFound[indexFound] = Object.category; indexFound++; } searchIndex++; } } boolean intExist(int[] array, int target) { if (sizeof(array) != 0) { for (int searchIndex = sizeof(array) - 1; searchIndex > 0 ; searchIndex--) { if (array[searchIndex] == target) { return true; } } } return false; } note -- You can define directly index 5, however the rest of the array 0 to 4 is also created and assigned with nan. example :: string[] text; text[5] = "hello world :p"; would actually make the array : text[0] = nan; text[1] = nan; text[2] = nan; text[3] = nan; text[4] = nan; text[5] = "hello world :p"; --------------------------------------------------------------------------------------------------------- Syntax : -- object radar(int[] Category, float[] Angle, float[] Focus, float[] Min, float[] Max, float[] Sens) note -- All variable accept arrays, you may use for example a array of alien category to detect multiple kinds of alien foes at once. example :: object target; int foes[]; foes[0] = AlienQueen; foes[1] = AlienEgg; foes[2] = AlienAnt; foes[3] = AlienSpider; foes[4] = AlienWasp; foes[5] = AlienWorm; target = radar(foes); --------------------------------------------------------------------------------------------------------- Syntax : -- object search(int preferedCategory, int x, int y) Returns a prefered object or the nearest object at a specified location. note -- the x and y ofcourse optional, however y is needed when x is specified. --------------------------------------------------------------------------------------------------------- Syntax : -- int produce(point Position, float Direction, int Category, string Script) Produces objects like bots and powercells out of thin air, amazing! :) (Doesn't work on all kinds of objects) Returns 0 if successful, 1 if not. A name of a script filename can be given to be runned on a produced bot. example: "script.txt" example :: produce(position, 0, PowerCell, ""); --------------------------------------------------------------------------------------------------------- Syntax : -- public type functionName(type variable1, type variable2, etc) You can make a function accessible with public from another script and also from another bot! example :: // bot #1 public string indentify() { return "Hi, my name is, my name is, my name is..."; } // bot #2 message(indentify()); --------------------------------------------------------------------------------------------------------- I know there is more i could see it in their face ;), but this is it for now, maybe ever... =================================================================== Some usefull functions i wrote on those missions... --------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------- -- Returns the angle to the grid from pointA to pointB. Similar to direction except direction assumes pointA to be the bots position. float angle(point pointA, point pointB) { float offset = 90; if (deltaY(pointA, pointB) > 0) { offset = 270; } return offset + atan(deltaX(pointA, pointB) / deltaY(pointA, pointB)); } --------------------------------------------------------------------------------------------------------- float deltaX(point origin, point target) { return target.x - origin.x; } --------------------------------------------------------------------------------------------------------- float deltaY(point origin, point target) { return target.y - origin.y; } --------------------------------------------------------------------------------------------------------- Calculates a point from another point with a horizontal angle, a vertical angle and a distance. point triangulate(point origin, float Distance, float angleH, float angleV) { point dest; dest.x = cos(angleH) * cos(angleV) * Distance; dest.y = sin(angleH) * cos(angleV) * Distance; dest.z = sin(angleV) * Distance; return dest; } --------------------------------------------------------------------------------------------------------- Same as triangulate but only using 2 dimensions. (horizontal) point triangulate2d(point origin, float Distance, float angle) { point dest; dest.x = cos(angle) * Distance; dest.y = sin(angle) * Distance; return dest; }
Телохранитель
Нуждаетесь в телохранителе? :-) В этой программой Ваш робот-охранник будет следовать за Вами. В опасных ситуациях будет защищать Вас, стреляя в находящихся рядом врагов. Можете создавать эскорты для охраны чего-либо. Также можете делать несколько роботов охранниками друг друга для скоординированной помощи.
extern void object::Guard() { int allyType = Me; // put ally category here (i.e. LeggedGrabber) int keepCloseDist = 10; // how far behind to follow int parimeterToScan = 50; // range to look for enemy object enemy; while(true) { enemy = radar(AlienAnt,0,360,0,parimeterToScan); if(enemy == null) follow(allyType,keepCloseDist); else moveAndDestroy(enemy); } } void object::follow(int category, int parimeter) { object ally = radar(category); float dis = distance(position,ally.position); if(dis > parimeter) // if too far away from ally { float dif = ally.position.z-position.z; float ang = asin(dif/dis); jet(1-(ang/-20)); float dir = direction(ally.position); motor(1-dir/22.5,1+dir/22.5); // move in closer } else // otherwise too close { motor(dis/parimeter-1, dis/parimeter-1); // back up a little if(topo(position) > 0) // if not over water jet(-1); // then land to conserve energy/minimize heat } } void object::moveAndDestroy(object target) { float dir; // direction of target from shooter float dis; // distance of target from shooter float dif; // difference in altitude of target & shooter (relative to sea-level) float ang; // angle shooter must aim (-20 degrees favorable) dis = distance(position,target.position); dif = target.position.z-position.z; ang = asin(dif/dis); jet(1-(ang/-20)); // thrust until 20 degress above target dir = direction(target.position); motor(1-dir/22.5,1+dir/22.5); // move towards enemy dis = distance(position,target.position); dif = target.position.z-position.z; ang = asin(dif/dis); aim(ang); // take aim dir = direction(target.position); if(dis < 30 and dir > -10 and dir < 10) // if within range fire(0.1); }
Авто-чарджер
Лучшая программа для зарядки летающих роботов-охотников. Робот найдет батарейку, перезарядит ее при необходимости, переместится к летающему роботу и перезарядит батарейку. Работает даже если нет свободных батареек: возьмет у робота разряженную батарейку -> слетает на база для подзарядки -> вернется обратно.
// locates a WingedShooter with less than 'full' (0.9) // energy and resupplies it with a cell that's at least at // 'minevel' (0.8). // precond: hands empty or carrying power cell extern void object::ReloadWingedShooter() { // level at which we decide to reload power cells float minLevel = 0.8; // full is defined in pickNonFullWS, below point home = position; object ws = pickNonFullWS(); if (ws == null) { message("Nobody to resupply"); return; } if (load==null) grabPowerCell(); if (load.category!=PowerCell) { message("I cannot resupply the WS because I am carrrying something already"); // (and it's not a power cell) return; } if (load.energyLevel<minLevel) { message("reloading power cell first, it is below "+minLevel); sub_reload(); } /// go to winged shooter and replace power cell goto(ws.position); if (ws.load!=null) { // switch old cell for new message("Removing old cell"); drop(Behind); // drop our loaded cell grab(); // take old one turn(90); drop(); // drop old one turn(-90); grab(Behind); // take loaded cell } // insert new cell in winged shooter drop(); message("Done refueling WS, returning to starting point"); goto(home); } // makes sure we grab a power cell. Gets a power cell around // us or from the power plant if that's closer. // precond: hands empty void object::grabPowerCell() { object energy = radar(PowerCell); object factory = radar(PowerPlant); if (factory!=null) { object bat = factory.energyCell; if (null!=bat) { // power plant has a battery ready if (distance(position,bat.position)<distance(position,energy.position)) { // power plant is closer, take its battery // instead energy = bat; } } } if (energy == null) { message("No power cell around"); return; } goto(energy.position); grab(); } // reload power and shield void object::sub_reload() { object item; // info. about power station point start = position; // store initial position item = radar(PowerStation); // look for station goto(item.position); // go to the power station object l = load; if (null!=l) { if (l.category != EnergyCell) l = null; } int cl = 0; if (l == null) cl = 1; else cl = l.energyLevel; while ( energyCell.energyLevel < 1 or cl < 1) { wait(1); // wait until recharged if (l == null) cl = 1; else cl = l.energyLevel; } object rep = radar(RepairCenter); if (shieldLevel<1.0 and null!=rep) { goto(rep.position); while (shieldLevel<1.0) { wait(1); } } message("Recharge completed"); } // returns a winged shooter with energy below 'full', // or null if none exist object object::pickNonFullWS() { // we will not pick a WS with power above this level float full=1; float m =0; int count=0; object ws = null; float l; // energy level of WS in consideration do { count++; ws = radar(WingedShooter,0,360,m); l=0; if (null!=ws){ if (null!=ws.energyCell) { l = ws.energyCell.energyLevel; } } if (l>=full and null!=ws) { m=distance(position,ws.position)+0.1; ws = null; } else if (null!=ws) { message("picked a WS with energy ("+l+")"); } } while (l>=full and count<100); if (null==ws) { message("There is no WS under "+full+" around"); } return ws; }
Миссия на Земле. Автопрохождение
Программа, полностью автоматизирующая Земную миссию в демо-версии. Все возможные задачи и действия автоматизированы. Вам достаточно только загрузить программу в WheeledGrabber и TrackedGrabber. Некоторые действия вроде перемещения астронавта на корабль и создание зданий автоматизировать нельзя, так как игра это не позволяет.
extern void object::Mission1() { object rdr; if(category ==WheeledGrabber) { rdr = radar(PowerCell); goto(rdr.position); grab(); rdr = radar(ResearchCenter); goto(rdr.position); drop(); message("Research center powered - begin research."); rdr = radar(PowerCell); // There are two powercells that get in the way goto(rdr.position); grab(); turn(90); drop(); move(-5); rdr = radar(PowerCell); goto(rdr.position); grab(); turn(90); drop(); rdr = radar(Titanium); goto(rdr.position); grab(); rdr = radar(BotFactory); goto(rdr.position); drop(); move(-5); message("Bot factory loaded. Create new bot."); rdr = radar(PowerCell); goto(rdr.position); grab(); rdr = radar(TrackedGrabber); message("Waiting for manufacture of Tracked Grabber."); while(rdr == null) rdr = radar(TrackedGrabber); goto(rdr.position); drop(); message("Tracked grabber is ready."); rdr = radar(SpaceShip); goto(rdr.position); } else { move(-5); rdr = radar(BlackBox); goto(rdr.position); grab(); rdr = radar(SpaceShip); goto(rdr.position); drop(); } message(category + ": Mission complete"); }
Миссия на Луне. Автопрохождение
Программа, полностью автоматизирующая Лунную миссию в демо-версии. Вам достаточно только загрузить программу в WheeledGrabber и TrackedGrabber. Некоторые действия вроде перемещения астронавта на корабль и создание зданий автоматизировать нельзя, так как игра это не позволяет.
extern void object::MoonOre() { object rdr; int counter = 0; float range = 0; int errcode = 0; errmode(0); if(category == WheeledGrabber) { rdr = radar(PowerCell); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); grab(); rdr = radar(ResearchCenter); if(rdr == null) message("Waiting for Researchcenter to be built."); while(rdr == null) rdr = radar(ResearchCenter); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); drop(); message("Researchcenter is powered."); rdr = radar(Titanium); errcode = goto(rdr.position); while(errcode != 0) { rdr = radar(Titanium); errcode = goto(rdr.position); } grab(); rdr = radar(BotFactory); if(rdr == null) message("Waiting for Botfactory to be built."); while(rdr == null) rdr = radar(BotFactory); errcode = goto(rdr.position); while(errcode != 0) { turn(direction(rdr.position)); move(distance2d(position, rdr.position)); errcode = goto(rdr.position); } drop(); message("Titanium loaded into BotFactory"); rdr = radar(PowerCell); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); grab(); rdr = radar(WingedGrabber); if(rdr == null) message("Waiting for Wingedgrabber to be built."); while(rdr == null) rdr = radar(WingedGrabber); wait(5); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); drop(); message("Wingedgrabber ready."); move(-6); rdr = radar(Titanium); //Get the extra Titanium out of the way if(rdr != null) { errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); grab(); errcode = goto(space(position)); while(errcode != 0) errcode = goto(space(position)); drop(); } message("Waiting for ore to be delivered."); while(counter < 4) { counter = 0; rdr = radar(TitaniumOre,0,360,range,100); while(rdr != null) { counter++; range = distance2d(position, rdr.position) + 0.01; rdr = radar(TitaniumOre,0,360,range,100); } range = 0; } rdr = radar(SpaceShip); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); } else { for(counter = 0; counter < 4; counter++) { rdr = radar(TitaniumOre,0,360,100,1000); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); grab(); rdr = radar(SpaceShip); errcode = goto(rdr.position); while(errcode != 0) errcode = goto(rdr.position); errcode = drop(); while(errcode != 0) { turn(-45); errcode = drop(); } message("Delivered " + (counter +1) + " ore samples."); } } message(category + ": Mission Complete."); }
Миссия в воздухе. Автопрохождение
Программа, полностью автоматизирующая летающую миссию в демо-версии. Робот автоматически пролетает через все воздушные цели. Никаких ручных действий не требуется.
extern void object::FlyingDrill() { object rdr; object last; while(true) { rdr = radar(Target2,0,180,1,100); if(rdr == null) { rdr = radar(SpaceShip,0,180,1,100); turn(direction(rdr.position)); move(distance(position, rdr.position)); break; } if(rdr.position.z > position.z) jet(0.3); if(rdr.position.z < position.z) jet(-0.3); if(direction(rdr.position) > 2) motor(0.5,1); if(direction(rdr.position) < 2) motor(1,0.5); if(abs(direction(rdr.position)) <= 2) motor(1,1); if(temperature > 0.9) //Should not need this part { motor(0,0); while(temperature > 0) wait(1); } } }
Робот-достал
Программа, которая приказывает боту следовать за конкретным объектом. Например, за Вами.
extern void object::FollowMe() { object spaceguy; while(true) { spaceguy=radar(Me); goto(spaceguy.position,spaceguy.altitude,1,1); } }
Количество объектов
Выводит количество объектов в какой-либо конкретной категории.
extern void object::ScanforObject() { object item; int number=0; float min=0,max=1000; string catname; do{ // >>>>>>> change category here <<<<<<< item=radar(PowerCell,0,360,min,max,1); // >>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<< if(item!=null) { ++number; min=distance(position,item.position)+0.01; catname="["+item.category+"s]"; } }while(item!=null); if(number==0) message("[none found]",DisplayInfo); else message
RSS