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) --------------------------------------------------------