Advertisement
Guest User

Mirror Shielded Enemies

a guest
Mar 26th, 2016
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.17 KB | None | 0 0
  1. void check_collisions()
  2. {
  3.     for(int i=0; i<Lwpns.Count(); i++)
  4.     {
  5.         weapon *w = (weapon*)Lwpns.spr(i);
  6.        
  7.         if(!(w->Dead()) && w->id!=wSword && w->id!=wHammer && w->id!=wWand)
  8.         {
  9.             for(int j=0; j<guys.Count(); j++)
  10.             {
  11.                 enemy *e = (enemy*)guys.spr(j);
  12.                 if(e->hit(w))
  13.                 {
  14.                     int h = e->takehit(w);
  15.                    
  16.                     if(h)
  17.                     {
  18.                         if(h==3)
  19.                         {
  20.                             //Enemies can be shielded in four directions
  21.                             // We need to figure out which direction the shield is facing.
  22.                             double ddir=atan2(double(w->y-e->y),double(e->x-w->X));
  23.                             int xdir=rand()&3;
  24.                             if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
  25.                             {
  26.                                 xdir=down;
  27.                             }
  28.                             else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
  29.                             {
  30.                                 xdir=right;
  31.                             }
  32.                             else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
  33.                             {
  34.                                 xdir=up;
  35.                             }
  36.                             else
  37.                             {
  38.                                 xdir=left;
  39.                             }
  40.                             w->onhit(false, 3, xdir);
  41.                         }
  42.                         else                       
  43.                             w->onhit(false);
  44.                     }
  45.                    
  46.                     if(h==2) //apparently this never runs.
  47.                     {
  48.                         break;
  49.                     }
  50.                 }
  51.                
  52.                 if(w->Dead())
  53.                 {
  54.                     break;
  55.                 }
  56.             }
  57.            
  58.             if(get_bit(quest_rules,qr_Z3BRANG_HSHOT))
  59.             {
  60.                 if(w->id == wBrang || w->id==wHookshot)
  61.                 {
  62.                     for(int j=0; j<items.Count(); j++)
  63.                     {
  64.                         if(items.spr(j)->hit(w))
  65.                         {
  66.                             bool priced = ((item*)items.spr(j))->PriceIndex >-1;
  67.                            
  68.                             if((((item*)items.spr(j))->pickup & ipTIMER && ((item*)items.spr(j))->clk2 >= 32)
  69.                                     || (get_bit(quest_rules,qr_BRANGPICKUP) && !priced && !(((item*)items.spr(j))->pickup & ipDUMMY)))
  70.                             {
  71.                                 if(w->id == wBrang)
  72.                                 {
  73.                                     w->onhit(false);
  74.                                 }
  75.                                
  76.                                 if(w->dragging==-1)
  77.                                 {
  78.                                     w->dead=1;
  79.                                     ((item*)items.spr(j))->clk2=256;
  80.                                     w->dragging=j;
  81.                                 }
  82.                             }
  83.                         }
  84.                     }
  85.                 }
  86.             }
  87.             else
  88.             {
  89.                 if(w->id == wBrang || w->id == wArrow || w->id==wHookshot)
  90.                 {
  91.                     for(int j=0; j<items.Count(); j++)
  92.                     {
  93.                         if(items.spr(j)->hit(w))
  94.                         {
  95.                             bool priced = ((item*)items.spr(j))->PriceIndex >-1;
  96.                            
  97.                             if((((item*)items.spr(j))->pickup & ipTIMER && ((item*)items.spr(j))->clk2 >= 32)
  98.                                     || (get_bit(quest_rules,qr_BRANGPICKUP) && !priced))
  99.                             {
  100.                                 if(itemsbuf[items.spr(j)->id].collect_script)
  101.                                 {
  102.                                     ZScriptVersion::RunScript(SCRIPT_ITEM, itemsbuf[items.spr(j)->id].collect_script, items.spr(j)->id & 0xFFF);
  103.                                 }
  104.                                
  105.                                 //getitem(items.spr(j)->id);
  106.                                 //items.del(j);
  107.                                 Link.checkitems(j);
  108.                                 //--j;
  109.                             }
  110.                         }
  111.                     }
  112.                 }
  113.             }
  114.         }
  115.     }
  116. }
  117.  
  118. int enemy::takehit(weapon *w)
  119. {
  120.     int wpnId = w->id;
  121.     int power = w->power;
  122.     int wpnx = w->x;
  123.     int wpny = w->y;
  124.     int enemyHitWeapon = w->parentitem;
  125.     int wpnDir;
  126.    
  127.     // If it's a boomerang that just bounced, use the opposite direction;
  128.     // otherwise, it might bypass a shield. This probably won't handle
  129.     // every case correctly, but it's better than having shields simply
  130.     // not work against boomerangs.
  131.     if(w->id==wBrang && w->misc==1 && w->clk2>=256 && w->clk2<264)
  132.         wpnDir = oppositeDir[w->dir];
  133.     else
  134.         wpnDir = w->dir;
  135.        
  136.     if(dying || clk<0 || hclk>0 || superman)
  137.     {
  138.         return 0;
  139.     }
  140.    
  141.     int ret = -1;
  142.    
  143.     // This obscure quest rule...
  144.     if(get_bit(quest_rules,qr_BOMBDARKNUTFIX) && (wpnId==wBomb || wpnId==wSBomb))
  145.     {
  146.         double ddir=atan2(double(wpny-y),double(x-wpnx));
  147.         wpnDir=rand()&3;
  148.        
  149.         if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
  150.         {
  151.             wpnDir=down;
  152.         }
  153.         else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
  154.         {
  155.             wpnDir=right;
  156.         }
  157.         else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
  158.         {
  159.             wpnDir=up;
  160.         }
  161.         else
  162.         {
  163.             wpnDir=left;
  164.         }
  165.     }
  166.    
  167.     int xdir = dir;
  168.     shieldCanBlock=false;
  169.    
  170.     //if (family==eeFLOAT && flags&(inv_front|inv_back_inv_left|inv_right)) xdir=down;
  171.     if((wpnId==wHookshot && hitshield(wpnx, wpny, xdir))
  172.             || ((flags&inv_front && wpnDir==(xdir^down)) || (flags&inv_back && wpnDir==(xdir^up)) || (flags&inv_left && wpnDir==(xdir^left)) || (flags&inv_right && wpnDir==(xdir^right)))
  173.       )
  174.         // The hammer should already be dealt with by subclasses (Walker etc.)
  175.     {
  176.         switch(wpnId)
  177.         {
  178.             // Weapons which shields protect against
  179.         case wSword:
  180.         case wWand:
  181.             Link.onMeleeWeaponHit();
  182.                
  183.             //fallthrough
  184.         case wHookshot:
  185.         case wHSHandle:
  186.         case wBrang:
  187.             shieldCanBlock=true;
  188.             break;
  189.            
  190.         case wBeam:
  191.         case wRefBeam:
  192.         case wRefRock:
  193.         case wRefFireball:
  194.         case wMagic:
  195.         case wRefMagic:
  196.             if(wpnId>wEnemyWeapons)
  197.                 return 0;
  198.                
  199.             //fallthrough
  200.         default:
  201.             if(flags2&guy_mirror)
  202.             {
  203.                 shieldCanBlock=true;
  204.                 return 3;
  205.             }
  206.             shieldCanBlock=true;
  207.             break;
  208.            
  209.             // Bombs
  210.         case wSBomb:
  211.         case wBomb:
  212.             goto hitclock;
  213.            
  214.             // Weapons which ignore shields
  215.         case wWhistle:
  216.         case wHammer:
  217.             break;
  218.            
  219.             // Weapons which shouldn't be removed by shields
  220.         case wLitBomb:
  221.         case wLitSBomb:
  222.         case wWind:
  223.         case wPhantom:
  224.         case wSSparkle:
  225.         case wBait:
  226.             return 0;
  227.            
  228.         case wFire:
  229.             ;
  230.         }
  231.     }
  232.    
  233.     switch(wpnId)
  234.     {
  235.     case wWhistle:
  236.         return 0;
  237.        
  238.     case wPhantom:
  239.         return 0;
  240.        
  241.     case wLitBomb:
  242.     case wLitSBomb:
  243.     case wBait:
  244.     case wWind:
  245.     case wSSparkle:
  246.         return 0;
  247.        
  248.     case wFSparkle:
  249.    
  250.         // Only take sparkle damage if the sparkle's parent item is not
  251.         // defended against.
  252.         if(enemyHitWeapon > -1)
  253.         {
  254.             int p = 0;
  255.             int f = itemsbuf[enemyHitWeapon].family;
  256.            
  257.             switch(f)
  258.             {
  259.             case itype_arrow:
  260.                 if(!candamage(p, edefARROW)) return 0;
  261.                
  262.                 break;
  263.                
  264.             case itype_cbyrna:
  265.                 if(!candamage(p, edefBYRNA)) return 0;
  266.                
  267.                 break;
  268.                
  269.             case itype_brang:
  270.                 if(!candamage(p, edefBRANG)) return 0;
  271.                
  272.                 break;
  273.                
  274.             default:
  275.                 return 0;
  276.             }
  277.         }
  278.        
  279.         wpnId = wSword;
  280.         power = DAMAGE_MULTIPLIER>>1;
  281.         goto fsparkle;
  282.         break;
  283.        
  284.     case wBrang:
  285.     {
  286.         int def = defend(wpnId, &power, edefBRANG);
  287.        
  288.         if(def >= 0) return def;
  289.        
  290.         // Not hurt by 0-damage weapons
  291.         if(!(flags & guy_bhit))
  292.         {
  293.             stunclk=160;
  294.            
  295.             if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))
  296.             {
  297.                 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))*DAMAGE_MULTIPLIER;
  298.                 goto hitclock;
  299.             }
  300.            
  301.             break;
  302.         }
  303.        
  304.         if(!power)
  305.             hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_brang))*DAMAGE_MULTIPLIER;
  306.         else
  307.             hp-=power;
  308.            
  309.         goto hitclock;
  310.     }
  311.    
  312.     case wHookshot:
  313.     {
  314.         int def = defend(wpnId, &power, edefHOOKSHOT);
  315.        
  316.         if(def >= 0) return def;
  317.        
  318.         if(!(flags & guy_bhit))
  319.         {
  320.             stunclk=160;
  321.            
  322.             if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))
  323.             {
  324.                 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))*DAMAGE_MULTIPLIER;
  325.                 goto hitclock;
  326.             }
  327.            
  328.             break;
  329.         }
  330.        
  331.         if(!power) hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_hookshot))*DAMAGE_MULTIPLIER;
  332.         else
  333.             hp-=power;
  334.            
  335.         goto hitclock;
  336.     }
  337.     break;
  338.    
  339.     case wHSHandle:
  340.     {
  341.         if(itemsbuf[enemyHitWeapon>-1 ? enemyHitWeapon : current_item_id(itype_hookshot)].flags & ITEM_FLAG1)
  342.             return 0;
  343.            
  344.         bool ignorehookshot = ((defense[edefHOOKSHOT] == edIGNORE) || ((defense[edefHOOKSHOT] == edIGNOREL1 || defense[edefHOOKSHOT] == edSTUNORIGNORE)
  345.                                && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot)) <= 0));
  346.                                
  347.         // Peahats, Darknuts, Aquamentuses, Pols Voices, Wizzrobes, Manhandlas
  348.         if(!(family==eePEAHAT || family==eeAQUA || family==eeMANHAN || (family==eeWIZZ && !ignorehookshot)
  349.                 || (family==eeWALK && dmisc9==e9tPOLSVOICE) || (family==eeWALK && flags&(inv_back|inv_front|inv_left|inv_right))))
  350.             return 0;
  351.            
  352.         power = DAMAGE_MULTIPLIER;
  353.         //fallthrough
  354.     }
  355.    
  356. fsparkle:
  357.  
  358.     default:
  359.         // Work out the defenses!
  360.     {
  361.         int def = defenditemclass(wpnId, &power);
  362.        
  363.         if(def >= 0)
  364.             return def;
  365.         else if(def == -2)
  366.         {
  367.             ret = 0;
  368.         }
  369.     }
  370.    
  371.     if(!power)
  372.     {
  373.         if(flags & guy_bhit)
  374.             hp-=1;
  375.         else
  376.         {
  377.             // Don't make a long chain of 'stun' hits
  378.             if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wSword) && stunclk>0)
  379.                 return 1;
  380.                
  381.             stunclk=160;
  382.             break;
  383.         }
  384.     }
  385.     else hp-=power;
  386.    
  387. hitclock:
  388.     hclk=33;
  389.    
  390.     // Use w->dir instead of wpnDir to make sure boomerangs don't push enemies the wrong way
  391.     if((dir&2)==(w->dir&2))
  392.     {
  393.         sclk=(w->dir<<8)+16;
  394.     }
  395.     }
  396.    
  397.     if(((wpnId==wBrang) || (get_bit(quest_rules,qr_NOFLASHDEATH))) && hp<=0)
  398.     {
  399.         fading=fade_blue_poof;
  400.     }
  401.    
  402.     sfx(WAV_EHIT, pan(int(x)));
  403.    
  404.     hitSFX.play(x);
  405.        
  406.     if(family==eeGUY)
  407.         sfx(WAV_EDEAD, pan(int(x)));
  408.        
  409.     // Penetrating weapons
  410.     if((wpnId==wArrow || wpnId==wBeam) && !cannotpenetrate())
  411.     {
  412.         int item=enemyHitWeapon;
  413.        
  414.         if(wpnId==wArrow)
  415.         {
  416.             if(item<0)
  417.                 item=current_item_id(itype_arrow);
  418.                
  419.             if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG1))
  420.                 return 0;
  421.         }
  422.        
  423.         else
  424.         {
  425.             if(item<0)
  426.                 item=current_item_id(itype_sword);
  427.                
  428.             if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG3))
  429.                 return 0;
  430.         }
  431.     }
  432.    
  433.     return ret;
  434. }
  435.  
  436. void weapon::onhit(bool clipped, int special, int linkdir)
  437. {
  438.     if((scriptcoldet&1) == 0)
  439.     {
  440.         // These won't hit anything, but they can still go too far offscreen...
  441.         // Unless the compatibility rule is set.
  442.         if(get_bit(quest_rules, qr_OFFSCREENWEAPONS) || !clipped)
  443.             return;
  444.         goto offscreenCheck;
  445.     }
  446.         if(special==3)                                         // hit an enemie's mirror shield
  447.     {
  448.         switch(id)
  449.         {
  450.         case wRefFireball
  451.             id = wRefFireball;
  452.         case wRefRock
  453.             id = wRefRock
  454.         case wBeam:
  455.         case wRefBeam:
  456.             id = wRefBeam
  457.            
  458.         case wMagic:
  459.         case wRefMagic:
  460.             id = wRefMagic
  461.  
  462.         case wScript1:
  463.         case wScript2:
  464.         case wScript3:
  465.         case wScript4:
  466.         case wScript5:
  467.         case wScript6:
  468.         case wScript7:
  469.         case wScript8:
  470.         case wScript9:
  471.         case wScript10:
  472.         // fall through
  473.         default:
  474.             ignoreLink=false;
  475.             goto reflect;
  476.     }
  477.     if(special==2)                                            // hit Link's mirror shield
  478.     {
  479.         switch(id)
  480.         {
  481.         case ewFireball2:
  482.         case ewFireball:
  483.             id = wRefFireball;
  484.             ignoreLink=true;
  485.             goto reflect;
  486.            
  487.         case ewRock:
  488.         case ewSword:
  489.         case wRefBeam:
  490.         case ewMagic:
  491.         case wRefMagic:
  492.             //otherwise he can get hit by the newly-created projectile if he's walking into it fast enough -DD
  493.             ignoreLink=true;
  494.             id = ((id==ewMagic || id==wRefMagic) ? wRefMagic : id==ewRock ? wRefRock : wRefBeam);
  495.             goto reflect;
  496.            
  497.         case wScript1:
  498.         case wScript2:
  499.         case wScript3:
  500.         case wScript4:
  501.         case wScript5:
  502.         case wScript6:
  503.         case wScript7:
  504.         case wScript8:
  505.         case wScript9:
  506.         case wScript10:
  507.             // If this isn't set, the weapon may reflect repeatedly
  508.             ignoreLink=true;
  509. reflect:
  510.  
  511.             if(angular) switch(linkdir)
  512.                 {
  513.                 case up:
  514.                     angle += (PI - angle) * 2.0;
  515.                     break;
  516.                    
  517.                 case down:
  518.                     angle = -angle;
  519.                     break;
  520.                    
  521.                 case left:
  522.                     angle += ((-PI/2) - angle) * 2.0;
  523.                     break;
  524.                    
  525.                 case right:
  526.                     angle += ((PI/2) - angle) * 2.0;
  527.                     break;
  528.                    
  529.                 default:
  530.                     angle += PI;
  531.                     break;
  532.                 }
  533.             else
  534.             {
  535.                 dir ^= 1;
  536.                
  537.                 if(dir&2)
  538.                     flip ^= 1;
  539.                 else
  540.                     flip ^= 2;
  541.             }
  542.            
  543.             return;
  544.         }
  545.     }
  546.    
  547.     if(special>=1)                                            // hit Link's shield
  548.     {
  549.         switch(id)
  550.         {
  551.         case ewRock:
  552.         case ewMagic:
  553.         case ewArrow:
  554.         case ewSword:
  555.             bounce=true;
  556.             dead=16;
  557.             return;
  558.            
  559.         case ewBrang:
  560.             if(misc==0)
  561.             {
  562.                 clk2=256;
  563.                 misc=1;
  564.                 dir^=1;
  565.             }
  566.            
  567.             return;
  568.         }
  569.     }
  570.    
  571. offscreenCheck:
  572.     switch(id)
  573.     {
  574.     case wSword:
  575.     case wWand:
  576.     case wHammer:
  577.         break;
  578.        
  579.     case ewBomb:
  580.         step=0;
  581.         break;
  582.        
  583.     case ewLitBomb:
  584.         step=0;
  585.         misc=50;
  586.         clk=misc-3;
  587.         hxofs=hyofs=-7;
  588.         hxsz=hysz=30;
  589.         break;
  590.        
  591.     case ewSBomb:
  592.         step=0;
  593.         break;
  594.        
  595.     case ewLitSBomb:
  596.         step=0;
  597.         misc=50;
  598.         clk=misc-3;
  599.         hxofs=hyofs=-16;
  600.         hxsz=hysz=48;
  601.         break;
  602.        
  603.     case wLitBomb:
  604.         if(!clipped) dead=1;
  605.        
  606.     case wLitSBomb:
  607.         if(!clipped) dead=1;
  608.        
  609.     case wWhistle:
  610.     case wBomb:
  611.     case wSBomb:
  612.     case wBait:
  613.     case wFire:
  614.     case wHSHandle:
  615.     case wPhantom:
  616.         break;                                   // don't worry about clipping or hits with these
  617.        
  618.     case ewFireTrail:
  619.         if(!clipped) dead=1;
  620.        
  621.         break;
  622.        
  623.     case ewFlame:
  624.         if(!clipped) dead=1;
  625.        
  626.         break;
  627.        
  628.     case wRefBeam:
  629.     case wBeam:
  630.         dead=23;
  631.         break;
  632.        
  633.     case wArrow:
  634.         dead=4;
  635.         break;                           //findentrance(x,y,mfARROW,true); break;
  636.        
  637.     case ewArrow:
  638.         dead=clipped?4:1;
  639.         break;
  640.        
  641.     case wCByrna:
  642.    
  643.         // byrna keeps going
  644.         if(parentitem<0 || !(itemsbuf[parentitem].flags&ITEM_FLAG1))
  645.             dead=0;
  646.            
  647.         break;
  648.        
  649.     case wWind:
  650.         if(x>=240)
  651.             dead=2;
  652.            
  653.         break;
  654.        
  655.     case wBrang:
  656.         if(misc==0)
  657.         {
  658.             clk2=256;
  659.             int deadval=(itemsbuf[parentitem>-1 ? parentitem : current_item_id(itype_brang)].flags & ITEM_FLAG3)?-2:4;
  660.            
  661.             if(clipped)
  662.             {
  663.                 dead=deadval;
  664.             }
  665.             else
  666.             {
  667.                 if(deadval==-2)
  668.                 {
  669.                     dead=deadval;
  670.                 }
  671.                
  672.                 misc=1;
  673.             }
  674.         }
  675.        
  676.         break;
  677.        
  678.     case wHookshot:
  679.         if(misc==0)
  680.         {
  681.             clk2=256;
  682.            
  683.             if(clipped)
  684.                 dead=4;
  685.             else
  686.                 dead=1;
  687.         }
  688.        
  689.         break;
  690.        
  691.     case ewBrang:
  692.         if(misc==0)
  693.         {
  694.             clk2=256;
  695.             dead=4;
  696.         }
  697.        
  698.         break;
  699.        
  700.     case wRefMagic:
  701.     case wMagic:
  702.         dead=1; //remove the dead part to make the wand only die when clipped
  703.        
  704.         if(((id==wMagic && current_item(itype_book) &&
  705.                 (itemsbuf[current_item_id(itype_book)].flags&ITEM_FLAG1))) && Lwpns.idCount(wFire)<2)
  706.         {
  707.             Lwpns.add(new weapon(x,y,z,wFire,2,1*DAMAGE_MULTIPLIER,0,current_item_id(itype_book),-1));
  708.             sfx(WAV_FIRE,pan(x));
  709.         }
  710.        
  711.         break;
  712.        
  713.     case ewWind:
  714.         if(clipped)
  715.         {
  716.             if(misc==999)                                       // in enemy wind
  717.             {
  718.                 ewind_restart=true;
  719.             }
  720.            
  721.             dead=1;
  722.         }
  723.        
  724.         break;
  725.        
  726.     default:
  727.         dead=1;
  728.     }}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement