Przeglądaj źródła

* Shipyard window had it's wood and gold spots swapped, fixed.
* Melee cursor in battle now works like it should for 2-hex creatures.

OnionKnight 16 lat temu
rodzic
commit
d8c2055809
3 zmienionych plików z 143 dodań i 28 usunięć
  1. 129 22
      client/CBattleInterface.cpp
  2. 9 1
      client/CCursorHandler.cpp
  3. 5 5
      client/GUIClasses.cpp

+ 129 - 22
client/CBattleInterface.cpp

@@ -744,47 +744,118 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 						const double hexMidX = hoveredHex.pos.x + hoveredHex.pos.w/2;
 						const double hexMidY = hoveredHex.pos.y + hoveredHex.pos.h/2;
 						const double cursorHexAngle = M_PI - atan2(hexMidY - cursor->ypos, cursor->xpos - hexMidX) + subdividingAngle/2;
-						int cursorIndex = fmod(cursorHexAngle/subdividingAngle, 6.0);
-
-						int sectorCursor[] = {8, 9, 10, 11, 12, 7}; // From left to bottom left.
+						const double sector = fmod(cursorHexAngle/subdividingAngle, 6.0);
 						const int zigzagCorrection = !((myNumber/BFIELD_WIDTH)%2); // Off-by-one correction needed to deal with the odd battlefield rows.
 
+						std::vector<int> sectorCursor; // From left to bottom left.
+						sectorCursor.push_back(8);
+						sectorCursor.push_back(9);
+						sectorCursor.push_back(10);
+						sectorCursor.push_back(11);
+						sectorCursor.push_back(12);
+						sectorCursor.push_back(7);
+
+						const bool doubleWide = LOCPLINT->cb->battleGetStackByID(activeStack)->hasFeatureOfType(StackFeature::DOUBLE_WIDE);
+						bool aboveAttackable = true, belowAttackable = true;
+
 						// Exclude directions which cannot be attacked from.
 						// Check to the left.
 						if (myNumber%BFIELD_WIDTH <= 1 || !vstd::contains(shadedHexes, myNumber - 1)) {
 							sectorCursor[0] = -1;
 						}
-						// Check top left and top right.
+						// Check top left, top right as well as above for 2-hex creatures.
 						if (myNumber/BFIELD_WIDTH == 0) {
-							sectorCursor[1] = -1;
-							sectorCursor[2] = -1;
-						} else {
-							if (!vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH - 1 + zigzagCorrection))
 								sectorCursor[1] = -1;
-							if (!vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH + zigzagCorrection))
 								sectorCursor[2] = -1;
+								aboveAttackable = false;
+						} else {
+							if (doubleWide) {
+								bool attackRow[4] = {true, true, true, true};
+
+								if (myNumber%BFIELD_WIDTH <= 1 || !vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH - 2 + zigzagCorrection))
+									attackRow[0] = false;
+								if (!vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH - 1 + zigzagCorrection))
+									attackRow[1] = false;
+								if (!vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH + zigzagCorrection))
+									attackRow[2] = false;
+								if (myNumber%BFIELD_WIDTH >= BFIELD_WIDTH - 2 || !vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH + 1 + zigzagCorrection))
+									attackRow[3] = false;
+
+								if (!(attackRow[0] && attackRow[1]))
+									sectorCursor[1] = -1;
+								if (!(attackRow[1] && attackRow[2]))
+									aboveAttackable = false;
+								if (!(attackRow[2] && attackRow[3]))
+									sectorCursor[2] = -1;
+							} else {
+								if (!vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH - 1 + zigzagCorrection))
+									sectorCursor[1] = -1;
+								if (!vstd::contains(shadedHexes, myNumber - BFIELD_WIDTH + zigzagCorrection))
+									sectorCursor[2] = -1;
+							}
 						}
 						// Check to the right.
 						if (myNumber%BFIELD_WIDTH >= BFIELD_WIDTH - 2 || !vstd::contains(shadedHexes, myNumber + 1)) {
 							sectorCursor[3] = -1;
 						}
