From: Keith F. <ven...@us...> - 2007-02-06 07:14:38
|
Update of /cvsroot/planeshift/planeshift/src/server In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24119/src/server Modified Files: combatmanager.cpp combatmanager.h Log Message: - Made several small but important revisions to combat. a. Now if you go out of range, you don't lose combat mode. This will prevent players from jumping in and out of range to kite npcs and duel in unfun ways. b. Now if you are hit by an attack, you are not interrupted if you are casting spells or crafting, etc. You will only auto-target if you are at PEACE mode, doing nothing. c. We now also do angle of attack checking on each hit. You must be roughly facing the mob in order to hit it now. Index: combatmanager.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/combatmanager.cpp,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -d -r1.143 -r1.144 *** combatmanager.cpp 8 Jan 2007 16:10:30 -0000 1.143 --- combatmanager.cpp 6 Feb 2007 07:13:54 -0000 1.144 *************** *** 527,531 **** // If the target wasn't in combat, it is now... ! if (gemTarget->GetMode() != PSCHARACTER_MODE_COMBAT) { if (gemTarget->GetClient()) // Set reciprocal target --- 527,532 ---- // If the target wasn't in combat, it is now... ! // Note that other modes shouldn't be interrupted automatically ! if (gemTarget->GetMode() == PSCHARACTER_MODE_PEACE) { if (gemTarget->GetClient()) // Set reciprocal target *************** *** 597,601 **** gemTarget->GetEntity()->GetID(), event->AttackLocation, ! 0, // no dmg on a block weapon->GetAttackAnimID( gemAttacker->GetCharacterData(),gemAttacker->GetEntity() ), (unsigned int)-1); // no defense anims yet --- 598,602 ---- gemTarget->GetEntity()->GetID(), event->AttackLocation, ! 0, // no dmg on a miss weapon->GetAttackAnimID( gemAttacker->GetCharacterData(),gemAttacker->GetEntity() ), (unsigned int)-1); // no defense anims yet *************** *** 609,614 **** { psserver->SendSystemError(event->AttackerCID,"You are too far away to attack!"); ! if (event->attacker && event->attacker.IsValid()) ! StopAttack(dynamic_cast<gemActor*>((gemObject *) event->attacker)); // if you run away, you exit attack mode } break; --- 610,629 ---- { psserver->SendSystemError(event->AttackerCID,"You are too far away to attack!"); ! ! // Auto-stop attack is commented out below, when out of range to prevent npc kiting by jumping in and out of range ! //if (event->attacker && event->attacker.IsValid()) ! // StopAttack(dynamic_cast<gemActor*>((gemObject *) event->attacker)); // if you run away, you exit attack mode ! } ! break; ! } ! case ATTACK_BADANGLE: ! { ! if (event->AttackerCID) // if human player ! { ! psserver->SendSystemError(event->AttackerCID,"You must face the enemy to attack!"); ! ! // Auto-stop attack is commented out below, when out of range to prevent npc kiting by jumping in and out of range ! //if (event->attacker && event->attacker.IsValid()) ! // StopAttack(dynamic_cast<gemActor*>((gemObject *) event->attacker)); // if you run away, you exit attack mode } break; *************** *** 703,712 **** } else { // If we didn't attack last time target might have forgotten about us by now // so we should remind him. ! if(event->PreviousAttackResult==ATTACK_OUTOFRANGE) NotifyTarget(gemAttacker,gemTarget); attack_result=CalculateAttack(event); } --- 718,736 ---- } + // If attacker is not pointing at target, skip this attack round, send a warning + else if ( !ValidateCombatAngle(gemAttacker, gemTarget, weapon) ) + { + // Attacker is a npc so does not realise it's attack is cancelled + attack_result=ATTACK_BADANGLE; + + } else { // If we didn't attack last time target might have forgotten about us by now // so we should remind him. ! if(event->PreviousAttackResult == ATTACK_OUTOFRANGE || ! event->PreviousAttackResult == ATTACK_BADANGLE) NotifyTarget(gemAttacker,gemTarget); + attack_result=CalculateAttack(event); } *************** *** 762,769 **** } else ! return false; // Range weapons to be added later } void psCombatManager::HandleMessage(MsgEntry *me,Client *client) { --- 786,825 ---- } else ! return false; // TODO: Range weapons to be added later } + bool psCombatManager::ValidateCombatAngle(gemObject *attacker,gemObject *target,psItem *Weapon) + { + csVector3 attackPos, targetPos; + iSector *sector; + + if (attacker->GetNPCPtr()) + return true; // We don't check this for npc's because they are too stupid + + attacker->GetPosition(attackPos,sector); + target->GetPosition(targetPos,sector); + + csVector3 diff = targetPos - attackPos; + if (!diff.x) + diff.x = 0.00001F; // div/0 protect + + float angle = atan2(-diff.x,-diff.z); // Incident angle to npc + float attackFacing = attacker->GetAngle(); + angle = attackFacing - angle; // Where is user facing vs. incident angle? + if (angle > 3.14159F) + angle -= TWO_PI; + else if (angle < -3.14159F) + angle += TWO_PI; + + float dist = diff.SquaredNorm(); + + // Use a slightly tighter angle if the player is farther away + if (dist > 1.5) + return ( fabs(angle) < 3.14159F * .30); + else + return ( fabs(angle) < 3.14159F * .40); + } + void psCombatManager::HandleMessage(MsgEntry *me,Client *client) { Index: combatmanager.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/combatmanager.h,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** combatmanager.h 19 Nov 2006 21:55:56 -0000 1.40 --- combatmanager.h 6 Feb 2007 07:13:54 -0000 1.41 *************** *** 35,39 **** ATTACK_BLOCKED, ATTACK_MISSED, ! ATTACK_OUTOFRANGE }; --- 35,40 ---- ATTACK_BLOCKED, ATTACK_MISSED, ! ATTACK_OUTOFRANGE, ! ATTACK_BADANGLE }; *************** *** 94,97 **** --- 95,99 ---- bool ValidateDistance(gemObject *attacker,gemObject *target,psItem *Weapon); + bool ValidateCombatAngle(gemObject *attacker,gemObject *target,psItem *Weapon); void NotifyTarget(gemActor *attacker,gemObject *target); void QueueNextEvent(psCombatGameEvent *event); |