//AntiChrist - do the sound effect ( only if HITTEN! ) void cCombat::doSoundEffect(P_CHAR pc, int fightskill, P_ITEM pWeapon) { bool heavy=false; int a=rand()%4; //check if a heavy weapon if (pWeapon && IsAxe(pWeapon->id())) heavy=true; if(heavy) { if (a==0 || a==1) soundeffect2(pc, 0x0236); else soundeffect2(pc, 0x0237); return; } switch(fightskill) { case ARCHERY: soundeffect2(pc, 0x0234); break; case FENCING: case SWORDSMANSHIP: if (a==0 || a==1) soundeffect2(pc, 0x023B); else soundeffect2(pc, 0x023C); break; case MACEFIGHTING: if (a==0 || a==1) soundeffect2(pc, 0x0232); else if (a==2) soundeffect2(pc, 0x0139); else soundeffect2(pc, 0x0233); break; case WRESTLING: if (a==0) soundeffect2(pc, 0x0135); else if (a==1) soundeffect2(pc, 0x0137); else if (a==2) soundeffect2(pc, 0x013D); else soundeffect2(pc, 0x013B); break; default: soundeffect2(pc, 0x013D); } }
void Player::AttackAnimationTimerFinished() { if (IsBow()) { } else if (IsBoomerang()) { vec3 boomerangSpawnPosition = GetCenter() + (m_forward*0.75f) + (GetRightVector()*-0.4f) + (GetUpVector()*0.5f); float cameraModification = (m_cameraForward.y*17.5f); if (m_cameraForward.y < 0.0f) { cameraModification = (m_cameraForward.y*5.0f); } vec3 boomerangTarget = boomerangSpawnPosition + m_forward*15.0f + (vec3(0.0f, 1.0f, 0.0f) * cameraModification); if (m_pTargetEnemy != NULL) { boomerangTarget = m_pTargetEnemy->GetProjectileHitboxCenter(); if (m_pTargetEnemy->IsMoving()) { boomerangTarget += m_pTargetEnemy->GetForwardVector() * (m_pTargetEnemy->GetMovementSpeed() / 3.0f); } } float curveTime = length(boomerangTarget - boomerangSpawnPosition) / 15.0f; if (curveTime <= 0.4f) curveTime = 0.4f; Projectile* pProjectile = m_pProjectileManager->CreateProjectile(boomerangSpawnPosition, vec3(0.0f, 0.0f, 0.0f), 0.0f, "media/gamedata/weapons/Boomerang/BoomerangThrown.weapon", 0.05f); pProjectile->SetProjectileType(true, false, false); pProjectile->SetOwner(this, NULL, NULL); pProjectile->SetGravityMultiplier(0.0f); pProjectile->SetReturnToPlayer(true); pProjectile->SetProjectileCurveParams(m_forward, boomerangTarget, curveTime); pProjectile->SetWorldCollisionEnabled(true); m_pVoxelCharacter->SetRenderRightWeapon(false); } else if (IsStaff()) { float powerAmount = 25.0f; float cameraMultiplier = 25.0f; vec3 spellSpawnPosition = GetCenter() + (m_forward*1.25f) + (GetUpVector()*0.25f); if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson) { cameraMultiplier = 30.0f; spellSpawnPosition.y += 0.75f; } vec3 spellSpawnVelocity = m_forward * powerAmount + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier); if (m_pTargetEnemy != NULL) { vec3 toTarget = m_pTargetEnemy->GetProjectileHitboxCenter() - GetCenter(); spellSpawnVelocity = (normalize(toTarget) * powerAmount); } Projectile* pProjectile = m_pProjectileManager->CreateProjectile(spellSpawnPosition, spellSpawnVelocity, 0.0f, "media/gamedata/items/Fireball/Fireball.item", 0.05f); pProjectile->SetProjectileType(true, false, false); pProjectile->SetOwner(this, NULL, NULL); pProjectile->SetGravityMultiplier(0.0f); } else if (IsWand()) { } else if (IsBomb()) { vec3 bombSpawnPosition = GetCenter() + (m_forward*0.75f) + (GetUpVector()*0.5f); float liftAmount = 8.0f; float powerAmount = 30.0f; float cameraMultiplier = 25.0f; if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson) { cameraMultiplier = 30.0f; } vec3 bombSpawnVelocity; if (m_pTargetEnemy) { // Enemy target vec3 toTarget = m_pTargetEnemy->GetCenter() - GetCenter(); float toTargetDistance = length(toTarget); liftAmount += toTargetDistance * 0.04f; bombSpawnVelocity = (normalize(toTarget) * powerAmount) + vec3(0.0f, liftAmount, 0.0f); } else { bombSpawnVelocity = (m_forward * powerAmount) + (GetUpVector() * liftAmount) + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier); } Projectile* pProjectile = m_pProjectileManager->CreateProjectile(bombSpawnPosition, bombSpawnVelocity, 0.0f, "media/gamedata/items/Bomb/BombThrown.item", 0.05f); pProjectile->SetProjectileType(true, false, false); pProjectile->SetOwner(this, NULL, NULL); pProjectile->SetGravityMultiplier(3.5f); float explodeRadius = 3.5f - (GetRandomNumber(-150, 0, 2) * 0.01f); pProjectile->SetExplodingProjectile(true, explodeRadius); //m_pVoxelCharacter->SetRenderRightWeapon(false); InventoryItem* pItem = m_pInventoryManager->GetInventoryItemForEquipSlot(EquipSlot_RightHand); if (pItem != NULL) { if (pItem->m_quantity != -1) { pItem->m_quantity -= 1; } if (pItem->m_quantity == 0) { // Remove this item from the manager, and remove it from the inventory and GUI UnequipItem(EquipSlot_RightHand, false, false); m_pInventoryManager->RemoveInventoryItem(EquipSlot_RightHand); m_pActionBar->RemoveInventoryItemFromActionBar(pItem->m_title); } } } else if (IsConsumable()) { } else if (IsDagger()) { } else if (IsHammer()) { } else if (IsMace()) { } else if (IsSickle()) { } else if (IsPickaxe()) { Item* pInteractItem = VoxGame::GetInstance()->GetInteractItem(); if (pInteractItem != NULL) { pInteractItem->Interact(); } else { DestroyBlock(); } } else if (IsAxe()) { } else if (Is2HandedSword()) { } else if (IsSword()) { } else if (IsBlockPlacing()) { } else if (IsItemPlacing()) { } else if (IsSceneryPlacing()) { } else if (IsSpellHands()) { float powerAmount = 25.0f; float cameraMultiplier = 25.0f; vec3 spellSpawnPosition = GetCenter() + (m_forward*0.5f) + (GetUpVector()*0.0f); // For right hand spellSpawnPosition += -(GetRightVector()*0.4f); if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson) { cameraMultiplier = 30.0f; spellSpawnPosition.y += 0.75f; } vec3 spellSpawnVelocity = m_forward * powerAmount + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier); if (m_pTargetEnemy != NULL) { vec3 toTarget = m_pTargetEnemy->GetProjectileHitboxCenter() - GetCenter(); spellSpawnVelocity = (normalize(toTarget) * powerAmount); } Projectile* pProjectile = m_pProjectileManager->CreateProjectile(spellSpawnPosition, spellSpawnVelocity, 0.0f, "media/gamedata/items/Fireball/FireballBlue.item", 0.05f); pProjectile->SetProjectileType(true, false, false); pProjectile->SetOwner(this, NULL, NULL); pProjectile->SetGravityMultiplier(0.0f); } else if (IsShield()) { } else if (IsTorch()) { } }
// Combat void Player::PressAttack() { if (IsDead()) { return; } if (IsBow()) { if (m_bowAttackDelay <= 0.0f) { if (m_bIsChargingAttack == false) { m_bIsChargingAttack = true; m_chargeAmount = 0.0f; LoadWeapon(false, "media/gamedata/items/Arrow/ArrowHold.item"); if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson) { // Make sure we set arrow alpha if we are in first person mode m_pVoxelCharacter->SetMeshAlpha(0.45f, true); } if (m_bIsIdle) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, false, AnimationSections_FullBody, "BowCharge", 0.2f); } else { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Head_Body, false, AnimationSections_Head_Body, "BowCharge", 0.2f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "BowCharge", 0.2f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "BowCharge", 0.2f); } VoxGame::GetInstance()->PlaySoundEffect(eSoundEffect_BowDraw); } } } else if (IsBoomerang()) { if (CanAttackRight()) { if (m_bCanThrowWeapon) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, true, AnimationSections_FullBody, "SwordAttack1", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "SwordAttack1", 0.01f); Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.22f, 0.22f, 0.0f, NULL, _AttackAnimationTimerFinished, this); m_bCanAttackRight = false; m_bCanThrowWeapon = false; // Start weapon trails if (m_pVoxelCharacter->GetRightWeapon()) { if (m_pVoxelCharacter->IsRightWeaponLoaded()) { m_pVoxelCharacter->GetRightWeapon()->StartWeaponTrails(); } } } } } else if (IsStaff()) { if (m_magic >= 10.0f) { if (CanAttackRight()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "StaffAttack", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "StaffAttack", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Head_Body, false, AnimationSections_Head_Body, "StaffAttack", 0.01f); m_bCanInteruptCombatAnim = false; Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.2f, 0.2f, 0.0f, NULL, _AttackAnimationTimerFinished, this); m_magic -= 10.0f; VoxGame::GetInstance()->GetHUD()->UpdatePlayerData(); m_bCanAttackRight = false; } VoxGame::GetInstance()->PlaySoundEffect(eSoundEffect_FireballCast, 0.5f); } } else if (IsWand()) { } else if (IsBomb()) { if (CanAttackRight()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, true, AnimationSections_FullBody, "SwordAttack2", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "SwordAttack2", 0.01f); Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.25f, 0.25f, 0.0f, NULL, _AttackAnimationTimerFinished, this); m_bCanAttackRight = false; } } else if (IsConsumable()) { } else if (IsDagger()) { InventoryItem* pRightHand = m_pInventoryManager->GetInventoryItemForEquipSlot(EquipSlot_RightHand); InventoryItem* pLeftHand = m_pInventoryManager->GetInventoryItemForEquipSlot(EquipSlot_LeftHand); if (pRightHand != NULL && pRightHand->m_itemType == InventoryType_Weapon_Dagger && CanAttackRight()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "SwordAttack2", 0.01f); Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.3f, 0.3f, 0.0f, NULL, _AttackAnimationTimerFinished, this); m_bCanInteruptCombatAnim = true; m_attackEnabledDelayTimer = 0.0f; m_attackSegmentAngle = 0.75f; float attackTime = 0.4f; float startRotation = -10.0f; float endRotation = -10.0f; float easingRotation = 0.0f; m_attackEnabled = true; m_attackEnabledTimer = 0.0f; m_attackRotation = startRotation; Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledTimer, 0.0f, attackTime, attackTime, 0.0f, NULL, _AttackEnabledTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledDelayTimer, m_attackEnabledDelayTimer, 0.0f, m_attackEnabledDelayTimer, 0.0f, NULL, _AttackEnabledDelayTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackRotation, startRotation, endRotation, attackTime, easingRotation); m_bCanAttackRight = false; } else if (pLeftHand != NULL && pLeftHand->m_itemType == InventoryType_Weapon_Dagger && CanAttackLeft()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "SwordAttack2", 0.01f); Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.3f, 0.3f, 0.0f, NULL, _AttackAnimationTimerFinished_Alternative, this); m_bCanInteruptCombatAnim = true; m_attackEnabledDelayTimer = 0.0f; m_attackSegmentAngle = 0.75f; float attackTime = 0.4f; float startRotation = -10.0f; float endRotation = -10.0f; float easingRotation = 0.0f; m_attackEnabled = true; m_attackEnabledTimer = 0.0f; m_attackRotation = startRotation; Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledTimer, 0.0f, attackTime, attackTime, 0.0f, NULL, _AttackEnabledTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledDelayTimer, m_attackEnabledDelayTimer, 0.0f, m_attackEnabledDelayTimer, 0.0f, NULL, _AttackEnabledDelayTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackRotation, startRotation, endRotation, attackTime, easingRotation); m_bCanAttackLeft = false; } } else if (IsHammer()) { } else if (IsMace()) { } else if (IsSickle()) { } else if (IsPickaxe()) { if (CanAttackRight()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, true, AnimationSections_FullBody, "Mine", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "Mine", 0.01f); m_bCanInteruptCombatAnim = false; Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.4f, 0.4f, 0.0f, NULL, _AttackAnimationTimerFinished, this); m_bCanAttackRight = false; } } else if (IsAxe()) { } else if (Is2HandedSword()) { if (CanAttackRight()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, true, AnimationSections_FullBody, "2HandedSwordAttack", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "2HandedSwordAttack", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "2HandedSwordAttack", 0.01f); m_bCanInteruptCombatAnim = false; m_attackEnabledDelayTimer = 0.175f; m_attackSegmentAngle = 0.60f; float attackTime = 0.6f; float startRotation = 240.0f; float endRotation = -60.0f; float easingRotation = -50.0f; m_attackEnabled = true; m_attackEnabledTimer = 0.0f; m_attackRotation = startRotation; Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledTimer, 0.0f, attackTime, attackTime, 0.0f, NULL, _AttackEnabledTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledDelayTimer, m_attackEnabledDelayTimer, 0.0f, m_attackEnabledDelayTimer, 0.0f, NULL, _AttackEnabledDelayTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackRotation, startRotation, endRotation, attackTime, easingRotation); m_bCanAttackRight = false; } } else if (IsSword()) { if (CanAttackRight()) { float attackTime = 0.0f; float startRotation = 0.0f; float endRotation = 0.0f; float easingRotation = 0.0f; int randomAttack = GetRandomNumber(1, 3); if (randomAttack == 1) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, true, AnimationSections_FullBody, "SwordAttack1", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Head_Body, false, AnimationSections_Head_Body, "SwordAttack1", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "SwordAttack1", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "SwordAttack1", 0.01f); m_bCanInteruptCombatAnim = false; m_attackEnabledDelayTimer = 0.1f; m_attackSegmentAngle = 0.75f; attackTime = 0.4f; startRotation = -20.0f; endRotation = -20.0f; easingRotation = 0.0f; } else if (randomAttack == 2) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, true, AnimationSections_FullBody, "SwordAttack2", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Head_Body, false, AnimationSections_Head_Body, "SwordAttack2", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "SwordAttack2", 0.01f); m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "SwordAttack1", 0.01f); m_bCanInteruptCombatAnim = false; m_attackEnabledDelayTimer = 0.2f; m_attackSegmentAngle = 0.75f; attackTime = 0.4f; startRotation = -10.0f; endRotation = -10.0f; easingRotation = 0.0f; } else if (randomAttack == 3) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_FullBody, false, AnimationSections_FullBody, "SwordAttack3", 0.01f); m_bCanInteruptCombatAnim = false; m_attackEnabledDelayTimer = 0.0f; m_attackSegmentAngle = 0.60f; attackTime = 0.6f; startRotation = 360.0f; endRotation = -45.0f; easingRotation = -75.0f; } m_bCanAttackRight = false; m_attackEnabled = true; m_attackEnabledTimer = 0.0f; m_attackRotation = startRotation; Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledTimer, 0.0f, attackTime, attackTime, 0.0f, NULL, _AttackEnabledTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackEnabledDelayTimer, m_attackEnabledDelayTimer, 0.0f, m_attackEnabledDelayTimer, 0.0f, NULL, _AttackEnabledDelayTimerFinished, this); Interpolator::GetInstance()->AddFloatInterpolation(&m_attackRotation, startRotation, endRotation, attackTime, easingRotation); } } else if (IsBlockPlacing()) { } else if (IsItemPlacing()) { } else if (IsSceneryPlacing()) { } else if (IsSpellHands()) { if (m_magic >= 5.0f) { InventoryItem* pRightHand = m_pInventoryManager->GetInventoryItemForEquipSlot(EquipSlot_RightHand); InventoryItem* pLeftHand = m_pInventoryManager->GetInventoryItemForEquipSlot(EquipSlot_LeftHand); if (pRightHand != NULL && pRightHand->m_itemType == InventoryType_Weapon_SpellHands && CanAttackRight()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Right_Arm_Hand, false, AnimationSections_Right_Arm_Hand, "HandSpellCastRight", 0.01f); Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.3f, 0.3f, 0.0f, NULL, _AttackAnimationTimerFinished, this); m_magic -= 5.0f; VoxGame::GetInstance()->GetHUD()->UpdatePlayerData(); m_bCanAttackRight = false; } else if (pLeftHand != NULL && pLeftHand->m_itemType == InventoryType_Weapon_SpellHands && CanAttackLeft()) { m_pVoxelCharacter->BlendIntoAnimation(AnimationSections_Left_Arm_Hand, false, AnimationSections_Left_Arm_Hand, "HandSpellCastLeft", 0.01f); Interpolator::GetInstance()->AddFloatInterpolation(&m_animationTimer, 0.0f, 0.3f, 0.3f, 0.0f, NULL, _AttackAnimationTimerFinished_Alternative, this); m_magic -= 5.0f; VoxGame::GetInstance()->GetHUD()->UpdatePlayerData(); m_bCanAttackLeft = false; } VoxGame::GetInstance()->PlaySoundEffect(eSoundEffect_FireballCast, 0.5f); } } else if (IsShield()) { } else if (IsTorch()) { } }
void Player::AttackAnimationTimerFinished_Alternative() { if (IsBow()) { } else if (IsBoomerang()) { } else if (IsStaff()) { } else if (IsWand()) { } else if (IsBomb()) { } else if (IsConsumable()) { } else if (IsDagger()) { } else if (IsHammer()) { } else if (IsMace()) { } else if (IsSickle()) { } else if (IsPickaxe()) { } else if (IsAxe()) { } else if (Is2HandedSword()) { } else if (IsSword()) { } else if (IsBlockPlacing()) { } else if (IsItemPlacing()) { } else if (IsSceneryPlacing()) { } else if (IsSpellHands()) { float powerAmount = 25.0f; float cameraMultiplier = 25.0f; vec3 spellSpawnPosition = GetCenter() + (m_forward*0.5f) + (GetUpVector()*0.0f); // For left hand spellSpawnPosition += (GetRightVector()*0.4f); if (VoxGame::GetInstance()->GetCameraMode() == CameraMode_FirstPerson) { cameraMultiplier = 30.0f; spellSpawnPosition.y += 0.75f; } vec3 spellSpawnVelocity = m_forward * powerAmount + vec3(0.0f, 1.0f, 0.0f) * (m_cameraForward.y*cameraMultiplier); if (m_pTargetEnemy != NULL) { vec3 toTarget = m_pTargetEnemy->GetProjectileHitboxCenter() - GetCenter(); spellSpawnVelocity = (normalize(toTarget) * powerAmount); } Projectile* pProjectile = m_pProjectileManager->CreateProjectile(spellSpawnPosition, spellSpawnVelocity, 0.0f, "media/gamedata/items/Fireball/FireballBlue.item", 0.05f); pProjectile->SetProjectileType(true, false, false); pProjectile->SetOwner(this, NULL, NULL); pProjectile->SetGravityMultiplier(0.0f); } else if (IsShield()) { } else if (IsTorch()) { } }
bool IsSwordType(short id) { return ( IsSword(id) || IsAxe(id) ); }
// CombatHit now expects that LineOfSight has been checked before (Duke, 10.7.2001) void cCombat::CombatHit(P_CHAR pc_attacker, P_CHAR pc_deffender, unsigned int currenttime, short los) { char hit; if (pc_deffender == NULL || pc_attacker == NULL) return; UOXSOCKET s1=calcSocketFromChar(pc_attacker), s2=calcSocketFromChar(pc_deffender); unsigned short fightskill = Skills->GetCombatSkill(pc_attacker), bowtype = Combat->GetBowType(pc_attacker),splitnum,splitcount,hitin; unsigned int basedamage; int damage; // removed from unsigne by Magius(CHE) signed int x; // Magius(CHE) - For armour absorbtion system int maxabs, maxnohabs, tmpj; P_ITEM pWeapon=pc_attacker->getWeapon();// get the weapon item only once if (pWeapon && !(rand()%50) // a 2 percent chance (Duke, 07.11.2000) && pWeapon->type !=9) // but not for spellbooks (Duke, 09/10/00) { pWeapon->hp--; //Take off a hit point if(pWeapon->hp<=0) { sysmessage(s1, tr("Your weapon has been destroyed")); if ((pWeapon->trigon==1) && (pWeapon->layer>0))// -Frazurbluu- Trigger Type 2 is my new trigger type *- { Trig->triggerwitem(s1, pWeapon, 1); // trigger is fired when item destroyed } Items->DeleItem(pWeapon); } } // End here - Magius(CHE) - For armour absorbtion system pc_attacker->swingtarg=-1; if((chardist(pc_attacker, pc_deffender)>1 && fightskill!=ARCHERY) || !los) return; if(pc_deffender->isNpc() && pc_deffender->isInvul()) return; // ripper hit=Skills->CheckSkill(pc_attacker, fightskill, 0, 1000); // increase fighting skill for attacker and defender if (!hit) { if (pc_attacker->isPlayer()) doMissedSoundEffect(pc_attacker); if ((fightskill==ARCHERY)&&(los)) { if (rand()%3-1)//-1 0 or 1 { short id=0x1BFB; // bolts if (bowtype==1) id=0x0F3F; // arrows P_ITEM pAmmo=Items->SpawnItem(pc_deffender,1,"#",1,id,0,0); if(pAmmo) { pAmmo->moveTo(pc_deffender->pos); pAmmo->priv=1; RefreshItem(pAmmo); } } } } else { if (!pc_deffender->isInvul()) { if (pc_deffender->xid==0x0191) soundeffect2(pc_deffender,0x014b); else if (pc_deffender->xid==0x0190) soundeffect2(pc_deffender,0x0156); playmonstersound(pc_deffender, pc_deffender->id(), SND_DEFEND); //AntiChrist -- for poisoned weapons if((pWeapon) && (pWeapon->poisoned>0)) { pc_deffender->poisoned=pWeapon->poisoned; pc_deffender->poisontime=uiCurrentTime+(MY_CLOCKS_PER_SEC*(40/pc_deffender->poisoned)); // a lev.1 poison takes effect after 40 secs, a deadly pois.(lev.4) takes 40/4 secs - AntiChrist pc_deffender->poisonwearofftime=pc_deffender->poisontime+(MY_CLOCKS_PER_SEC*SrvParams->poisonTimer()); //wear off starts after poison takes effect - AntiChrist } CheckPoisoning(s2, pc_attacker, pc_deffender); // attacker poisons defender CheckPoisoning(s1, pc_deffender, pc_attacker); // and vice versa if ((pc_deffender->effDex()>0)) pc_deffender->priv2&=0xFD; // unfreeze if (fightskill!=WRESTLING && los) Combat->ItemSpell(pc_attacker, pc_deffender); if (fightskill!=WRESTLING || pc_attacker->isNpc()) basedamage=Combat->CalcAtt(pc_attacker); // Calc base damage else { if ((pc_attacker->skill[WRESTLING]/100) > 0) { if (pc_attacker->skill[WRESTLING]/100!=0) basedamage=rand()%(pc_attacker->skill[WRESTLING]/100); else basedamage=0; } else basedamage=rand()%2; } if((pc_attacker->isPlayer()) && (fightskill!=WRESTLING)) { if (pWeapon->racehate != 0 && pc_deffender->race != 0)//-Fraz- Racehating combat { if (pWeapon->racehate==pc_deffender->race) { basedamage *=2; if(pc_deffender->isPlayer()) { sysmessage(s2, tr("You scream in agony from being hit by the accursed metal!")); if (pc_deffender->xid == 0x0191) soundeffect2(pc_deffender,0x0152); else if (pc_deffender->xid==0x0190) soundeffect2(pc_deffender,0x0157); }// can add a possible effect below here for npc's being hit } } } Skills->CheckSkill(pc_attacker, TACTICS, 0, 1000); damage=(int)(basedamage*((pc_attacker->skill[TACTICS]+500.0)/1000.0)); // Add Tactical bonus damage=damage+(int)((basedamage*(pc_attacker->st/500.0))); // Add Strength bonus //Adds a BONUS DAMAGE for ANATOMY //Anatomy=100 -> Bonus +20% Damage - AntiChrist (11/10/99) if (Skills->CheckSkill(pc_attacker, ANATOMY, 0, 1000)) { float multiplier=(((pc_attacker->skill[ANATOMY]*20)/1000.0f)/100.0f)+1; damage=(int) (damage * multiplier); } //Adds a BONUS DEFENCE for TACTICS //Tactics=100 -> Bonus -20% Damage - AntiChrist (11/10/99) float multiplier=1-(((pc_deffender->skill[TACTICS]*20)/1000.0f)/100.0f); damage=(int) (damage * multiplier); P_ITEM pShield=pc_deffender->getShield(); if(pShield) { if (Skills->CheckSkill(pc_deffender, PARRYING, 0, 1000))// chance to block with shield { if (pShield->def!=0) damage-=rand()%(pShield->def);// damage absorbed by shield if(rand()%2) pShield->hp--; //Take off a hit point if(pShield->hp<=0) { sysmessage(s2, tr("Your shield has been destroyed")); if ((pShield->trigon==1) && (pShield->layer >0))// -Frazurbluu- Trigger Type 2 is my new trigger type *- { Trig->triggerwitem(s2, pShield, 1); // trigger is fired when item destroyed } Items->DeleItem(pShield); } } } // Armor destruction and sped up by hitting with maces should go in here somewhere // According to lacation of body hit Id imagine -Frazurbluu- **NEEDS ADDED** x=rand()%100;// determine area of body hit if (!SrvParams->combatHitMessage()) { if (x<=44) x=1; // body else if (x<=58) x=2; // arms else if (x<=72) x=3; // head else if (x<=86) x=4; // legs else if (x<=93) x=5; // neck else x=6; // hands } else { temp[0] = '\0'; hitin = rand()%2; if (x<=44) { x=1; // body switch (hitin) { case 1: //later take into account dir facing attacker during battle if (damage < 10) strcpy(temp, "hits you in your Chest!"); else if (damage >=10) strcpy(temp, "lands a terrible blow to your Chest!"); break; case 2: if (damage < 10) strcpy(temp, "lands a blow to your Stomach!"); else if (damage >=10) strcpy(temp, "knocks the wind out of you!"); break; default: if (damage < 10) strcpy(temp, "hits you in your Ribs!"); else if (damage >=10) strcpy(temp, "broken your Rib?!"); } } else if (x<=58) { if (damage > 1) { x=2; // arms switch (hitin) { case 1: strcpy(temp, "hits you in Left Arm!"); break; case 2: strcpy(temp, "hits you in Right Arm!"); break; default:strcpy(temp, "hits you in Right Arm!"); } } } else if (x<=72) { x=3; // head switch (hitin) { case 1: if (damage < 10) strcpy(temp, "hits you you straight in the Face!"); else if (damage >=10) strcpy(temp, "lands a stunning blow to your Head!"); break; case 2: if (damage < 10) strcpy(temp, "hits you to your Head!"); //kolours - (09/19/98) else if (damage >=10) strcpy(temp, "smashed a blow across your Face!"); break; default: if (damage < 10) strcpy(temp, "hits you you square in the Jaw!"); else if (damage >=10) strcpy(temp, "lands a terrible hit to your Temple!"); } } else if (x<=86) { x=4; // legs switch (hitin) { case 1: strcpy(temp, "hits you in Left Thigh!"); break; case 2: strcpy(temp, "hits you in Right Thigh!"); break; default:strcpy(temp, "hits you in Groin!"); } } else if (x<=93) { x=5; // neck strcpy(temp, "hits you to your Throat!"); } else { x=6; // hands switch (hitin) { case 1: if (damage > 1) strcpy(temp, tr("hits you in Left Hand!").latin1()); break; case 2: if (damage > 1) strcpy(temp, tr("hits you in Right Hand!").latin1()); break; default: if (damage > 1) strcpy(temp, tr("hits you in Right Hand!").latin1()); } } sprintf((char*)temp2,"%s %s",pc_attacker->name.c_str(), temp); if (pc_deffender->isPlayer() && s2!=-1) sysmessage(s2, (char*)temp2); //kolours -- hit display } x = CalcDef(pc_deffender,x); // Magius(CHE) - For armour absorbtion system maxabs = 20; // // there are monsters with DEF >20, this makes them undefeatable maxnohabs=100; if (SrvParams->maxAbsorbtion() > 0) { maxabs = SrvParams->maxAbsorbtion(); } if (SrvParams->maxnohabsorbtion() > 0) { maxnohabs = SrvParams->maxnohabsorbtion(); } if (!ishuman(pc_deffender)) maxabs=maxnohabs; tmpj=(int) (damage*x)/maxabs; // Absorbtion by Magius(CHE) damage -= tmpj; if (damage<0) damage=0; if (pc_deffender->isPlayer()) damage /= SrvParams->npcdamage(); // Rate damage against other players // End Armour Absorbtion by Magius(CHE) (See alse reactive armour spell damage) if (pc_attacker->isPlayer())//Zippy ItemCastSpell(s1, pc_deffender,pWeapon); //AntiChrist - 26/10/99 //when hitten and damage >1, defender fails if casting a spell! if(damage>1 && pc_deffender->isPlayer())//only if damage>1 and against a player { if(pc_deffender->casting && currentSpellType[s2]==0 ) {//if casting a normal spell (scroll: no concentration loosen) Magic->SpellFail(s2); currentSpellType[s2]=0; pc_deffender->spell=-1; pc_deffender->casting=0; pc_deffender->spelltime=0; pc_deffender->priv2 &= 0xfd; // unfreeze, bugfix LB } } if(damage>0) { if (pc_deffender->ra) // For reactive armor spell { // -Frazurbluu- RA may need a rewrite to be more OSI standard here // Its said 80% deflected 10% to attacker / 10% defender gotta check special effects int damage1; damage1=(int)( damage*(pc_deffender->skill[MAGERY]/2000.0)); pc_deffender->hp -= damage-damage1; if (pc_deffender->isNpc()) damage1 = damage1 * SrvParams->npcdamage(); // by Magius(CHE) pc_attacker->hp -= damage1; // Remove damage from attacker staticeffect(pc_deffender, 0x37, 0x4A, 0, 15);//RA effect - AntiChrist (9/99) if ((fightskill==MACEFIGHTING) && (IsSpecialMace(pWeapon->id())))// Stamina Loss -Fraz- { //pc_attacker->stm-=3+(rand()%4); } if ((fightskill==FENCING) && (IsFencing2H(pWeapon->id())))// Paralyzing -Fraz- { //will call the combat caused paralyzation **NEED TO DO** } if ((fightskill==SWORDSMANSHIP) && (IsAxe(pWeapon->id())))// Concussion Hit -Fraz- { //will call the combat caused concussion (loss of int for 30 secs) **NEED TO DO** // for now make it subtract mana //pc_attacker->mn-=(pc_attacker->mn/2); } updatestats(pc_attacker, 0); } else { // -Fraz- Now needs adjusted to happen on a skill percentage pc_deffender->hp-=damage; // Remove damage from defender only apply special hits to non-npc's if ((fightskill==MACEFIGHTING) && (IsSpecialMace(pWeapon->id())) && (pc_deffender->isPlayer()))// Stamina Loss -Fraz- { pc_deffender->stm-=3+(rand()%3); } if ((fightskill==FENCING) && (IsFencing2H(pWeapon->id())) && (pc_deffender->isPlayer()))// Paralyzing -Fraz- { tempeffect(pc_attacker, pc_deffender, 44, 0, 0, 0); sysmessage(s1, tr("You delivered a paralyzing blow")); } if ((fightskill==SWORDSMANSHIP) && (IsAxe(pWeapon->id())) && (pc_deffender->isPlayer()))// Concussion Hit -Fraz- { tempeffect(pc_attacker, pc_deffender, 45, 0, 0, 0); //pc_attacker->mn-=(pc_attacker->mn/2); //-Fraz- temp use of this for concussion } updatestats((pc_deffender), 0); } // blood shred by blackwind if (damage>10) { short id = 0x122c; if (damage>50) id=0x122a; else if (damage>40) id=0x122d; else if (damage>30) id=0x122e; else if (damage>20) id=0x122b; P_ITEM pBlood = Items->SpawnItem(pc_deffender, 1, "#", 0, id, 0, 0); if (pBlood) { pBlood->moveTo(pc_deffender->pos); pBlood->priv = 1; pBlood->setGMMovable(); //Moveable by GM RefreshItem(pBlood); pBlood->decaytime = (SrvParams->decayTime()/2)*MY_CLOCKS_PER_SEC+uiCurrentTime; } } ///////// For Splitting NPCs /// McCleod if ((pc_deffender->split>0)&&(pc_deffender->hp>=1)) { if (rand()%100<=pc_deffender->splitchnc) { if (pc_deffender->split==1) splitnum=1; else splitnum=rand()%pc_deffender->split+1; for (splitcount=0;splitcount<splitnum;splitcount++) Npcs->Split(pc_deffender); } } //////// End of spliting NPCs } if (pc_attacker->isPlayer()) if((fightskill==ARCHERY && los)|| fightskill!=ARCHERY) doSoundEffect(pc_attacker, fightskill, pWeapon); if (pc_deffender->hp<0) pc_deffender->hp=0; updatestats((pc_deffender), 0); x = pc_deffender->id(); if (x>=0x0190) { if (!pc_deffender->onhorse) npcaction(pc_deffender, 0x14); } } } }
//play animation for weapon in hand for combat on foot //kolours - (09/20/98) void cCombat::CombatOnFoot(P_CHAR pc) { if ( pc == NULL ) return; P_ITEM pWeapon=pc->getWeapon(); int m = rand()%4; //randomize the animation sequence if (pWeapon) { short id = pWeapon->id(); if (IsBow(id)) { npcaction(pc, 0x12); //bow return; } if (IsCrossbow(id) || IsHeavyCrossbow(id)) { npcaction(pc, 0x13); //crossbow - regular return; } if (IsSword(id)) { switch (m) //swords { case 0: npcaction(pc, 0x0D); return; //side swing case 1: npcaction(pc, 0x0A); return; //poke default: npcaction(pc, 0x09); return; //top-down swing } } if (IsMace1H(id)) { switch (m) //maces { case 0: npcaction(pc, 0x0D); return; //side swing default: npcaction(pc, 0x09); return; //top-down swing } } if (IsMace2H(id) || IsAxe(id)) { switch (m) { case 0: npcaction(pc, 0x0D); return; //2H top-down case 1: npcaction(pc, 0x0C); return; //2H swing default: npcaction(pc, 0x0D); return; //2H top-down } } if (IsFencing1H(id)) // one handed fencing { switch (m) //fencing { case 0: npcaction(pc, 0x09); return; //top-down case 1: npcaction(pc, 0x0D); return; //side-swipe default: npcaction(pc, 0x0A); return; //default: poke } } if (IsFencing2H(id)) //pitchfork & spear { switch (m) //pitchfork { case 0: npcaction(pc, 0x0D); return; //top-down default: npcaction(pc, 0x0E); return; //default: 2-handed poke } } } // end of !=-1 else { switch (m) //fist fighting { case 0: npcaction(pc, 0x0A); return; //fist straight-punch case 1: npcaction(pc, 0x09); return; //fist top-down default: npcaction(pc, 0x1F); return; //default: //fist over-head } } }
//play animation for weapon in hand during combat on a horse //kolours - modularized (09/20/98) void cCombat::CombatOnHorse(P_CHAR pc) { if ( pc == NULL ) return; P_ITEM pWeapon=pc->getWeapon(); // tweak for better fight animations if on Lama, ostards, kirin, seahorse, or ridgeback // LB (04-02-2002) P_ITEM pHorseItem=pc->GetItemOnLayer(0x19); int base; switch(pHorseItem->id2) { case 0xab: // llamas case 0xa6: base=0x2b; break; case 0xa3: // ostards case 0xa4: case 0xa5: case 0xac: base=0x35; break; case 0xad: // kirin base=0x3f; break; case 0xb3: // sea horse base=0x49; break; case 0xb8: //ridgeback base=0x53; break; default: base = 0x17; // default (horse) base animation break; } if (pWeapon) { short id = pWeapon->id(); if (IsBow(id)) { npcaction(pc, 0x1B); return; } if (IsCrossbow(id) || IsHeavyCrossbow(id)) { npcaction(pc, 0x1C); return; } if( IsSword(id) || IsMaceType(id) || (id ==0x0FB4 || id ==0x0FB5) || // sledge hammer IsFencing1H(id) ) { npcaction(pc, 0x1A); return; } if ( IsAxe(id) || IsFencing2H(id) ) { npcaction(pc, 0x1D); //2Handed return; } } // end of !=-1 else { npcaction(pc, 0x1A); //fist fighting return; } }