예제 #1
0
    public void AttackDetect(Fighter plr)
    {
        //projectile checks
        SPoint[] pHdr = new SPoint[8];
        SPoint[] plBox;
        plBox = plr.GetHitBox();
        int hbLen=4;
        float[] plAng ={0, Mathf.PI/2, Mathf.PI, -Mathf.PI/2};
        bool hitflag = true;
                for (int i=0; i<8; i++)
                        pHdr [i] = new SPoint (v [i].x + pos.x, v [i].y +pos.y);
        float atkLen = GetVNum ();
                for (int j = 0; j < atkLen; j++)
                        if (!CheckAxis (pHdr [0], ang [j], plBox, pHdr, hbLen, GetVNum ())) //no axis intersection
                                hitflag = false;

                if (hitflag)//test on the axis of the player hit box to confirm
                        for (int j = 0; j < 4; j++)
                                if (!CheckAxis (plBox [j], plAng [j], plBox, pHdr, hbLen,GetVNum ())) //no axis intersection
                                        hitflag = false;
                if (hitflag) {
                        active = false;
                        plr.GetHit (hitdata);
                        Detonate ();
                }
    }
예제 #2
0
파일: Fighter.cs 프로젝트: cWalters2/ShSoul
    protected virtual void Attack(Fighter plr,int tr, AttkTrack aBox, AttkData data)
    {
        //pHit is a bool array of flags that tell whether a sub-poly held collision
        //aBox is a modified track taken from current frame
        //plr is the player hit
        //check pnum else we cut Serenuity's sword
        if((plr.stats.id.num<100)&&(attackBox.trackList[fHelper.atkType].hit[tr][plr.stats.id.num])){//if this attack was recorded already
            data.noHit=true; //flag so this does not trigger impact
            return;//don't hit again
        }
        attackBox.trackList[fHelper.atkType].hit[tr][plr.stats.id.num]=true;

        bool isInBox=false;
        bool vNextInBox=false;
        AttkVtx iVt;
        bool[] cornerFlag = new bool[4];
        SPoint[] hb = plr.GetHitBox();// double[4]
        for(int i=0;i<4;i++){
            cornerFlag[i]=true;
            hb[i].x = hb[i].x-GetPos().x;//translate to origin
            hb[i].y = hb[i].y-GetPos().y;
        }
        bool emptyFlag = true;
        bool fullFlag =true;//assume true, disprove by counterexample
        SPoint vPos = new SPoint ();
        SPoint opp = new SPoint();
        int vNext,vLast,jl, il;
        float nX, nY, lY=0, lX=0, vX, vY, ppX, ppY, ph2, pw2, diDist,vDir, vDmg, vMag, vWgt = 0;
        //add poitional value (for wgt=0) into data
        opp.x=plr.GetPos().x-GetPos().x;//used to store the centerpoint
        if(fHelper.IsFacingRight())      //for input into data
            opp.x-=(aBox.centre.pos.x);
        else
            opp.x+=(aBox.centre.pos.x);
        opp.y=plr.GetPos().y-GetPos().y+aBox.centre.pos.y;
        data.SetAVals(opp);
        il = aBox.iLength;
        //set data.abds as an sPoint holding the vertices for aBox.vtx
        //this is done purely for debug rendering
        //which will later handle 'data'
        data.aBds = new SPoint[il][];
        for(int j=0;j<il;j++){
            data.aBds[j] = new SPoint[aBox.GetJlength(j)];
            for(int i=0;i<aBox.GetJlength(j);i++)
                data.aBds[j][i] = new SPoint(aBox.aVtx[j][i].pos.x-GetPos().x, aBox.aVtx[j][i].pos.y-GetPos().y);
        }

        emptyFlag=true;
        fullFlag=true;
        ph2 = plr.stats.size.y/2;
        pw2 = plr.stats.size.x/2;
        ppX = plr.GetPos().x;
        ppY = plr.GetPos().y+ph2;
        for(int i=0;i<4;i++)//assume true then prove false
            cornerFlag[i]=true;
        for(int p=0; p<aBox.iLength;p++){
            jl = aBox.GetJlength(p);
            for(int v = 0; v < jl;v++){//loop through the second index
                vPos = aBox.aVtx[p][v].pos;//use this vertex to check whether it falls
                if((Mathf.Abs(vPos.x-ppX)<pw2)&&(Mathf.Abs(vPos.y-ppY)<ph2))// within hitbox
                    emptyFlag = false;//can't be empty
                else
                    fullFlag = false;//can't be full
            }
            if(fullFlag){
                for(int v = 0; v < jl;v++){
                    int before = v-1;
                    if(before<0)
                        before=jl-1;
                    diDist = Mathf.Sqrt(Mathf.Pow(aBox.aVtx[p][before].pos.x-aBox.aVtx[p][v].pos.x, 2) + Mathf.Pow(aBox.aVtx[p][before].pos.y-aBox.aVtx[p][v].pos.y, 2));
                    vMag = aBox.aVtx[p][v].mag;
                    vDir = aBox.aVtx[p][v].dir;
                    vDmg = aBox.aVtx[p][v].dmg;
                    vWgt = aBox.aVtx[p][v].wgt;
                    data.addVal(aBox.aVtx[p][v].pos, vMag, vDir, diDist, vDmg, vWgt);
                    for(int i=0;i<4;i++)
                        cornerFlag[i]=false;//none possible to be included
                }
            }
            else if(emptyFlag){
                for(int j = 0;j<jl;j++){
                    diDist=1;
                    vMag = aBox.aVtx[p][j].mag;
                    vDir = aBox.aVtx[p][j].dir;
                    vDmg = aBox.aVtx[p][j].dmg;
                    vWgt = aBox.aVtx[p][j].wgt;
                    vPos = aBox.aVtx[p][j].pos;
                    vPos.x-=GetPos().x;
                    vPos.y-=GetPos().y;
                    data.addVal(vPos, vMag, vDir, diDist, vDmg, vWgt);
                }
            }
            else
            for(int v = 0; v < jl;v++){
                vNext = (v+1)%jl;//circular array
                vPos = aBox.aVtx[p][vNext].pos;
                vNextInBox = ((Mathf.Abs(vPos.x-ppX)<pw2)&&(Mathf.Abs(vPos.y-ppY)<ph2));
                vLast=v-1;
                if(vLast<0)
                    vLast=jl-1;
                vMag = aBox.aVtx[p][v].mag;
                vDir = aBox.aVtx[p][v].dir;
                vDmg = aBox.aVtx[p][v].dmg;
                vWgt = aBox.aVtx[p][v].wgt;
                vPos = aBox.aVtx[p][v].pos;
                vX = aBox.aVtx[p][v].pos.x-GetPos().x;//all values translated to origin
                vY = aBox.aVtx[p][v].pos.y-GetPos().y;
                if(v==0){
                    lX=vX;//mustdefine these ahead of time
                    lY=vY;//so the first dir is properly averaged
                }     //in case the loop below is not entered
                if((Mathf.Abs(vPos.x-ppX)<pw2)&&(Mathf.Abs(vPos.y-ppY)<ph2)){//within the victim's hitbox
                    diDist = Mathf.Sqrt( (lX-vX)*(lX-vX) + (lY-vY)*(lY-vY));
                    data.addVal(new SPoint(vX, vY), vMag, vDir, diDist, vDmg, vWgt);
                    lX=vX;
                    lY=vY;
                    if(!vNextInBox){
                        iVt = InterpVert(aBox.aVtx[p][v], aBox.aVtx[p][vNext], plr);
                        iVt.pos.x-=GetPos().x;//all values translated to origin
                        iVt.pos.y-=GetPos().y;
                        diDist = Mathf.Sqrt(Mathf.Pow(iVt.pos.x-vX, 2)+Mathf.Pow(iVt.pos.y-vY, 2));
                        data.addVal(iVt.pos, iVt.mag, iVt.dir, diDist, iVt.dmg, iVt.wgt);
                        lX=iVt.pos.x;
                        lY=iVt.pos.y;
                    }
                }
                else {
                    if(vNextInBox){
                        iVt = InterpVert(aBox.aVtx[p][vNext], aBox.aVtx[p][v], plr);
                        iVt.pos.x-=GetPos().x;//all values translated to origin
                        iVt.pos.y-=GetPos().y;
                        diDist = Mathf.Sqrt(Mathf.Pow(iVt.pos.x-lX, 2)+Mathf.Pow(iVt.pos.y-lY, 2));
                        data.addVal(iVt.pos, iVt.mag, iVt.dir, diDist, iVt.dmg, iVt.wgt);
                        lX=iVt.pos.x;
                        lY=iVt.pos.y;
                    }
                }
                for(int i = 0; i<4;i++){//check player corner axis
                    vX = aBox.aVtx[p][v].pos.x-GetPos().x-hb[i].x;//all values translated to origin
                    vY = aBox.aVtx[p][v].pos.y-GetPos().y-hb[i].y;
                    nX = aBox.aVtx[p][vNext].pos.x-GetPos().x-hb[i].x;
                    nY = aBox.aVtx[p][vNext].pos.y-GetPos().y-hb[i].y;
                    if((fHelper.IsFacingRight())&&(nX*vY-vX*nY<0))//second part is a shortcut formula
                        cornerFlag[i]=false;
                    else if((!fHelper.IsFacingRight())&&(nX*vY-vX*nY>0))
                        cornerFlag[i]=false;
                }
            }
            //last step; add corners that retained their flag
            if(emptyFlag){//for now ; TODO: add case later
                for(int i=0;i<4;i++)
                if(cornerFlag[i]){
                    iVt = InterpCorner(aBox.aVtx[p], aBox.GetJlength(p), plr.GetPos());
                    iVt.pos.x-=GetPos().x;//all values translated to origin
                    iVt.pos.y-=GetPos().y;
                    diDist = Mathf.Sqrt(Mathf.Pow(iVt.pos.x-lX, 2)+Mathf.Pow(iVt.pos.y-lY, 2));
                    data.addVal(iVt.pos, iVt.mag, iVt.dir, diDist, iVt.dmg,iVt.wgt);
                    lX=iVt.pos.x;
                    lY=iVt.pos.y;
                }
            }
        }

        data.rollIntoAvg();
        if (attackBox.trackList [fHelper.atkType].isVacuum) {
            data.isVacuum=true;
        }

        data.SetConOrigin(aBox.centre.pos);
        data.PlayerHitBoxInput(hb);
    }
