int pln_hitchance(struct plnstr *pp, int hardtarget, int type) { struct plchrstr *pcp = plchr + pp->pln_type; double tfact = (double)(pp->pln_tech - pcp->pl_tech) / (pp->pln_tech - pcp->pl_tech / 2); int acc = pln_acc(pp); int hitchance; if (type == EF_SHIP) { if (pcp->pl_flags & P_A) acc -= 20; if (!(pcp->pl_flags & P_T)) acc += 35; } hitchance = (int)(pp->pln_effic * (1.0 - 0.1 * tfact) * (1.0 - acc / 100.0)) - hardtarget; /* smooth out the bottom of the graph with asymtote at 5 -KHS */ if (hitchance < 20) hitchance = 5 + ldround(300.0 / (40.0 - hitchance), 1); if (hitchance > 100) hitchance = 100; return hitchance; }
void plane_sweep(struct emp_qelem *plane_list, coord x, coord y) { struct plnstr *pp; struct plchrstr *pcp; struct emp_qelem *qp; struct emp_qelem *next; struct plist *ip; struct sctstr sect; int mines_there; int found = 0; getsect(x, y, §); mines_there = sect.sct_mines; if (mines_there == 0) return; if (sect.sct_type != SCT_WATER) return; for (qp = plane_list->q_forw; ((qp != plane_list) && (mines_there)); qp = next) { next = qp->q_forw; ip = (struct plist *)qp; pp = &ip->plane; pcp = ip->pcp; if (!(pcp->pl_flags & P_SWEEP)) /* if it isn't an sweep plane */ continue; if (chance((100.0 - pln_acc(pp)) / 100.0)) { pr("Sweep! in %s\n", xyas(sect.sct_x, sect.sct_y, player->cnum)); mines_there--; found = 1; } } if (found && map_set(player->cnum, sect.sct_x, sect.sct_y, 'X', 0)) writemap(player->cnum); sect.sct_mines = mines_there; putsect(§); }
int pdump(void) { int nplanes; struct nstr_item np; struct plnstr plane; struct nukstr nuke; int field[128]; struct natstr *natp; int n, i; time_t now; if (!snxtitem(&np, EF_PLANE, player->argp[1], NULL)) return RET_SYN; prdate(); if (!player->argp[2]) { for (n = 1; n <= 32; n++) field[n - 1] = n; field[n - 1] = 0; } else { n = 2; i = 0; while (player->argp[n]) { if (!strcmp("type", player->argp[n])) { field[i++] = 1; } else if (!strcmp("x", player->argp[n])) { field[i++] = 2; } else if (!strcmp("y", player->argp[n])) { field[i++] = 3; } else if (!strcmp("wing", player->argp[n])) { field[i++] = 4; } else if (!strcmp("eff", player->argp[n])) { field[i++] = 5; } else if (!strcmp("mob", player->argp[n])) { field[i++] = 6; } else if (!strcmp("tech", player->argp[n])) { field[i++] = 7; } else if (!strcmp("att", player->argp[n])) { field[i++] = 8; } else if (!strcmp("def", player->argp[n])) { field[i++] = 9; } else if (!strcmp("acc", player->argp[n])) { field[i++] = 10; } else if (!strcmp("react", player->argp[n])) { field[i++] = 11; } else if (!strcmp("range", player->argp[n])) { field[i++] = 12; } else if (!strcmp("load", player->argp[n])) { field[i++] = 13; } else if (!strcmp("fuel", player->argp[n])) { field[i++] = 14; } else if (!strcmp("hard", player->argp[n])) { field[i++] = 15; } else if (!strcmp("ship", player->argp[n])) { field[i++] = 16; } else if (!strcmp("land", player->argp[n])) { field[i++] = 17; } else if (!strcmp("laun", player->argp[n])) { field[i++] = 18; } else if (!strcmp("orb", player->argp[n])) { field[i++] = 19; } else if (!strcmp("nuke", player->argp[n])) { field[i++] = 20; } else if (!strcmp("grd", player->argp[n])) { field[i++] = 21; } else { pr("Unrecognized field %s\n", player->argp[n]); } if (n++ > 100) { pr("Too many fields\n"); return RET_FAIL; } } field[i] = 0; } if (player->god) pr(" "); time(&now); pr("DUMP PLANES %ld\n", (long)now); if (player->god) pr("own "); pr("id"); n = 0; while (field[n]) { switch (field[n]) { case 1: pr(" type"); break; case 2: pr(" x"); break; case 3: pr(" y"); break; case 4: pr(" wing"); break; case 5: pr(" eff"); break; case 6: pr(" mob"); break; case 7: pr(" tech"); break; case 8: pr(" att"); break; case 9: pr(" def"); break; case 10: pr(" acc"); break; case 11: pr(" react"); break; case 12: pr(" range"); break; case 13: pr(" load"); break; case 14: pr(" fuel"); break; case 15: pr(" hard"); break; case 16: pr(" ship"); break; case 17: pr(" land"); break; case 18: pr(" laun"); break; case 19: pr(" orb"); break; case 20: pr(" nuke"); break; case 21: pr(" grd"); break; } n++; } pr("\n"); nplanes = 0; natp = getnatp(player->cnum); while (nxtitem(&np, &plane)) { if (!player->owner || plane.pln_own == 0) continue; nplanes++; if (player->god) pr("%d ", plane.pln_own); pr("%d", np.cur); n = 0; while (field[n]) { switch (field[n++]) { case 1: pr(" %.4s", plchr[(int)plane.pln_type].pl_name); break; case 2: pr(" %d", xrel(natp, plane.pln_x)); break; case 3: pr(" %d", yrel(natp, plane.pln_y)); break; case 4: pr(" %c", plane.pln_wing ? plane.pln_wing : '~'); break; case 5: pr(" %d", plane.pln_effic); break; case 6: pr(" %d", plane.pln_mobil); break; case 7: pr(" %d", plane.pln_tech); break; case 8: pr(" %d", pln_att(&plane)); break; case 9: pr(" %d", pln_def(&plane)); break; case 10: pr(" %d", pln_acc(&plane)); break; case 11: pr(" %d", plane.pln_range); break; case 12: pr(" %d", pln_range_max(&plane)); break; case 13: pr(" %d", pln_load(&plane)); break; case 14: pr(" %d", plchr[(int)plane.pln_type].pl_fuel); break; case 15: pr(" %d", plane.pln_harden); break; case 16: pr(" %d", plane.pln_ship); break; case 17: pr(" %d", plane.pln_land); break; case 18: pr(pln_is_in_orbit(&plane) ? " Y" : " N"); break; case 19: pr(pln_is_in_orbit(&plane) && (plane.pln_flags & PLN_SYNCHRONOUS) ? " Y" : " N"); break; case 20: if (getnuke(nuk_on_plane(&plane), &nuke)) { pr(" %.5s", nchr[nuke.nuk_type].n_name); break; } else pr(" N/A"); break; case 21: pr(" %c", plane.pln_flags & PLN_AIRBURST ? 'A' : 'G'); break; } } pr("\n"); } if (nplanes == 0) { if (player->argp[1]) pr("%s: No plane(s)\n", player->argp[1]); else pr("%s: No plane(s)\n", ""); return RET_FAIL; } else pr("%d plane%s\n", nplanes, splur(nplanes)); return RET_OK; }
void plane_sona(struct emp_qelem *plane_list, int x, int y, struct shiplist **head) { struct plnstr *pp; struct plchrstr *pcp; struct mchrstr *tmcp; struct shpstr *targ, s; struct natstr *natp; struct emp_qelem *qp; struct emp_qelem *next; struct plist *ip; struct sctstr sect; int found = 0; int range, i, vis; int pingrange; int vrange; int dist; getsect(x, y, §); if ((sect.sct_type != SCT_WATER) && (sect.sct_type != SCT_HARBR)) return; for (qp = plane_list->q_forw; qp != plane_list; qp = next) { next = qp->q_forw; ip = (struct plist *)qp; pp = &ip->plane; pcp = ip->pcp; if (!(pcp->pl_flags & P_A)) /* if it isn't an ASW plane */ continue; range = (int)techfact(pp->pln_tech, (100.0 - pln_acc(pp)) / 10.0); for (i = 0; getship(i, &s); i++) { targ = &s; if (targ->shp_own == pp->pln_own || targ->shp_own == 0) continue; if (on_shiplist(targ->shp_uid, *head)) continue; tmcp = &mchr[(int)targ->shp_type]; if (!(tmcp->m_flags & M_SUB)) continue; if (!pct_chance(pln_identchance(pp, shp_hardtarget(targ), EF_SHIP))) continue; vis = shp_visib(targ); pingrange = MAX(vis, 10) * range / 10; vrange = pingrange * (pp->pln_effic / 200.0); dist = mapdist(targ->shp_x, targ->shp_y, x, y); pingrange = (MAX(pingrange, 2) * targ->shp_effic); pingrange = roundavg(pingrange / 100.0); if (dist > pingrange) continue; if (tmcp->m_flags & M_SONAR && targ->shp_own) { natp = getnatp(targ->shp_own); if (natp->nat_flags & NF_SONAR) wu(0, targ->shp_own, "Sonar ping from %s detected by %s!\n", xyas(x, y, targ->shp_own), prship(targ)); } if ((dist > vrange)) continue; add_shiplist(targ->shp_uid, head); if (!found) { pr("Sonar contact in %s\n", xyas(x, y, player->cnum)); found = 1; } if (relations_with(targ->shp_own, pp->pln_own) < FRIENDLY && !pct_chance(pln_identchance(pp, shp_hardtarget(targ), EF_SHIP))) if (!pct_chance(pln_identchance(pp, shp_hardtarget(targ), EF_SHIP))) pr("sub #%d %s\n", targ->shp_uid, xyas(targ->shp_x, targ->shp_y, player->cnum)); else pr("%s %s\n", prship(targ), xyas(targ->shp_x, targ->shp_y, player->cnum)); else pr("%s %s @ %s\n", cname(targ->shp_own), prship(targ), xyas(targ->shp_x, targ->shp_y, player->cnum)); } } if (found) pr("\n"); }
int pln_damage(struct plnstr *pp, char type, int noisy) { struct plchrstr *pcp = plchr + pp->pln_type; int load, i, hitroll, aim, len; int dam = 0; int effective = 1; int pinbomber = 0; char buf[80]; if (CANT_HAPPEN(nuk_on_plane(pp) >= 0)) return 0; load = pln_load(pp); if (!load) /* e.g. ab, blowing up on launch pad */ return 0; i = roll(load) + 1; if (i > load) i = load; if (pcp->pl_flags & P_M) { if (pcp->pl_flags & P_MAR) pinbomber = 1; } else if (pcp->pl_flags & P_T) pinbomber = 1; aim = pln_acc(pp); if (type == 's') { effective = !pinbomber; aim = 30 + (pinbomber ? aim : 100 - aim); } else { effective = pinbomber; aim = 100 - aim; } len = 0; while (i--) { dam += roll(6); hitroll = roll(100); if (hitroll >= 90) { dam += 8; if (noisy) len += sprintf(buf + len, "BLAM"); } else if (hitroll < aim) { dam += 5; if (noisy) len += sprintf(buf + len, "Blam"); } else { dam += 1; if (noisy) len += sprintf(buf + len, "blam"); } if (noisy) { if (len > 75) { mpr(pp->pln_own, "%s\n", buf); len = 0; } if (i) len += sprintf(buf + len, "-"); } } if (noisy && len) mpr(pp->pln_own, "%s\n", buf); if (effective) dam *= 2; return dam; }