Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void check_collisions()
- {
- for(int i=0; i<Lwpns.Count(); i++)
- {
- weapon *w = (weapon*)Lwpns.spr(i);
- if(!(w->Dead()) && w->id!=wSword && w->id!=wHammer && w->id!=wWand)
- {
- for(int j=0; j<guys.Count(); j++)
- {
- enemy *e = (enemy*)guys.spr(j);
- if(e->hit(w))
- {
- int h = e->takehit(w);
- if(h)
- {
- if(h==3)
- {
- //Enemies can be shielded in four directions
- // We need to figure out which direction the shield is facing.
- double ddir=atan2(double(w->y-e->y),double(e->x-w->X));
- int xdir=rand()&3;
- if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
- {
- xdir=down;
- }
- else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
- {
- xdir=right;
- }
- else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
- {
- xdir=up;
- }
- else
- {
- xdir=left;
- }
- w->onhit(false, 3, xdir);
- }
- else
- w->onhit(false);
- }
- if(h==2) //apparently this never runs.
- {
- break;
- }
- }
- if(w->Dead())
- {
- break;
- }
- }
- if(get_bit(quest_rules,qr_Z3BRANG_HSHOT))
- {
- if(w->id == wBrang || w->id==wHookshot)
- {
- for(int j=0; j<items.Count(); j++)
- {
- if(items.spr(j)->hit(w))
- {
- bool priced = ((item*)items.spr(j))->PriceIndex >-1;
- if((((item*)items.spr(j))->pickup & ipTIMER && ((item*)items.spr(j))->clk2 >= 32)
- || (get_bit(quest_rules,qr_BRANGPICKUP) && !priced && !(((item*)items.spr(j))->pickup & ipDUMMY)))
- {
- if(w->id == wBrang)
- {
- w->onhit(false);
- }
- if(w->dragging==-1)
- {
- w->dead=1;
- ((item*)items.spr(j))->clk2=256;
- w->dragging=j;
- }
- }
- }
- }
- }
- }
- else
- {
- if(w->id == wBrang || w->id == wArrow || w->id==wHookshot)
- {
- for(int j=0; j<items.Count(); j++)
- {
- if(items.spr(j)->hit(w))
- {
- bool priced = ((item*)items.spr(j))->PriceIndex >-1;
- if((((item*)items.spr(j))->pickup & ipTIMER && ((item*)items.spr(j))->clk2 >= 32)
- || (get_bit(quest_rules,qr_BRANGPICKUP) && !priced))
- {
- if(itemsbuf[items.spr(j)->id].collect_script)
- {
- ZScriptVersion::RunScript(SCRIPT_ITEM, itemsbuf[items.spr(j)->id].collect_script, items.spr(j)->id & 0xFFF);
- }
- //getitem(items.spr(j)->id);
- //items.del(j);
- Link.checkitems(j);
- //--j;
- }
- }
- }
- }
- }
- }
- }
- }
- int enemy::takehit(weapon *w)
- {
- int wpnId = w->id;
- int power = w->power;
- int wpnx = w->x;
- int wpny = w->y;
- int enemyHitWeapon = w->parentitem;
- int wpnDir;
- // If it's a boomerang that just bounced, use the opposite direction;
- // otherwise, it might bypass a shield. This probably won't handle
- // every case correctly, but it's better than having shields simply
- // not work against boomerangs.
- if(w->id==wBrang && w->misc==1 && w->clk2>=256 && w->clk2<264)
- wpnDir = oppositeDir[w->dir];
- else
- wpnDir = w->dir;
- if(dying || clk<0 || hclk>0 || superman)
- {
- return 0;
- }
- int ret = -1;
- // This obscure quest rule...
- if(get_bit(quest_rules,qr_BOMBDARKNUTFIX) && (wpnId==wBomb || wpnId==wSBomb))
- {
- double ddir=atan2(double(wpny-y),double(x-wpnx));
- wpnDir=rand()&3;
- if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
- {
- wpnDir=down;
- }
- else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
- {
- wpnDir=right;
- }
- else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
- {
- wpnDir=up;
- }
- else
- {
- wpnDir=left;
- }
- }
- int xdir = dir;
- shieldCanBlock=false;
- //if (family==eeFLOAT && flags&(inv_front|inv_back_inv_left|inv_right)) xdir=down;
- if((wpnId==wHookshot && hitshield(wpnx, wpny, xdir))
- || ((flags&inv_front && wpnDir==(xdir^down)) || (flags&inv_back && wpnDir==(xdir^up)) || (flags&inv_left && wpnDir==(xdir^left)) || (flags&inv_right && wpnDir==(xdir^right)))
- )
- // The hammer should already be dealt with by subclasses (Walker etc.)
- {
- switch(wpnId)
- {
- // Weapons which shields protect against
- case wSword:
- case wWand:
- Link.onMeleeWeaponHit();
- //fallthrough
- case wHookshot:
- case wHSHandle:
- case wBrang:
- shieldCanBlock=true;
- break;
- case wBeam:
- case wRefBeam:
- case wRefRock:
- case wRefFireball:
- case wMagic:
- case wRefMagic:
- if(wpnId>wEnemyWeapons)
- return 0;
- //fallthrough
- default:
- if(flags2&guy_mirror)
- {
- shieldCanBlock=true;
- return 3;
- }
- shieldCanBlock=true;
- break;
- // Bombs
- case wSBomb:
- case wBomb:
- goto hitclock;
- // Weapons which ignore shields
- case wWhistle:
- case wHammer:
- break;
- // Weapons which shouldn't be removed by shields
- case wLitBomb:
- case wLitSBomb:
- case wWind:
- case wPhantom:
- case wSSparkle:
- case wBait:
- return 0;
- case wFire:
- ;
- }
- }
- switch(wpnId)
- {
- case wWhistle:
- return 0;
- case wPhantom:
- return 0;
- case wLitBomb:
- case wLitSBomb:
- case wBait:
- case wWind:
- case wSSparkle:
- return 0;
- case wFSparkle:
- // Only take sparkle damage if the sparkle's parent item is not
- // defended against.
- if(enemyHitWeapon > -1)
- {
- int p = 0;
- int f = itemsbuf[enemyHitWeapon].family;
- switch(f)
- {
- case itype_arrow:
- if(!candamage(p, edefARROW)) return 0;
- break;
- case itype_cbyrna:
- if(!candamage(p, edefBYRNA)) return 0;
- break;
- case itype_brang:
- if(!candamage(p, edefBRANG)) return 0;
- break;
- default:
- return 0;
- }
- }
- wpnId = wSword;
- power = DAMAGE_MULTIPLIER>>1;
- goto fsparkle;
- break;
- case wBrang:
- {
- int def = defend(wpnId, &power, edefBRANG);
- if(def >= 0) return def;
- // Not hurt by 0-damage weapons
- if(!(flags & guy_bhit))
- {
- stunclk=160;
- if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))
- {
- hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))*DAMAGE_MULTIPLIER;
- goto hitclock;
- }
- break;
- }
- if(!power)
- hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_brang))*DAMAGE_MULTIPLIER;
- else
- hp-=power;
- goto hitclock;
- }
- case wHookshot:
- {
- int def = defend(wpnId, &power, edefHOOKSHOT);
- if(def >= 0) return def;
- if(!(flags & guy_bhit))
- {
- stunclk=160;
- if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))
- {
- hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))*DAMAGE_MULTIPLIER;
- goto hitclock;
- }
- break;
- }
- if(!power) hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_hookshot))*DAMAGE_MULTIPLIER;
- else
- hp-=power;
- goto hitclock;
- }
- break;
- case wHSHandle:
- {
- if(itemsbuf[enemyHitWeapon>-1 ? enemyHitWeapon : current_item_id(itype_hookshot)].flags & ITEM_FLAG1)
- return 0;
- bool ignorehookshot = ((defense[edefHOOKSHOT] == edIGNORE) || ((defense[edefHOOKSHOT] == edIGNOREL1 || defense[edefHOOKSHOT] == edSTUNORIGNORE)
- && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot)) <= 0));
- // Peahats, Darknuts, Aquamentuses, Pols Voices, Wizzrobes, Manhandlas
- if(!(family==eePEAHAT || family==eeAQUA || family==eeMANHAN || (family==eeWIZZ && !ignorehookshot)
- || (family==eeWALK && dmisc9==e9tPOLSVOICE) || (family==eeWALK && flags&(inv_back|inv_front|inv_left|inv_right))))
- return 0;
- power = DAMAGE_MULTIPLIER;
- //fallthrough
- }
- fsparkle:
- default:
- // Work out the defenses!
- {
- int def = defenditemclass(wpnId, &power);
- if(def >= 0)
- return def;
- else if(def == -2)
- {
- ret = 0;
- }
- }
- if(!power)
- {
- if(flags & guy_bhit)
- hp-=1;
- else
- {
- // Don't make a long chain of 'stun' hits
- if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wSword) && stunclk>0)
- return 1;
- stunclk=160;
- break;
- }
- }
- else hp-=power;
- hitclock:
- hclk=33;
- // Use w->dir instead of wpnDir to make sure boomerangs don't push enemies the wrong way
- if((dir&2)==(w->dir&2))
- {
- sclk=(w->dir<<8)+16;
- }
- }
- if(((wpnId==wBrang) || (get_bit(quest_rules,qr_NOFLASHDEATH))) && hp<=0)
- {
- fading=fade_blue_poof;
- }
- sfx(WAV_EHIT, pan(int(x)));
- hitSFX.play(x);
- if(family==eeGUY)
- sfx(WAV_EDEAD, pan(int(x)));
- // Penetrating weapons
- if((wpnId==wArrow || wpnId==wBeam) && !cannotpenetrate())
- {
- int item=enemyHitWeapon;
- if(wpnId==wArrow)
- {
- if(item<0)
- item=current_item_id(itype_arrow);
- if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG1))
- return 0;
- }
- else
- {
- if(item<0)
- item=current_item_id(itype_sword);
- if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG3))
- return 0;
- }
- }
- return ret;
- }
- void weapon::onhit(bool clipped, int special, int linkdir)
- {
- if((scriptcoldet&1) == 0)
- {
- // These won't hit anything, but they can still go too far offscreen...
- // Unless the compatibility rule is set.
- if(get_bit(quest_rules, qr_OFFSCREENWEAPONS) || !clipped)
- return;
- goto offscreenCheck;
- }
- if(special==3) // hit an enemie's mirror shield
- {
- switch(id)
- {
- case wRefFireball
- id = wRefFireball;
- case wRefRock
- id = wRefRock
- case wBeam:
- case wRefBeam:
- id = wRefBeam
- case wMagic:
- case wRefMagic:
- id = wRefMagic
- case wScript1:
- case wScript2:
- case wScript3:
- case wScript4:
- case wScript5:
- case wScript6:
- case wScript7:
- case wScript8:
- case wScript9:
- case wScript10:
- // fall through
- default:
- ignoreLink=false;
- goto reflect;
- }
- if(special==2) // hit Link's mirror shield
- {
- switch(id)
- {
- case ewFireball2:
- case ewFireball:
- id = wRefFireball;
- ignoreLink=true;
- goto reflect;
- case ewRock:
- case ewSword:
- case wRefBeam:
- case ewMagic:
- case wRefMagic:
- //otherwise he can get hit by the newly-created projectile if he's walking into it fast enough -DD
- ignoreLink=true;
- id = ((id==ewMagic || id==wRefMagic) ? wRefMagic : id==ewRock ? wRefRock : wRefBeam);
- goto reflect;
- case wScript1:
- case wScript2:
- case wScript3:
- case wScript4:
- case wScript5:
- case wScript6:
- case wScript7:
- case wScript8:
- case wScript9:
- case wScript10:
- // If this isn't set, the weapon may reflect repeatedly
- ignoreLink=true;
- reflect:
- if(angular) switch(linkdir)
- {
- case up:
- angle += (PI - angle) * 2.0;
- break;
- case down:
- angle = -angle;
- break;
- case left:
- angle += ((-PI/2) - angle) * 2.0;
- break;
- case right:
- angle += ((PI/2) - angle) * 2.0;
- break;
- default:
- angle += PI;
- break;
- }
- else
- {
- dir ^= 1;
- if(dir&2)
- flip ^= 1;
- else
- flip ^= 2;
- }
- return;
- }
- }
- if(special>=1) // hit Link's shield
- {
- switch(id)
- {
- case ewRock:
- case ewMagic:
- case ewArrow:
- case ewSword:
- bounce=true;
- dead=16;
- return;
- case ewBrang:
- if(misc==0)
- {
- clk2=256;
- misc=1;
- dir^=1;
- }
- return;
- }
- }
- offscreenCheck:
- switch(id)
- {
- case wSword:
- case wWand:
- case wHammer:
- break;
- case ewBomb:
- step=0;
- break;
- case ewLitBomb:
- step=0;
- misc=50;
- clk=misc-3;
- hxofs=hyofs=-7;
- hxsz=hysz=30;
- break;
- case ewSBomb:
- step=0;
- break;
- case ewLitSBomb:
- step=0;
- misc=50;
- clk=misc-3;
- hxofs=hyofs=-16;
- hxsz=hysz=48;
- break;
- case wLitBomb:
- if(!clipped) dead=1;
- case wLitSBomb:
- if(!clipped) dead=1;
- case wWhistle:
- case wBomb:
- case wSBomb:
- case wBait:
- case wFire:
- case wHSHandle:
- case wPhantom:
- break; // don't worry about clipping or hits with these
- case ewFireTrail:
- if(!clipped) dead=1;
- break;
- case ewFlame:
- if(!clipped) dead=1;
- break;
- case wRefBeam:
- case wBeam:
- dead=23;
- break;
- case wArrow:
- dead=4;
- break; //findentrance(x,y,mfARROW,true); break;
- case ewArrow:
- dead=clipped?4:1;
- break;
- case wCByrna:
- // byrna keeps going
- if(parentitem<0 || !(itemsbuf[parentitem].flags&ITEM_FLAG1))
- dead=0;
- break;
- case wWind:
- if(x>=240)
- dead=2;
- break;
- case wBrang:
- if(misc==0)
- {
- clk2=256;
- int deadval=(itemsbuf[parentitem>-1 ? parentitem : current_item_id(itype_brang)].flags & ITEM_FLAG3)?-2:4;
- if(clipped)
- {
- dead=deadval;
- }
- else
- {
- if(deadval==-2)
- {
- dead=deadval;
- }
- misc=1;
- }
- }
- break;
- case wHookshot:
- if(misc==0)
- {
- clk2=256;
- if(clipped)
- dead=4;
- else
- dead=1;
- }
- break;
- case ewBrang:
- if(misc==0)
- {
- clk2=256;
- dead=4;
- }
- break;
- case wRefMagic:
- case wMagic:
- dead=1; //remove the dead part to make the wand only die when clipped
- if(((id==wMagic && current_item(itype_book) &&
- (itemsbuf[current_item_id(itype_book)].flags&ITEM_FLAG1))) && Lwpns.idCount(wFire)<2)
- {
- Lwpns.add(new weapon(x,y,z,wFire,2,1*DAMAGE_MULTIPLIER,0,current_item_id(itype_book),-1));
- sfx(WAV_FIRE,pan(x));
- }
- break;
- case ewWind:
- if(clipped)
- {
- if(misc==999) // in enemy wind
- {
- ewind_restart=true;
- }
- dead=1;
- }
- break;
- default:
- dead=1;
- }}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement