Mercurial > mm7
comparison Actor.cpp @ 1940:a50511e4f3c6
Слияние
author | Ritor1 |
---|---|
date | Thu, 24 Oct 2013 15:31:22 +0600 |
parents | 68f2d9d3a1d9 1cbfb6e50e48 |
children | 431d3da6e945 |
comparison
equal
deleted
inserted
replaced
1939:027ed24b8017 | 1940:a50511e4f3c6 |
---|---|
846 a1.uType = 555; | 846 a1.uType = 555; |
847 break; | 847 break; |
848 default: | 848 default: |
849 return; | 849 return; |
850 } | 850 } |
851 a1.uObjectDescID = GetObjDescId(a1.uType); | 851 bool found = false; |
852 for ( uint i = 0; i < pObjectList->uNumObjects; i++) | |
853 { | |
854 if (pObjectList->pObjects[i].uObjectID == a1.uType) | |
855 { | |
856 a1.uObjectDescID = i; | |
857 found = true; | |
858 break; | |
859 } | |
860 } | |
861 if (!found) | |
862 { | |
863 Error("Item not found"); | |
864 return; | |
865 } | |
852 a1.stru_24.Reset(); | 866 a1.stru_24.Reset(); |
853 a1.vPosition.x = actPtr->vPosition.x; | 867 a1.vPosition.x = actPtr->vPosition.x; |
854 a1.spell_id = 0; | 868 a1.spell_id = 0; |
855 a1.vPosition.y = actPtr->vPosition.y; | 869 a1.vPosition.y = actPtr->vPosition.y; |
856 a1.spell_level = 0; | 870 a1.spell_level = 0; |
3557 } | 3571 } |
3558 } | 3572 } |
3559 //----- (00439474) -------------------------------------------------------- | 3573 //----- (00439474) -------------------------------------------------------- |
3560 void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity) | 3574 void DamageMonsterFromParty(signed int a1, unsigned int uActorID_Monster, Vec3_int_ *pVelocity) |
3561 { | 3575 { |
3562 //signed int v3; // eax@1 | 3576 SpriteObject *projectileSprite; // ebx@1 |
3563 SpriteObject *v4; // ebx@1 | |
3564 //int v5; // edx@3 | |
3565 //bool uPlayerID; // eax@3 | |
3566 //Player *pPlayer; // edi@4 | |
3567 Actor *pMonster; // esi@7 | 3577 Actor *pMonster; // esi@7 |
3568 //SpriteObject *v9; // ebx@12 | |
3569 int v10; // eax@12 | |
3570 int v11; // ebx@12 | |
3571 unsigned int v12; // ecx@12 | |
3572 int v13; // edx@15 | |
3573 int v14; // edx@17 | |
3574 int v15; // eax@24 | |
3575 unsigned __int16 v16; // cx@25 | 3578 unsigned __int16 v16; // cx@25 |
3576 int v17; // eax@29 | |
3577 int v18; // eax@38 | |
3578 unsigned __int8 v19; // zf@38 | |
3579 unsigned __int8 v20; // sf@38 | |
3580 int v21; // edx@44 | |
3581 int v22; // eax@44 | |
3582 unsigned __int8 v23; // zf@44 | |
3583 unsigned __int8 v24; // sf@44 | |
3584 int v25; // edx@51 | |
3585 int v26; // ecx@51 | |
3586 //signed int v27; // eax@51 | |
3587 //int v28; // eax@53 | |
3588 signed int v29; // eax@76 | |
3589 signed int v30; // eax@84 | |
3590 signed int v31; // eax@92 | |
3591 int v32; // eax@94 | |
3592 int v33; // eax@100 | 3579 int v33; // eax@100 |
3593 int v34; // eax@104 | |
3594 signed int v35; // eax@104 | |
3595 double v36; // st7@104 | |
3596 float v37; // ST08_4@104 | |
3597 float v38; // ST04_4@104 | |
3598 float v39; // ST00_4@104 | |
3599 int v40; // ebx@107 | 3580 int v40; // ebx@107 |
3600 unsigned int v41; // ebx@109 | 3581 int extraRecoveryTime; // qax@125 |
3601 signed __int64 v42; // qax@125 | |
3602 unsigned __int16 v43; // ax@132 | 3582 unsigned __int16 v43; // ax@132 |
3603 char v44; // bl@132 | |
3604 unsigned __int16 v45; // ax@132 | 3583 unsigned __int16 v45; // ax@132 |
3605 unsigned __int64 v46; // [sp+Ch] [bp-60h]@6 | 3584 unsigned __int64 v46; // [sp+Ch] [bp-60h]@6 |
3606 const char *v47; // [sp+14h] [bp-58h]@104 | |
3607 char *pPlayerName; // [sp+18h] [bp-54h]@12 | 3585 char *pPlayerName; // [sp+18h] [bp-54h]@12 |
3608 char *pMonsterName; // [sp+1Ch] [bp-50h]@6 | 3586 char *pMonsterName; // [sp+1Ch] [bp-50h]@6 |
3609 int v50; // [sp+20h] [bp-4Ch]@6 | |
3610 //unsigned __int64 *v51; // [sp+30h] [bp-3Ch]@6 | |
3611 int v52; // [sp+34h] [bp-38h]@12 | |
3612 //int v53; // [sp+38h] [bp-34h]@10 | |
3613 //int v54; // [sp+3Ch] [bp-30h]@1 | |
3614 //int v55; // [sp+40h] [bp-2Ch]@12 | |
3615 signed int a4; // [sp+44h] [bp-28h]@1 | 3587 signed int a4; // [sp+44h] [bp-28h]@1 |
3616 PlayerEquipment *v57; // [sp+48h] [bp-24h]@10 | 3588 bool IsAdditionalDamagePossible; // [sp+50h] [bp-1Ch]@1 |
3617 //int v58; // [sp+4Ch] [bp-20h]@10 | |
3618 int v59; // [sp+50h] [bp-1Ch]@1 | |
3619 unsigned int uActorID_Monster_; // [sp+54h] [bp-18h]@1 | |
3620 int v61; // [sp+58h] [bp-14h]@1 | 3589 int v61; // [sp+58h] [bp-14h]@1 |
3621 bool v62; // [sp+5Ch] [bp-10h]@1 | 3590 bool isLifeStealing; // [sp+5Ch] [bp-10h]@1 |
3622 int uDamageAmount; // [sp+60h] [bp-Ch]@1 | 3591 int uDamageAmount; // [sp+60h] [bp-Ch]@1 |
3623 int a2; // [sp+64h] [bp-8h]@27 | 3592 DAMAGE_TYPE attackElement; // [sp+64h] [bp-8h]@27 |
3624 int a3; // [sp+6Bh] [bp-1h]@6 | 3593 |
3625 | 3594 projectileSprite = 0; |
3626 //v3 = a1; | |
3627 v4 = 0; | |
3628 uActorID_Monster_ = uActorID_Monster; | |
3629 //v54 = a1; | |
3630 uDamageAmount = 0; | 3595 uDamageAmount = 0; |
3631 a4 = 0; | 3596 a4 = 0; |
3632 v61 = 0; | 3597 v61 = 0; |
3633 v59 = 0; | 3598 IsAdditionalDamagePossible = false; |
3634 v62 = 0; | 3599 isLifeStealing = 0; |
3635 if ( PID_TYPE(a1) == OBJECT_Item) | 3600 if ( PID_TYPE(a1) == OBJECT_Item) |
3636 { | 3601 { |
3637 v4 = &pSpriteObjects[PID_ID(a1)]; | 3602 projectileSprite = &pSpriteObjects[PID_ID(a1)]; |
3638 v61 = v4->field_60_distance_related_prolly_lod; | 3603 v61 = projectileSprite->field_60_distance_related_prolly_lod; |
3639 a1 = v4->spell_caster_pid; | 3604 a1 = projectileSprite->spell_caster_pid; |
3640 } | 3605 } |
3641 if (PID_TYPE(a1) != OBJECT_Player) | 3606 if (PID_TYPE(a1) != OBJECT_Player) |
3642 return; | 3607 return; |
3643 | 3608 |
3644 assert(PID_ID(abs(a1)) < 4); | 3609 assert(PID_ID(abs(a1)) < 4); |
3645 auto player = &pParty->pPlayers[PID_ID(a1)]; | 3610 Player* player = &pParty->pPlayers[PID_ID(a1)]; |
3646 pMonster = &pActors[uActorID_Monster_]; | 3611 pMonster = &pActors[uActorID_Monster]; |
3647 if (pMonster->IsNotAlive()) | 3612 if (pMonster->IsNotAlive()) |
3648 return; | 3613 return; |
3649 | 3614 |
3650 pMonster->uAttributes |= 0xC000; | 3615 pMonster->uAttributes |= 0xC000; |
3651 if ( pMonster->uAIState == Fleeing ) | 3616 if ( pMonster->uAIState == Fleeing ) |
3652 pMonster->uAttributes |= 0x20000u; | 3617 pMonster->uAttributes |= 0x20000u; |
3653 bool hit_will_stun = false, | 3618 bool hit_will_stun = false, |
3654 hit_will_paralyze = false; | 3619 hit_will_paralyze = false; |
3655 if ( !v4 ) | 3620 if ( !projectileSprite ) |
3656 { | 3621 { |
3657 int main_hand_idx = player->pEquipment.uMainHand; | 3622 int main_hand_idx = player->pEquipment.uMainHand; |
3658 v59 = 1; | 3623 IsAdditionalDamagePossible = true; |
3659 if ( player->HasItemEquipped(EQUIP_MAIN_HAND) ) | 3624 if ( player->HasItemEquipped(EQUIP_MAIN_HAND) ) |
3660 { | 3625 { |
3661 auto main_hand_skill = player->GetMainHandItem()->GetPlayerSkillType(); | 3626 uint main_hand_skill = player->GetMainHandItem()->GetPlayerSkillType(); |
3662 auto main_hand_mastery = SkillToMastery(player->pActiveSkills[main_hand_skill]); | 3627 uint main_hand_mastery = SkillToMastery(player->pActiveSkills[main_hand_skill]); |
3663 switch (main_hand_skill) | 3628 switch (main_hand_skill) |
3664 { | 3629 { |
3665 case PLAYER_SKILL_STAFF: | 3630 case PLAYER_SKILL_STAFF: |
3666 if (main_hand_mastery >= 3) | 3631 if (main_hand_mastery >= 3) |
3667 { | 3632 { |
3682 hit_will_paralyze = true; | 3647 hit_will_paralyze = true; |
3683 } | 3648 } |
3684 break; | 3649 break; |
3685 } | 3650 } |
3686 } | 3651 } |
3687 v50 = pMonster->pMonsterInfo.uID; | 3652 attackElement = DMGT_PHISYCAL; |
3688 a2 = 4; | 3653 uDamageAmount = player->CalculateMeleeDamageTo(false, false, pMonster->pMonsterInfo.uID); |
3689 uDamageAmount = player->CalculateMeleeDamageTo(false, false, v50); | |
3690 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) | 3654 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) |
3691 { | 3655 { |
3692 player->PlaySound(SPEECH_52, 0); | 3656 player->PlaySound(SPEECH_52, 0); |
3693 return; | 3657 return; |
3694 } | 3658 } |
3695 } | 3659 } |
3696 else | 3660 else |
3697 { | 3661 { |
3698 v19 = v4->spell_id == SPELL_DARK_SOULDRINKER; | 3662 v61 = projectileSprite->field_60_distance_related_prolly_lod; |
3699 v61 = v4->field_60_distance_related_prolly_lod; | 3663 if ( projectileSprite->spell_id != SPELL_DARK_SOULDRINKER ) |
3700 if ( !v19 ) | 3664 { |
3701 { | 3665 std::array<int, 3> distances; |
3702 v50 = pParty->vPosition.x - v4->vPosition.x; | 3666 distances[0] = abs(pParty->vPosition.x - projectileSprite->vPosition.x); |
3703 pMonsterName = (char *)(pParty->vPosition.y - v4->vPosition.y); | 3667 distances[1] = abs(pParty->vPosition.y - projectileSprite->vPosition.y); |
3704 pPlayerName = (char *)(pParty->vPosition.z - v4->vPosition.z); | 3668 distances[2] = abs(pParty->vPosition.z - projectileSprite->vPosition.z); |
3705 v52 = abs((int)pPlayerName); | 3669 std::sort(distances.begin(), distances.end()); |
3706 v61 = abs(v50); | 3670 v61 = ((unsigned int)(11 * distances[1]) >> 5) + (distances[0] >> 2) + distances[2]; |
3707 v10 = abs(v50); | 3671 |
3708 v11 = (int)abs((int)pMonsterName); | 3672 if ( v61 >= 5120 && !(BYTE1(pMonster->uAttributes) & 4) ) |
3709 v12 = v52; | 3673 { |
3710 if ( v10 < v11) | 3674 return; |
3711 { | 3675 } |
3712 v10 = (int)v11; | 3676 else if ( v61 >= 2560 ) |
3713 v11 = v10; | 3677 { |
3714 } | |
3715 if ( v10 < v52 ) | |
3716 { | |
3717 v13 = v10; | |
3718 v10 = v52; | |
3719 v12 = v13; | |
3720 } | |
3721 if ( v11 < (signed int)v12 ) | |
3722 { | |
3723 v14 = v12; | |
3724 v12 = v11; | |
3725 v11 = v14; | |
3726 } | |
3727 v61 = ((unsigned int)(11 * v11) >> 5) + (v12 >> 2) + v10; | |
3728 if ( v61 >= 2560 ) | |
3729 { | |
3730 if ( v61 >= 5120 && !(BYTE1(pMonster->uAttributes) & 4) ) | |
3731 return; | |
3732 v61 = 2; | 3678 v61 = 2; |
3733 } | 3679 } |
3734 else | 3680 else |
3735 { | 3681 { |
3736 v61 = 1; | 3682 v61 = 1; |
3737 } | 3683 } |
3738 } | 3684 } |
3739 | 3685 |
3740 switch (v4->spell_id) | 3686 switch (projectileSprite->spell_id) |
3741 { | 3687 { |
3742 case SPELL_LASER_PROJECTILE: | 3688 case SPELL_LASER_PROJECTILE: |
3743 v16 = player->pActiveSkills[7]; | 3689 v16 = player->pActiveSkills[PLAYER_SKILL_BLASTER]; |
3744 v61 = 1; | 3690 v61 = 1; |
3745 if ( (signed int)SkillToMastery(v16) >= 3 ) | 3691 if ( (signed int)SkillToMastery(v16) >= 3 ) |
3746 a4 = player->pActiveSkills[7] & 0x3F; | 3692 a4 = player->pActiveSkills[PLAYER_SKILL_BLASTER] & 0x3F; |
3747 a2 = 4; | 3693 attackElement = DMGT_PHISYCAL; |
3748 uDamageAmount = player->CalculateMeleeDamageTo(true, true, 0); | 3694 uDamageAmount = player->CalculateMeleeDamageTo(true, true, 0); |
3749 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) | 3695 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) |
3750 { | 3696 { |
3751 player->PlaySound(SPEECH_52, 0); | 3697 player->PlaySound(SPEECH_52, 0); |
3752 return; | 3698 return; |
3753 } | 3699 } |
3754 break; | 3700 break; |
3755 case SPELL_101: | 3701 case SPELL_101: |
3756 a2 = 0; | 3702 attackElement = DMGT_FIRE; |
3757 v18 = player->CalculateRangedDamageTo(0); | 3703 uDamageAmount = player->CalculateRangedDamageTo(0); |
3758 v19 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0; | 3704 if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 ) |
3759 v20 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0; | |
3760 uDamageAmount = v18; | |
3761 if ( !v20 && (!(v20 | v19) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) ) | |
3762 uDamageAmount >>= 1; | 3705 uDamageAmount >>= 1; |
3763 v59 = 1; | 3706 IsAdditionalDamagePossible = true; |
3764 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) | 3707 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) |
3765 { | 3708 { |
3766 player->PlaySound(SPEECH_52, 0); | 3709 player->PlaySound(SPEECH_52, 0); |
3767 return; | 3710 return; |
3768 } | 3711 } |
3769 break; | 3712 break; |
3770 case SPELL_EARTH_BLADES: | 3713 case SPELL_EARTH_BLADES: |
3771 a4 = 5 * v4->spell_level; | 3714 a4 = 5 * projectileSprite->spell_level; |
3772 a2 = player->GetSpellSchool(0x27u); | 3715 attackElement = (DAMAGE_TYPE)player->GetSpellSchool(SPELL_EARTH_BLADES); |
3773 v21 = v4->spell_level; | 3716 uDamageAmount = _43AFE3_calc_spell_damage(39, projectileSprite->spell_level, projectileSprite->spell_skill, pMonster->sCurrentHP); |
3774 v50 = pMonster->sCurrentHP; | 3717 if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 ) |
3775 pMonsterName = (char *)v4->spell_skill; | |
3776 v22 = _43AFE3_calc_spell_damage(39, v21, v4->spell_skill, v50); | |
3777 v23 = HIDWORD(pMonster->pActorBuffs[15].uExpireTime) == 0; | |
3778 v24 = SHIDWORD(pMonster->pActorBuffs[15].uExpireTime) < 0; | |
3779 uDamageAmount = v22; | |
3780 if ( !v24 && (!(v24 | v23) || LODWORD(pMonster->pActorBuffs[15].uExpireTime)) ) | |
3781 uDamageAmount >>= 1; | 3718 uDamageAmount >>= 1; |
3782 v59 = 0; | 3719 IsAdditionalDamagePossible = false; |
3783 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) | 3720 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) |
3784 { | 3721 { |
3785 player->PlaySound(SPEECH_52, 0); | 3722 player->PlaySound(SPEECH_52, 0); |
3786 return; | 3723 return; |
3787 } | 3724 } |
3788 break; | 3725 break; |
3789 case SPELL_EARTH_STUN: | 3726 case SPELL_EARTH_STUN: |
3790 uDamageAmount = 0; | 3727 uDamageAmount = 0; |
3791 a2 = 4; | 3728 attackElement = DMGT_PHISYCAL; |
3792 hit_will_stun = 1; | 3729 hit_will_stun = 1; |
3793 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) | 3730 if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) |
3794 { | 3731 { |
3795 player->PlaySound(SPEECH_52, 0); | 3732 player->PlaySound(SPEECH_52, 0); |
3796 return; | 3733 return; |
3797 } | 3734 } |
3798 break; | 3735 break; |
3799 case SPELL_BOW_ARROW: | 3736 case SPELL_BOW_ARROW: |
3800 v50 = pMonster->word_000086_some_monster_id; | 3737 attackElement = DMGT_PHISYCAL; |
3801 a2 = 4; | 3738 uDamageAmount = player->CalculateRangedDamageTo(pMonster->word_000086_some_monster_id); |
3802 uDamageAmount = player->CalculateRangedDamageTo(v50); | |
3803 if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 ) | 3739 if ( pMonster->pActorBuffs[ACTOR_BUFF_SHIELD].uExpireTime > 0 ) |
3804 uDamageAmount /= 2; | 3740 uDamageAmount /= 2; |
3805 v59 = 1; | 3741 IsAdditionalDamagePossible = true; |
3806 if ( v4->stru_24.uItemID != 0 && v4->stru_24.uSpecEnchantmentType == 3 ) //of carnage | 3742 if ( projectileSprite->stru_24.uItemID != 0 && projectileSprite->stru_24.uSpecEnchantmentType == 3 ) //of carnage |
3807 { | 3743 { |
3808 a2 = 0; | 3744 attackElement = DMGT_FIRE; |
3809 } | 3745 } |
3810 else if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) | 3746 else if ( !stru_50C198.PlayerHitOrMiss(player, pMonster, v61, a4) ) |
3811 { | 3747 { |
3812 player->PlaySound(SPEECH_52, 0); | 3748 player->PlaySound(SPEECH_52, 0); |
3813 return; | 3749 return; |
3814 } | 3750 } |
3815 break; | 3751 break; |
3816 | 3752 |
3817 default: | 3753 default: |
3818 a2 = player->GetSpellSchool(v4->spell_id); | 3754 attackElement = (DAMAGE_TYPE)player->GetSpellSchool(projectileSprite->spell_id); |
3819 v25 = v4->spell_level; | 3755 IsAdditionalDamagePossible = false; |
3820 v26 = v4->spell_id; | 3756 uDamageAmount = _43AFE3_calc_spell_damage(projectileSprite->spell_id, projectileSprite->spell_level, projectileSprite->spell_skill, pMonster->sCurrentHP); |
3821 v50 = pMonster->sCurrentHP; | |
3822 pMonsterName = (char *)v4->spell_skill; | |
3823 v59 = 0; | |
3824 uDamageAmount = _43AFE3_calc_spell_damage(v26, v25, v4->spell_skill, v50); | |
3825 break; | 3757 break; |
3826 } | 3758 } |
3827 } | 3759 } |
3828 | 3760 |
3829 if (player->IsWeak()) | 3761 if (player->IsWeak()) |
3830 uDamageAmount /= 2; | 3762 uDamageAmount /= 2; |
3831 if ( pMonster->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 ) | 3763 if ( pMonster->pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 ) |
3832 uDamageAmount = 0; | 3764 uDamageAmount = 0; |
3833 v61 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, uDamageAmount); | 3765 v61 = stru_50C198.CalcMagicalDamageToActor(pMonster, attackElement, uDamageAmount); |
3834 if ( !v4 && player->IsUnarmed() && player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime > 0 ) | 3766 if ( !projectileSprite && player->IsUnarmed() && player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uExpireTime > 0 ) |
3835 { | 3767 { |
3836 v50 = player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uPower; | 3768 v61 += stru_50C198.CalcMagicalDamageToActor(pMonster, 8, player->pPlayerBuffs[PLAYER_BUFF_HAMMERHANDS].uPower); |
3837 v29 = stru_50C198.CalcMagicalDamageToActor(pMonster, 8, v50); | |
3838 v61 += v29; | |
3839 } | 3769 } |
3840 uDamageAmount = v61; | 3770 uDamageAmount = v61; |
3841 if ( v59 ) | 3771 if ( IsAdditionalDamagePossible ) |
3842 { | 3772 { |
3843 if ( v4 ) | 3773 if ( projectileSprite ) |
3844 { | 3774 { |
3845 a4 = v4->stru_24._439DF3_get_additional_damage(&a2, &v62); | 3775 a4 = projectileSprite->stru_24._439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing); |
3846 if ( v62 && pMonster->sCurrentHP > 0 ) | 3776 if ( isLifeStealing && pMonster->sCurrentHP > 0 ) |
3847 { | 3777 { |
3848 player->sHealth += v61 / 5; | 3778 player->sHealth += v61 / 5; |
3849 if ( player->sHealth > player->GetMaxHealth() ) | 3779 if ( player->sHealth > player->GetMaxHealth() ) |
3850 player->sHealth = player->GetMaxHealth(); | 3780 player->sHealth = player->GetMaxHealth(); |
3851 v62 = 0; | 3781 } |
3852 } | 3782 uDamageAmount += stru_50C198.CalcMagicalDamageToActor(pMonster, attackElement, a4); |
3853 v30 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4); | |
3854 uDamageAmount = v61 + v30; | |
3855 } | 3783 } |
3856 else | 3784 else |
3857 { | 3785 { |
3858 v59 = 0; | 3786 for (int i = 0; i < 2; i++) |
3859 v57 = &player->pEquipment; | 3787 { |
3860 do | 3788 if ( player->HasItemEquipped((ITEM_EQUIP_TYPE)i) ) |
3861 { | |
3862 if ( player->HasItemEquipped((ITEM_EQUIP_TYPE)v59) ) | |
3863 { | 3789 { |
3864 auto _s = (ItemGen *)&player->pInventoryItemList[v57->uShield - 1]; | 3790 ItemGen* item; |
3865 a4 = _s->_439DF3_get_additional_damage(&a2, &v62); | 3791 if (i == 0) |
3866 if ( v62 && pMonster->sCurrentHP > 0 ) | 3792 item = player->GetMainHandItem(); |
3793 else | |
3794 item = player->GetOffHandItem(); | |
3795 a4 = item->_439DF3_get_additional_damage((int*)&attackElement, &isLifeStealing); | |
3796 if ( isLifeStealing && pMonster->sCurrentHP > 0 ) | |
3867 { | 3797 { |
3868 player->sHealth += v61 / 5; | 3798 player->sHealth += v61 / 5; |
3869 if ( player->sHealth > player->GetMaxHealth() ) | 3799 if ( player->sHealth > player->GetMaxHealth() ) |
3870 player->sHealth = player->GetMaxHealth(); | 3800 player->sHealth = player->GetMaxHealth(); |
3871 v62 = 0; | |
3872 } | 3801 } |
3873 v31 = stru_50C198.CalcMagicalDamageToActor(pMonster, a2, a4); | 3802 uDamageAmount += stru_50C198.CalcMagicalDamageToActor(pMonster, attackElement, a4); |
3874 uDamageAmount += v31; | |
3875 } | 3803 } |
3876 ++v59; | 3804 } |
3877 v57 = (PlayerEquipment *)((char *)v57 + 4); | 3805 } |
3878 } | 3806 } |
3879 while ( v59 <= 1 ); | |
3880 } | |
3881 } | |
3882 v32 = uDamageAmount; | |
3883 pMonster->sCurrentHP -= uDamageAmount; | 3807 pMonster->sCurrentHP -= uDamageAmount; |
3884 if ( !v32 && !hit_will_stun ) | 3808 if ( uDamageAmount == 0 && !hit_will_stun ) |
3885 { | 3809 { |
3886 player->PlaySound(SPEECH_52, 0); | 3810 player->PlaySound(SPEECH_52, 0); |
3887 return; | 3811 return; |
3888 } | 3812 } |
3889 if ( pMonster->sCurrentHP > 0 ) | 3813 if ( pMonster->sCurrentHP > 0 ) |
3890 { | 3814 { |
3891 Actor::AI_Stun(uActorID_Monster_, a1, 0); | 3815 Actor::AI_Stun(uActorID_Monster, a1, 0); |
3892 Actor::AggroSurroundingPeasants(uActorID_Monster_, 1); | 3816 Actor::AggroSurroundingPeasants(uActorID_Monster, 1); |
3893 if ( bShowDamage ) | 3817 if ( bShowDamage ) |
3894 { | 3818 { |
3895 v50 = uDamageAmount; | 3819 if ( projectileSprite ) |
3896 pMonsterName = (char *)pMonster; | 3820 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[189], player->pName, pMonster->pActorName, uDamageAmount);// "%s shoots %s for %lu points" |
3897 pPlayerName = player->pName; | |
3898 if ( v4 ) | |
3899 v47 = pGlobalTXT_LocalizationStrings[189];// "%s shoots %s for %lu points" | |
3900 else | 3821 else |
3901 v47 = pGlobalTXT_LocalizationStrings[164];// "%s hits %s for %lu damage" | 3822 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[164], player->pName, pMonster->pActorName, uDamageAmount);// "%s hits %s for %lu damage" |
3902 sprintfex(pTmpBuf.data(), v47, pPlayerName, pMonsterName, v50); | |
3903 ShowStatusBarString(pTmpBuf.data(), 2u); | 3823 ShowStatusBarString(pTmpBuf.data(), 2u); |
3904 } | 3824 } |
3905 v41 = 0; | |
3906 } | 3825 } |
3907 else | 3826 else |
3908 { | 3827 { |
3909 if ( pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].bQuestMonster & 1 ) | 3828 if ( pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].bQuestMonster & 1 ) |
3910 { | 3829 { |
3911 v33 = byte_4D864C && BYTE2(pGame->uFlags) & 8 ? 10 * pMonster->uActorRadius : pMonster->uActorRadius; | 3830 if ( pRenderer->pRenderD3D && pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS ) |
3912 //v55 = v33; | 3831 { |
3913 if ( pRenderer->pRenderD3D ) | 3832 v33 = byte_4D864C && pGame->uFlags & 80000 ? 10 * pMonster->uActorRadius : pMonster->uActorRadius; |
3914 { | 3833 pDecalBuilder->AddBloodsplat((float)pMonster->vPosition.x, (float)pMonster->vPosition.y, (float)pMonster->vPosition.z, 1.0, 0.0, 0.0, (float)v33, 0, 0); |
3915 if ( pGame->uFlags2 & GAME_FLAGS_2_DRAW_BLOODSPLATS ) | 3834 } |
3916 { | 3835 } |
3917 v50 = 0; | 3836 Actor::Die(uActorID_Monster); |
3918 pMonsterName = 0; | 3837 Actor::ApplyFineForKillingPeasant(uActorID_Monster); |
3919 v34 = pMonster->vPosition.z; | 3838 Actor::AggroSurroundingPeasants(uActorID_Monster, 1); |
3920 *(float *)&pPlayerName = (double)v33; | |
3921 //v51 = (unsigned __int64 *)v34; | |
3922 *(float *)&v47 = 0.0; | |
3923 v35 = pMonster->vPosition.y; | |
3924 *((float *)&v46 + 1) = 0.0; | |
3925 *(float *)&v46 = 1.0; | |
3926 v36 = (double)(signed int)pMonster->vPosition.z; | |
3927 //v51 = (unsigned __int64 *)v35; | |
3928 v37 = v36; | |
3929 //v51 = (unsigned __int64 *)pMonster->vPosition.x; | |
3930 v38 = (double)v35; | |
3931 v39 = (double)(signed int)pMonster->vPosition.x; | |
3932 pDecalBuilder->AddBloodsplat(v39, v38, v37, 1.0, 0.0, 0.0, *(float *)&pPlayerName, 0, 0); | |
3933 } | |
3934 } | |
3935 } | |
3936 Actor::Die(uActorID_Monster_); | |
3937 Actor::ApplyFineForKillingPeasant(uActorID_Monster_); | |
3938 Actor::AggroSurroundingPeasants(uActorID_Monster_, 1); | |
3939 if ( pMonster->pMonsterInfo.uExp ) | 3839 if ( pMonster->pMonsterInfo.uExp ) |
3940 pParty->GivePartyExp(pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].uExp); | 3840 pParty->GivePartyExp(pMonsterStats->pInfos[pMonster->pMonsterInfo.uID].uExp); |
3941 v40 = SPEECH_51; | 3841 v40 = SPEECH_51; |
3942 if ( rand() % 100 < 20 ) | 3842 if ( rand() % 100 < 20 ) |
3943 v40 = ((signed int)pMonster->pMonsterInfo.uHP >= 100) + 1; | 3843 v40 = ((signed int)pMonster->pMonsterInfo.uHP >= 100) + 1; |
3944 player->PlaySound((PlayerSpeech)v40, 0); | 3844 player->PlaySound((PlayerSpeech)v40, 0); |
3945 v41 = 0; | |
3946 if ( bShowDamage ) | 3845 if ( bShowDamage ) |
3947 { | 3846 { |
3948 v50 = (int)pMonster; | |
3949 pMonsterName = (char *)uDamageAmount; | 3847 pMonsterName = (char *)uDamageAmount; |
3950 pPlayerName = player->pName; // "%s inflicts %lu points killing %s" | 3848 pPlayerName = player->pName; // "%s inflicts %lu points killing %s" |
3951 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[175], player->pName, uDamageAmount, pMonster); | 3849 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[175], player->pName, uDamageAmount, pMonster); |
3952 ShowStatusBarString(pTmpBuf.data(), 2u); | 3850 ShowStatusBarString(pTmpBuf.data(), 2u); |
3953 } | 3851 } |
3954 } | 3852 } |
3955 if ( SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) >= (signed int)v41 | 3853 if ( pMonster->pActorBuffs[ACTOR_BUFF_PAIN_REFLECTION].uExpireTime > 0 |
3956 && (SHIDWORD(pMonster->pActorBuffs[20].uExpireTime) > (signed int)v41 | 3854 && uDamageAmount != 0 ) |
3957 || LODWORD(pMonster->pActorBuffs[20].uExpireTime) > v41) | 3855 player->ReceiveDamage(uDamageAmount, attackElement); |
3958 && uDamageAmount != v41 ) | 3856 int knockbackValue = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP; |
3959 player->ReceiveDamage(uDamageAmount, (DAMAGE_TYPE)a2); | 3857 if ( (player->GetSpecialItemBonus(24) || hit_will_stun) && stru_50C198.GetMagicalResistance(pMonster, DMGT_EARTH) ) |
3960 v50 = 24; | 3858 { |
3961 v59 = 20 * v61 / (signed int)pMonster->pMonsterInfo.uHP; | 3859 extraRecoveryTime = 20; |
3962 if ( (player->GetSpecialItemBonus(24) || hit_will_stun != v41) | 3860 knockbackValue = 10; |
3963 && stru_50C198.GetMagicalResistance(pMonster, 3u) ) | 3861 if ( !pParty->bTurnBasedModeOn ) |
3964 { | 3862 extraRecoveryTime = (int)(flt_6BE3A8_debug_recmod2 * 42.66666666666666); |
3965 LODWORD(v42) = 20; | 3863 pMonster->pMonsterInfo.uRecoveryTime += extraRecoveryTime; |
3966 v59 = 10; | 3864 if ( bShowDamage ) |
3967 if ( pParty->bTurnBasedModeOn == v41 ) | 3865 { |
3968 v42 = (signed __int64)(flt_6BE3A8_debug_recmod2 * 42.66666666666666); | |
3969 pMonster->pMonsterInfo.uRecoveryTime += v42; | |
3970 if ( bShowDamage != v41 ) | |
3971 { | |
3972 v50 = (int)pMonster; | |
3973 pMonsterName = player->pName; // "%s stuns %s" | 3866 pMonsterName = player->pName; // "%s stuns %s" |
3974 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[635], player->pName, pMonster); | 3867 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[635], player->pName, pMonster); |
3975 ShowStatusBarString(pTmpBuf.data(), 2u); | 3868 ShowStatusBarString(pTmpBuf.data(), 2u); |
3976 } | 3869 } |
3977 } | 3870 } |
3978 if ( hit_will_paralyze != v41 ) | 3871 if ( hit_will_paralyze && pMonster->CanAct() && stru_50C198.GetMagicalResistance(pMonster, DMGT_EARTH)) |
3979 { | 3872 { |
3980 if ( pMonster->CanAct() ) | 3873 v43 = player->GetActualSkillLevel(PLAYER_SKILL_MACE); |
3981 { | 3874 v45 = SkillToMastery(v43); |
3982 if ( stru_50C198.GetMagicalResistance(pMonster, 3) ) | 3875 v46 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(7680 * (v43 & 0x3F)) * 0.033333335); |
3983 { | 3876 pMonster->pActorBuffs[ACTOR_BUFF_PARALYZED].Apply(v46, v45, 0, 0, 0); |
3984 LOBYTE(v43) = player->GetActualSkillLevel(PLAYER_SKILL_MACE); | 3877 if ( bShowDamage ) |
3985 v44 = v43; | 3878 { |
3986 v45 = SkillToMastery(v43); | 3879 pMonsterName = player->pName; // "%s paralyzes %s" |
3987 //v51 = (unsigned __int64 *)(7680 * (v44 & 0x3F)); | 3880 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[636], player->pName, pMonster); |
3988 v46 = pParty->uTimePlayed + (signed int)(signed __int64)((double)(signed int)(7680 * (v44 & 0x3F)) * 0.033333335); | 3881 ShowStatusBarString(pTmpBuf.data(), 2u); |
3989 pMonster->pActorBuffs[6].Apply(v46, v45, 0, 0, 0); | 3882 } |
3990 if ( bShowDamage ) | 3883 } |
3991 { | 3884 if ( knockbackValue > 10 ) |
3992 v50 = (int)pMonster; | 3885 knockbackValue = 10; |
3993 pMonsterName = player->pName; // "%s paralyzes %s" | |
3994 sprintfex(pTmpBuf.data(), pGlobalTXT_LocalizationStrings[636], player->pName, pMonster); | |
3995 ShowStatusBarString(pTmpBuf.data(), 2u); | |
3996 } | |
3997 } | |
3998 } | |
3999 } | |
4000 if ( v59 > 10 ) | |
4001 v59 = 10; | |
4002 if ( !MonsterStats::BelongsToSupertype(pMonster->pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) ) | 3886 if ( !MonsterStats::BelongsToSupertype(pMonster->pMonsterInfo.uID, MONSTER_SUPERTYPE_TREANT) ) |
4003 { | 3887 { |
4004 pVelocity->x = (unsigned __int64)(v59 * (signed __int64)pVelocity->x) >> 16; | 3888 pVelocity->x = (unsigned __int64)(knockbackValue * (signed __int64)pVelocity->x) >> 16; |
4005 pVelocity->y = (unsigned __int64)(v59 * (signed __int64)pVelocity->y) >> 16; | 3889 pVelocity->y = (unsigned __int64)(knockbackValue * (signed __int64)pVelocity->y) >> 16; |
4006 pVelocity->z = (unsigned __int64)(v59 * (signed __int64)pVelocity->z) >> 16; | 3890 pVelocity->z = (unsigned __int64)(knockbackValue * (signed __int64)pVelocity->z) >> 16; |
4007 pMonster->vVelocity.x = 50 * LOWORD(pVelocity->x); | 3891 pMonster->vVelocity.x = 50 * LOWORD(pVelocity->x); |
4008 pMonster->vVelocity.y = 50 * LOWORD(pVelocity->y); | 3892 pMonster->vVelocity.y = 50 * LOWORD(pVelocity->y); |
4009 pMonster->vVelocity.z = 50 * LOWORD(pVelocity->z); | 3893 pMonster->vVelocity.z = 50 * LOWORD(pVelocity->z); |
4010 } | 3894 } |
4011 Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster_, 1, v61); | 3895 Actor::AddBloodsplatOnDamageOverlay(uActorID_Monster, 1, v61); |
4012 } | 3896 } |
4013 //----- (004BBF61) -------------------------------------------------------- | 3897 //----- (004BBF61) -------------------------------------------------------- |
4014 void __fastcall _4BBF61_summon_actor(int a1, __int16 x, int y, int z) | 3898 void Actor::_4BBF61_summon_actor( int a1, __int16 x, int y, int z ) |
4015 { | 3899 { |
4016 size_t v4; // esi@1 | |
4017 int monster_id; // edi@1 | |
4018 __int16 v6; // ax@4 | |
4019 Actor *v7; // esi@5 | 3900 Actor *v7; // esi@5 |
4020 int v8; // eax@5 | |
4021 MonsterInfo *v9; // edi@5 | 3901 MonsterInfo *v9; // edi@5 |
4022 MonsterDesc *v10; // ebx@5 | 3902 MonsterDesc *v10; // ebx@5 |
4023 unsigned __int16 *v11; // ebx@5 | |
4024 int v12; // ebx@7 | 3903 int v12; // ebx@7 |
4025 int v13; // eax@8 | 3904 int v13; // eax@8 |
4026 __int16 x_; // [sp+8h] [bp-Ch]@1 | |
4027 __int16 v15; // [sp+Ch] [bp-8h]@1 | |
4028 __int16 v16; // [sp+10h] [bp-4h]@3 | 3905 __int16 v16; // [sp+10h] [bp-4h]@3 |
4029 signed int ya; // [sp+1Ch] [bp+8h]@5 | 3906 |
4030 | |
4031 v4 = uNumActors; | |
4032 monster_id = a1; | |
4033 x_ = x; | |
4034 v15 = a1; | |
4035 if (uNumActors < 500) | 3907 if (uNumActors < 500) |
4036 { | 3908 { |
4037 v16 = 0; | 3909 v16 = 0; |
4038 if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) | 3910 if ( uCurrentlyLoadedLevelType == LEVEL_Indoor ) |
4039 { | 3911 { |
4040 v6 = pIndoor->GetSector(x, y, z); | 3912 v16 = pIndoor->GetSector(x, y, z); |
4041 v4 = uNumActors; | 3913 } |
4042 v16 = v6; | 3914 v7 = &pActors[uNumActors]; |
4043 } | |
4044 v7 = &pActors[v4]; | |
4045 v7->Reset(); | 3915 v7->Reset(); |
4046 v8 = monster_id; | 3916 v9 = &pMonsterStats->pInfos[a1]; |
4047 v9 = &pMonsterStats->pInfos[monster_id]; | 3917 v10 = &pMonsterList->pMonsters[a1 - 1]; |
4048 v10 = &pMonsterList->pMonsters[v8 - 1]; | |
4049 strcpy(v7->pActorName, v9->pName); | 3918 strcpy(v7->pActorName, v9->pName); |
4050 v7->sCurrentHP = LOWORD(v9->uHP); | 3919 v7->sCurrentHP = LOWORD(v9->uHP); |
4051 memcpy(&v7->pMonsterInfo, v9, 0x58u); | 3920 memcpy(&v7->pMonsterInfo, v9, 0x58u); |
4052 v7->word_000086_some_monster_id = v15; | 3921 v7->word_000086_some_monster_id = a1; |
4053 v7->uActorRadius = v10->uMonsterRadius; | 3922 v7->uActorRadius = v10->uMonsterRadius; |
4054 v7->uActorHeight = v10->uMonsterHeight; | 3923 v7->uActorHeight = v10->uMonsterHeight; |
4055 v7->uMovementSpeed = v10->uMovementSpeed; | 3924 v7->uMovementSpeed = v10->uMovementSpeed; |
4056 v7->vInitialPosition.x = x_; | 3925 v7->vInitialPosition.x = x; |
4057 v7->vPosition.x = x_; | 3926 v7->vPosition.x = x; |
4058 BYTE2(v7->uAttributes) |= 8u; | 3927 v7->uAttributes |= 80000; |
4059 v7->pMonsterInfo.uTreasureType = 0; | 3928 v7->pMonsterInfo.uTreasureType = 0; |
4060 v7->pMonsterInfo.uTreasureLevel = 0; | 3929 v7->pMonsterInfo.uTreasureLevel = 0; |
4061 v7->pMonsterInfo.uTreasureDiceSides = 0; | 3930 v7->pMonsterInfo.uTreasureDiceSides = 0; |
4062 v7->pMonsterInfo.uTreasureDiceRolls = 0; | 3931 v7->pMonsterInfo.uTreasureDiceRolls = 0; |
4063 v7->pMonsterInfo.uTreasureDropChance = 0; | 3932 v7->pMonsterInfo.uTreasureDropChance = 0; |
4068 v7->uTetherDistance = 256; | 3937 v7->uTetherDistance = 256; |
4069 v7->uSectorID = v16; | 3938 v7->uSectorID = v16; |
4070 v7->uGroup = 1; | 3939 v7->uGroup = 1; |
4071 v7->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long; | 3940 v7->pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Long; |
4072 v7->PrepareSprites(0); | 3941 v7->PrepareSprites(0); |
4073 v11 = v10->pSoundSampleIDs; | 3942 for ( int i = 0; i < 4; i++) |
4074 ya = 4; | 3943 { |
4075 do | 3944 pSoundList->LoadSound(v10->pSoundSampleIDs[i], 0); |
4076 { | 3945 } |
4077 pSoundList->LoadSound((signed __int16)*v11, 0); | |
4078 ++v11; | |
4079 --ya; | |
4080 } | |
4081 while ( ya ); | |
4082 v12 = 0; | 3946 v12 = 0; |
4083 do | 3947 do |
4084 LOWORD(v13) = pSoundList->LoadSound(v12++ + word_4EE088_sound_ids[v9->uSpell1ID], 1u); | 3948 { |
3949 LOWORD(v13) = pSoundList->LoadSound(v12 + word_4EE088_sound_ids[v9->uSpell1ID], 1u); | |
3950 v12++; | |
3951 } | |
4085 while ( v13 ); | 3952 while ( v13 ); |
4086 ++uNumActors; | 3953 ++uNumActors; |
4087 } | 3954 } |
4088 } | 3955 } |
4089 //----- (00426E10) -------------------------------------------------------- | 3956 //----- (00426E10) -------------------------------------------------------- |