118697Sedward /* 221230Sdist * Copyright (c) 1983 Regents of the University of California. 333695Sbostic * All rights reserved. 433695Sbostic * 5*42603Sbostic * %sccs.include.redist.c% 618697Sedward */ 718697Sedward 811591Sleres #ifndef lint 9*42603Sbostic static char sccsid[] = "@(#)dr_3.c 5.4 (Berkeley) 06/01/90"; 1033695Sbostic #endif /* not lint */ 1111591Sleres 1214011Sedward #include "driver.h" 1311591Sleres 1411591Sleres moveall() /* move all comp ships */ 1511591Sleres { 1614011Sedward register struct ship *sp, *sq; /* r11, r10 */ 1714011Sedward register int n; /* r9 */ 1815722Sedward register int k, l; /* r8, r7 */ 1915708Sedward int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP]; 2015708Sedward char moved[NSHIP]; 2111591Sleres 2214011Sedward /* 2314011Sedward * first try to create moves for OUR ships 2414011Sedward */ 2514011Sedward foreachship(sp) { 2615708Sedward struct ship *closest; 2715708Sedward int ma, ta; 2815708Sedward char af; 2915708Sedward 3015203Sedward if (sp->file->captain[0] || sp->file->dir == 0) 3114011Sedward continue; 3214011Sedward if (!sp->file->struck && windspeed && !snagged(sp) 3314011Sedward && sp->specs->crew3) { 3415203Sedward ta = maxturns(sp, &af); 3514011Sedward ma = maxmove(sp, sp->file->dir, 0); 3614011Sedward closest = closestenemy(sp, 0, 0); 3714011Sedward if (closest == 0) 3815722Sedward *sp->file->movebuf = '\0'; 3911591Sleres else 4015722Sedward closeon(sp, closest, sp->file->movebuf, 4114011Sedward ta, ma, af); 4214011Sedward } else 4315722Sedward *sp->file->movebuf = '\0'; 4411591Sleres } 4514011Sedward /* 4614011Sedward * Then execute the moves for ALL ships (dead ones too), 4715708Sedward * checking for collisions and snags at each step. 4815708Sedward * The old positions are saved in row[], col[], dir[]. 4915708Sedward * At the end, we compare and write out the changes. 5014011Sedward */ 5114011Sedward n = 0; 5214011Sedward foreachship(sp) { 5314011Sedward if (snagged(sp)) 5415722Sedward (void) strcpy(sp->file->movebuf, "d"); 5514011Sedward else 5615722Sedward if (*sp->file->movebuf != 'd') 5715722Sedward (void) strcat(sp->file->movebuf, "d"); 5814011Sedward row[n] = sp->file->row; 5914011Sedward col[n] = sp->file->col; 6014011Sedward dir[n] = sp->file->dir; 6115708Sedward drift[n] = sp->file->drift; 6215708Sedward moved[n] = 0; 6314011Sedward n++; 6411591Sleres } 6514011Sedward /* 6614011Sedward * Now resolve collisions. 6714011Sedward * This is the tough part. 6814011Sedward */ 6915708Sedward for (k = 0; stillmoving(k); k++) { 7014011Sedward /* 7114011Sedward * Step once. 7215722Sedward * And propagate the nulls at the end of sp->file->movebuf. 7314011Sedward */ 7414011Sedward n = 0; 7514011Sedward foreachship(sp) { 7615722Sedward if (!sp->file->movebuf[k]) 7715722Sedward sp->file->movebuf[k+1] = '\0'; 7815708Sedward else if (sp->file->dir) 7915722Sedward step(sp->file->movebuf[k], sp, &moved[n]); 8014011Sedward n++; 8111591Sleres } 8214011Sedward /* 8314011Sedward * The real stuff. 8414011Sedward */ 8514011Sedward n = 0; 8614011Sedward foreachship(sp) { 8715708Sedward if (sp->file->dir == 0 || isolated(sp)) 8815238Sedward goto cont1; 8914011Sedward l = 0; 9014011Sedward foreachship(sq) { 9115708Sedward char snap = 0; 9215708Sedward 9315238Sedward if (sp == sq) 9415238Sedward goto cont2; 9515708Sedward if (sq->file->dir == 0) 9615238Sedward goto cont2; 9715708Sedward if (!push(sp, sq)) 9815708Sedward goto cont2; 9915708Sedward if (snagged2(sp, sq) && range(sp, sq) > 1) 10015708Sedward snap++; 10115708Sedward if (!range(sp, sq) && !fouled2(sp, sq)) { 10214011Sedward makesignal(sp, 10314011Sedward "collision with %s (%c%c)", sq); 10414011Sedward if (die() < 4) { 10514011Sedward makesignal(sp, 10614011Sedward "fouled with %s (%c%c)", 10714011Sedward sq); 10815722Sedward Write(W_FOUL, sp, 0, l, 0, 0, 0); 10915722Sedward Write(W_FOUL, sq, 0, n, 0, 0, 0); 11011591Sleres } 11115708Sedward snap++; 11215708Sedward } 11315708Sedward if (snap) { 11415722Sedward sp->file->movebuf[k + 1] = 0; 11515722Sedward sq->file->movebuf[k + 1] = 0; 11615708Sedward sq->file->row = sp->file->row - 1; 11714011Sedward if (sp->file->dir == 1 11814011Sedward || sp->file->dir == 5) 11915708Sedward sq->file->col = 12015708Sedward sp->file->col - 1; 12114011Sedward else 12215708Sedward sq->file->col = sp->file->col; 12315708Sedward sq->file->dir = sp->file->dir; 12411591Sleres } 12515238Sedward cont2: 12614011Sedward l++; 12711591Sleres } 12815238Sedward cont1: 12914011Sedward n++; 13011591Sleres } 13111591Sleres } 13214011Sedward /* 13315708Sedward * Clear old moves. And write out new pos. 13414011Sedward */ 13515708Sedward n = 0; 13615708Sedward foreachship(sp) { 13715708Sedward if (sp->file->dir != 0) { 13815722Sedward *sp->file->movebuf = 0; 13915708Sedward if (row[n] != sp->file->row) 14015722Sedward Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0); 14115708Sedward if (col[n] != sp->file->col) 14215722Sedward Write(W_COL, sp, 0, sp->file->col, 0, 0, 0); 14315708Sedward if (dir[n] != sp->file->dir) 14415722Sedward Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0); 14515708Sedward if (drift[n] != sp->file->drift) 14615708Sedward Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0); 14715708Sedward } 14815708Sedward n++; 14915708Sedward } 15011591Sleres } 15111591Sleres 15215708Sedward stillmoving(k) 15311591Sleres register int k; 15411591Sleres { 15514011Sedward register struct ship *sp; 15611591Sleres 15715708Sedward foreachship(sp) 15815722Sedward if (sp->file->movebuf[k]) 15914011Sedward return 1; 16014011Sedward return 0; 16111591Sleres } 16211591Sleres 16311591Sleres isolated(ship) 16414011Sedward register struct ship *ship; 16511591Sleres { 16614011Sedward register struct ship *sp; 16711591Sleres 16814011Sedward foreachship(sp) { 16914011Sedward if (ship != sp && range(ship, sp) <= 10) 17014011Sedward return 0; 17114011Sedward } 17214011Sedward return 1; 17311591Sleres } 17411591Sleres 17511591Sleres push(from, to) 17614011Sedward register struct ship *from, *to; 17711591Sleres { 17811591Sleres register int bs, sb; 17911591Sleres 18015708Sedward sb = to->specs->guns; 18115708Sedward bs = from->specs->guns; 18214011Sedward if (sb > bs) 18314011Sedward return 1; 18411591Sleres if (sb < bs) 18514011Sedward return 0; 18614011Sedward return from < to; 18711591Sleres } 18811591Sleres 18915708Sedward step(com, sp, moved) 19011591Sleres char com; 19115708Sedward register struct ship *sp; 19215708Sedward char *moved; 19311591Sleres { 19411591Sleres register int dist; 19511591Sleres 19614011Sedward switch (com) { 19714011Sedward case 'r': 19815708Sedward if (++sp->file->dir == 9) 19915708Sedward sp->file->dir = 1; 20014011Sedward break; 20114011Sedward case 'l': 20215708Sedward if (--sp->file->dir == 0) 20315708Sedward sp->file->dir = 8; 20414011Sedward break; 20515879Sedward case '0': case '1': case '2': case '3': 20615879Sedward case '4': case '5': case '6': case '7': 20715708Sedward if (sp->file->dir % 2 == 0) 20814011Sedward dist = dtab[com - '0']; 20914011Sedward else 21014011Sedward dist = com - '0'; 21115708Sedward sp->file->row -= dr[sp->file->dir] * dist; 21215708Sedward sp->file->col -= dc[sp->file->dir] * dist; 21315708Sedward *moved = 1; 21414011Sedward break; 21514011Sedward case 'b': 21614011Sedward break; 21714011Sedward case 'd': 21815708Sedward if (!*moved) { 21916426Sedward if (windspeed != 0 && ++sp->file->drift > 2 && 22015708Sedward (sp->specs->class >= 3 && !snagged(sp) 22115708Sedward || (turn & 1) == 0)) { 22215708Sedward sp->file->row -= dr[winddir]; 22315708Sedward sp->file->col -= dc[winddir]; 22415708Sedward } 22515708Sedward } else 22615708Sedward sp->file->drift = 0; 22714011Sedward break; 22811591Sleres } 22911591Sleres } 23011591Sleres 23114011Sedward sendbp(from, to, sections, isdefense) 23214011Sedward register struct ship *from, *to; 23314011Sedward int sections; 23414011Sedward char isdefense; 23511591Sleres { 23611591Sleres int n; 23714011Sedward register struct BP *bp; 23811591Sleres 23914011Sedward bp = isdefense ? from->file->DBP : from->file->OBP; 24015879Sedward for (n = 0; n < NBP && bp[n].turnsent; n++) 24114011Sedward ; 24215879Sedward if (n < NBP && sections) { 24314011Sedward Write(isdefense ? W_DBP : W_OBP, from, 0, 24415879Sedward n, turn, to->file->index, sections); 24514011Sedward if (isdefense) 24614011Sedward makesignal(from, "repelling boarders", 24714011Sedward (struct ship *)0); 24811591Sleres else 24914011Sedward makesignal(from, "boarding the %s (%c%c)", to); 25011591Sleres } 25111591Sleres } 25211591Sleres 25314011Sedward toughmelee(ship, to, isdefense, count) 25414011Sedward register struct ship *ship, *to; 25514011Sedward int isdefense, count; 25611591Sleres { 25714011Sedward register struct BP *bp; 25814011Sedward register obp = 0; 25914011Sedward int n, OBP = 0, DBP = 0, dbp = 0; 26011591Sleres int qual; 26111591Sleres 26214011Sedward qual = ship->specs->qual; 26314011Sedward bp = isdefense ? ship->file->DBP : ship->file->OBP; 26414011Sedward for (n = 0; n < NBP; n++, bp++) { 26514011Sedward if (bp->turnsent && (to == bp->toship || isdefense)) { 26614011Sedward obp += bp->mensent / 100 26714011Sedward ? ship->specs->crew1 * qual : 0; 26814011Sedward obp += (bp->mensent % 100)/10 26914011Sedward ? ship->specs->crew2 * qual : 0; 27014011Sedward obp += bp->mensent % 10 27114011Sedward ? ship->specs->crew3 * qual : 0; 27211591Sleres } 27311591Sleres } 27414011Sedward if (count || isdefense) 27514011Sedward return obp; 27614011Sedward OBP = toughmelee(to, ship, 0, count + 1); 27714011Sedward dbp = toughmelee(ship, to, 1, count + 1); 27814011Sedward DBP = toughmelee(to, ship, 1, count + 1); 27911591Sleres if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10) 28014011Sedward return 1; 28111591Sleres else 28214011Sedward return 0; 28311591Sleres } 28411591Sleres 28511591Sleres reload() 28611591Sleres { 28714011Sedward register struct ship *sp; 28811591Sleres 28914011Sedward foreachship(sp) { 29014011Sedward sp->file->loadwith = 0; 29114011Sedward } 29211591Sleres } 29311591Sleres 29411591Sleres checksails() 29511591Sleres { 29614011Sedward register struct ship *sp; 29714011Sedward register int rig, full; 29814011Sedward struct ship *close; 29911591Sleres 30014011Sedward foreachship(sp) { 30114011Sedward if (sp->file->captain[0] != 0) 30214011Sedward continue; 30314011Sedward rig = sp->specs->rig1; 30414011Sedward if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4) 30511591Sleres rig = 0; 30614011Sedward if (rig && sp->specs->crew3) { 30714011Sedward close = closestenemy(sp, 0, 0); 30814011Sedward if (close != 0) { 30914011Sedward if (range(sp, close) > 9) 31014011Sedward full = 1; 31114011Sedward else 31211591Sleres full = 0; 31314011Sedward } else 31411591Sleres full = 0; 31514011Sedward } else 31614011Sedward full = 0; 31714011Sedward if ((sp->file->FS != 0) != full) 31814011Sedward Write(W_FS, sp, 0, full, 0, 0, 0); 31911591Sleres } 32011591Sleres } 321