118697Sedward /*
2*60846Sbostic * Copyright (c) 1983, 1993
3*60846Sbostic * The Regents of the University of California. All rights reserved.
433695Sbostic *
542603Sbostic * %sccs.include.redist.c%
618697Sedward */
718697Sedward
811591Sleres #ifndef lint
9*60846Sbostic static char sccsid[] = "@(#)dr_3.c 8.1 (Berkeley) 05/31/93";
1033695Sbostic #endif /* not lint */
1111591Sleres
1214011Sedward #include "driver.h"
1311591Sleres
moveall()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
stillmoving(k)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
isolated(ship)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
push(from,to)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
step(com,sp,moved)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
sendbp(from,to,sections,isdefense)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
toughmelee(ship,to,isdefense,count)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
reload()28511591Sleres reload()
28611591Sleres {
28714011Sedward register struct ship *sp;
28811591Sleres
28914011Sedward foreachship(sp) {
29014011Sedward sp->file->loadwith = 0;
29114011Sedward }
29211591Sleres }
29311591Sleres
checksails()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