キル時経験値の処理GetFinalExp

Last-modified: 2022-06-02 (木) 17:51:25

関数名や引数はプログラム側に残されたものを復元していますが
変数名は可読性をあげるために解析時につけたものになります

整理版はおおまかに処理がわかるようにエラーチェックやログ出力などをざっくり適当に削除しています

GetFinalExp整理版

void MobaBattleModule.Property.L.LPropertySys$$GetFinalExp
               (int32_t exp,int32_t src,MobaBattleModule_Property_L_LPropertySysComp_o *sysComp,
               MobaBattleModule_Property_L_EntityPropertyComp_o *propertyComp,int32_t killedEntityId,int32_t *finalExp,int32_t *expFromStorage,
               MethodInfo *method)

{
    if (bVar1 == false) {
        //キルした相手とのレベル差補正
        expRaw = MobaBattleModule.Property.L.LPropertySys$$CalculateExpAfterKillLevelDiffAddition
                           (src,sysComp,exp,propertyComp,killedEntityId,in_stack_ffffffc4);

        //最もレベルが高いプレイヤーとのレベル差補正
        expRaw = MobaBattleModule.Property.L.LPropertySys$$CalculateExpIncludingCompensation
                           (sysComp,expRaw,(propertyComp->fields).mLevel,&expExtra,(MethodInfo *)killedEntityId);

        //最もレベルが高いプレイヤーとのレベル差補正で加算された経験値を記録(他所では使われてないっぽい)
        MobaBattleModule.Stat.L.LBattleStatUtil$$AccCompensationExp((propertyComp->fields).super.EntityId,expExtra,(MethodInfo *)0x0);

        *finalExp = expRaw;

        //ストレージExp補正
        expRaw = MobaBattleModule.Property.L.LPropertySys$$GetConversionStorageExp(propertyComp,expRaw,method_00);
        *expFromStorage = expRaw;
    }
    return;

原文

void MobaBattleModule.Property.L.LPropertySys$$GetFinalExp
               (int32_t exp,int32_t src,MobaBattleModule_Property_L_LPropertySysComp_o *sysComp,
               MobaBattleModule_Property_L_EntityPropertyComp_o *propertyComp,int32_t killedEntityId,int32_t *finalExp,int32_t *expFromStorage,
               MethodInfo *method)

{
    bool bVar1;
    IFix_ILFixDynamicMethodWrapper_3_o *__this;
    int32_t expRaw;
    MethodInfo *method_00;
    MethodInfo *in_stack_ffffffc4;
    int32_t expExtra;

    if (DAT_065270cb == '\0') {
        thunk_FUN_0109b1b8(0xb2f2);
        DAT_065270cb = '\x01';
    }
    expExtra = 0;
    bVar1 = IFix.WrappersManagerImpl$$IsPatched(0xb75,(MethodInfo *)0x0);
    if (bVar1 == false) {
        if ((((MobaBattleModule.Property.L.LPropertySys_TypeInfo->_2).minimumAlignment & 2) != 0) &&
           (*(int *)&(MobaBattleModule.Property.L.LPropertySys_TypeInfo->_2).field_0x14 == 0)) {
            lua_error();
        }
        //キルした相手とのレベル差補正
        expRaw = MobaBattleModule.Property.L.LPropertySys$$CalculateExpAfterKillLevelDiffAddition
                           (src,sysComp,exp,propertyComp,killedEntityId,in_stack_ffffffc4);
        if ((((SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).minimumAlignment & 2) != 0) &&
           (*(int *)&(SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).field_0x14 == 0)) {
            lua_error();
        }
        SnakeTrackModule.L.SnakeTrack$$Trace((uint32_t)&DAT_02292095,expRaw,(MethodInfo *)0x0);
        if (propertyComp == (MobaBattleModule_Property_L_EntityPropertyComp_o *)0x0) {
                    /* WARNING: Subroutine does not return */
            throwError();
        }
        //最もレベルが高いプレイヤーとのレベル差補正
        expRaw = MobaBattleModule.Property.L.LPropertySys$$CalculateExpIncludingCompensation
                           (sysComp,expRaw,(propertyComp->fields).mLevel,&expExtra,(MethodInfo *)killedEntityId);
        method_00 = (MethodInfo *)0x0;

        //最もレベルが高いプレイヤーとのレベル差補正で加算された経験値を記録(他所では使われてないっぽい)
        MobaBattleModule.Stat.L.LBattleStatUtil$$AccCompensationExp((propertyComp->fields).super.EntityId,expExtra,(MethodInfo *)0x0);
        *finalExp = expRaw;
        //ストレージExp(進化前の貯蔵されたExp)の補正を計算
        expRaw = MobaBattleModule.Property.L.LPropertySys$$GetConversionStorageExp(propertyComp,expRaw,method_00);
        *expFromStorage = expRaw;
    }
    else {
        __this = IFix.WrappersManagerImpl$$GetPatch(0xb75,(MethodInfo *)0x0);
        if (__this == (IFix_ILFixDynamicMethodWrapper_3_o *)0x0) {
                    /* WARNING: Subroutine does not return */
            throwError();
        }
        IFix.ILFixDynamicMethodWrapper$$__Gen_Wrap_710
                  (__this,exp,src,(Il2CppObject *)sysComp,(Il2CppObject *)propertyComp,killedEntityId,finalExp,expFromStorage,(MethodInfo *)0x0);
    }
    return;

CalculateExpAfterKillLevelDiffAddition整理板


int32_t MobaBattleModule.Property.L.LPropertySys$$CalculateExpAfterKillLevelDiffAddition
                  (int32_t src,MobaBattleModule_Property_L_LPropertySysComp_o *sysComp,int32_t inExp,
                  MobaBattleModule_Property_L_EntityPropertyComp_o *inAttackerPropertyComp,int32_t killedEntityId,MethodInfo *method)

{

            // デス側のレベル
            dead_Level = (temp->fields).mLevel;
            // レベル差計算
            levelDiff = dead_Level - (inAttackerPropertyComp->fields).mLevel;


            if (0 < levelDiff) {
                    /* mPokemonExpGoldCfgsに補正のデータが格納されている */
                mPokemonExpGoldCfgs = (sysComp->fields).mPokemonExpGoldCfgs;


                dead_Level2 = System.Math$$Min(dead_Level,mPokemonExpGoldCfgs->size );
                dead_level3 = dead_Level2 - 1;


                // レベル差が1以上なら
                if (-1 < dead_level3) {

                    levelDiff2 = System.Math$$Min(levelDiff,levelDiff2);

                    levelDiff3 = levelDiff2 + -1;

                        pbPokemonExpGold_Base_o2 =
                             *(PbProtocol_pbPokemonExpGold_Base_o **)((int)mPokemonExpGoldCfgs->m_Items[dead_Level2]);
                        levelDiffAdditionRatio_ = (pbPokemonExpGold_Base_o2->fields).levelDiffAdditionRatio_;

                        ratio = Google.Protobuf.Collections.RepeatedField<int>$$get_Item
                                          (levelDiffAdditionRatio_,levelDiff3,Method$Google.Protobuf.Collections.RepeatedField<int>.get_Item());

                    /* 経験値×補正÷10000 */
                        inExp = __aeabi_ldivmod((int)((longlong)ratio * (longlong)inExp),(int)((ulonglong)((longlong)ratio * (longlong)inExp) >> 0 x20)
                                                ,10000,0);
                    }
                }
            }
        }
    }
    return inExp;
}