예제 #3
0
파일: Fighter.cs 프로젝트: cWalters2/ShSoul
    public virtual void AttackDetect(Fighter plr)
    {
        bool multiHitFlag = false;
        string hitText;
        //std::stringstream log;
        bool hitflag = true;
        int atkLen;
        int spI=0;
        int spJ=0;
        int hbLen=4;
        SPoint[] plBox;
        SPoint[][] spBox;
        float[] plAng ={0, Mathf.PI/2, Mathf.PI, -Mathf.PI/2};
        int il = 0;
        if (fHelper.atkType  == GRAB)
             il = 1;
        else
            il = attackBox.trackList[fHelper.atkType].iLength;//num of tracks
        AttkTrack aBox = new AttkTrack();

        int polyHit=-1;
        plBox = plr.GetHitBox();//loads victim hitbox into plBox
        //each side is made from the vertices [i] and [+1]
        int numPoly = 0; //number of polygons in a track;
        int pInd = 0;//polygon index
        SPoint[] pHdr = new SPoint[8];

        //projectile checks
        for(int p=0;p<PROJ_LMT;p++){
            if(projectile[p].active){
                for(int i=0;i<8;i++)
                    pHdr[i]=new SPoint(projectile[p].v[i].x+projectile[p].pos.x,projectile[p].v[i].y+projectile[p].pos.y);
                atkLen =  projectile[p].GetVNum();
                for(int j = 0; j < atkLen; j++)
                    if(!CheckAxis(pHdr[0], projectile[p].ang[j], plBox, pHdr, hbLen, projectile[p].GetVNum()) ) //no axis intersection
                        hitflag = false;

                if(hitflag)//test on the axis of the player hit box to confirm
                    for(int j = 0; j < 4; j++)
                        if(!CheckAxis(plBox[j], plAng[j], plBox, pHdr, hbLen, projectile[p].GetVNum())) //no axis intersection
                            hitflag = false;
                if(hitflag){
                    projectile[p].active=false;
                    plr.GetHit(projectile[p].hitdata);
                }

            }
        }
        if(!atkTmr.IsReady()){//only continue if an attack is out
            if(fHelper.atkType==GRAB){
                aBox= new AttkTrack();
                aBox.noHit=false;
                float gCheck = grabTime/fHelper.actionTmr.GetLen();
                float fCheck = fHelper.frame/fHelper.actionTmr.GetLen();
                if(Mathf.Abs(fCheck-gCheck)<Time.deltaTime){

                    aBox.SetGrabBox(GetPos (), stats.grabRange);

                    float[] atAng = new float[4];
                    atAng[0]=0;
                    atAng[1]=Mathf.PI/2;
                    atAng[2]=Mathf.PI;
                    atAng[3]=-Mathf.PI/2;
                    //for(pInd=0;pInd<numPoly;pInd++)//iterate per poly
                    atkLen =  4;
                    hitflag=true;
                    attackBox.grabRange= stats.grabRange;
                    SPoint[] spArr = attackBox.FetchGrabRenderFrame(fHelper.frame, GetPos (), fHelper.IsFacingRight());

                    for(int j = 0; j < atkLen; j++)
                        if(!CheckAxis(spArr[j], atAng[j], plBox, spArr, hbLen, atkLen) ) //no axis intersection
                            hitflag = false;

                    if(hitflag)//test on the axis of the player hit box to confirm
                        for(int j = 0; j < 4; j++)
                            if(!CheckAxis(plBox[j], plAng[j], plBox, spArr, hbLen, atkLen)) //no axis intersection
                                hitflag = false;

                    if(hitflag){//hit
                        if(plr.grabbedPlr!=null){
                            plr.grabbedPlr. state=IDLE;
                            plr.grabbedPlr.Idle();
                            plr.grabbedPlr.fHelper.Animate ("Idle", true, 0);
                            plr.fHelper.Animate ("Idle", true, 0);
                            plr.grabbedPlr.stats.flags.mBusy=false;
                            plr.grabbedPlr.stats.flags.aBusy=false;
                            plr.grabbedPlr=null;
                            Idle();
                            fHelper.Animate ("Idle", true, 0);

                        }
                        else if(plr.stats.dodge.IsReady()){
                        grabbedPlr=plr;
                            plr.Grabbed ();}
                    }
                }

            }else{
            //attack checks

            for(int t=0;t<il;t++){//iterate through all sub tr

                //if(plr.CharName().CompareTo("PsySword")==0)
                //	int ds=2;//checkpt
                if((fHelper.seqInd!=0)&&((fHelper.seqInd-1)!=t)){
                    hitflag=false;//do nothing, for now
                }else {
                    aBox= new AttkTrack();
                    aBox.noHit=false;
                        if(attackBox.trackList[fHelper.atkType].trackType==AttkBox.FLASH){
                            if(fHelper.frame>lastFlash){

                                for(AttkVtx av = attackBox.trackList[fHelper.atkType].aVtx[0][0]; av!=null;av=av.next){
                                    if((av.frame==lastFlash)&&(av.next!=null)){
                                        lastFlash=av.next.frame;
                                        attackBox.flashAtkRdy=true;
                                        attackBox.ResetHits (fHelper.atkType);
                                        while(av.next!=null)
                                            av=av.next;
                                        //av=null;//force exit
                                    }
                                }
                            }
                        }
                    attackBox.FetchFrame(fHelper.atkType, atkTmr.GetLen(), fHelper.frame, t, new SPoint(GetPos().x, GetPos().y), fHelper.IsFacingRight(), aBox);//fetches frame into aBox

                        //aBox has its polygons separated into different tracks for efficiency
                    //make a new SPoint array, spBox, to use checkAxis.

                    hitflag=true;
                    if(aBox.noHit==false){

                        //if(plr.CharName().CompareTo("PsySword")==0)
                        //	int d2s=2;//checkpt
                        spBox=new SPoint[aBox.iLength][];
                        for(int i=0;i<aBox.iLength;i++)
                            spBox[i]=new SPoint[aBox.jLength[i]];
                        aBox.FetchSPArr(spBox);
                            if(ClashCheck(plr, spBox, aBox.atkAng)){

                                return;
                            }

                        numPoly=aBox.iLength;
                            bool hitCheck = false;
                        for(pInd=0;pInd<numPoly;pInd++){//iterate per poly
                                hitflag=true;
                            atkLen =  aBox.GetJlength(pInd);
                            for(int j = 0; j < atkLen; j++)
                                if(!CheckAxis(aBox.aVtx[pInd][j].pos, aBox.atkAng[pInd][j], plBox, spBox[pInd], hbLen, aBox.GetJlength(pInd)) ) //no axis intersection
                                    hitflag = false;

                            if(hitflag)//test on the axis of the player hit box to confirm
                                for(int j = 0; j < 4; j++)
                                    if(!CheckAxis(plBox[j], plAng[j], plBox, spBox[pInd], hbLen, aBox.GetJlength(pInd))) //no axis intersection
                                        hitflag = false;
                            if(hitflag)
                                    hitCheck=true;

                        }
                            hitflag=hitCheck;
                        //log.str(std::string());
                        /*	for(int i=0;i<aBox.iLength;i++){//tidy up
                            if(!aBox.noHit)
                                delete [] spBox[i];
                        }
                        if(aBox.iLength==0){
                            int ee = 2;
                            //log.str(std::string());
                        }
                        else if(!aBox.noHit){//make sure it was hit
                            if(aBox.iLength>1)
                                delete [] spBox;
                            else
                                delete spBox;
                            spBox=NULL;
                        }*/
                    }else
                        hitflag=false;//abandon
                    if(hitflag){
                        AttkData retOb  = new AttkData(aBox.GetJlength(t));//initilize for holding vals
                        Attack(plr, t, aBox, retOb);
                        if(!retOb.noHit){
                                if(debugModeOn){
                                if(multiHitFlag)
                                    hitText = CharName() + " multi-hit\r\n" + plr.CharName() + "!";
                                else
                                    hitText =  CharName() + " hit \r\n" + plr.CharName() + "!";
                                ConsoleLog(hitText);
                                }
                            plr.GetHit(retOb);
                            if((cons!=null)&&(!multiHitFlag)&&(retOb!=null))
                                cons.PostHit(retOb.GetSPArr(), retOb.curInd, retOb.aBds[0], retOb.attLen, retOb.pBds, retOb.GetConOrigin(), retOb.GetConInter());
                            multiHitFlag=true;
                            t=il;//force exit; one track hit
                        }
                    }

                    }

                }
            }
        }
        //seems the ideal place to determine pushback
        //if the difference in z is less than their average width
        if((Mathf.Abs(plr.GetPos().x-GetPos().x) < (plr.stats.size.x+stats.size.x)/2  )
           &&(Mathf.Abs(plr.GetPos().y-GetPos().y) < (plr.stats.size.y+stats.size.y)/2)
           &&(!fHelper.airborne)&&(!plr.fHelper.airborne))
        if(plr.GetPos().x-GetPos().x>0){
            stats.motion.move.x-=0.1f;
            plr.stats.motion.move.x+=0.1f;}
        else{
            stats.motion.move.x+=0.1f;
            plr.stats.motion.move.x-=0.1f;}

        //prob at a second case here for seren sword
        //	if(plr.CharName().CompareTo("Serenity")==0){
        //		AttackDetect(plr.GetFamiliar());
        //	}
        if (fHelper.atkType == DATK) {
            if ((rightLip != 0) && (stats.motion.pos.x < rightLip)) {
                stats.motion.vel.x = 0;
                stats.walk.gndSpeed = 0;

            } else if ((leftLip != 0) && (stats.motion.pos.x > leftLip)) {
                stats.motion.vel.x = 0;
                stats.walk.gndSpeed = 0;
            }
        }
    }