void advManager::UpdateScreen(int a2, int a3) { static int update_width = 0x1C0u + 160; static int update_height = 448 + 10; if(a3 || bShowIt) { PollSound(); giScrollX = this->field_1F6; giScrollY = this->field_1FA; if(giLimitUpdMinX == -1) BlitBitmapToScreen(gpWindowManager->screenBuffer, 16, 16, update_width, update_height, 16, 16); else BlitBitmapToScreen( gpWindowManager->screenBuffer, giLimitUpdMinX, giLimitUpdMinY, giLimitUpdMaxX - giLimitUpdMinX + 160, giLimitUpdMaxY - giLimitUpdMinY, giLimitUpdMinX, giLimitUpdMinY); giScrollY = 0; giScrollX = 0; PollSound(); if(KBTickCount() > glTimers) { ++this->field_202; ++this->field_1FE; if(this->field_1FE >= 6) this->field_1FE = 0; glTimers = KBTickCount() + 120; if(this->field_1FE != 1 && this->field_1FE != 3 && this->field_1FE != 5) { ++this->field_20A; this->field_20A %= 18; ++this->field_212; this->field_212 %= 18; } else { ++this->field_20E; this->field_20E %= 18; ++this->field_216; this->field_216 %= 18; } } giLimitUpdMinX = -1; Process1WindowsMessage(); } else if(KBTickCount() > glTimers) { glTimers = KBTickCount() + 120; } }
void combatManager::ArcShot(icon *icn, int fromX, int fromY, int targX, int targY) { bool firingLeft = false; if (fromX > targX) firingLeft = true; int imageIdx = 0; // changes the sprite when its angle changes // temporarily save the screen so we can clear it from the projectile sprite later bitmap *savedscreen = new bitmap(0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT); gpWindowManager->screenBuffer->CopyTo(savedscreen, 0, 0, 0, 0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT); std::vector<COORD> points; const int NUM_FRAMES = 24; // equals to the number of frames for the whole arc path points = MakeCatapultArc(NUM_FRAMES, firingLeft, fromX, fromY, targX, targY); for(int i = 0; i < (int)points.size(); i++) { if (i % 3 == 0) // every 3rd cycle if(imageIdx < (icn->numSprites - 1)) imageIdx++; // changes the sprite of projectile savedscreen->CopyTo(gpWindowManager->screenBuffer, 0, 0, 0, 0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT); // clear the screen from the previous projectile sprite icn->CombatClipDrawToBuffer(points[i].X, points[i].Y, imageIdx, NULL, firingLeft, 0, 0, 0); gpWindowManager->UpdateScreenRegion(0, 0, INTERNAL_WINDOW_WIDTH, INTERNAL_WINDOW_HEIGHT); glTimers = (signed __int64)((double)KBTickCount() + (double)40 * gfCombatSpeedMod[giCombatSpeed]); DelayTil(&glTimers); } delete savedscreen; this->DrawFrame(1, 0, 0, 0, 1, 1, 1); // clear screen from the projectile }
void __thiscall combatManager::DrawFrame(int redrawAll, int a3, int a4, int a5, signed int delay, int a7, int waitUntilItIsTime) { int v8; // ecx@127 int v9; // ST50_4@148 int v10; // eax@146 int offsetX; // [sp+24h] [bp-C4h]@22 int offsetY; // [sp+28h] [bp-C0h]@19 int offY; // [sp+34h] [bp-B4h]@96 int imageIdx; // [sp+38h] [bp-B0h]@96 int offX; // [sp+3Ch] [bp-ACh]@96 unsigned __int8 v17[7]; // [sp+44h] [bp-A4h]@94 Point16 v18[6][4]; // [sp+4Ch] [bp-9Ch]@94 int v19; // [sp+ACh] [bp-3Ch]@151 int colBound; // [sp+B0h] [bp-38h]@55 int v21; // [sp+B4h] [bp-34h]@72 int deltaX; // [sp+B8h] [bp-30h]@55 int colStart; // [sp+BCh] [bp-2Ch]@55 int i; // [sp+C0h] [bp-28h]@7 int v25; // [sp+D4h] [bp-14h]@5 int l; // [sp+DCh] [bp-Ch]@5 int j; // [sp+E0h] [bp-8h]@47 int k; // [sp+E4h] [bp-4h]@78 if(this->field_F357 || gbNoShowCombat || !this->field_F42F) return; PollSound(); gpMouseManager->couldBeShowMouse = 0; if(a3) { v25 = 0; for(l = 0; l < 2; ++l) { for(i = 0; i < 20; ++i) { if(limitCreature[l][i] > 0) { v25 = 1; gbComputeExtent = 1; gbSaveBiggestExtent = 1; gbReturnAfterComputeExtent = 1; (&(creatures[l][i]))->DrawToBuffer( combatGrid[creatures[l][i].occupiedHex].centerX, combatGrid[creatures[l][i].occupiedHex].occupyingCreatureBottomY, 0); gbReturnAfterComputeExtent = 0; gbComputeExtent = 0; gbSaveBiggestExtent = 0; } } } for(l = 0; l < 2; ++l) { if(field_F41F[l]) { v25 = 1; gbComputeExtent = 1; gbSaveBiggestExtent = 1; gbReturnAfterComputeExtent = 1; heroIcon[l]->CombatClipDrawToBuffer( (unsigned int)l < 1 ? 30 : 610, (unsigned int)l < 1 ? 183 : 148, sCmbtHero[heroType[l]].frameIndex[heroAnimationType[l]][heroAnimationFrameCount[l]], (SLimitData*)&(heroBounds[l]), 1, 0, 0, 0); gbReturnAfterComputeExtent = 0; gbComputeExtent = 0; gbSaveBiggestExtent = 0; } if(field_F427[l]) { v25 = 1; gbComputeExtent = 1; gbSaveBiggestExtent = 1; gbReturnAfterComputeExtent = 1; if(l) offsetY = (unsigned int)heroes[l]->isCaptain < 1 ? 148 : 135; else offsetY = 183; if(l) offsetX = (unsigned int)heroes[l]->isCaptain < 1 ? 610 : 103; else offsetX = 30; heroFlagIcon[l]->CombatClipDrawToBuffer( offsetX, offsetY, heroFlagIconIdx[l], (SLimitData*)&(heroFlagBounds[l]), 1, 0, 0, 0); gbReturnAfterComputeExtent = 0; gbComputeExtent = 0; gbSaveBiggestExtent = 0; } } if(a5 || !v25) goto LABEL_168; --giMinExtentX; --giMinExtentY; ++giMaxExtentX; ++giMaxExtentY; if(giMinExtentX < 0) giMinExtentX = 0; if(giMinExtentY < 0) giMinExtentY = 0; if(giMaxExtentX > 639) giMaxExtentX = 639 + 160; if(giMaxExtentY > 442) giMaxExtentY = 442; } if(a7) { if(zeroedAfterAnimatingDeathAndHolySpells) { if(a3 || a4 || gbLimitToExtent) probablyBitmapForCombatScreen->CopyTo( gpWindowManager->screenBuffer, giMinExtentX, giMinExtentY, giMinExtentX, giMinExtentY, giMaxExtentX - giMinExtentX + 1, giMaxExtentY - giMinExtentY + 1); else probablyBitmapForCombatScreen->CopyTo(gpWindowManager->screenBuffer, 0, 0, 0, 0, 640u + 160, 443); } else { DrawBackground(); } } if(a3) { gbLimitToExtent = 1; gbComputeExtent = 1; } for(j = 0; j < 9; ++j) { if(j == 1 && heroes[1]) { heroIcon[1]->CombatClipDrawToBuffer( (unsigned int)heroes[1]->isCaptain < 1 ? 610 : 103, (unsigned int)heroes[1]->isCaptain < 1 ? 148 : 0x87u, sCmbtHero[heroType[1]].frameIndex[heroAnimationType[1]][heroAnimationFrameCount[1]], (SLimitData*)&(heroBounds[1]), 1, 0, 0, 0); heroFlagIcon[1]->CombatClipDrawToBuffer( 610, 148, heroFlagIconIdx[1], (SLimitData*)&(heroFlagBounds[1]), 1, 0, 0, 0); } if(j == 2 && heroes[0]) { int third_arg = sCmbtHero[heroType[0]].frameIndex[heroAnimationType[0]][heroAnimationFrameCount[0]]; heroIcon[0]->CombatClipDrawToBuffer( 30, 183, third_arg, (SLimitData*)(&heroBounds[0]), //(SLimitData*)&heroBounds, 0, 0, 0, 0); heroFlagIcon[0]->CombatClipDrawToBuffer( 30, 183, heroFlagIconIdx[0], (SLimitData*)(&heroFlagBounds[0]), 0, 0, 0, 0); } colStart = 1; colBound = 12; deltaX = 1; if(isCastleBattle && j >= 5) { colStart = 11; colBound = 0; deltaX = -1; } if(isCastleBattle && j == 7) combatScreenIcons[3]->CombatClipDrawToBuffer( 22, 390, probablyCatapultImgIdx[0], (SLimitData*)&catapultBounds, 0, 0, 0, 0); if(isCastleBattle && j == 4 && drawBridgePosition != 4) combatScreenIcons[5]->CombatClipDrawToBuffer( 0, 0, drawBridgePosition + 21, (SLimitData*)&drawbridgeBounds, 0, 0, 0, 0); if(isCastleBattle && j == 5 && !drawBridgePosition) combatScreenIcons[5]->CombatClipDrawToBuffer(0, 0, 25, (SLimitData*)&field_F303, 0, 0, 0, 0); if(isCastleBattle && j == 6) combatScreenIcons[5]->CombatClipDrawToBuffer( 0, 0, (unsigned int)ballistaDestroyed < 1 ? 20 : 26, (SLimitData*)&ballistaBounds, 0, 0, 0, 0); v21 = 0; if(isCastleBattle && wallStatus[3] != 2 && wallStatus[3] != 6) { v21 = 1; for(l = 0; l < 4; ++l) { (&combatGrid[114])->DrawOccupant(l, 0); (&combatGrid[115])->DrawOccupant(l, 0); } } for(k = colStart; k != colBound; k += deltaX) (&(combatGrid[13 * j]) + k)->DrawLowerDeadOccupants(); for(k = colStart; k != colBound; k += deltaX) (&(combatGrid[13 * j]) + k)->DrawUpperDeadOccupant(); for(l = 0; l < 4; ++l) { if(l == 1) { for(k = colStart; k != colBound; k += deltaX) { if(combatGrid[k + 13 * j].combatObjIdx != -1) (&(combatGrid[13 * j]) + k)->DrawObstacle(); } } for(k = colStart; k != colBound; k += deltaX) { v18[0][0].x = 443; v18[0][0].y = 153; v18[0][1].x = 399; v18[0][1].y = 237; v18[0][2].x = 399; v18[0][2].y = 321; v18[0][3].x = 443; v18[0][3].y = 405; v18[1][0].x = 443; v18[1][0].y = 153; v18[1][1].x = 399; v18[1][1].y = 237; v18[1][2].x = 399; v18[1][2].y = 321; v18[1][3].x = 443; v18[1][3].y = 405; v18[2][0].x = 443; v18[2][0].y = 153; v18[2][1].x = 399; v18[2][1].y = 237; v18[2][2].x = 399; v18[2][2].y = 321; v18[2][3].x = 443; v18[2][3].y = 405; v18[3][0].x = 443; v18[3][0].y = 153; v18[3][1].x = 399; v18[3][1].y = 237; v18[3][2].x = 399; v18[3][2].y = 321; v18[3][3].x = 443; v18[3][3].y = 405; v18[4][0].x = 443; v18[4][0].y = 153; v18[4][1].x = 399; v18[4][1].y = 237; v18[4][2].x = 399; v18[4][2].y = 321; v18[4][3].x = 443; v18[4][3].y = 405; v18[5][0].x = 443; v18[5][0].y = 153; v18[5][1].x = 399; v18[5][1].y = 237; v18[5][2].x = 399; v18[5][2].y = 321; v18[5][3].x = 443; v18[5][3].y = 405; v17[0] = 0; v17[1] = 4; v17[2] = 8; v17[3] = 23; v17[4] = 27; v17[5] = 35; v17[6] = 31; if(isCastleBattle && !l) { imageIdx = 0; offX = 0; offY = 0; switch(k + 13 * j) { case 9: imageIdx = v17[wallStatus[0]] + 5; break; case 34: imageIdx = v17[wallStatus[1]] + 6; break; case 86: imageIdx = v17[wallStatus[2]] + 7; break; case 113: imageIdx = v17[wallStatus[3]] + 8; break; case 22: imageIdx = turretStatus[0] + 17; offX = *(DWORD *)v18[castles[1]->factionID] & 0xFFFF; offY = v18[castles[1]->factionID][0].y; break; case 47: imageIdx = turretStatus[1] + 17; offX = v18[castles[1]->factionID][1].x; offY = v18[castles[1]->factionID][1].y; break; case 73: imageIdx = turretStatus[2] + 17; offX = v18[castles[1]->factionID][2].x; offY = v18[castles[1]->factionID][2].y; break; case 100: imageIdx = turretStatus[3] + 17; offX = v18[castles[1]->factionID][3].x; offY = v18[castles[1]->factionID][3].y; break; case 59: if(drawBridgePosition != 3) imageIdx = 4; break; default: break; } if(imageIdx) combatScreenIcons[5]->CombatClipDrawToBuffer( offX, offY, imageIdx, (SLimitData*)((char *)&combatGrid[13 * j].drawingBounds + 98 * k), 0, 0, 0, 0); } if(!v21 || k + 13 * j != 114 && k + 13 * j != 115) (&combatGrid[13 * j] + k)->DrawOccupant(l, 0); } } if(isCastleBattle && BYTE1(castles[1]->buildingsBuiltFlags) & 0x10 && (j != 4 || drawBridgePosition == 4)) { if(moatCell[j] != giWalkingTo && moatCell[j] != giWalkingTo2 && moatCell[j] != giWalkingFrom && moatCell[j] != giWalkingFrom2) { if(combatGrid[moatCell[j]].unitOwner != -1) goto LABEL_150; } else { if(abs(giWalkingTo - giWalkingFrom) <= 1) goto LABEL_150; v8 = giWalkingFrom / 13; if(giWalkingFrom / 13 <= giWalkingTo / 13) v8 = giWalkingTo / 13; if(v8 == j) { if(gpCombatManager->drawBridgePosition == 4 || giWalkingTo / 13 != 4 && giWalkingFrom / 13 != 4) { v10 = giWalkingFrom; if(giWalkingFrom <= giWalkingTo) v10 = giWalkingTo; v9 = giWalkingYMod + combatGrid[giWalkingFrom].occupyingCreatureBottomY - 9; IconToBitmap( combatScreenIcons[14], gpWindowManager->screenBuffer, 0, 0, 0, 1, 0, v9, 0x280u, combatGrid[v10].occupyingCreatureBottomY + 5 - v9 + 1, 0); } else if((giWalkingTo / 13 != 4 || giWalkingFrom / 13 != 3) && (giWalkingTo / 13 != 3 || giWalkingFrom / 13 != 4)) { if(giWalkingFrom <= giWalkingTo) { if(moatCell[j] == giWalkingTo || moatCell[j] == giWalkingTo2) { LABEL_150: combatScreenIcons[13]->CombatClipDrawToBuffer( 0, 0, j, (SLimitData*)&moatPartBounds[j], 0, 0, 0, 0); ((hexcell *)&field_49F[98 * moatCell[j] + 19])->DrawOccupant(100, 1); (&combatGrid[moatCell[j]])->DrawOccupant(100, 1); (&combatGrid[moatCell[j] + 1])->DrawOccupant(100, 1); goto LABEL_151; } } else if(moatCell[j] == giWalkingFrom || moatCell[j] == giWalkingFrom2) { goto LABEL_150; } } } } } LABEL_151: v19 = 0; } //FIXME //if(*(_DWORD *)&combatArmyInfoLevel > 0 && *(_DWORD *)&_15[100] != -1) // { // DrawSmallView(0, 0); // DrawSmallView(1, 0); // } gpMouseManager->couldBeShowMouse = 1; PollSound(); if(a3 || a4) { gbLimitToExtent = 0; gbComputeExtent = 0; if(waitUntilItIsTime) DelayTil(&glTimers); glTimers = (signed __int64)((double)KBTickCount() + (double)delay * gfCombatSpeedMod[giCombatSpeed]); gbFullCombatScreenDrawn = 0; if(redrawAll == 1) { giMaxExtentX += 160; if(giMaxExtentY > 442 + 160) giMaxExtentY = 442 + 160; gbEnlargeScreenBlit = 0; gpWindowManager->UpdateScreenRegion( giMinExtentX, giMinExtentY, giMaxExtentX - giMinExtentX + 1, giMaxExtentY - giMinExtentY + 1); gbEnlargeScreenBlit = 1; } } else if(redrawAll == 1) { if(waitUntilItIsTime) DelayTil(&glTimers); gbFullCombatScreenDrawn = 1; glTimers = (signed __int64)((double)KBTickCount() + (double)delay * gfCombatSpeedMod[giCombatSpeed]); UpdateCombatArea(); } LABEL_168: gpMouseManager->couldBeShowMouse = 1; PollSound(); }