|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 11725 (0x2dcd) Types: TextFile Names: »moveships.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Trek73/src/moveships.c«
#ident "@(#) TREK73 $Header: moveships.c,v 1.2 87/10/09 14:02:09 okamoto Exp $" /* * $Source: /ccc/okamoto/src/trek/src/RCS/moveships.c,v $ * * $Header: moveships.c,v 1.2 87/10/09 14:02:09 okamoto Exp $ * * $Log: moveships.c,v $ * Revision 1.2 87/10/09 14:02:09 14:02:09 okamoto (Jeff Okamoto) * Fix bug in self-destruct code. * * Revision 1.1 87/10/09 11:09:00 11:09:00 okamoto (Jeff Okamoto) * Initial revision * */ /* * TREK73: moveships.c * * Actual command execution * * move_ships, check_targets, misc_timers, disposition * */ #include "externs.h" move_ships() { register int i; register float j; register float k; register struct list *lp; register struct ship *sp; register float fuel_use; struct torpedo *tp; struct ship *fed; struct list *lp1; struct ship *sp1; float iterations; float tmpf; float energy; float course, newcourse; float warp, newwarp; int x, y; struct ship *target; double d0; float Mpersegment; double floor(), fabs(); /* * The value 100 is the number of Megameters per second * per warp-factor */ Mpersegment = segment * 100.0; iterations = (int)floor(timeperturn/segment + 0.5); /* What a crock! */ for (i=0; i<=shipnum; i++) distribute(shiplist[i]); fed = shiplist[0]; for (i=0; i<iterations; i++) { for (lp = &head; lp != NULL; lp = lp->fwd) { if (lp == tail) break; if (lp->type == I_UNDEFINED) continue; sp = NULL; tp = NULL; if (lp->type == I_SHIP) sp = lp->data.sp; else tp = lp->data.tp; if (sp && is_dead(sp, S_DEAD)) continue; if ((sp) && (i % sp->p_firing_delay == 0)) (void) phaser_firing(sp); if ((sp) && (i % sp->t_firing_delay == 0)) (void) torpedo_firing(sp); /* * time fuses */ if (tp) { tp->timedelay -= segment; if (tp->timedelay <= 0.) { torp_detonate(tp, lp); continue; } } else { sp->delay -= segment; if (sp->delay < segment / 2) { ship_detonate(sp, lp); continue; } } /* * proximity fuse */ if (tp && tp->prox != 0) { for (lp1 = &head; lp1 != tail; lp1 = lp1->fwd) { if (lp1->type == I_SHIP) { sp1 = lp1->data.sp; if (sp1 == tp->from) continue; if (cantsee(sp1)) continue; j = rangefind(tp->x, sp1->x, tp->y, sp1->y); } else if (lp1->type == I_ENG) { sp1 = lp1->data.sp; if (sp1 == tp->from) continue; if (cantsee(sp1)) continue; j = rangefind(tp->x, sp1->x, tp->y, sp1->y); } else continue; if (j >= tp->prox) continue; torp_detonate(tp, lp); break; } if (lp1 != tail) continue; } /* * movement simulation */ if (sp && is_dead(sp, S_DEAD)) continue; if (sp) { x = sp->x; y = sp->y; warp = sp->warp; if (fabs(sp->newwarp) > sp->max_speed) sp->newwarp = (sp->newwarp > 0) ? sp->max_speed : -sp->max_speed; newwarp = sp->newwarp; course = sp->course; newcourse = sp->newcourse; target = sp->target; energy = sp->energy; /* * fuel consumption */ if (fabs(warp) > 1.0) fuel_use = (fabs(warp) * sp->eff * segment); else fuel_use = 0.; #ifdef TRACE /* if (trace) printf("*** Fuel use = %.2f, energy = %.2f\n", fuel_use, energy); */ #endif if (fuel_use > energy) { if (!shutup[BURNOUT + sp->id] && !(is_dead(sp, S_WARP)) && cansee(sp)) { printf("%s's warp drive burning out.\n", sp->name); shutup[BURNOUT + sp->id]++; } newwarp = (warp < 0.0) ? -0.99 : 0.99; energy = 0; } else energy -= fuel_use; } else { x = tp->x; y = tp->y; warp = tp->speed; newwarp = tp->newspeed; course = tp->course; newcourse = course; target = tp->target; } /* * destroyed warp drive */ if (sp && (is_dead(sp, S_WARP))) if (fabs(warp) > 1.0) newwarp = (warp < 0.0) ? -0.99 : 0.99; /* * automatic pilot */ if (target != NULL) if (sp && (is_dead(target, S_DEAD))) { if ((sp == fed) && !shutup[DISENGAGE] && !is_dead(sp, S_DEAD)) { printf("%s's autopilot disengaging.\n", sp->name); shutup[DISENGAGE]++; } newcourse = course; target = NULL; sp->relbear = 0.0; } else { if (cantsee(target)) j =bearing(x,target->position.x, y, target->position.y); else j = bearing(x, target->x, y, target->y); if (sp) j = rectify(j - sp->relbear); newcourse = j; } /* * turn rate (known to be a ship) */ if (tp) course = newcourse; if (sp && course != newcourse) { j = rectify(newcourse - course); if (j > 180) j -= 360; /* * maximum degrees turned in one turn */ k = ((sp->max_speed + 2.0 - warp) * sp->deg_turn * segment); /* If you have no warp drive, you're less * maneuverable */ if (is_dead(sp, S_WARP)) k /= 2; k = course + (j < 0.0 ? -1.0 : 1.0) * min(fabs(j), k); course = rectify(k); } /* * acceleration */ tmpf = newwarp - warp; d0 = fabs(tmpf); warp += ((tmpf < 0.0) ? -1 : 1) * sqrt(d0) * segment; d0 = toradians(course); x += (int) (warp * cos(d0) * Mpersegment); y += (int) (warp * sin(d0) * Mpersegment); /* * projected position (cloaked) */ if (sp && cantsee(sp)) { d0 = toradians(sp->position.course); sp->position.x += (sp->position.warp * cos(d0) * segment); sp->position.y += (sp->position.warp * sin(d0) * segment); } /* * reset all the vars */ if (sp) { sp->x = x; sp->y = y; sp->warp = warp; sp->newwarp = newwarp; /* XXXXX should these be rectified? */ sp->course = rectify(course); sp->newcourse = rectify(newcourse); sp->energy = energy; sp->target = target; } else { tp->x = x; tp->y = y; tp->speed = warp; tp->course = rectify(course); tp->target = target; } } } } check_targets() { register int i; register int j; struct ship *sp; struct ship *fed; struct ship *target; fed = shiplist[0]; for (i=0; i <= shipnum; i++) { /* Check targets */ sp = shiplist[i]; if (is_dead(sp, S_DEAD)) continue; target = sp->target; if (target && is_dead(target, S_DEAD)) { if ((sp == fed) && !shutup[DISENGAGE]) { puts(" helm lock disengaging"); shutup[DISENGAGE]++; } sp->target = NULL; sp->relbear = 0.0; } for (j=0; j<sp->num_phasers; j++) { target = sp->phasers[j].target; if (target && is_dead(target, S_DEAD)) { if ((sp == fed) && (!shutup[PHASERS+j]) && !(is_dead(sp, S_DEAD))) { printf(" phaser %d disengaging\n",j+1); shutup[PHASERS+j]++; } sp->phasers[j].target = NULL; } else if (target) sp->phasers[j].bearing = rectify(bearing(sp->x, (cantsee(target)) ? target->position.x : target->x, sp->y, (cantsee(target)) ? target->position.y : target->y) - sp->course); } for (j=0; j<sp->num_tubes; j++) { target = sp->tubes[j].target; if (target && is_dead(target, S_DEAD)) { if ((sp == fed) && (!shutup[TUBES+j]) && !(is_dead(sp, S_DEAD))) { printf(" tube %d disengaging\n", j+1); shutup[TUBES+j]++; } sp->tubes[j].target = NULL; } else if (target) sp->tubes[j].bearing = rectify(bearing(sp->x, (cantsee(target)) ? target->position.x : target->x, sp->y, (cantsee(target)) ? target->position.y : target->y) - sp->course); } } if (sp->cloak_delay > 0) sp->cloak_delay--; } misc_timers() { struct ship *fed; /* * self-destruct warning */ fed = shiplist[0]; if ((fed->delay < 1000.) && (fed->delay > segment / 2)) { if (is_dead(fed, S_COMP)) { printf("%s: Self-destruct has been aborted due to computer damage\n", science); fed->delay = 10000.; } else printf("Computer: %5.2f seconds to self destruct.\n", fed->delay); } fed->probe_status = PR_NORMAL; /* * Ruses, bluffs, surrenders */ if (defenseless) defenseless++; if (corbomite) corbomite++; if (surrender) surrender++; if (surrenderp) surrenderp++; } disposition() { struct ship *sp; struct ship *fed; struct ship *ep; int kills; int others; int fedstatus; register int i; register int j; register int k; /* * Federation dispostion */ fed = shiplist[0]; sp = fed; kills = others = fedstatus = 0; if (sp->complement <= 0 && !is_dead(sp, S_DEAD)) { sp->status[S_DEAD] = 100; sp->newwarp = 0.0; sp->newcourse = sp->course; sp->target = NULL; sp->relbear = 0.0; for (i = 0; i < sp->num_phasers; i++) { sp->phasers[i].target = NULL; sp->phasers[i].drain = MIN_PHASER_DRAIN; sp->phasers[i].status &= ~P_FIRING; } for (i = 0; i < sp->num_tubes; i++) { sp->tubes[i].target = NULL; sp->tubes[i].status &= ~T_FIRING; } for (i = 0; i < SHIELDS; i++) sp->shields[i].attemp_drain = 0.0; sp->regen = 0.0; sp->cloaking = C_NONE; } if (is_dead(sp, S_DEAD)) fedstatus = 1; else { for (i=0; i<sp->num_phasers; i++) if (!(sp->phasers[i].status & P_DAMAGED)) break; if (i == sp->num_phasers) { for (i=0; i<sp->num_tubes; i++) if (!(sp->tubes[i].status & T_DAMAGED)) break; if (i == sp->num_tubes) fedstatus = 1; } } /* * enemy disposition */ for (k=1; k <= shipnum; k++) { ep = shiplist[k]; if (ep->complement <= 0 && !is_dead(ep, S_DEAD)) { ep->status[S_DEAD] = 100; ep->newwarp = 0.0; ep->newcourse = ep->course; ep->target = NULL; ep->relbear = 0.0; for (i = 0; i < ep->num_phasers; i++) { ep->phasers[i].target = NULL; ep->phasers[i].drain = MIN_PHASER_DRAIN; ep->phasers[i].status &= ~P_FIRING; } for (i = 0; i < ep->num_tubes; i++) { ep->tubes[i].target = NULL; ep->tubes[i].status &= ~T_FIRING; } for (i = 0; i < SHIELDS; i++) ep->shields[i].attemp_drain = 0.0; ep->regen = 0.0; ep->cloaking = C_NONE; } if (is_dead(ep, S_DEAD)) { kills++; continue; } if (fedstatus) continue; j = rangefind(sp->x, ep->x, sp->y, ep->y); if ((j>3500 && is_dead(ep, S_WARP)) || (j>4500 && ep->delay<10.)) { others++; continue; } /* Check if we are within range to turn off the flag */ if ((j <= 3500) && (reengaged)) reengaged = 0; if (ep->energy > 10) continue; for (i=0; i<ep->num_phasers; i++) if (!(ep->phasers[i].status & P_DAMAGED)) break; if (i != ep->num_phasers) continue; for (i=0; i<ep->num_tubes; i++) if (!(ep->tubes[i].status & T_DAMAGED)) break; if (i != ep->num_tubes) continue; kills++; } if (!fedstatus && (global & E_SURRENDER)) /* enemy surrender */ if (leftovers()) (void) warn(FIN_E_SURRENDER); else (void) final(FIN_E_SURRENDER); if ((is_dead(fed, S_SURRENDER)) && (kills + others < shipnum)) if (leftovers()) /* federation surrender */ (void) warn(FIN_F_SURRENDER); else (void) final(FIN_F_SURRENDER); if (!fedstatus && (kills + others) < shipnum) /* play continues */ return 0; if (fedstatus && kills < shipnum) /* Fed. defeated */ if (leftovers()) (void) warn(FIN_F_LOSE); else (void) final(FIN_F_LOSE); if (!fedstatus && kills == shipnum) /* Fed. victory */ if (leftovers()) (void) warn(FIN_E_LOSE); else (void) final(FIN_E_LOSE); if (!fedstatus && (kills + others) == shipnum) /* outmaneuvered */ if (leftovers()) (void) warn(FIN_TACTICAL); else (void) final(FIN_TACTICAL); if (fedstatus && kills == shipnum) (void) final(FIN_COMPLETE); /* both sides dead */ return 0; }