extern void object::ZbierajTytan() { int surowiec = TitaniumOre; int przetwornia = Converter; int produkt = Titanium; object rzecz, budynek; point tutaj; float odl; // co trzymasz w łapie, robocie? WyrzucInne(surowiec); while (true) { // powtarzaj w nieskończoność WezSurowiec(surowiec); // znajdź przetwórnię i idź tam budynek = radar(przetwornia); // opróznij przetwórnię, jeśli jest w niej produkt OproznijPrzetwornie(surowiec, produkt, przetwornia); // upewnij się, że masz w łapce surowiec, zostaw go w przetwórni WezSurowiec(surowiec); Idz(budynek.position); drop(); // poczekaj na produkt i odłóż go ObsluzProdukt(surowiec, produkt, przetwornia); } } // ========================= podprogramy ========================= // void object::WyrzucInne(int surowiec) { if (load != null) { if (load.category != surowiec) { // trzyma coś, ale nie surowiec! // zostaw to gdzieś w pobliżu goto(space()); drop(); } } } void object::WezSurowiec(int surowiec) { int err; object rzecz; if (load == null) { // puste łapki - weź surowiec // idź do surowca i podnieś go do { rzecz = radar(surowiec); // znajdź Idz(rzecz.position); // idź do surowca // podnieś go errmode(0); err=grab(); errmode(1); } while (err != 0); } } void object::ObsluzProdukt(int surowiec, int produkt, int przetwornia) { object rzecz, budynek; boolean ok; budynek = radar(przetwornia); move(-2.5); // cofnij się o 2,5 m turn(direction(budynek.position)); // obróć się do przetwórni ok = true; // jeśli nie ma w pobliżu kolejnego surowca, nie czekaj na produkt // tylko w czasie przetwarzania udaj się po kolejny surowiec rzecz = radar(surowiec); if (rzecz != null) { if (distance(rzecz.position, position)>30) { ok = false; } } if (ok) { // poczekaj na przetworzenie surowca i zabierz produkt do { wait(1); // poczekaj na produkt rzecz = radar(produkt, 0, 30, 0, 5); } while ( rzecz == null ); goto(rzecz.position); grab(); // weź produkt OdlozProdukt(produkt); } } void object::OproznijPrzetwornie(int surowiec, int produkt, int przetwornia) { object rzecz, budynek; float odl; int err; // czy w przetwórni nie ma aby gotowego produktu? - wyjmij go budynek = radar(przetwornia); odl=distance(position, budynek.position); rzecz=radar(produkt,direction(budynek.position),5, odl-3,odl+3); if (rzecz != null) { // przetwórnia zajęta, leży w niej gotowy prokukt if (load != null) { // trzyma coś, trzeba to odłożyć, żeby wyjąć produkt // odłóz w poblizu przetwórni Idz(space(budynek.position,5,20,2)); drop(); } Idz(budynek.position); errmode(0); err=grab(); errmode(1); // wyjmij produkt if (err == 0) { OdlozProdukt(produkt); } } } void object::OdlozProdukt(int produkt) { object rzecz; // idź do wolnego miejsca i zostaw produkt // staraj się układać gęsto.. rzecz = radar(produkt); if (rzecz == null) { rzecz = this; Idz(space(rzecz.position,5,20,2)); } else { Idz(space(rzecz.position,0,20,2)); } drop(); } void object::czujnikTemp() { czujnikTemp(0.75); } void object::czujnikTemp(float maxTemp) // ląduj jeśli temperatura silnika jest zbyt wysoka // 50m w powietrzu to wzrost temperatury o ~0.17 { float hmin = -0.5; // min.wys.terenu (max.głębokość wody) point punkt, togo; float r, omega, grunt, wysLotu, ciag; int ok; if (temperature > maxTemp) { message("Szukam miejsca do lądowania technicznego", DisplayInfo); jet(0); while ( !(bezpiecznylad(position, hmin)) ) { // znajdź miejsce do lądowania motor(1,1); ok = 0; omega = 0; punkt = tp(omega, 10); if ( bezpiecznylad(punkt, hmin) ) { ok = 1; // świetnie - miejsce do lądowania jest przed nami } ipf(800); if (ok ==0) { for (r=10; r<35; r+=5) { for (omega=22.5; omega<=180; omega+=22.5) { // w kierunku możliwie bliskim dotychczasowemu punkt = tp(omega, r); if ( bezpiecznylad(punkt, hmin) ) { ok = 1; turn(omega); break; } punkt = tp(-omega, r); if ( bezpiecznylad(punkt, hmin) ) { ok = 1; turn(-omega); break; } } // end of 'for omega...' if ( ok ==1 ) { break; } } // end of ' for r...' } // którędy? togo.x = (2*cos(orientation))+position.x; togo.y = (2*sin(orientation))+position.y; togo.z = position.z; ipf(100); if ( ok == 1 ) { while ( !(bezpiecznylad(position, hmin)) ) { 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.1); } motor(1, 1); wait(0.1); } break; } 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.1); } wait(0.1); } // end of 'while "miejsce nie do ladowania"...' motor(0, 0); // zatrzymaj się nad tym miejscem jet( -1 ); //...i ląduj while (altitude > 0) { // opuść się wait(0.2); } jet(0); message("Wylądowałem dla ostudzenia", DisplayInfo); while (temperature > 0) { // poczekaj na ostygnięcie silnika wait(0.1); } } } point object::tp(float alfa, float r) { point pkt; pkt.x = position.x + cos(orientation + alfa) * r; pkt.y = position.y + sin(orientation + alfa) * r; pkt.z = 0; return pkt; } boolean bezpiecznylad(point punkt, float hmin) { point sasiedni; float nachmax = 30; // max.nachylenie terenu do lądowan float dx, dy, dh, dhmax; if ( topo(punkt) < hmin ) return false; dhmax = 0; dx = dy = 1; for (int i=-1; i<=1; i++) { for (int j=-1; j<=1; j++) { sasiedni.x = punkt.x + dx*i; sasiedni.y = punkt.y + dy*j; dh = abs( topo(punkt) - topo(sasiedni) ); if ( dh > dhmax ) dhmax = dh; } } return (atan(dhmax/dx) <= nachmax); } void object::DoElektrowni(point budynek) { int err1, err2; // idzie do zadanej elektrowni errmode(0); mygoto(budynek); err1 = goto(budynek); // blisko - niech się tym goto() zajmie if (err1 != 0) { // jeśli nie dało się dotrzeć do elektrowni, znajdź inne miejsce turn(direction(budynek)); czujnikTemp(); err2 = goto(space(budynek,8,60,4)); while (err2 != 0) { wait(1); err2 = goto(space(budynek,8,60,4)); } message("Budynek uzupełniajacy energię zajęty, czekam...", DisplayInfo); while (err1 != 0) { wait(1); err1 = goto(budynek); } } errmode(1); // podładowywanie na platformie budynku while (energyCell.energyLevel < 1 ) { wait(0.5); // poczekaj aż się w pełni podładuje } if (load!=null && load.category==PowerCell) { // trzyma baterię while (load.energyLevel < 1) { // ją też warto podładować wait(0.5); } } // koniec podładowywania // turn(90); motor(1, 1); wait(1.5); // zejdź z platformy } float object::EnergiaNaDroge(float odl) { float energia; if (category==WingedGrabber || category==WingedShooter || category==WingedOrgaShooter || category==WingedSniffer) { energia=0.03+odl*0.0005; } else { energia=0.03+odl*0.001; } return (energia); } void object::Idz(point punkt) { float energia1=0, energia2=0; float zapasEn=0.08; float odl, minodl=99999; point elektro[], budynek; odl=distance(punkt, position); energia1=EnergiaNaDroge(odl); // en.na dotarcie do celu elektro=elektrownie(); if (sizeof(elektro)==0) { message("Nie ma budynków zasilających!"); } else { budynek=najblEl(elektro, punkt); energia2=EnergiaNaDroge(distance(budynek, punkt)); // en.na powrót od celu do elektrowni } if (energyCell.energyLevel= energia1+zapasEn) { // przede wszystkim trzeba się dostać do tego budynku // a potem - z którego będzie bliżej? odl=distance(elektro[i], punkt); if (odl < minodl) { minodl=odl; budynek=elektro[i]; } } } DoElektrowni(budynek); } mygoto(punkt); } point najblEl(point[] elektro, point pt) { point minpt; float odl, minodl; minodl=99999; for (int i=0; iodl) { minodl=odl; minpt=elektro[i]; } } return (minpt); } point[] object::elektrownie() { int zasilanie[]; zasilanie[0] = PowerStation; zasilanie[1] = PowerCaptor; object budynek; point elektro[]; float j; int i; i=0; j=0; do { budynek=radar(zasilanie,0,360,j,2000); if (budynek!=null) { // dodaj do listy j=distance(position,budynek.position)+0.01; elektro[i]=budynek.position; i++; } } while (budynek != null); return (elektro); } void object::mygoto(point gdzie) { float odl; point punkt; // obsługa temperatury if (category==WingedGrabber || category==WingedShooter || category==WingedOrgaShooter || category==WingedSniffer) { // 50m w powietrzu to wzrost temperatury o ~0.17 (1/50=0.02) odl=distance(position, gdzie); while (temperature+0.17*odl*0.02 > 0.75) { // staraj się nie dopuścić do przekroczenia 75% max.temp. silnika // 75% = ok.220m odl=(0.75-temperature)/(0.02*0.17); turn(direction(gdzie)); punkt.z=position.z; do { punkt.x = (odl*cos(orientation))+position.x; punkt.y = (odl*sin(orientation))+position.y; odl = odl-5; } while (!(bezpiecznylad(punkt, 1))); goto(punkt); czujnikTemp(0); odl=distance(position, gdzie); } } // koniec obsługi temperatury goto(gdzie); }