Combat Physics Detection


This section will cover hit detection and attack handling between fighters.

Combat and the main loop.

The Main-Match-Loop covers 5 phases per turn of combat. A brief example of what happens at each step:

Phase I: Input

Both characters get a chance to input. Yara decides on a quick-attack, which will leave an impact on Serenity next turn.

Phase II: Attack Detection

But sadly, this example will only last one turn and Serenity's attack strikes Yara first. Yara is no longer making an attack and has been sent into tumble. Her velocity receives a change here, depending on where Serenity hit her, and with what attack.

Phase III: Player Updates.

Because Yara was hit before she made her attack, her update takes her into tumble and sends her flying away.

Phase IV: Terrain Detection

Yara hits a wall. Ow. Terrain detection stops her at the wall (and she will rebound)

Phase V: Post Update

Yara's sprite is now translated against the wall. This is done here, because if I did a translate for every possible time we thought Yara was going to change position until now, Mr. GPU would hate us

AttkData and how hits are calculated

So, in step 2 I mentioned that when Yara received her hit, her trajectory changed. This is done via an object called AttkData

 if(hitflag){  //no, you won't find these comments in the .cpp but I have to point this out somehow.
                c_AttkData retOb  = c_AttkData(aBox.GetJlength(t)); //this here is the object, copied from whatever attack was used (aBox)
                Attack(plr, atkType, t, aBox, retOb); //c_AttkData retOb is passed by reference into the attack function. This will load 
                //retOb with the results of interescting the victim's (plr) spatial box with the player's (this) attack box.
                if(!retOb.noHit){//c_AttkData.noHit is flagged to true if this was a miss.
                    if(multiHitFlag)//for ease of physics, only one frame hits per turn
                        hitText = CharName() + " multi-hit\r\n" + plr->CharName() + "!"; //string to display to console
                        hitText =  CharName() + " hit \r\n" + plr->CharName() + "!";   //same stuff
                    console->SetHitCaption(hitText);//change console text to string to display to console
                    plr->GetHit(retOb); //this is where the victim's (plr) velocity is changed and dmg taken
                    if(!multiHitFlag) //Graphical update to console
                        console->PostHit(retOb.GetSPArr(), retOb.curInd, retOb.aBds[0], retOb.attLen, retOb.pBds, retOb.GetConOrigin(), retOb.GetConInter());
                    multiHitFlag=true;//trip this to not calc more frames
                    t=il;//force exit here

Vertex Variables

Each vertex comes with several editable variables which will define the attack. These variables are:

.dmg damage. The highest value found will always be used.

.mag magnitude, or how far the victim will fly. Set to the highest value found.

.dir direction the player will fly at. Will be a proportional average of all verts found.

.wgt value from 1 to 0, determines how the hit behaves between, or blending 2 modes. More on this below.

.center the centre point of the attack; the attack is considered to 'start' from this point, aimed at the victim's midpoint. Whether or not a guard is successful depends on whether it contains the center within it's arcs.

Weighting attacks.

So, weight determines at what proportion to average the two available modes of redirection . At wgt=0, the attack proceeds according to the attackbox; the victims will always be moved in the direction the attack vertices say they will. At wgt=1, the value of these verts is not even used at all for direction; rather the direction from the attacks .center to the victim's center is used. In between 0 and 1, it is a weighted average of the two.

Example; for weight = 0.3 the final direction would be 0.7*whatTheVertsSay + 0.3*whatDirectionTheVictimWasAttackedFrom.

Final Modifiers

So after all the math, we have a direction and magnitude to determine redirection, and damage to determine the amount of damage received.

Magnitude Scaling

magnitude will be scaled according to the victim's existing damage: 1+(existingDamage)/def, where def is the defence of the player, currently averaged around 50. So at 50 damage a character will fly back twice as far. At 100 dmg; three times as far, and so on.

Tumble time will also be scaled according to existing damage, at 1+(existingDamage)/(def x 2), with a cap of 3.

dev's note; I have yet to firmly decide where to put this variable. Currently it is a player attribute, it really should be an attribute of an attack.* I will likely start with a base tumble time based on damage received, and then scale this based on the variable within the attack.

Damage is then simply added to the victim's damage.