111591Sleres #ifndef lint 2*15722Sedward static char *sccsid = "@(#)dr_3.c 2.4 83/12/17"; 311591Sleres #endif 411591Sleres 514011Sedward #include "driver.h" 611591Sleres 711591Sleres moveall() /* move all comp ships */ 811591Sleres { 914011Sedward register struct ship *sp, *sq; /* r11, r10 */ 1014011Sedward register int n; /* r9 */ 11*15722Sedward register int k, l; /* r8, r7 */ 1215708Sedward int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; 1315708Sedward char moved[NSHIP]; 1411591Sleres 1514011Sedward /* 1614011Sedward * first try to create moves for OUR ships 1714011Sedward */ 1814011Sedward foreachship(sp) { 1915708Sedward struct ship *closest; 2015708Sedward int ma, ta; 2115708Sedward char af; 2215708Sedward 2315203Sedward if (sp->file->captain[0] || sp->file->dir == 0) 2414011Sedward continue; 2514011Sedward if (!sp->file->struck && windspeed && !snagged(sp) 2614011Sedward && sp->specs->crew3) { 2715203Sedward ta = maxturns(sp, &af); 2814011Sedward ma = maxmove(sp, sp->file->dir, 0); 2914011Sedward closest = closestenemy(sp, 0, 0); 3014011Sedward if (closest == 0) 31*15722Sedward *sp->file->movebuf = '\0'; 3211591Sleres else 33*15722Sedward closeon(sp, closest, sp->file->movebuf, 3414011Sedward ta, ma, af); 3514011Sedward } else 36*15722Sedward *sp->file->movebuf = '\0'; 3711591Sleres } 3814011Sedward /* 3914011Sedward * Then execute the moves for ALL ships (dead ones too), 4015708Sedward * checking for collisions and snags at each step. 4115708Sedward * The old positions are saved in row[], col[], dir[]. 4215708Sedward * At the end, we compare and write out the changes. 4314011Sedward */ 4414011Sedward n = 0; 4514011Sedward foreachship(sp) { 4614011Sedward if (snagged(sp)) 47*15722Sedward (void) strcpy(sp->file->movebuf, "d"); 4814011Sedward else 49*15722Sedward if (*sp->file->movebuf != 'd') 50*15722Sedward (void) strcat(sp->file->movebuf, "d"); 5114011Sedward row[n] = sp->file->row; 5214011Sedward col[n] = sp->file->col; 5314011Sedward dir[n] = sp->file->dir; 5415708Sedward drift[n] = sp->file->drift; 5515708Sedward moved[n] = 0; 5614011Sedward n++; 5711591Sleres } 5814011Sedward /* 5914011Sedward * Now resolve collisions. 6014011Sedward * This is the tough part. 6114011Sedward */ 6215708Sedward for (k = 0; stillmoving(k); k++) { 6314011Sedward /* 6414011Sedward * Step once. 65*15722Sedward * And propagate the nulls at the end of sp->file->movebuf. 6614011Sedward */ 6714011Sedward n = 0; 6814011Sedward foreachship(sp) { 69*15722Sedward if (!sp->file->movebuf[k]) 70*15722Sedward sp->file->movebuf[k+1] = '\0'; 7115708Sedward else if (sp->file->dir) 72*15722Sedward step(sp->file->movebuf[k], sp, &moved[n]); 7314011Sedward n++; 7411591Sleres } 7514011Sedward /* 7614011Sedward * The real stuff. 7714011Sedward */ 7814011Sedward n = 0; 7914011Sedward foreachship(sp) { 8015708Sedward if (sp->file->dir == 0 || isolated(sp)) 8115238Sedward goto cont1; 8214011Sedward l = 0; 8314011Sedward foreachship(sq) { 8415708Sedward char snap = 0; 8515708Sedward 8615238Sedward if (sp == sq) 8715238Sedward goto cont2; 8815708Sedward if (sq->file->dir == 0) 8915238Sedward goto cont2; 9015708Sedward if (!push(sp, sq)) 9115708Sedward goto cont2; 9215708Sedward if (snagged2(sp, sq) && range(sp, sq) > 1) 9315708Sedward snap++; 9415708Sedward if (!range(sp, sq) && !fouled2(sp, sq)) { 9514011Sedward makesignal(sp, 9614011Sedward "collision with %s (%c%c)", sq); 9714011Sedward if (die() < 4) { 9814011Sedward makesignal(sp, 9914011Sedward "fouled with %s (%c%c)", 10014011Sedward sq); 101*15722Sedward Write(W_FOUL, sp, 0, l, 0, 0, 0); 102*15722Sedward Write(W_FOUL, sq, 0, n, 0, 0, 0); 10311591Sleres } 10415708Sedward snap++; 10515708Sedward } 10615708Sedward if (snap) { 107*15722Sedward sp->file->movebuf[k + 1] = 0; 108*15722Sedward sq->file->movebuf[k + 1] = 0; 10915708Sedward sq->file->row = sp->file->row - 1; 11014011Sedward if (sp->file->dir == 1 11114011Sedward || sp->file->dir == 5) 11215708Sedward sq->file->col = 11315708Sedward sp->file->col - 1; 11414011Sedward else 11515708Sedward sq->file->col = sp->file->col; 11615708Sedward sq->file->dir = sp->file->dir; 11711591Sleres } 11815238Sedward cont2: 11914011Sedward l++; 12011591Sleres } 12115238Sedward cont1: 12214011Sedward n++; 12311591Sleres } 12411591Sleres } 12514011Sedward /* 12615708Sedward * Clear old moves. And write out new pos. 12714011Sedward */ 12815708Sedward n = 0; 12915708Sedward foreachship(sp) { 13015708Sedward if (sp->file->dir != 0) { 131*15722Sedward *sp->file->movebuf = 0; 13215708Sedward if (row[n] != sp->file->row) 133*15722Sedward Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0); 13415708Sedward if (col[n] != sp->file->col) 135*15722Sedward Write(W_COL, sp, 0, sp->file->col, 0, 0, 0); 13615708Sedward if (dir[n] != sp->file->dir) 137*15722Sedward Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0); 13815708Sedward if (drift[n] != sp->file->drift) 13915708Sedward Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0); 14015708Sedward } 14115708Sedward n++; 14215708Sedward } 14311591Sleres } 14411591Sleres 14515708Sedward stillmoving(k) 14611591Sleres register int k; 14711591Sleres { 14814011Sedward register struct ship *sp; 14911591Sleres 15015708Sedward foreachship(sp) 151*15722Sedward if (sp->file->movebuf[k]) 15214011Sedward return 1; 15314011Sedward return 0; 15411591Sleres } 15511591Sleres 15611591Sleres isolated(ship) 15714011Sedward register struct ship *ship; 15811591Sleres { 15914011Sedward register struct ship *sp; 16011591Sleres 16114011Sedward foreachship(sp) { 16214011Sedward if (ship != sp && range(ship, sp) <= 10) 16314011Sedward return 0; 16414011Sedward } 16514011Sedward return 1; 16611591Sleres } 16711591Sleres 16811591Sleres push(from, to) 16914011Sedward register struct ship *from, *to; 17011591Sleres { 17111591Sleres register int bs, sb; 17211591Sleres 17315708Sedward sb = to->specs->guns; 17415708Sedward bs = from->specs->guns; 17514011Sedward if (sb > bs) 17614011Sedward return 1; 17711591Sleres if (sb < bs) 17814011Sedward return 0; 17914011Sedward return from < to; 18011591Sleres } 18111591Sleres 18215708Sedward step(com, sp, moved) 18311591Sleres char com; 18415708Sedward register struct ship *sp; 18515708Sedward char *moved; 18611591Sleres { 18711591Sleres register int dist; 18811591Sleres 18914011Sedward switch (com) { 19014011Sedward case 'r': 19115708Sedward if (++sp->file->dir == 9) 19215708Sedward sp->file->dir = 1; 19314011Sedward break; 19414011Sedward case 'l': 19515708Sedward if (--sp->file->dir == 0) 19615708Sedward sp->file->dir = 8; 19714011Sedward break; 19814011Sedward case '0': case '1': case '2': case '3': 19914011Sedward case '4': case '5': case '6': case '7': 20015708Sedward if (sp->file->dir % 2 == 0) 20114011Sedward dist = dtab[com - '0']; 20214011Sedward else 20314011Sedward dist = com - '0'; 20415708Sedward sp->file->row -= dr[sp->file->dir] * dist; 20515708Sedward sp->file->col -= dc[sp->file->dir] * dist; 20615708Sedward *moved = 1; 20714011Sedward break; 20814011Sedward case 'b': 20914011Sedward break; 21014011Sedward case 'd': 21115708Sedward if (!*moved) { 21215708Sedward if (++sp->file->drift > 2 && 21315708Sedward (sp->specs->class >= 3 && !snagged(sp) 21415708Sedward || (turn & 1) == 0)) { 21515708Sedward sp->file->row -= dr[winddir]; 21615708Sedward sp->file->col -= dc[winddir]; 21715708Sedward } 21815708Sedward } else 21915708Sedward sp->file->drift = 0; 22014011Sedward break; 22111591Sleres } 22211591Sleres } 22311591Sleres 22414011Sedward sendbp(from, to, sections, isdefense) 22514011Sedward register struct ship *from, *to; 22614011Sedward int sections; 22714011Sedward char isdefense; 22811591Sleres { 22911591Sleres int n; 23014011Sedward register struct BP *bp; 23111591Sleres 23214011Sedward bp = isdefense ? from->file->DBP : from->file->OBP; 23314011Sedward for (n = 0; n < 3 && bp[n].turnsent; n++) 23414011Sedward ; 23514011Sedward if (n < 3 && sections) { 23614011Sedward Write(isdefense ? W_DBP : W_OBP, from, 0, 237*15722Sedward turn, to->file->index, sections, 0); 23814011Sedward if (isdefense) 23914011Sedward makesignal(from, "repelling boarders", 24014011Sedward (struct ship *)0); 24111591Sleres else 24214011Sedward makesignal(from, "boarding the %s (%c%c)", to); 24311591Sleres } 24411591Sleres } 24511591Sleres 24614011Sedward toughmelee(ship, to, isdefense, count) 24714011Sedward register struct ship *ship, *to; 24814011Sedward int isdefense, count; 24911591Sleres { 25014011Sedward register struct BP *bp; 25114011Sedward register obp = 0; 25214011Sedward int n, OBP = 0, DBP = 0, dbp = 0; 25311591Sleres int qual; 25411591Sleres 25514011Sedward qual = ship->specs->qual; 25614011Sedward bp = isdefense ? ship->file->DBP : ship->file->OBP; 25714011Sedward for (n = 0; n < NBP; n++, bp++) { 25814011Sedward if (bp->turnsent && (to == bp->toship || isdefense)) { 25914011Sedward obp += bp->mensent / 100 26014011Sedward ? ship->specs->crew1 * qual : 0; 26114011Sedward obp += (bp->mensent % 100)/10 26214011Sedward ? ship->specs->crew2 * qual : 0; 26314011Sedward obp += bp->mensent % 10 26414011Sedward ? ship->specs->crew3 * qual : 0; 26511591Sleres } 26611591Sleres } 26714011Sedward if (count || isdefense) 26814011Sedward return obp; 26914011Sedward OBP = toughmelee(to, ship, 0, count + 1); 27014011Sedward dbp = toughmelee(ship, to, 1, count + 1); 27114011Sedward DBP = toughmelee(to, ship, 1, count + 1); 27211591Sleres if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10) 27314011Sedward return 1; 27411591Sleres else 27514011Sedward return 0; 27611591Sleres } 27711591Sleres 27811591Sleres reload() 27911591Sleres { 28014011Sedward register struct ship *sp; 28111591Sleres 28214011Sedward foreachship(sp) { 28314011Sedward sp->file->loadwith = 0; 28414011Sedward } 28511591Sleres } 28611591Sleres 28711591Sleres checksails() 28811591Sleres { 28914011Sedward register struct ship *sp; 29014011Sedward register int rig, full; 29114011Sedward struct ship *close; 29211591Sleres 29314011Sedward foreachship(sp) { 29414011Sedward if (sp->file->captain[0] != 0) 29514011Sedward continue; 29614011Sedward rig = sp->specs->rig1; 29714011Sedward if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4) 29811591Sleres rig = 0; 29914011Sedward if (rig && sp->specs->crew3) { 30014011Sedward close = closestenemy(sp, 0, 0); 30114011Sedward if (close != 0) { 30214011Sedward if (range(sp, close) > 9) 30314011Sedward full = 1; 30414011Sedward else 30511591Sleres full = 0; 30614011Sedward } else 30711591Sleres full = 0; 30814011Sedward } else 30914011Sedward full = 0; 31014011Sedward if ((sp->file->FS != 0) != full) 31114011Sedward Write(W_FS, sp, 0, full, 0, 0, 0); 31211591Sleres } 31311591Sleres } 314