Skip to content

Commit f8a45c5

Browse files
committed
Changelog 2025/10/11
1. Fixed an issue where duplicate unit IDs could assign positions and items to the wrong unit, causing sync errors. You need to abort the mission and start a new one for the fix to take effect. You do not need to start a new campaign. 2. Fixed MonthlyReport not appearing for the second player 3. Fixed UFOs sometimes not appearing and crashing the game 4. PVP campaign removed message STR_UNABLE_TO_USE_ALIEN_ARTIFACT_UNTIL_RESEARCHED and UFOs can now fire weapons 5. Settings General added Toggle Chat option with a configurable hotkey 6. PVP Battlescape fixed issue where the other player could see unit arrows when holding Alt 7. Minor fixes and polish
1 parent d853f49 commit f8a45c5

File tree

12 files changed

+115
-37
lines changed

12 files changed

+115
-37
lines changed

src/Battlescape/ActionMenuState.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,15 +315,17 @@ void ActionMenuState::handleAction()
315315
bool newHitLog = false;
316316
std::string actionResult = "STR_UNKNOWN"; // needs a non-empty default/fall-back !
317317

318+
// coop
318319
if (_action->type != BA_THROW &&
319320
_action->actor->getOriginalFaction() == FACTION_PLAYER &&
320-
!_game->getSavedGame()->isResearched(weapon->getRequirements()))
321+
!_game->getSavedGame()->isResearched(weapon->getRequirements()) && _game->getCoopMod()->getCoopGamemode() != 2 && _game->getCoopMod()->getCoopGamemode() != 3 && _game->getCoopMod()->getCoopGamemode() != 4)
321322
{
322323
_action->result = "STR_UNABLE_TO_USE_ALIEN_ARTIFACT_UNTIL_RESEARCHED";
323324
_game->popState();
324325
}
326+
// coop
325327
else if (_action->type != BA_THROW &&
326-
!_game->getSavedGame()->getSavedBattle()->canUseWeapon(_action->weapon, _action->actor, false, _action->type, &actionResult))
328+
!_game->getSavedGame()->getSavedBattle()->canUseWeapon(_action->weapon, _action->actor, false, _action->type, &actionResult) && _game->getCoopMod()->getCoopGamemode() != 2 && _game->getCoopMod()->getCoopGamemode() != 3 && _game->getCoopMod()->getCoopGamemode() != 4)
327329
{
328330
_action->result = actionResult;
329331
_game->popState();

src/Battlescape/Map.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,14 @@ void Map::drawUnit(UnitSprite &unitSprite, Tile *unitTile, Tile *currTile, Posit
720720
{
721721
shade = std::min(+NIGHT_VISION_SHADE, shade);
722722
}
723+
724+
// coop
725+
if (_game->getCoopMod()->getCurrentTurn() == 1)
726+
{
727+
_isAltPressed = false;
728+
_isCtrlPressed = false;
729+
}
730+
723731
unitSprite.draw(bu, part, tileScreenPosition.x + offsets.ScreenOffset.x, tileScreenPosition.y + offsets.ScreenOffset.y, shade, mask, _isAltPressed && !_isCtrlPressed);
724732
}
725733

src/Battlescape/UnitWalkBState.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ UnitWalkBState::UnitWalkBState(BattlescapeGame *parent, BattleAction action) : B
5252
*/
5353
UnitWalkBState::~UnitWalkBState()
5454
{
55-
5655
}
5756

5857
/**

src/CoopMod/CoopMenu.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,13 @@ CoopMenu::CoopMenu() : _craft(0), _selectType(NewBattleSelectType::MISSION), _is
183183
_btnMessage->setVisible(false);
184184
_btnMessage->onMouseClick((ActionHandler)&CoopMenu::disconnect);
185185

186-
_btnChat->setText(tr("CHAT ('C')"));
186+
std::string n = SDL_GetKeyName(Options::keyChat);
187+
if (n.size() == 1)
188+
n[0] = (char)std::toupper((unsigned char)n[0]);
189+
190+
std::string label = std::string(tr("CHAT").c_str()) + " [" + n + "]";
191+
_btnChat->setText(label.c_str());
192+
187193
_btnChat->setVisible(false);
188194
_btnChat->onMouseClick((ActionHandler)&CoopMenu::btnChatClick);
189195

src/CoopMod/CoopState.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ void CoopState::loadWorld()
715715
for (auto& client_base : *client_save->getBases())
716716
{
717717

718-
// ITEROIDAAN SOTILAAT
718+
// Iterate soldiers
719719
for (auto& soldier : *client_base->getSoldiers())
720720
{
721721

@@ -729,21 +729,30 @@ void CoopState::loadWorld()
729729
// if the same craft
730730
std::vector<Soldier*>* soldiers = hostBase->getSoldiers();
731731

732-
Soldier* lastSoldier = soldiers->back(); // Points to the last soldier
733-
int lastId = lastSoldier->getId(); // Assuming Soldier class has getId()
732+
int lastId = 0;
733+
Soldier* lastSoldier = nullptr;
734734

735-
// Check if one with the same name already exists
736-
auto it = std::find_if(soldiers->begin(), soldiers->end(), [&](Soldier* s)
737-
{ return s->getName() == soldier->getName(); });
738-
739-
// If found, remove it
740-
if (it != soldiers->end())
735+
if (soldiers && !soldiers->empty())
741736
{
742-
delete *it; // Remove the old soldier if needed
743-
soldiers->erase(it);
737+
auto it = std::max_element(
738+
soldiers->begin(), soldiers->end(),
739+
[](const Soldier* a, const Soldier* b)
740+
{
741+
// Treat nullptr as smaller
742+
if (!a)
743+
return true;
744+
if (!b)
745+
return false;
746+
return a->getId() < b->getId();
747+
});
748+
749+
if (it != soldiers->end() && *it)
750+
{
751+
lastSoldier = *it;
752+
lastId = (*it)->getId();
753+
}
744754
}
745-
746-
755+
747756
if (selected_craft)
748757
{
749758

src/CoopMod/connectionTCP.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,14 @@ void connectionTCP::onTCPMessage(std::string stateString, Json::Value obj)
20992099

21002100
}
21012101

2102+
// months
2103+
if (stateString == "time1Month")
2104+
{
2105+
2106+
time1MonthCoop = true;
2107+
2108+
}
2109+
21022110
// target positions
21032111
if (stateString == "target_positions")
21042112
{
@@ -2145,7 +2153,7 @@ void connectionTCP::onTCPMessage(std::string stateString, Json::Value obj)
21452153
if (!craft)
21462154
{
21472155

2148-
RuleCraft* rule = _game->getMod()->getCraft(rule_id);
2156+
RuleCraft* rule = _game->getMod()->getCraft(rule_id, false);
21492157

21502158
if (rule)
21512159
{
@@ -2222,7 +2230,7 @@ void connectionTCP::onTCPMessage(std::string stateString, Json::Value obj)
22222230
if (!alien_mission)
22232231
{
22242232

2225-
const RuleAlienMission* alien_mission_rule = _game->getMod()->getAlienMission(mission_rule_id, true);
2233+
const RuleAlienMission* alien_mission_rule = _game->getMod()->getAlienMission(mission_rule_id, false);
22262234

22272235
if (alien_mission_rule)
22282236
{
@@ -2266,9 +2274,20 @@ void connectionTCP::onTCPMessage(std::string stateString, Json::Value obj)
22662274
if (!ufo)
22672275
{
22682276

2269-
const MissionWave& wave = alien_mission->getRules().getWave(waveNumber);
2277+
std::string str_ufo_id = "";
2278+
2279+
if (waveNumber < 0)
2280+
{
2281+
str_ufo_id = ufo_rule_id;
2282+
}
2283+
else
2284+
{
2285+
2286+
const MissionWave& wave = alien_mission->getRules().getWave(waveNumber);
2287+
str_ufo_id = wave.ufoType;
2288+
}
22702289

2271-
RuleUfo* ufoRule = _game->getMod()->getUfo(wave.ufoType);
2290+
RuleUfo* ufoRule = _game->getMod()->getUfo(str_ufo_id, false);
22722291

22732292
if (ufoRule)
22742293
{

src/CoopMod/connectionTCP.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ class connectionTCP
196196
UnitStatus intToUnitstatus(int status);
197197
int ufostatusToInt(Ufo::UfoStatus status);
198198
Ufo::UfoStatus intToUfostatus(int status);
199+
bool time1MonthCoop = false;
199200
};
200201

201202
}

src/Engine/Game.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ void Game::run()
297297
{
298298
if (_event.type == SDL_KEYDOWN)
299299
{
300-
// Close chat with SDLK_c
301-
if (_event.key.keysym.sym == SDLK_c)
300+
// Close chat with Options::keyChat
301+
if (_event.key.keysym.sym == Options::keyChat)
302302
{
303303
_tcpConnection->getChatMenu()->setActive(false);
304304
}
@@ -319,8 +319,8 @@ void Game::run()
319319
{
320320

321321
// coop
322-
// Activate chat with SDLK_c
323-
if (_event.key.keysym.sym == SDLK_c && (_tcpConnection->getCoopStatic() == true || _tcpConnection->getServerOwner() == true) && _tcpConnection->getChatMenu())
322+
// Activate chat with Options::keyChat
323+
if (_event.key.keysym.sym == Options::keyChat && (_tcpConnection->getCoopStatic() == true || _tcpConnection->getServerOwner() == true) && _tcpConnection->getChatMenu())
324324
{
325325
_tcpConnection->getChatMenu()->setActive(true);
326326
}

src/Engine/Options.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ void createAdvancedOptionsOXC()
279279

280280
void createControlsOXC()
281281
{
282+
283+
// coop
284+
_info.push_back(OptionInfo(OPTION_OXC, "keyChat", &keyChat, SDLK_c, "Toggle Chat", "STR_GENERAL"));
282285
// controls
283286
_info.push_back(OptionInfo(OPTION_OXC, "keyOk", &keyOk, SDLK_RETURN, "STR_OK", "STR_GENERAL"));
284287
_info.push_back(OptionInfo(OPTION_OXC, "keyCancel", &keyCancel, SDLK_ESCAPE, "STR_CANCEL", "STR_GENERAL"));

src/Engine/Options.inc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ OPT SoundFormat preferredSound;
1717
OPT VideoFormat preferredVideo;
1818
OPT SDL_GrabMode captureMouse;
1919
OPT TextWrapping wordwrap;
20-
OPT SDLKey keyOk, keyCancel, keyScreenshot, keyFps, keyQuickLoad, keyQuickSave;
20+
OPT SDLKey keyOk, keyCancel, keyScreenshot, keyFps, keyQuickLoad, keyQuickSave, keyChat;
2121

2222
// Geoscape options
2323
OPT int geoClockSpeed, dogfightSpeed, geoScrollSpeed, geoDragScrollButton, geoscapeScale;

0 commit comments

Comments
 (0)