Skip to content

Commit 3836ed9

Browse files
authored
Merge branch 'dev' into change-serv-map-arguments
2 parents 05022e2 + 7391d7d commit 3836ed9

5 files changed

Lines changed: 38 additions & 11 deletions

File tree

‎Changelog.txt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4149,6 +4149,10 @@ When setting a property like MORE to the a spell or skill defname, trying to rea
41494149
WARNING! POTENTIALLY BREAKING CHANGE!
41504150
- Changed: Chance to hit in `CombatDamageEra=0` (Sphere custom) now returns calculated value, instead of random number from that value.
41514151

4152+
03-10-2026, yeiffet
4153+
- Fixed: "vector too long" exception in CWorldTicker, which made some characters stop ticking, so they couldn't die (#1593).
4154+
41524155
08-10-2026, Mulambo
4156+
- Changed: Equipped armor / weapon will also drop on ground when moving it while overweight, like other items (unless OF_OWNoDropCarriedItem is enabled).
41534157
WARNING! POTENTIALLY BREAKING CHANGE!
41544158
- Changed: `serv.map(location)` 3rd parameter is now always `z` position (was `map` when received 3 arguments or `z` when received 4 arguments).

‎src/game/CWorldTicker.cpp‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ static void UnsortedVecDifference(
3232
ASSERT(vecElemBuffer.empty());
3333

3434
// Reserve space in vecElemBuffer to avoid reallocations
35-
vecElemBuffer.reserve(vecMain.size() - vecToRemoveUnsorted.size());
35+
vecElemBuffer.reserve(vecMain.size());
3636

3737
/*
3838
// IMPLEMENTATION 1: linear, no bulk insertions
@@ -116,14 +116,10 @@ static void SortedVecRemoveAddQueued(
116116
ASSERT(!sl::SortedContainerHasDuplicates(vecToAdd));
117117
#endif
118118

119-
if (!vecToRemoveUnsorted.empty())
119+
if (!vecToRemoveUnsorted.empty() && !vecMain.empty())
120120
{
121-
if (vecMain.empty()) {
122-
ASSERT(false); // Shouldn't ever happen.
123-
}
124-
125121
vecElemBuffer.clear();
126-
vecElemBuffer.reserve(vecMain.size() - vecToRemoveUnsorted.size());
122+
vecElemBuffer.reserve(vecMain.size());
127123

128124
// Unsorted custom algorithm.
129125
// We can't use a classical sorted algorithm because vecMain is sorted by pair.first (int64 timeout)
@@ -355,6 +351,7 @@ bool CWorldTicker::_EraseTimedObject(CTimedObject* pTimedObject)
355351
{
356352
// It isn't in the ticking list, or we already have received a remove request.
357353
ASSERT(false); // Not legit.
354+
return false;
358355
}
359356

360357
#ifdef DEBUG_CTIMEDOBJ_TIMED_TICKING
@@ -625,6 +622,12 @@ bool CWorldTicker::_EraseCharTicking(CChar* pChar)
625622
}
626623
#endif
627624

625+
if (_vPeriodicCharsEraseRequests.cend() !=
626+
std::find(_vPeriodicCharsEraseRequests.cbegin(), _vPeriodicCharsEraseRequests.cend(), pChar))
627+
{
628+
return true;
629+
}
630+
628631
_vPeriodicCharsEraseRequests.emplace_back(pChar);
629632

630633
return true;
@@ -1316,6 +1319,8 @@ void CWorldTicker::ProcessCharPeriodicTicks()
13161319
if (pChar->_IsSleeping() || pChar->_IsBeingDeleted())
13171320
continue;
13181321

1322+
pChar->_iTimePeriodicTick = 0;
1323+
13191324
_vPeriodicCharsTicksBuffer.emplace_back(pChar);
13201325
_vIndexMiscBuffer.emplace_back(uiProgressive);
13211326
}
@@ -1350,7 +1355,11 @@ void CWorldTicker::ProcessCharPeriodicTicks()
13501355
EXC_TRYSUB("Char Periodic Ticks Loop");
13511356
for (CChar* pChar : _vPeriodicCharsTicksBuffer) // Loop through all msecs stored, unless we passed the timestamp.
13521357
{
1353-
pChar->_iTimePeriodicTick = 0;
1358+
if (pChar->_IsBeingDeleted() || pChar->_IsSleeping())
1359+
{
1360+
continue;
1361+
}
1362+
13541363
if (pChar->OnTickPeriodic())
13551364
{
13561365
if (!pChar->IsPeriodicTickPending())

‎src/game/chars/CCharAct.cpp‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3126,7 +3126,8 @@ bool CChar::ItemBounce( CItem * pItem, bool fDisplayMsg )
31263126
}
31273127
}
31283128
}
3129-
else if ( pItem->GetEquipLayer() > LAYER_NONE && pItem->GetEquipLayer() <= LAYER_LEGS) //If we are overweight, we don't want our equipped items to fall on the ground. They will remain equipped.
3129+
// Item is equipped (armor / weapon), char is overweight and optional flag OWNoDropCarriedItem is enabled, so we keep it equipped.
3130+
else if (pItem->GetEquipLayer() > LAYER_NONE && pItem->GetEquipLayer() <= LAYER_LEGS && IsSetOF(OF_OWNoDropCarriedItem))
31303131
{
31313132
SysMessageDefault(DEFMSG_MSG_HEAVY);
31323133
return false;
@@ -3142,6 +3143,7 @@ bool CChar::ItemBounce( CItem * pItem, bool fDisplayMsg )
31423143
}
31433144
else if (fDropOnGround)
31443145
{
3146+
// @todo This duplicates CItem::MoveToCheck() almost exactly.
31453147
if ( !GetTopPoint().IsValidPoint() )
31463148
{
31473149
// NPC is being created and has no valid point yet.
@@ -3157,6 +3159,14 @@ bool CChar::ItemBounce( CItem * pItem, bool fDisplayMsg )
31573159
const CObjBase* pItemContPrev = pItem->GetContainer();
31583160
int64 iDecayTime = pItem->GetDecayTime();
31593161
CPointMap ptDrop(GetTopPoint());
3162+
3163+
if ( iDecayTime > 0 )
3164+
{
3165+
const CRegion * pRegion = ptDrop.GetRegion(REGION_TYPE_MULTI|REGION_TYPE_AREA|REGION_TYPE_ROOM);
3166+
if ( pRegion != nullptr && pRegion->IsFlag(REGION_FLAG_NODECAY) )
3167+
iDecayTime = -1 * MSECS_PER_SEC;
3168+
}
3169+
31603170
TRIGRET_TYPE ttResult = TRIGRET_RET_DEFAULT;
31613171
if (IsTrigUsed(TRIGGER_DROPON_GROUND) || IsTrigUsed(TRIGGER_ITEMDROPON_GROUND))
31623172
{

‎src/game/chars/CCharStat.cpp‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,10 @@ void CChar::Stat_AddVal( STAT_TYPE i, int iVal )
209209

210210
if ((i == STAT_STR) && (iVal <= 0))
211211
{ // Ensure this char will tick and die
212-
CWorldTickingList::AddCharPeriodic(this, false);
212+
if (!IsPeriodicTickPending())
213+
{
214+
CWorldTickingList::AddCharPeriodic(this, false);
215+
}
213216
}
214217
}
215218

‎src/game/clients/CClientMsg.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2929,8 +2929,9 @@ byte CClient::Setup_Play( uint iSlot ) // After hitting "Play Character" button
29292929
if ( pCharLast && pAccount->IsMyAccountChar( pCharLast ) && pAccount->GetPrivLevel() <= PLEVEL_GM &&
29302930
! pCharLast->IsDisconnected() && (pChar->GetUID() != pCharLast->GetUID()))
29312931
{
2932+
// Login was successful, display warning only.
29322933
addIdleWarning(PacketWarningMessage::CharacterInWorld);
2933-
return(PacketLoginError::CharIdle);
2934+
return PacketLoginError::Success;
29342935
}
29352936

29362937
// LastLogged update

0 commit comments

Comments
 (0)