// File: /workspace/github_c_makefile_star2_O0/schroeder-lvb[P]sissm/src/pidynbots.c
// Function: computeBotParams
static int _computeBotParams( int refresh )
{
    int minBots, maxBots, i;
    unsigned int currHuman, currBots, minHuman, maxHuman;
    double aiDifficulty;
    char *objName, *mapName, objLetter;
    char strBuf[256], *w, *v;
    int adjust = 0, errCode = 0, botBias, offsetIndex;

    // default parameters
    // 
    minBots      = pidynbotsConfig.MinimumEnemies;
    maxBots      = pidynbotsConfig.MaximumEnemies;
    minHuman     = 1;
    maxHuman     = pidynbotsConfig.MaxPlayersToScaleEnemyCount;
    currHuman    = rosterCount();

    // a wedge code to disable this plugin if non-Checkpoint mode is running
    //
    v = apiGetServerMode();
    if (! ((0==strcmp( v, "checkpoint" )) || (0==strcmp( v, "hardcore"))) )  return 0;

#if 0 
    // DEBUG tap for simulating humans joining and leaving - take out this block later
    static int currHuman_static = 1;
    int currHuman_tmp;
    if ( 0 == debugPoke( "delme.txt", &currHuman_tmp ) ) {
        currHuman_static = currHuman_tmp;
    }
    currHuman = currHuman_static;
    printf("\nDEBUG pidynbots: override to %d\n", currHuman );
    apiSay("pidynbots: override to %d humans", currHuman );
#endif

    aiDifficulty = pidynbotsConfig.AIDifficulty;

    // get current side, map, and objective
    //
    objName   = rosterGetObjective();                    // e.g., "OCCheckpoint_A"
    mapName   = rosterGetMapName();                      // e.g., "Farmhouse_Checkpoint_Security"
    objLetter = rosterGetCoopObjectiveLetter();          // e.g., 'A', 'B', 'C', ... ' '

    logPrintf( LOG_LEVEL_INFO, "pidynbots", "ObjName ::%s:: MapName ::%s:: objLetter ::%c::", 
        objName, mapName, objLetter );

    // search the table if override is found (look for matching map name)
    //
    for (i=0; i<PIDYN_MAXADJUSTERS; i++) {

        if ( NULL != strcasestr( pidynbotsConfig.Adjuster[i], mapName )) {

            // get min/max/dif values 
            //
            if ( NULL != (w = getWord( pidynbotsConfig.Adjuster[i], 1, " " ))) 
                errCode |= ( 1 != sscanf( w, "%d", &minBots ));
            if ( NULL != (w = getWord( pidynbotsConfig.Adjuster[i], 2, " " ))) 
                errCode |= ( 1 != sscanf( w, "%d", &maxBots ));
            if ( NULL != (w = getWord( pidynbotsConfig.Adjuster[i], 3, " " ))) 
                errCode |= ( 1 != sscanf( w, "%lf", &aiDifficulty ));

            // if override was found, look for per-objective adjustments
            //
            if (( !errCode  ) && ( (objLetter >= 'A') && (objLetter <= 'Z') )) {
                offsetIndex = objLetter - 'A';
                offsetIndex += 4;        
                if ( NULL != (w = getWord( pidynbotsConfig.Adjuster[i], offsetIndex, " " ))) {
                    errCode |= ( 1 != sscanf( w, "%d", &adjust ));
                    if ( !errCode ) maxBots += adjust;
                }
            }
            break;
        }
    }

    // poke the new values
    //
    if ( !errCode )  {

        // Update the bot difficulty if it was not overridden by the 
        // operator (picladmin)
        //
        if ( 0L == p2pGetL( "picladmin.p2p.botAdminControlDifficulty", 0L )) {  // check if in-game admin took control
            logPrintf( LOG_LEVEL_INFO, "pidynbots", "Adjusting bot difficulty %lf", aiDifficulty );
            snprintf( strBuf, 256, "%lf", aiDifficulty );
                 apiGameModePropertySet( "aidifficulty",   strBuf ) ;

            // if enabled in config, update the players by showing new params in-game
            //
            if ( 0 != strlen( pidynbotsConfig.showInGame ) ) {
                apiSay("%s Difficulty %6.3lf", pidynbotsConfig.showInGame, aiDifficulty*10.0 );
            }
        }
        
        // Update the bot count if it was not overridden by the 
        // operator (picladmin)
        //
        if ( 0L == p2pGetL( "picladmin.p2p.botAdminControl", 0L )) {  // check if in-game admin took control
            logPrintf( LOG_LEVEL_INFO, "pidynbots", "Adjusting bots %d:%d" , minBots, maxBots );

            // Apply BotBias - this changes min/maxenemies by a specified offset in function of 
            // number of human players are present
            //
            botBias = 0;
            if ( NULL != (w = getWord( pidynbotsConfig.BotBias, currHuman, " " ))) 
               if ( 1 != sscanf( w, "%d", &botBias )) botBias = 0;

            // validate to keep the server from crashing
            // 
            minBots += botBias;                           // offset from bias table
            maxBots += botBias;
            minBots += pidynMinimumOffset;                // offset from game mode table
            maxBots += pidynMmaximumOffset;

            if ( maxBots > pidynbotsConfig.MaxBotsCrashProtect )  
                maxBots = pidynbotsConfig.MaxBotsCrashProtect;
            if ( minBots < 1  )      minBots =  1;
            if ( minBots > maxBots ) maxBots = minBots; 

            snprintf( strBuf, 256, "%d", minBots );
                apiGameModePropertySet( "minimumenemies", strBuf );
            snprintf( strBuf, 256, "%d", maxBots );
                apiGameModePropertySet( "maximumenemies", strBuf );

            // for instant-respawn mode, it uses SoloPlayer set of parameters.  Compute
            // the scaled bots linearly here and poke in the value;
            //
            currBots =  _botScale( currHuman, maxBots, minBots, maxHuman, minHuman );
            snprintf( strBuf, 256, "%d", currBots );
                apiGameModePropertySet( "soloenemies", strBuf );

            // apiSay("Bias %d Bots %d:%d:%d Humans %d", botBias, minBots, maxBots, currBots, currHuman);
            // printf("\n****Bias %d Bots %d:%d:%d Humans %d***\n", botBias, minBots, maxBots, currBots, currHuman);

            // if enabled in config, update the players by showing new params in-game
            //
            if ( 0 != strlen( pidynbotsConfig.showInGame ) ) {
                apiSay("%s Count %d:%d [%d]", pidynbotsConfig.showInGame, minBots*2, maxBots*2, currBots );
            }

        }

        // Admin Bot override is "on", but still must process if instand respawn mode to emulate
        // dynamic bot changes
        //
        else {
           
            // If "respawnMode" AND "not fixed bot" then, recompute the dynamic scaling for this objective
            // Poke the resulting value to soloenemies
            //
            if ( _inRespawnCoopMode( refresh ) ) {

                 // read gamemodeproperty for minenemies and maximumenemies
                 // convert to integer for math
                 //
                 if ( 1 != sscanf( apiGameModePropertyGet( "minimumenemies" ), "%d", &minBots )) errCode = 1;
                 if ( 1 != sscanf( apiGameModePropertyGet( "maximumenemies" ), "%d", &maxBots )) errCode = 1;

                 if ( 0 == errCode ) {
                     // program currBots to soloenemies
                     // 
                     if ( minBots != maxBots )  {
                         currBots =  _botScale( currHuman, maxBots, minBots, maxHuman, minHuman );
                         snprintf( strBuf, 256, "%d", currBots );

                         apiGameModePropertySet( "soloenemies", strBuf );

                         logPrintf( LOG_LEVEL_INFO, "pidynbots", 
                             "Adjusting bots respawn mode with operator override params %d:%d [%d] difficulty %lf", 
                             minBots, maxBots, currBots, aiDifficulty );

                         // if enabled in config, update the players by showing new params in-game
                         //
                         if ( 0 != strlen( pidynbotsConfig.showInGame ) ) {
                             apiSay("%s Count %d:%d [%d]", pidynbotsConfig.showInGame, minBots*2, maxBots*2, currBots );
                         }
                     }
                 }
             }
             else {
                 logPrintf( LOG_LEVEL_INFO, "pidynbots", "Adjusting bots bypassed due to Admin override %d:%d difficulty %lf", 
                     minBots, maxBots, aiDifficulty );
             }
        }

    }
    return 0;  
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movl %edi, -0x8(%rbp)
movl $0x0, -0x164(%rbp)
movl $0x0, -0x168(%rbp)
movl 0x74004(%rip), %eax     # 0x840ec
movl %eax, -0xc(%rbp)
movl 0x73fff(%rip), %eax     # 0x840f0
movl %eax, -0x10(%rbp)
movl $0x1, -0x20(%rbp)
movl 0x73ff3(%rip), %eax     # 0x840f4
movl %eax, -0x24(%rbp)
callq 0x19fc0
movl %eax, -0x18(%rbp)
callq 0x187d0
movq %rax, -0x160(%rbp)
movq -0x160(%rbp), %rdi
leaq 0x14eb5(%rip), %rsi     # 0x24fdb
callq 0x8200
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x1015a
movq -0x160(%rbp), %rdi
leaq 0x13ebe(%rip), %rsi     # 0x23fff
callq 0x8200
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0x1015a
movl $0x0, -0x4(%rbp)
jmp 0x10846
movsd 0x73f9e(%rip), %xmm0    # 0x84100
movsd %xmm0, -0x30(%rbp)
callq 0x193c0
movq %rax, -0x38(%rbp)
callq 0x19410
movq %rax, -0x40(%rbp)
callq 0x19560
movb %al, -0x41(%rbp)
movq -0x38(%rbp), %rcx
movq -0x40(%rbp), %r8
movsbl -0x41(%rbp), %r9d
movl $0x2, %edi
leaq 0x14ddf(%rip), %rsi     # 0x24f79
leaq 0x14e45(%rip), %rdx     # 0x24fe6
movb $0x0, %al
callq 0x21bf0
movl $0x0, -0x14(%rbp)
cmpl $0x80, -0x14(%rbp)
jge 0x10413
movslq -0x14(%rbp), %rax
leaq 0x73f21(%rip), %rdi     # 0x840e8
addq $0x20, %rdi
shlq $0xa, %rax
addq %rax, %rdi
movq -0x40(%rbp), %rsi
callq 0x8340
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x10403
movslq -0x14(%rbp), %rax
leaq 0x73ef4(%rip), %rdi     # 0x840e8
addq $0x20, %rdi
shlq $0xa, %rax
addq %rax, %rdi
movl $0x1, %esi
leaq 0x13f4d(%rip), %rdx     # 0x24158
callq 0x122d0
movq %rax, %rcx
movq %rcx, -0x158(%rbp)
xorl %eax, %eax
cmpq %rcx, %rax
je 0x10257
movq -0x158(%rbp), %rdi
leaq 0x13ea0(%rip), %rsi     # 0x240cf
leaq -0xc(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
orl -0x168(%rbp), %eax
movl %eax, -0x168(%rbp)
movslq -0x14(%rbp), %rax
leaq 0x73e86(%rip), %rdi     # 0x840e8
addq $0x20, %rdi
shlq $0xa, %rax
addq %rax, %rdi
movl $0x2, %esi
leaq 0x13edf(%rip), %rdx     # 0x24158
callq 0x122d0
movq %rax, %rcx
movq %rcx, -0x158(%rbp)
xorl %eax, %eax
cmpq %rcx, %rax
je 0x102c5
movq -0x158(%rbp), %rdi
leaq 0x13e32(%rip), %rsi     # 0x240cf
leaq -0x10(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
orl -0x168(%rbp), %eax
movl %eax, -0x168(%rbp)
movslq -0x14(%rbp), %rax
leaq 0x73e18(%rip), %rdi     # 0x840e8
addq $0x20, %rdi
shlq $0xa, %rax
addq %rax, %rdi
movl $0x3, %esi
leaq 0x13e71(%rip), %rdx     # 0x24158
callq 0x122d0
movq %rax, %rcx
movq %rcx, -0x158(%rbp)
xorl %eax, %eax
cmpq %rcx, %rax
je 0x10333
movq -0x158(%rbp), %rdi
leaq 0x14db5(%rip), %rsi     # 0x250c0
leaq -0x30(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
orl -0x168(%rbp), %eax
movl %eax, -0x168(%rbp)
cmpl $0x0, -0x168(%rbp)
jne 0x10401
movsbl -0x41(%rbp), %eax
cmpl $0x41, %eax
jl 0x10401
movsbl -0x41(%rbp), %eax
cmpl $0x5a, %eax
jg 0x10401
movsbl -0x41(%rbp), %eax
subl $0x41, %eax
movl %eax, -0x170(%rbp)
movl -0x170(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x170(%rbp)
movslq -0x14(%rbp), %rax
leaq 0x73d67(%rip), %rdi     # 0x840e8
addq $0x20, %rdi
shlq $0xa, %rax
addq %rax, %rdi
movl -0x170(%rbp), %esi
leaq 0x13dbf(%rip), %rdx     # 0x24158
callq 0x122d0
movq %rax, %rcx
movq %rcx, -0x158(%rbp)
xorl %eax, %eax
cmpq %rcx, %rax
je 0x103ff
movq -0x158(%rbp), %rdi
leaq 0x13d12(%rip), %rsi     # 0x240cf
leaq -0x164(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
orl -0x168(%rbp), %eax
movl %eax, -0x168(%rbp)
cmpl $0x0, -0x168(%rbp)
jne 0x103fd
movl -0x164(%rbp), %eax
addl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
jmp 0x103ff
jmp 0x10401
jmp 0x10413
jmp 0x10405
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x101af
cmpl $0x0, -0x168(%rbp)
jne 0x1083f
leaq 0x1368c(%rip), %rdi     # 0x23ab3
xorl %eax, %eax
movl %eax, %esi
callq 0x1eda0
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0x104d0
movsd -0x30(%rbp), %xmm0
movl $0x2, %edi
leaq 0x14b2a(%rip), %rsi     # 0x24f79
leaq 0x14bbf(%rip), %rdx     # 0x25015
movb $0x1, %al
callq 0x21bf0
leaq -0x150(%rbp), %rdi
movsd -0x30(%rbp), %xmm0
movl $0x100, %esi            # imm = 0x100
leaq 0x14c4b(%rip), %rdx     # 0x250c0
movb $0x1, %al
callq 0x8180
leaq -0x150(%rbp), %rsi
leaq 0x1361c(%rip), %rdi     # 0x23aa6
callq 0x176f0
leaq 0x9807e(%rip), %rdi     # 0xa8514
callq 0x8110
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x104ce
movsd 0x1323b(%rip), %xmm0    # 0x236e8
mulsd -0x30(%rbp), %xmm0
leaq 0x14b79(%rip), %rdi     # 0x25032
leaq 0x73c28(%rip), %rsi     # 0x840e8
addq $0x2442c, %rsi          # imm = 0x2442C
movb $0x1, %al
callq 0x178d0
jmp 0x104d0
leaq 0x13596(%rip), %rdi     # 0x23a6d
xorl %eax, %eax
movl %eax, %esi
callq 0x1eda0
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0x106c6
movl -0xc(%rbp), %ecx
movl -0x10(%rbp), %r8d
movl $0x2, %edi
leaq 0x14a78(%rip), %rsi     # 0x24f79
leaq 0x14b3f(%rip), %rdx     # 0x25047
movb $0x0, %al
callq 0x21bf0
movl $0x0, -0x16c(%rbp)
movl -0x18(%rbp), %esi
leaq 0x73bc5(%rip), %rdi     # 0x840e8
addq $0x24020, %rdi          # imm = 0x24020
leaq 0x13c27(%rip), %rdx     # 0x24158
callq 0x122d0
movq %rax, %rcx
movq %rcx, -0x158(%rbp)
xorl %eax, %eax
cmpq %rcx, %rax
je 0x1057a
movq -0x158(%rbp), %rdi
leaq 0x13b7a(%rip), %rsi     # 0x240cf
leaq -0x16c(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
je 0x10578
movl $0x0, -0x16c(%rbp)
jmp 0x1057a
movl -0x16c(%rbp), %eax
addl -0xc(%rbp), %eax
movl %eax, -0xc(%rbp)
movl -0x16c(%rbp), %eax
addl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
movl 0x73b48(%rip), %eax     # 0x840e0
addl -0xc(%rbp), %eax
movl %eax, -0xc(%rbp)
movl 0x73b40(%rip), %eax     # 0x840e4
addl -0x10(%rbp), %eax
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
cmpl 0x73b45(%rip), %eax     # 0x840f8
jle 0x105be
movl 0x73b3d(%rip), %eax     # 0x840f8
movl %eax, -0x10(%rbp)
cmpl $0x1, -0xc(%rbp)
jge 0x105cb
movl $0x1, -0xc(%rbp)
movl -0xc(%rbp), %eax
cmpl -0x10(%rbp), %eax
jle 0x105d9
movl -0xc(%rbp), %eax
movl %eax, -0x10(%rbp)
leaq -0x150(%rbp), %rdi
movl -0xc(%rbp), %ecx
movl $0x100, %esi            # imm = 0x100
leaq 0x13ae0(%rip), %rdx     # 0x240cf
movb $0x0, %al
callq 0x8180
leaq -0x150(%rbp), %rsi
leaq 0x1343f(%rip), %rdi     # 0x23a43
callq 0x176f0
leaq -0x150(%rbp), %rdi
movl -0x10(%rbp), %ecx
movl $0x100, %esi            # imm = 0x100
leaq 0x13ab0(%rip), %rdx     # 0x240cf
movb $0x0, %al
callq 0x8180
leaq -0x150(%rbp), %rsi
leaq 0x1341e(%rip), %rdi     # 0x23a52
callq 0x176f0
movl -0x18(%rbp), %edi
movl -0x10(%rbp), %esi
movl -0xc(%rbp), %edx
movl -0x24(%rbp), %ecx
movl -0x20(%rbp), %r8d
callq 0x10e20
movl %eax, -0x1c(%rbp)
leaq -0x150(%rbp), %rdi
movl -0x1c(%rbp), %ecx
movl $0x100, %esi            # imm = 0x100
leaq 0x13a68(%rip), %rdx     # 0x240cf
movb $0x0, %al
callq 0x8180
leaq -0x150(%rbp), %rsi
leaq 0x133e5(%rip), %rdi     # 0x23a61
callq 0x176f0
leaq 0x97e8c(%rip), %rdi     # 0xa8514
callq 0x8110
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x106c1
movl -0xc(%rbp), %edx
shll %edx
movl -0x10(%rbp), %ecx
shll %ecx
movl -0x1c(%rbp), %r8d
leaq 0x149b0(%rip), %rdi     # 0x2505c
leaq 0x73a35(%rip), %rsi     # 0x840e8
addq $0x2442c, %rsi          # imm = 0x2442C
movb $0x0, %al
callq 0x178d0
jmp 0x1083d
movl -0x8(%rbp), %edi
callq 0x10f00
cmpl $0x0, %eax
je 0x10815
leaq 0x13365(%rip), %rdi     # 0x23a43
callq 0x17720
movq %rax, %rdi
leaq 0x139e2(%rip), %rsi     # 0x240cf
leaq -0xc(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
je 0x1070d
movl $0x1, -0x168(%rbp)
leaq 0x1333e(%rip), %rdi     # 0x23a52
callq 0x17720
movq %rax, %rdi
leaq 0x139ac(%rip), %rsi     # 0x240cf
leaq -0x10(%rbp), %rdx
movb $0x0, %al
callq 0x82c0
movl %eax, %ecx
movl $0x1, %eax
cmpl %ecx, %eax
je 0x10743
movl $0x1, -0x168(%rbp)
xorl %eax, %eax
cmpl -0x168(%rbp), %eax
jne 0x10813
movl -0xc(%rbp), %eax
cmpl -0x10(%rbp), %eax
je 0x10811
movl -0x18(%rbp), %edi
movl -0x10(%rbp), %esi
movl -0xc(%rbp), %edx
movl -0x24(%rbp), %ecx
movl -0x20(%rbp), %r8d
callq 0x10e20
movl %eax, -0x1c(%rbp)
leaq -0x150(%rbp), %rdi
movl -0x1c(%rbp), %ecx
movl $0x100, %esi            # imm = 0x100
leaq 0x13944(%rip), %rdx     # 0x240cf
movb $0x0, %al
callq 0x8180
leaq -0x150(%rbp), %rsi
leaq 0x132c1(%rip), %rdi     # 0x23a61
callq 0x176f0
movl -0xc(%rbp), %ecx
movl -0x10(%rbp), %r8d
movl -0x1c(%rbp), %r9d
movsd -0x30(%rbp), %xmm0
movl $0x2, %edi
leaq 0x147b8(%rip), %rsi     # 0x24f79
leaq 0x148a8(%rip), %rdx     # 0x25070
movb $0x1, %al
callq 0x21bf0
leaq 0x97d3e(%rip), %rdi     # 0xa8514
callq 0x8110
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0x1080f
movl -0xc(%rbp), %edx
shll %edx
movl -0x10(%rbp), %ecx
shll %ecx
movl -0x1c(%rbp), %r8d
leaq 0x14862(%rip), %rdi     # 0x2505c
leaq 0x738e7(%rip), %rsi     # 0x840e8
addq $0x2442c, %rsi          # imm = 0x2442C
movb $0x0, %al
callq 0x178d0
jmp 0x10811
jmp 0x10813
jmp 0x1083b
movl -0xc(%rbp), %ecx
movl -0x10(%rbp), %r8d
movsd -0x30(%rbp), %xmm0
movl $0x2, %edi
leaq 0x1474c(%rip), %rsi     # 0x24f79
leaq 0x14890(%rip), %rdx     # 0x250c4
movb $0x1, %al
callq 0x21bf0
jmp 0x1083d
jmp 0x1083f
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
nopw %cs:(%rax,%rax)