|
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 d
Length: 7025 (0x1b71) Types: TextFile Names: »damage.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Trek73/src/damage.c«
#ident "@(#) TREK73 $Header: damage.c,v 1.1 87/10/09 11:03:30 okamoto Exp $" /* * $Source: /ccc/okamoto/src/trek/src/RCS/damage.c,v $ * * $Header: damage.c,v 1.1 87/10/09 11:03:30 okamoto Exp $ * * $Log: damage.c,v $ * Revision 1.1 87/10/09 11:03:30 11:03:30 okamoto (Jeff Okamoto) * Initial revision * */ /* * TREK73: damage.c * * Damage routines * * damage, check_locks * */ #include "externs.h" damage(hit, ep, s, dam, flag) int hit; struct ship *ep; int s; struct damage *dam; int flag; { register int i; register int j; register int k; float f1; /* Damage factor except for shields */ float f2; /* Shield damage factor */ int percent; struct ship *fed; fed = shiplist[0]; printf("hit %d on %s's shield %d\n", hit, ep->name, s); s--; /* * Note that if the shield is at 100% efficiency, no * damage at all will be taken (except to the shield itself) */ f1 = hit * (1.0 - ep->shields[s].eff * ep->shields[s].drain); if (f1 < 0) return 0; /* Calculate shield damage */ if (flag == D_ANTIMATTER) f2 = ep->tu_damage * 100; else if (flag == D_PHASER) f2 = ep->ph_damage * 100; if (s == 0) f2 *= SHIELD1; ep->shields[s].eff -= max(hit/f2, 0); if (ep->shields[s].eff < 0.0) ep->shields[s].eff = 0.0; /* Calculate loss of fuel, regeneration, etc. */ ep->eff += f1/dam->eff; ep->pods -= f1/dam->fuel; ep->energy -= f1/dam->fuel; ep->regen -= f1/dam->regen; if (ep->regen < 0.0) ep->regen = 0.0; if (ep->pods < 0.0) ep->pods = 0.0; if (ep->energy < 0.0) ep->energy = 0.0; if (ep->pods < ep->energy) ep->energy = ep->pods; /* Kill some crew */ if (ep->complement > 0) { j = f1 * dam->crew; if (j > 0) ep->complement -= randm(j); if (ep->complement < 0) ep->complement = 0; } /* Damage some weapons */ j = f1/dam->weapon; for(i=0; i<j; i++) { k = randm(ep->num_phasers + ep->num_tubes) - 1; if (k < ep->num_phasers) { if (ep->phasers[k].status & P_DAMAGED) continue; ep->phasers[k].status |= P_DAMAGED; ep->phasers[k].target = NULL; /* * Reroute the energy * back to the engines */ ep->energy = min(ep->pods, ep->energy + ep->phasers[k].load); ep->phasers[k].load = 0; ep->phasers[k].drain = 0; k++; if (ep == fed) printf(" phaser %d damaged\n", k); } else { k -= ep->num_phasers; if (ep->tubes[k].status & T_DAMAGED) continue; /* * If tubes are damaged, reroute the pods * back to the engines */ ep->pods += ep->tubes[k].load; ep->energy += ep->tubes[k].load; ep->tubes[k].load = 0; ep->tubes[k].status |= T_DAMAGED; ep->tubes[k].target = NULL; k++; if (ep == fed) printf(" tube %d damaged\n", k); } } /* Damage the different systems */ for (i=0; i<S_NUMSYSTEMS; i++) { if (is_dead(ep, i)) /* Don't damage a dead system */ continue; percent = 0; if (randm(dam->stats[i].roll) < f1) { /* A better method should be found */ percent = (int) randm((int) f1); /* * The expected value for the percent damage to each system is roughly * equal to: * f1 * f1 / (2 * dam->stats[i].roll) * Only these damages are proportional to hit squared. All others are * linearly proportional. This includes shield damage, ship's fuel * supply, consumption and regeneration rates, casualties, and weapons. * (When weapons are damaged, they are 100% damaged - the number of * weapons damaged is proportional to hit). I think the old way * decided whether or not to completely damage a system based on the * comparison "randm(dam->stats[i].roll) < f1". This is almost like * the weapons are still handled. Another possibility is to always * damage each system by: * 100 * randm((int)f1) / dam->stats[i].roll * percent. This adds some randomness and makes the approx. expected * value of the damage to each system: * 100 * f1 / (2 * dam->stats[i].roll) * percent. Perhaps this isn't such a good idea after all; this is * 100/f1 times the current expected value, often > 2. And it is * actually somewhat less random since each system gets damaged each * time. I had thought that the damage should be directly proportional * to f1, not to its square. But perhaps it makes sense that a hit * twice as big has an expected value of damage four times as big as * that from a smaller hit. The actual damage any given time is still * proportional to the hit, but the probability that any damage will be * done at all is also directly proportional to the hit. This is a * pretty good system after all. [RJN] */ ep->status[i] += percent; if (ep->status[i] > 100) ep->status[i] = 100; if (ep == fed) { if (is_dead(ep, i)) printf(" %s\n", dam->stats[i].mesg); else printf(" %s damaged.\n", sysname[i]); } /* Now check for the effects of the damage */ /* Do the effects of a totally destroyed system */ if (is_dead(ep, i)) { switch(i) { case S_SENSOR: case S_PROBE: /* No bookkeeping needed */ break; case S_WARP: /* Reduce max speed */ ep->max_speed = 1.0; break; case S_COMP: check_locks(ep, 100, fed); break; default: printf("How'd we get here?\n"); } } else { /* Now check partially damaged systems */ switch(i) { case S_SENSOR: case S_PROBE: /* No bookkeeping needed */ break; case S_WARP: f2 = percent * ep->orig_max / 100; ep->max_speed -= f2; if (ep->max_speed < 1.0) { ep->max_speed = 1.0; ep->status[S_WARP] = 100; } break; case S_COMP: check_locks(ep, percent, fed); break; default: printf("Oh, oh....\n"); } } } } #ifdef HISTORICAL /* * Historically, if more than 43 points of damage were done * to the ship, it would destroy itself. This led to much * abuse of probes and thus has been enclosed inside of * an #ifdef */ if (f1 > 43) ep->delay = 1.; #endif return 0; } check_locks(ep, percent, fed) struct ship *ep; int percent; struct ship *fed; { register int i, j = 0; for (i=0; i<ep->num_phasers; i++) { if ((ep->phasers[i].target != NULL) && (randm(100) <= percent)) { ep->phasers[i].target = NULL; if (ep != fed) continue; if (!j) printf("Computer: Phaser(s) %d", i+1); else printf(", %d", i+1); j++; } } if (j > 1) puts(" have lost their target locks."); else if (j == 1) puts(" has lost its target lock."); j = 0; for (i=0; i<ep->num_tubes; i++) { if ((ep->tubes[i].target != NULL) && (randm(100) <= percent)) { ep->tubes[i].target = NULL; if (ep != fed) continue; if (!j) printf("Computer: Tube(s) %d", i+1); else printf(", %d", i+1); j++; } } if (j > 1) puts(" have lost their target locks."); else if (j == 1) puts(" has lost its target lock."); if ((ep->target != NULL) && (randm(100) <= percent)) { ep->target = NULL; ep->relbear = 0; if (ep == fed) printf("Computer: %s has lost helm lock\n", shipname); } }