-						// Check bottom right and bottom left.
+						// Check bottom right, bottom left as well as below for 2-hex creatures.
 						if (myNumber/BFIELD_WIDTH == BFIELD_HEIGHT - 1) {
 							sectorCursor[4] = -1;
 							sectorCursor[5] = -1;
+							belowAttackable = false;
+						} else {
+							if (doubleWide) {
+								bool attackRow[4] = {true, true, true, true};
+
+								if (myNumber%BFIELD_WIDTH <= 1 || !vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH - 2 + zigzagCorrection))
+									attackRow[0] = false;
+								if (!vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH - 1 + zigzagCorrection))
+									attackRow[1] = false;
+								if (!vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH + zigzagCorrection))
+									attackRow[2] = false;
+								if (myNumber%BFIELD_WIDTH >= BFIELD_WIDTH - 2 || !vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH + 1 + zigzagCorrection))
+									attackRow[3] = false;
+
+								if (!(attackRow[0] && attackRow[1]))
+									sectorCursor[5] = -1;
+								if (!(attackRow[1] && attackRow[2]))
+									belowAttackable = false;
+								if (!(attackRow[2] && attackRow[3]))
+									sectorCursor[4] = -1;
+							} else {
+								if (!vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH + zigzagCorrection))
+									sectorCursor[4] = -1;
+								if (!vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH - 1 + zigzagCorrection))
+									sectorCursor[5] = -1;
+							}
+						}
+
+						// Determine index from sector.
+						int cursorIndex;
+						if (doubleWide) {
+							sectorCursor.insert(sectorCursor.begin() + 5, belowAttackable ? 13 : -1);
+							sectorCursor.insert(sectorCursor.begin() + 2, aboveAttackable ? 14 : -1);
+
+							if (sector < 1.5)
+								cursorIndex = sector;
+							else if (sector >= 1.5 && sector < 2.5)
+								cursorIndex = 2;
+							else if (sector >= 2.5 && sector < 4.5)
+								cursorIndex = (int) sector + 1;
+							else if (sector >= 4.5 && sector < 5.5)
+								cursorIndex = 6;
+							else
+								cursorIndex = (int) sector + 2;
 						} else {
-							if (!vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH + zigzagCorrection))
-								sectorCursor[4] = -1;
-							if (!vstd::contains(shadedHexes, myNumber + BFIELD_WIDTH - 1 + zigzagCorrection))
-								sectorCursor[5] = -1;
+							cursorIndex = sector;
 						}
 
 						// Find the closest direction attackable, starting with the right one.
 						// FIXME: Is this really how the original H3 client does it?
 						int i = 0;
-						while (sectorCursor[(cursorIndex + i)%6] == -1) 
+						while (sectorCursor[(cursorIndex + i)%sectorCursor.size()] == -1)
 							i = i <= 0 ? 1 - i : -i; // 0, 1, -1, 2, -2, 3, -3 etc..