原文


int32_t MobaBattleModule.Property.L.LPropertySys$$CalculateExpAfterKillLevelDiffAddition
                  (int32_t src,MobaBattleModule_Property_L_LPropertySysComp_o *sysComp,int32_t inExp,
                  MobaBattleModule_Property_L_EntityPropertyComp_o *inAttackerPropertyComp,int32_t killedEntityId,MethodInfo *method)

{
    bool isHero;
    IFix_ILFixDynamicMethodWrapper_3_o *__this;
    MobaBattleModule_Property_L_EntityPropertyComp_o *temp;
    EntityModule_L_Entity_o *dead_entity;
    bool isHero2;
    int32_t dead_Level2;
    undefined4 uVar1;
    int32_t ratio;
    int dead_Level;
    PbProtocol_pbPokemonExpGold_Base_o *pbPokemonExpGold_Base_o;
    Google_Protobuf_Collections_RepeatedField_int__o *levelDiffAdditionRatio_;
    int32_t levelDiff2;
    PbProtocol_pbPokemonExpGold_Base_o *pbPokemonExpGold_Base_o2;
    PbProtocol_pbPokemonExpGold_Base_array *mPokemonExpGoldCfgs;
    uint dead_level2-1;
    int levelDiff;
    int levelDiff2-1;

    if (DAT_065270c4 == '\0') {
        thunk_FUN_0109b1b8(0xb2d6);
        DAT_065270c4 = '\x01';
    }
    isHero2 = IFix.WrappersManagerImpl$$IsPatched(0xb76,(MethodInfo *)0x0);
    if (isHero2 != false) {
        __this = IFix.WrappersManagerImpl$$GetPatch(0xb76,(MethodInfo *)0x0);
        if (__this != (IFix_ILFixDynamicMethodWrapper_3_o *)0x0) {
            levelDiff2 = IFix.ILFixDynamicMethodWrapper$$__Gen_Wrap_708
                                   (__this,src,(Il2CppObject *)sysComp,inExp,(Il2CppObject *)inAttackerPropertyComp,killedEntityId,(MethodInfo *)0 x0);
            return levelDiff2;
        }
                    /* WARNING: Subroutine does not return */
        throwError();
    }
    if ((((SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).minimumAlignment & 2) != 0) &&
       (*(int *)&(SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).field_0x14 == 0)) {
        lua_error();
    }
    SnakeTrackModule.L.SnakeTrack$$Trace(0x200e095,inExp,(MethodInfo *)0x0);
    if ((((src == 1) && (sysComp != (MobaBattleModule_Property_L_LPropertySysComp_o *)0x0)) &&
        (inAttackerPropertyComp != (MobaBattleModule_Property_L_EntityPropertyComp_o *)0x0 && killedEntityId != -1)) &&
       (isHero = MobaBattleModule.Property.L.LPropertyUtil$$ContainsUnitFlag(inAttackerPropertyComp,1,(MethodInfo *)0x0), isHero != false)) {
        if ((((EntityModule.L.EntityMgr_TypeInfo->_2).minimumAlignment & 2) != 0) &&
           (*(int *)&(EntityModule.L.EntityMgr_TypeInfo->_2).field_0x14 == 0)) {
            lua_error();
        }
        temp = (MobaBattleModule_Property_L_EntityPropertyComp_o *)EntityModule.L.EntityMgr$$get_Instance((MethodInfo *)0x0);
        if (temp == (MobaBattleModule_Property_L_EntityPropertyComp_o *)0x0) {
                    /* WARNING: Subroutine does not return */
            throwError();
        }
        dead_entity = EntityModule.L.EntityMgr$$GetEntity((EntityModule_L_EntityMgr_o *)temp,killedEntityId,true,(MethodInfo *)0x0);
        if (dead_entity != (EntityModule_L_Entity_o *)0x0) {
            temp = (dead_entity->fields).mPropertyComp;
        }
        if ((dead_entity != (EntityModule_L_Entity_o *)0x0 && temp != (MobaBattleModule_Property_L_EntityPropertyComp_o *)0x0) &&
           (isHero2 = MobaBattleModule.Property.L.LPropertyUtil$$ContainsUnitFlag(temp,1,(MethodInfo *)0x0), isHero2 != false)) {
                    /* デス側のレベル */
            dead_Level = (temp->fields).mLevel;
                    /* レベル差計算 */
            levelDiff = dead_Level - (inAttackerPropertyComp->fields).mLevel;
            if (0 < levelDiff) {
                    /* mPokemonExpGoldCfgsに補正のデータが格納されている */
                mPokemonExpGoldCfgs = (sysComp->fields).mPokemonExpGoldCfgs;
                if (mPokemonExpGoldCfgs == (PbProtocol_pbPokemonExpGold_Base_array *)0x0) {
                    /* WARNING: Subroutine does not return */
                    throwError();
                }
                if ((((System.Math_TypeInfo->_2).minimumAlignment & 2) != 0) && (*(int *)&(System.Math_TypeInfo->_2).field_0x14 == 0)) {
                    lua_error();
                }
                dead_Level2 = System.Math$$Min(dead_Level,*(int32_t *)&mPokemonExpGoldCfgs->field_0xc,(MethodInfo *)0x0);
                dead_level2-1 = dead_Level2 - 1;
                if ((((SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).minimumAlignment & 2) != 0) &&
                   (*(int *)&(SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).field_0x14 == 0)) {
                    lua_error();
                }
                SnakeTrackModule.L.SnakeTrack$$Trace(0x2074095,dead_level2-1,(MethodInfo *)0x0);
                if (-1 < (int)dead_level2-1) {
                    mPokemonExpGoldCfgs = (sysComp->fields).mPokemonExpGoldCfgs;
                    if (mPokemonExpGoldCfgs == (PbProtocol_pbPokemonExpGold_Base_array *)0x0) {
                    /* WARNING: Subroutine does not return */
                        throwError();
                    }
                    if (*(uint *)&mPokemonExpGoldCfgs->field_0xc <= dead_level2-1) {
                        uVar1 = thunk_FUN_01093bf8();
                    /* WARNING: Subroutine does not return */
                        thunk_FUN_010918a8(uVar1,0);
                    }
                    pbPokemonExpGold_Base_o =
                         *(PbProtocol_pbPokemonExpGold_Base_o **)((int)mPokemonExpGoldCfgs->m_Items + (int)(&DAT_fffffff4 + dead_Level2 * 4));
                    if (pbPokemonExpGold_Base_o == (PbProtocol_pbPokemonExpGold_Base_o *)0x0) {
                    /* WARNING: Subroutine does not return */
                        throwError();
                    }
                    levelDiffAdditionRatio_ = (pbPokemonExpGold_Base_o->fields).levelDiffAdditionRatio_;
                    if (levelDiffAdditionRatio_ == (Google_Protobuf_Collections_RepeatedField_int__o *)0x0) {
                    /* WARNING: Subroutine does not return */
                        throwError();
                    }
                    levelDiff2 = (levelDiffAdditionRatio_->fields).count;
                    if ((((System.Math_TypeInfo->_2).minimumAlignment & 2) != 0) && (*(int *)&(System.Math_TypeInfo->_2).field_0x14 == 0)) {
                        lua_error();
                    }
                    levelDiff2 = System.Math$$Min(levelDiff,levelDiff2,(MethodInfo *)0x0);
                    levelDiff2-1 = levelDiff2 + -1;
                    if ((((SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).minimumAlignment & 2) != 0) &&
                       (*(int *)&(SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).field_0x14 == 0)) {
                        lua_error();
                    }
                    SnakeTrackModule.L.SnakeTrack$$Trace(0x2080095,levelDiff2-1,(MethodInfo *)0x0);
                    if (-1 < levelDiff2-1) {
                        mPokemonExpGoldCfgs = (sysComp->fields).mPokemonExpGoldCfgs;
                        if (mPokemonExpGoldCfgs == (PbProtocol_pbPokemonExpGold_Base_array *)0x0) {
                    /* WARNING: Subroutine does not return */
                            throwError();
                        }
                        if (*(uint *)&mPokemonExpGoldCfgs->field_0xc <= dead_level2-1) {
                            uVar1 = thunk_FUN_01093bf8();
                    /* WARNING: Subroutine does not return */
                            thunk_FUN_010918a8(uVar1,0);
                        }
                        pbPokemonExpGold_Base_o2 =
                             *(PbProtocol_pbPokemonExpGold_Base_o **)((int)mPokemonExpGoldCfgs->m_Items + (int)(&DAT_fffffff4 + dead_Level2 * 4));
                        if (pbPokemonExpGold_Base_o2 == (PbProtocol_pbPokemonExpGold_Base_o *)0x0) {
                    /* WARNING: Subroutine does not return */
                            throwError();
                        }
                        levelDiffAdditionRatio_ = (pbPokemonExpGold_Base_o2->fields).levelDiffAdditionRatio_;
                        if (levelDiffAdditionRatio_ == (Google_Protobuf_Collections_RepeatedField_int__o *)0x0) {
                    /* WARNING: Subroutine does not return */
                            throwError();
                        }
                        ratio = Google.Protobuf.Collections.RepeatedField<int>$$get_Item
                                          (levelDiffAdditionRatio_,levelDiff2-1,Method$Google.Protobuf.Collections.RepeatedField<int>.get_Item());
                    /* 経験値×補正÷10000 */
                        inExp = __aeabi_ldivmod((int)((longlong)ratio * (longlong)inExp),(int)((ulonglong)((longlong)ratio * (longlong)inExp) >> 0 x20)
                                                ,10000,0);
                        if ((((SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).minimumAlignment & 2) != 0) &&
                           (*(int *)&(SnakeTrackModule.L.SnakeTrack_TypeInfo->_2).field_0x14 == 0)) {
                            lua_error();
                        }
                        SnakeTrackModule.L.SnakeTrack$$Trace(0x2094095,inExp,(MethodInfo *)0x0);
                    }
                }
            }
        }
    }
    return inExp;
}

