home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / spacewar / part04 / damage.c < prev    next >
C/C++ Source or Header  |  1988-05-31  |  5KB  |  202 lines

  1. /*
  2.  * Spacewar - inflict damage (proximity based)
  3.  *          reports damage to inflictee
  4.  *          reports to and credits inflictor
  5.  *
  6.  * Copyright 1985 obo Systems, Inc.
  7.  * Copyright 1985 Dan Rosenblatt
  8.  */
  9.  
  10. #include "spacewar.h"
  11. #ifndef VMS
  12. #include <sys/types.h>
  13. #else /* BSD SYSIII SYSV */
  14. #include <types.h>
  15. #endif /* VMS */
  16. #include "universe.h"
  17. #include "sys.h"
  18. #include "login.h"
  19. #include "crft.h"
  20. #include "aln.h"
  21. #include "flds.h"
  22. #include "build.h"
  23. #include "obj.h"
  24. #include "torp.h"
  25.  
  26. VOID damage(patck,ptrgt,rng,dmg,msg)
  27. struct universe *patck,*ptrgt;
  28. double rng,dmg;
  29. char *msg;
  30. {
  31.     register struct universe *puniv;
  32.     struct universe *plhit,*prvatck;
  33.     register struct sys *psys,*psysdmg;
  34.     struct crft *pcrft;
  35.     struct aln *paln;
  36.     struct torp *ptorp;
  37.     double vdist(),trgtdist;
  38.     int inflict,savinflict,totinflict=0,sh,ishulldmg,sysdmg;
  39.     char buf[80+1];
  40.     dsplcmnt tmpdspl;
  41.  
  42. #ifdef DEBUG
  43.     DBG("damage(#%3d,.,%f,%f,%s)\n",patck-univlst,rng,dmg,msg);
  44. #endif
  45.  
  46.     /* is it from hull damage; last hit by */
  47.     ishulldmg = (SUB(dmg,DIV(1.,690.)) <= 0.);
  48.     plhit = patck;
  49.     if (plhit && plhit->uv_type == 'T')
  50.         plhit = plhit->uv_ptr.uv_torp->tp_fby.ip_ptr;
  51.  
  52.     /******************************************/
  53.     /* find all damageable stuff within range */
  54.     /******************************************/
  55.     for (puniv=univlst+MAXUNIVERSE;puniv-- > univlst;) {
  56.         if (!puniv->uv_type) continue;
  57.         if (puniv->uv_type == 'O') continue;
  58.  
  59.         tmpdspl = vdisp(puniv,ptrgt,'d');
  60.         /*if (SUB(vdist(puniv->uv_pstn,ptrgt->uv_pstn),rng) > 0.) continue;*/
  61.         if (SUB(tmpdspl.dst,rng) > 0.) continue;
  62.  
  63.         /*******************************/
  64.         /* figure shielding protection */
  65.         /*******************************/
  66.         psys = NULL;
  67.         pcrft = NULL;
  68.         paln = NULL;
  69.         ptorp = NULL;
  70.         switch(puniv->uv_type) {
  71.         case 'T':
  72.             if (patck == puniv) continue;
  73.             ptorp = puniv->uv_ptr.uv_torp;
  74.             sh = 30;
  75.             if (plhit) ptorp->tp_lhit.ip_ptr = plhit;
  76.             break;
  77.         case 'A':
  78.             paln = puniv->uv_ptr.uv_aln;
  79.             psys = paln->al_sys;
  80.             sh = 3;
  81.             if (plhit) {
  82.             prvatck = paln->al_lhit.ip_ptr;
  83.             paln->al_lhit.ip_ptr = plhit;
  84.             if (plhit->uv_type != 'P' ||
  85.             !plhit->uv_ptr.uv_crft->cr_dock.ip_ptr) {
  86.                 paln->al_dly = 2;
  87.                 paln->al_atck.ip_ptr = plhit;
  88.             }
  89.             }
  90.             break;
  91.         case 'P':
  92.             pcrft = puniv->uv_ptr.uv_crft;
  93.             psys = pcrft->cr_sys;
  94.             sh = 3;
  95.             if (plhit) pcrft->cr_lhit.ip_ptr = plhit;
  96.             break;
  97.         }
  98.         if (psys && psys[SHIELDS].s_cap)
  99.         if (!ishulldmg) {/* no shields if caused by hull dmg */
  100.             int tmpsh;
  101.             tmpsh = psys[SHIELDS].s_lvl;
  102.             tmpsh *= psys[SHIELDS].s_pct;
  103.             tmpsh /= 100;
  104.             tmpsh *= psys[SHIELDS].s_cap;
  105.             tmpsh /= 100;
  106.             sh += tmpsh;
  107.         }
  108.  
  109.         /******************/
  110.         /* inflict damage */
  111.         /******************/
  112.         /* compute damage to inflict */
  113.         if (patck) {
  114.         tmpdspl = vdisp(patck,puniv,'d');
  115.         trgtdist = /*vdist(patck->uv_pstn,puniv->uv_pstn)*/ tmpdspl.dst;
  116.         } else
  117.         trgtdist = 1.;
  118.         if (SUB(trgtdist,1.) < 0) trgtdist = 1.;
  119.         inflict = INT(DIV(MUL(125000.,dmg),trgtdist)) / (sh*sh);
  120.         if (inflict > 1000) inflict = 1000;
  121.         totinflict += savinflict = inflict;
  122.  
  123.         /* apply damage */
  124.         if (psys) /* non-torp */
  125.         while (inflict > 0) {
  126.  
  127.             /* randomly choose an existing system */
  128.             psysdmg = psys + RANDOM(MSYS);
  129.             if (!psysdmg->s_cap) continue;
  130.  
  131.             /* 35<=sysdmg<80 */
  132.             sysdmg = RANDOM(45) + 35;
  133.             if (sysdmg > inflict) sysdmg = inflict;
  134.             inflict -= sysdmg;
  135.  
  136.             /* actual damage affected by subsystem ease of damage */
  137.             psysdmg->s_dmg += (sysdmg*psysdmg->s_edmg)/100;
  138.             if (psysdmg->s_dmg > 100 || psysdmg->s_dmg < 0)
  139.             psysdmg->s_dmg = 100;
  140.  
  141.             if (pcrft)
  142.             biton(pcrft->cr_chng,BIT_SDMG+
  143.             (psysdmg-psys)*flds[FLD_SDMG].f_grpw);
  144.             if (psys == psysdmg)
  145.             puniv->uv_mass = psysdmg->s_dmg;
  146.         }
  147.  
  148.         else {/* torp */
  149.         if (ptorp->tp_dmg + inflict >= 100)
  150.             ptorp->tp_dmg = 100;
  151.         else
  152.             ptorp->tp_dmg += inflict;
  153.         puniv->uv_mass = ptorp->tp_dmg;
  154.         }
  155.  
  156.         /* report damage inflicted to inflictee */
  157.         if (pcrft) {
  158.         output(pcrft->cr_lgn,'B',0,0);
  159.         setrpt(pcrft);
  160.         sprintf(buf,"%s damage: %d",msg,savinflict);
  161.         rpt(pcrft,buf);
  162.  
  163.         /* report direction if not from hull damage and */
  164.         /* not torpedo or torpedo fired-by still around */
  165.         if (!ishulldmg && plhit) {
  166.             double tmpvec[3];
  167.             vcopy(pcrft->cr_lhpstn,plhit->uv_pstn);
  168.             /*vdiff(plhit->uv_pstn,puniv->uv_pstn,tmpvec);*/
  169.             tmpdspl = vdisp(plhit,puniv,'v');
  170.             rttosp(/*tmpvec*/tmpdspl.vec,tmpvec);
  171.             sprintf(buf,"Attacker @%ld %.1f %.1f",INT(tmpvec[0]),
  172.             DIV(tmpvec[1],DEGTORAD),DIV(tmpvec[2],DEGTORAD));
  173.             rpt(pcrft,buf);
  174.         }
  175.         fnshrpt(pcrft,1);
  176.  
  177.         /* alien attack evaluation */
  178.         } else if (paln) {
  179.  
  180.         /* acccumulate damage caused by attacker */
  181.         if (plhit) {
  182.             if (plhit != prvatck) paln->al_aeval = 0;
  183.             paln->al_aeval += savinflict;
  184.         }
  185.         }
  186.     }
  187.  
  188.     /* report to and credit inflictor */
  189.     if (!ishulldmg && plhit && plhit->uv_type == 'P') {
  190.         pcrft = plhit->uv_ptr.uv_crft;
  191.         pcrft->cr_pnts += totinflict/10;
  192.         output(pcrft->cr_lgn,'B',0,0);
  193.         setrpt(pcrft);
  194.         sprintf(buf,"%s damage inflicted: %d",msg,totinflict);
  195.         rpt(pcrft,buf);
  196.         fnshrpt(pcrft,1);
  197.     }
  198. #ifdef DEBUG
  199.     VDBG("damage return\n");
  200. #endif
  201. }
  202.