-						cursor->changeGraphic(1, sectorCursor[(cursorIndex + i)%6]);
+						cursor->changeGraphic(1, sectorCursor[(cursorIndex + i)%sectorCursor.size()]);
 					}
 					else //unavailable enemy
 					{
@@ -1646,7 +1717,8 @@ void CBattleInterface::hexLclicked(int whichOne)
 				{
 				case 12: //from bottom right
 					{
-						int destHex = whichOne + ( (whichOne/BFIELD_WIDTH)%2 ? BFIELD_WIDTH : BFIELD_WIDTH+1 );
+						bool doubleWide = LOCPLINT->cb->battleGetStackByID(activeStack)->hasFeatureOfType(StackFeature::DOUBLE_WIDE);
+						int destHex = whichOne + ( (whichOne/BFIELD_WIDTH)%2 ? BFIELD_WIDTH : BFIELD_WIDTH+1 ) + doubleWide;
 						if(vstd::contains(shadedHexes, destHex))
 							attackFromHex = destHex;
 						else if(actStack->attackerOwned) //if we are attacker
@@ -1654,7 +1726,7 @@ void CBattleInterface::hexLclicked(int whichOne)
 							if(vstd::contains(shadedHexes, destHex+1))
 								attackFromHex = destHex+1;
 						}
-						else //if we are defneder
+						else //if we are defender
 						{
 							if(vstd::contains(shadedHexes, destHex-1))
 								attackFromHex = destHex-1;
@@ -1671,7 +1743,7 @@ void CBattleInterface::hexLclicked(int whichOne)
 							if(vstd::contains(shadedHexes, destHex+1))
 								attackFromHex = destHex+1;
 						}
-						else //if we are defneder
+						else //if we are defender
 						{
 							if(vstd::contains(shadedHexes, destHex-1))
 								attackFromHex = destHex-1;
@@ -1702,7 +1774,7 @@ void CBattleInterface::hexLclicked(int whichOne)
 							if(vstd::contains(shadedHexes, destHex+1))
 								attackFromHex = destHex+1;
 						}
-						else //if we are defneder
+						else //if we are defender
 						{
 							if(vstd::contains(shadedHexes, destHex-1))
 								attackFromHex = destHex-1;
@@ -1711,7 +1783,8 @@ void CBattleInterface::hexLclicked(int whichOne)
 					}
 				case 10: //from top right
 					{
-						int destHex = whichOne - ( (whichOne/BFIELD_WIDTH)%2 ? BFIELD_WIDTH : BFIELD_WIDTH-1 );
+						bool doubleWide = LOCPLINT->cb->battleGetStackByID(activeStack)->hasFeatureOfType(StackFeature::DOUBLE_WIDE);
+						int destHex = whichOne - ( (whichOne/BFIELD_WIDTH)%2 ? BFIELD_WIDTH : BFIELD_WIDTH-1 ) + doubleWide;
 						if(vstd::contains(shadedHexes, destHex))
 							attackFromHex = destHex;
 						else if(actStack->attackerOwned) //if we are attacker
@@ -1719,7 +1792,7 @@ void CBattleInterface::hexLclicked(int whichOne)
 							if(vstd::contains(shadedHexes, destHex+1))
 								attackFromHex = destHex+1;
 						}
-						else //if we are defneder
+						else //if we are defender
 						{
 							if(vstd::contains(shadedHexes, destHex-1))
 								attackFromHex = destHex-1;
@@ -1740,6 +1813,40 @@ void CBattleInterface::hexLclicked(int whichOne)
 						attackFromHex = whichOne + 1;
 					}
 					break;
+				case 13: //from bottom
+					{
+						int destHex = whichOne + ( (whichOne/BFIELD_WIDTH)%2 ? BFIELD_WIDTH : BFIELD_WIDTH+1 );
+						if(vstd::contains(shadedHexes, destHex))
+							giveCommand(6,destHex,activeStack,whichOne);
+						else if(attackingHeroInstance->tempOwner == LOCPLINT->cb->getMyColor()) //if we are attacker
+						{
+							if(vstd::contains(shadedHexes, destHex+1))
+								giveCommand(6,destHex+1,activeStack,whichOne);
+						}
+						else //if we are defender
+						{
+							if(vstd::contains(shadedHexes, destHex-1))
+								giveCommand(6,destHex-1,activeStack,whichOne);
+						}
+						break;
+					}
+				case 14: //from top
+					{
+						int destHex = whichOne - ( (whichOne/BFIELD_WIDTH)%2 ? BFIELD_WIDTH : BFIELD_WIDTH-1 );
+						if(vstd::contains(shadedHexes, destHex))
+							giveCommand(6,destHex,activeStack,whichOne);
+						else if(attackingHeroInstance->tempOwner == LOCPLINT->cb->getMyColor()) //if we are attacker
+						{
+							if(vstd::contains(shadedHexes, destHex+1))
+								giveCommand(6,destHex+1,activeStack,whichOne);
+						}
+						else //if we are defender
+						{
+							if(vstd::contains(shadedHexes, destHex-1))
+								giveCommand(6,destHex-1,activeStack,whichOne);
+						}
+						break;
+					}
 				}
 
 				giveCommand(6, attackFromHex, activeStack, whichOne);

+ 9 - 1
client/CCursorHandler.cpp

@@ -57,7 +57,7 @@ void CCursorHandler::draw1()
 					break;
 				case 8: // Left
 					x -= 16;
-					y += 11;
+					y += 10;
 					break;
 				case 9: // Top left
 					x -= 6;
@@ -75,6 +75,14 @@ void CCursorHandler::draw1()
 					x += 16;
 					y += 16;
 					break;
+				case 13: // Below
+					x += 9;
+					y += 16;
+					break;
+				case 14: // Above
+					x += 9;
+					y -= 15;
+					break;
 			}
 		}
 	}

+ 5 - 5
client/GUIClasses.cpp

@@ -4119,12 +4119,12 @@ CShipyardWindow::CShipyardWindow(const std::vector<si32> &cost, int state, const
 	SDL_FreeSurface(bgtemp);
 
 	// Draw resource icons and costs.
-	std::string woodCost = boost::lexical_cast<std::string>(10);
 	std::string goldCost = boost::lexical_cast<std::string>(1000);
-	blitAt(graphics->resources32->ourImages[0].bitmap, 100, 244, bg);
-	printAtMiddle(woodCost.c_str(), 116, 290, GEOR13, zwykly, bg);
-	blitAt(graphics->resources32->ourImages[6].bitmap, 196, 244, bg);
-	printAtMiddle(goldCost.c_str(), 212, 290, GEOR13, zwykly, bg);
+	std::string woodCost = boost::lexical_cast<std::string>(10);
+	blitAt(graphics->resources32->ourImages[6].bitmap, 100, 244, bg);
+	printAtMiddle(goldCost.c_str(), 116, 290, GEOR13, zwykly, bg);
+	blitAt(graphics->resources32->ourImages[0].bitmap, 196, 244, bg);
+	printAtMiddle(woodCost.c_str(), 212, 290, GEOR13, zwykly, bg);
 
 	bool affordable = true;
 	for(int i = 0; i < cost.size(); i++)