CalculateExpIncludingCompensation整理板

int32_t MobaBattleModule.Property.L.LPropertySys$$CalculateExpIncludingCompensation
                  (MobaBattleModule_Property_L_LPropertySysComp_o *sysComp,int32_t expRaw,int32_t level,int32_t *expExtra,MethodInfo *method)

{
        *expExtra = 0;

            count = 0;
            while( true ) {
                mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;


                if ((mExpCompensationInfos->fields)._size <= (int)count) {
                    return expRaw;
                }

                mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;




                // レベル差に対応するデータが取得できたらbreak
                // 補正値データでは昇順だけど読み込み時に降順になってる?
                if (*(int *)((int)&(((MobaBattleModule_Property_L_ExpCompensationInfo_array *)(((mExpCompensationInfos->fields)._items)->m_Items[count] <= (sysComp->fields).mMaxLevelInbattleField - level) break;

                count = count + 1;
            }


            mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;

                    /* 経験値×補正÷10000 */
            iVar2 = ((*(int *)((int)((mExpCompensationInfos->fields)._items)->m_Items[count] ) + 10000) * expRaw) / 10000;
                    /* Exp増加分を計算 */
            *expExtra = iVar2 - expRaw;
            expRaw = iVar2;

    return expRaw;
}

原文


int32_t MobaBattleModule.Property.L.LPropertySys$$CalculateExpIncludingCompensation
                  (MobaBattleModule_Property_L_LPropertySysComp_o *sysComp,int32_t expRaw,int32_t level,int32_t *expExtra,MethodInfo *method)

{
    bool bVar1;
    IFix_ILFixDynamicMethodWrapper_3_o *__this;
    int iVar2;
    System_Collections_Generic_List_ExpCompensationInfo__o *mExpCompensationInfos;
    uint count;

    if (DAT_065270c5 == '\0') {
        thunk_FUN_0109b1b8(0xb2d7);
        DAT_065270c5 = '\x01';
    }
    bVar1 = IFix.WrappersManagerImpl$$IsPatched(0xb77,(MethodInfo *)0x0);
    if (bVar1 == false) {
        *expExtra = 0;
        if (sysComp != (MobaBattleModule_Property_L_LPropertySysComp_o *)0x0) {
            iVar2 = 0x10;
            count = 0;
            while( true ) {
                mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;
                if (mExpCompensationInfos == (System_Collections_Generic_List_ExpCompensationInfo__o *)0x0) {
                    /* WARNING: Subroutine does not return */
                    throwError();
                }
                if ((mExpCompensationInfos->fields)._size <= (int)count) {
                    return expRaw;
                }
                mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;
                if (mExpCompensationInfos == (System_Collections_Generic_List_ExpCompensationInfo__o *)0x0) {
                    /* WARNING: Subroutine does not return */
                    throwError();
                }
                if ((uint)(mExpCompensationInfos->fields)._size <= count) {
                    /* WARNING: Subroutine does not return */
                    System.ThrowHelper$$ThrowArgumentOutOfRangeException((MethodInfo *)0x0);
                }
                if (*(int *)((int)&(((MobaBattleModule_Property_L_ExpCompensationInfo_array *)(((mExpCompensationInfos->fields)._items)->m_Items +  -3)
                                    )->obj).klass + iVar2) == 0) {
                    return expRaw;
                }
                mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;
                if (mExpCompensationInfos == (System_Collections_Generic_List_ExpCompensationInfo__o *)0x0) {
                    /* WARNING: Subroutine does not return */
                    throwError();
                }
                if ((uint)(mExpCompensationInfos->fields)._size <= count) {
                    /* WARNING: Subroutine does not return */
                    System.ThrowHelper$$ThrowArgumentOutOfRangeException((MethodInfo *)0x0);
                }
                if (*(int *)((int)&(((MobaBattleModule_Property_L_ExpCompensationInfo_array *)(((mExpCompensationInfos->fields)._items)->m_Items +  -3)
                                    )->obj).klass + iVar2) <= (sysComp->fields).mMaxLevelInbattleField - level) break;
                iVar2 = iVar2 + 8;
                count = count + 1;
            }
            mExpCompensationInfos = (sysComp->fields).mExpCompensationInfos;
            if (mExpCompensationInfos == (System_Collections_Generic_List_ExpCompensationInfo__o *)0x0) {
                    /* WARNING: Subroutine does not return */
                throwError();
            }
            if ((uint)(mExpCompensationInfos->fields)._size <= count) {
                    /* WARNING: Subroutine does not return */
                System.ThrowHelper$$ThrowArgumentOutOfRangeException((MethodInfo *)0x0);
            }
                    /* 経験値×補正÷10000 */
            iVar2 = ((*(int *)((int)((mExpCompensationInfos->fields)._items)->m_Items + iVar2 + -0x14) + 10000) * expRaw) / 10000;
                    /* Exp増加分を計算 */
            *expExtra = iVar2 - expRaw;
            expRaw = iVar2;
        }
    }
    else {
        __this = IFix.WrappersManagerImpl$$GetPatch(0xb77,(MethodInfo *)0x0);
        if (__this == (IFix_ILFixDynamicMethodWrapper_3_o *)0x0) {
                    /* WARNING: Subroutine does not return */
            throwError();
        }
        expRaw = IFix.ILFixDynamicMethodWrapper$$__Gen_Wrap_709(__this,(Il2CppObject *)sysComp,expRaw,level,expExtra,(MethodInfo *)0x0);
    }
    return expRaw;
}