From 03c6fde58d3b12803eb2e5b61804c5d3f81eadf9 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Mon, 27 May 2019 10:47:38 -0700 Subject: [PATCH 01/10] Fixed one cause of rubber-banding player movement in client. No need to navigate all the way back to start of a new path sent by server if we're closer to a spot in the middle of the path. Fixed so that other players never slow down in their movement to match server timing, but still speed up if necessary. (It's always okay for another player to arrive at their destination early, client-side.) --- documentation/changeLog.txt | 14 +++++++++++ gameSource/LivingLifePage.cpp | 46 +++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index 0665db437..27d2a74d8 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -3,6 +3,20 @@ This file only list changes to game code. Changes to content can be found here: http://onehouronelife.com/updateLog.php + +Version 235 ??? + +--Fixed one cause of rubber-banding player movement in client. No need to + navigate all the way back to start of a new path sent by server if we're + closer to a spot in the middle of the path. + +--Fixed so that other players never slow down in their movement to match + server timing, but still speed up if necessary. (It's always okay for + another player to arrive at their destination early, client-side.) + + + + Version 234 2019-May-25 --Fixed long-standing bug when something decays in the hand of a moving player, diff --git a/gameSource/LivingLifePage.cpp b/gameSource/LivingLifePage.cpp index e966abc9d..32fde59ad 100644 --- a/gameSource/LivingLifePage.cpp +++ b/gameSource/LivingLifePage.cpp @@ -15359,26 +15359,33 @@ void LivingLifePage::step() { printf( "Manually forced\n" ); + // find closest spot along path + // to our current pos + double minDist = DBL_MAX; + // prev step - int b = - (int)floor( - fractionPassed * - ( existing->pathLength - 1 ) ); - // next step - int n = - (int)ceil( - fractionPassed * - ( existing->pathLength - 1 ) ); + int b = -1; - if( n == b ) { - if( n < existing->pathLength - 1 ) { - n ++ ; - } - else { - b--; + for( int testB=0; + testB < existing->pathLength - 1; + testB ++ ) { + + doublePair worldPos = gridToDouble( + existing->pathToDest[testB] ); + + double thisDist = + distance( worldPos, + existing->currentPos ); + if( thisDist < minDist ) { + b = testB; + minDist = thisDist; } } + + // next step + int n = b + 1; + existing->currentPathStep = b; doublePair nWorld = @@ -15428,7 +15435,14 @@ void LivingLifePage::step() { double timeAdjust = existing->moveTotalTime * fractionDiff; - existing->moveEtaTime += timeAdjust; + if( fractionDiff < 0 ) { + // only speed up... + // never slow down, because + // it's always okay if we show + // player arriving early + + existing->moveEtaTime += timeAdjust; + } } From 2419cdf75a3d64d2c637851434763c84efdd7649 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Mon, 27 May 2019 14:26:18 -0700 Subject: [PATCH 02/10] Changes to function of /DIE. Can no longer use it to cycle through all families and force yourself to be an unecessary Eve. Eve only spawns if there are really no available motehrs for an incoming baby. /DIE adds this family to your family skip list. If you eventually cycle through all families, so that you've skipped them all, and none are left, your skip list is cleared. --- documentation/changeLog.txt | 11 ++++ server/familySkipList.cpp | 112 ++++++++++++++++++++++++++++++++++++ server/familySkipList.h | 15 +++++ server/makeFileList | 1 + server/server.cpp | 75 ++++++++++++++++++------ 5 files changed, 197 insertions(+), 17 deletions(-) create mode 100644 server/familySkipList.cpp create mode 100644 server/familySkipList.h diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index 27d2a74d8..249e937d1 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -16,6 +16,17 @@ Version 235 ??? +Server Fixes + +--Changes to function of /DIE. Can no longer use it to cycle through all + families and force yourself to be an unecessary Eve. Eve only spawns if + there are really no available motehrs for an incoming baby. /DIE adds this + family to your family skip list. If you eventually cycle through all + families, so that you've skipped them all, and none are left, your skip list + is cleared. + + + Version 234 2019-May-25 diff --git a/server/familySkipList.cpp b/server/familySkipList.cpp new file mode 100644 index 000000000..74259b5ad --- /dev/null +++ b/server/familySkipList.cpp @@ -0,0 +1,112 @@ +#include "familySkipList.h" + +#include "minorGems/util/SimpleVector.h" +#include "minorGems/util/stringUtils.h" +#include "minorGems/system/Time.h" + + + +typedef struct FamilySkipListRecord { + char *babyEmail; + + SimpleVector *skippedLineageList; + + double lastUpdateTime; + } FamilySkipListRecord; + + +static void freeRecordMembers( FamilySkipListRecord *inR ) { + delete [] inR->babyEmail; + delete inR->skippedLineageList; + } + +SimpleVector skipListRecords; + + + +void initFamilySkipList() { + } + + + +void freeFamilySkipList() { + for( int i=0; ibabyEmail, inBabyEmail ) == 0 ) { + return r; + } + else if( curTime - r->lastUpdateTime > 7200 ) { + // record not touched for 2 hours + freeRecordMembers( r ); + skipListRecords.deleteElement( i ); + i--; + } + } + + // no matching email found + + if( ! inMakeNew ) { + return NULL; + } + + FamilySkipListRecord newR = + { stringDuplicate( inBabyEmail ), + new SimpleVector(), + curTime }; + + skipListRecords.push_back( newR ); + + return skipListRecords.getElement( skipListRecords.size() - 1 ); + } + + + +void skipFamily( char *inBabyEmail, int inLineageEveID ) { + FamilySkipListRecord *r = findRecord( inBabyEmail, true ); + + r->skippedLineageList->push_back( inLineageEveID ); + } + + + +void clearSkipList( char *inBabyEmail ) { + FamilySkipListRecord *r = findRecord( inBabyEmail ); + + if( r != NULL ) { + r->skippedLineageList->deleteAll(); + } + } + + + +char isSkipped( char *inBabyEmail, int inLineageEveID ) { + + FamilySkipListRecord *r = findRecord( inBabyEmail ); + + if( r == NULL ) { + return false; + } + + if( r->skippedLineageList->getElementIndex( inLineageEveID ) != -1 ) { + return true; + } + + return false; + } + diff --git a/server/familySkipList.h b/server/familySkipList.h new file mode 100644 index 000000000..3feb8cf6b --- /dev/null +++ b/server/familySkipList.h @@ -0,0 +1,15 @@ + + +void initFamilySkipList(); + + +void freeFamilySkipList(); + + +void skipFamily( char *inBabyEmail, int inLineageEveID ); + + +void clearSkipList( char *inBabyEmail ); + + +char isSkipped( char *inBabyEmail, int inLineageEveID ); diff --git a/server/makeFileList b/server/makeFileList index cbcdc91f0..aa7ea004e 100644 --- a/server/makeFileList +++ b/server/makeFileList @@ -53,6 +53,7 @@ curseLog.cpp \ spiral.cpp \ objectSurvey.cpp \ language.cpp \ +familySkipList.cpp \ diff --git a/server/server.cpp b/server/server.cpp index 7129f7479..75e68f2e9 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -50,6 +50,7 @@ #include "lineageLimit.h" #include "objectSurvey.h" #include "language.h" +#include "familySkipList.h" #include "minorGems/util/random/JenkinsRandomSource.h" @@ -1325,7 +1326,7 @@ void quitCleanup() { freeObjectSurvey(); freeLanguage(); - + freeFamilySkipList(); freeTriggers(); @@ -5197,6 +5198,31 @@ int processLoggedInPlayer( Socket *inSock, } else { // baby + + + + // filter parent choices by this baby's skip list + SimpleVector + filteredParentChoices( parentChoices.size() ); + + for( int i=0; ilineageEveID ) ) { + filteredParentChoices.push_back( p ); + } + } + + if( filteredParentChoices.size() == 0 ) { + // baby has skipped everyone + + // clear their list and let them start over again + clearSkipList( inEmail ); + + filteredParentChoices.push_back_other( &parentChoices ); + } + + // pick random mother from a weighted distribution based on // each mother's temperature @@ -5205,8 +5231,8 @@ int processLoggedInPlayer( Socket *inSock, int maxYumMult = 1; - for( int i=0; iyummyFoodChain.size() - 1; @@ -5226,8 +5252,8 @@ int processLoggedInPlayer( Socket *inSock, double totalWeight = 0; - for( int i=0; iheat - 0.5 ); @@ -5249,8 +5275,8 @@ int processLoggedInPlayer( Socket *inSock, totalWeight = 0; - for( int i=0; iheat - 0.5 ); @@ -8400,6 +8426,7 @@ int main() { initObjectSurvey(); initLanguage(); + initFamilySkipList(); initTriggers(); @@ -13546,16 +13573,30 @@ int main() { double yearsLived = getSecondsPlayed( nextPlayer ) * getAgeRate(); - if( ! nextPlayer->isTutorial ) - recordLineage( nextPlayer->email, - nextPlayer->originalBirthPos, - yearsLived, - // count true murder victims here, not suicide - ( killerID > 0 && killerID != nextPlayer->id ), - // killed other or committed SID suicide - nextPlayer->everKilledAnyone || - nextPlayer->suicide ); - + if( ! nextPlayer->isTutorial ) { + + recordLineage( + nextPlayer->email, + nextPlayer->originalBirthPos, + yearsLived, + // count true murder victims here, not suicide + ( killerID > 0 && killerID != nextPlayer->id ), + // killed other or committed SID suicide + // CHANGE: + // no longer count SID toward lineage ban + // we added this family to baby's skip + // list below + nextPlayer->everKilledAnyone ); + + if( nextPlayer->suicide ) { + // add to player's skip list + skipFamily( nextPlayer->email, + nextPlayer->lineageEveID ); + } + } + + + if( ! nextPlayer->deathLogged ) { char disconnect = true; From c964b815e94ecb955472b6b52635dbf33eba3986 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Tue, 28 May 2019 14:10:17 -0700 Subject: [PATCH 03/10] When the server has 15 or more simultaneous players, 200 map database entries are examined every periodic server step (4x per second), and any entries in regions that have not been seen by players in 8 hours are set back to their natural state. Depending on the size of the database, walking through all entries can take quite a while (the current bigserver2 database has 25 million entries, so that would take 8 hours at the current rate). Thus, the actual decay-back-to-nature time will be at least 8 hours, due to the time it takes to walk through all database entries. Also, a group of tiles will potentially clear in an uneven sequence, based on their order in the database. Thus, partial ruins are possible. --- documentation/changeLog.txt | 11 + server/map.cpp | 260 +++++++++++++----- server/map.h | 6 + server/server.cpp | 2 + server/settings/longTermNoLookCullSeconds.ini | 1 + .../minActivePlayersForLongTermCulling.ini | 1 + .../settings/numTilesExaminedPerCullStep.ini | 1 + 7 files changed, 215 insertions(+), 67 deletions(-) create mode 100644 server/settings/longTermNoLookCullSeconds.ini create mode 100644 server/settings/minActivePlayersForLongTermCulling.ini create mode 100644 server/settings/numTilesExaminedPerCullStep.ini diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index 249e937d1..bc602ec87 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -25,6 +25,17 @@ Server Fixes families, so that you've skipped them all, and none are left, your skip list is cleared. +--When the server has 15 or more simultaneous players, 200 map database entries + are examined every periodic server step (4x per second), and any entries in + regions that have not been seen by players in 8 hours are set back to their + natural state. Depending on the size of the database, walking through all + entries can take quite a while (the current bigserver2 database has 25 + million entries, so that would take 8 hours at the current rate). Thus, the + actual decay-back-to-nature time will be at least 8 hours, due to the time it + takes to walk through all database entries. Also, a group of tiles will + potentially clear in an uneven sequence, based on their order in the + database. Thus, partial ruins are possible. + diff --git a/server/map.cpp b/server/map.cpp index ba3d8e403..0a5a2b75e 100644 --- a/server/map.cpp +++ b/server/map.cpp @@ -5139,100 +5139,108 @@ void checkDecayContained( int inX, int inY, int inSubCont ) { } -int getMapObjectRaw( int inX, int inY ) { - int result = dbGet( inX, inY, 0 ); + + +int getTweakedBaseMap( int inX, int inY ) { - if( result == -1 ) { - // nothing in map - char wasGridPlacement = false; + // nothing in map + char wasGridPlacement = false; - result = getBaseMap( inX, inY, &wasGridPlacement ); + int result = getBaseMap( inX, inY, &wasGridPlacement ); - if( result > 0 ) { - ObjectRecord *o = getObject( result ); + if( result > 0 ) { + ObjectRecord *o = getObject( result ); - if( o->wide ) { - // make sure there's not possibly another wide object too close - int maxR = getMaxWideRadius(); + if( o->wide ) { + // make sure there's not possibly another wide object too close + int maxR = getMaxWideRadius(); - for( int dx = -( o->leftBlockingRadius + maxR ); - dx <= ( o->rightBlockingRadius + maxR ); dx++ ) { + for( int dx = -( o->leftBlockingRadius + maxR ); + dx <= ( o->rightBlockingRadius + maxR ); dx++ ) { - if( dx != 0 ) { - int nID = getBaseMap( inX + dx, inY ); + if( dx != 0 ) { + int nID = getBaseMap( inX + dx, inY ); - if( nID > 0 ) { - ObjectRecord *nO = getObject( nID ); + if( nID > 0 ) { + ObjectRecord *nO = getObject( nID ); - if( nO->wide ) { + if( nO->wide ) { - int minDist; - int dist; + int minDist; + int dist; - if( dx < 0 ) { - minDist = nO->rightBlockingRadius + - o->leftBlockingRadius; - dist = -dx; - } - else { - minDist = nO->leftBlockingRadius + - o->rightBlockingRadius; - dist = dx; - } + if( dx < 0 ) { + minDist = nO->rightBlockingRadius + + o->leftBlockingRadius; + dist = -dx; + } + else { + minDist = nO->leftBlockingRadius + + o->rightBlockingRadius; + dist = dx; + } - if( dist <= minDist ) { - // collision - // don't allow this wide object here - return 0; - } + if( dist <= minDist ) { + // collision + // don't allow this wide object here + return 0; } } } } } - else if( !wasGridPlacement && getObjectHeight( result ) < CELL_D ) { - // a short object should be here - // and it wasn't forced by a grid placement + } + else if( !wasGridPlacement && getObjectHeight( result ) < CELL_D ) { + // a short object should be here + // and it wasn't forced by a grid placement - // make sure there's not any semi-short objects below already + // make sure there's not any semi-short objects below already - // this avoids vertical stacking of short objects - // and ensures that the map is sparse with short object - // clusters, even in very dense map areas - // (we don't want the floor tiled with berry bushes) + // this avoids vertical stacking of short objects + // and ensures that the map is sparse with short object + // clusters, even in very dense map areas + // (we don't want the floor tiled with berry bushes) - // this used to be an unintentional bug, but it was in place - // for a year, and we got used to it. + // this used to be an unintentional bug, but it was in place + // for a year, and we got used to it. - // when the bug was fixed, the map became way too dense - // in short-object areas + // when the bug was fixed, the map became way too dense + // in short-object areas - // actually, fully replicate the bug for now - // only block short objects with objects to the south - // that extend above the tile midline + // actually, fully replicate the bug for now + // only block short objects with objects to the south + // that extend above the tile midline - // So we can have clusters of very short objects, like stones - // but not less-short ones like berry bushes, rabbit holes, etc. + // So we can have clusters of very short objects, like stones + // but not less-short ones like berry bushes, rabbit holes, etc. - // use the old buggy "2 pixels" and "3 pixels" above the - // midline measure just to keep the map the same + // use the old buggy "2 pixels" and "3 pixels" above the + // midline measure just to keep the map the same - // south - int sID = getBaseMap( inX, inY - 1 ); + // south + int sID = getBaseMap( inX, inY - 1 ); - if( sID > 0 && getObjectHeight( sID ) >= 2 ) { - return 0; - } + if( sID > 0 && getObjectHeight( sID ) >= 2 ) { + return 0; + } - int s2ID = getBaseMap( inX, inY - 2 ); + int s2ID = getBaseMap( inX, inY - 2 ); - if( s2ID > 0 && getObjectHeight( s2ID ) >= 3 ) { - return 0; - } - } - - } - + if( s2ID > 0 && getObjectHeight( s2ID ) >= 3 ) { + return 0; + } + } + } + return result; + } + + + +int getMapObjectRaw( int inX, int inY ) { + int result = dbGet( inX, inY, 0 ); + + if( result == -1 ) { + result = getTweakedBaseMap( inX, inY ); } return result; @@ -7659,3 +7667,121 @@ void setGravePlayerID( int inX, int inY, int inPlayerID ) { DB_put( &graveDB, key, value ); } + + + + + +static char tileCullingIteratorSet = false; +static DB_Iterator tileCullingIterator; + +static char floorCullingIteratorSet = false; +static DB_Iterator floorCullingIterator; + +static double lastSettingsLoadTime = 0; +static double settingsLoadInterval = 5 * 60; + +static int numTilesExaminedPerCullStep = 10; +static int longTermCullingSeconds = 3600 * 12; + +static int minActivePlayersForLongTermCulling = 15; + + +void stepMapLongTermCulling( int inNumCurrentPlayers ) { + + double curTime = Time::getCurrentTime(); + + if( curTime - lastSettingsLoadTime > settingsLoadInterval ) { + + lastSettingsLoadTime = curTime; + + numTilesExaminedPerCullStep = + SettingsManager::getIntSetting( + "numTilesExaminedPerCullStep", 10 ); + longTermCullingSeconds = + SettingsManager::getIntSetting( + "longTermNoLookCullSeconds", 3600 * 12 ); + minActivePlayersForLongTermCulling = + SettingsManager::getIntSetting( + "minActivePlayersForLongTermCulling", 15 ); + } + + + if( minActivePlayersForLongTermCulling > inNumCurrentPlayers ) { + return; + } + + + if( !tileCullingIteratorSet ) { + DB_Iterator_init( &db, &tileCullingIterator ); + tileCullingIteratorSet = true; + } + + unsigned char tileKey[16]; + unsigned char floorKey[8]; + unsigned char value[4]; + + + for( int i=0; i 0 ) { + // next value + + int s = valueToInt( &( tileKey[8] ) ); + int b = valueToInt( &( tileKey[12] ) ); + + if( s == 0 && b == 0 ) { + // main object + int x = valueToInt( tileKey ); + int y = valueToInt( &( tileKey[4] ) ); + + timeSec_t lastLookTime = dbLookTimeGet( x, y ); + + if( curTime - lastLookTime > longTermCullingSeconds ) { + // stale + clearAllContained( x, y ); + + // put proc-genned map value in there + setMapObject( x, y, getTweakedBaseMap( x, y ) ); + } + } + } + } + + + + if( !floorCullingIteratorSet ) { + DB_Iterator_init( &floorDB, &floorCullingIterator ); + floorCullingIteratorSet = true; + } + + + for( int i=0; i 0 ) { + // next value + + int x = valueToInt( floorKey ); + int y = valueToInt( &( floorKey[4] ) ); + + timeSec_t lastLookTime = dbLookTimeGet( x, y ); + + if( curTime - lastLookTime > longTermCullingSeconds ) { + // stale + setMapFloor( x, y, 0 ); + } + } + } + } diff --git a/server/map.h b/server/map.h index c34e4ac11..e3222551b 100644 --- a/server/map.h +++ b/server/map.h @@ -299,4 +299,10 @@ int getGravePlayerID( int inX, int inY ); void setGravePlayerID( int inX, int inY, int inPlayerID ); + +// culling regions of map that haven't been seen in a long time +void stepMapLongTermCulling( int inNumCurrentPlayers ); + + + #endif diff --git a/server/server.cpp b/server/server.cpp index 75e68f2e9..25ce33799 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -8637,6 +8637,8 @@ int main() { stepPlayerStats(); stepLineageLog(); stepCurseServerRequests(); + + stepMapLongTermCulling( players.size() ); } diff --git a/server/settings/longTermNoLookCullSeconds.ini b/server/settings/longTermNoLookCullSeconds.ini new file mode 100644 index 000000000..b913d7e04 --- /dev/null +++ b/server/settings/longTermNoLookCullSeconds.ini @@ -0,0 +1 @@ +28800 \ No newline at end of file diff --git a/server/settings/minActivePlayersForLongTermCulling.ini b/server/settings/minActivePlayersForLongTermCulling.ini new file mode 100644 index 000000000..3f10ffe7a --- /dev/null +++ b/server/settings/minActivePlayersForLongTermCulling.ini @@ -0,0 +1 @@ +15 \ No newline at end of file diff --git a/server/settings/numTilesExaminedPerCullStep.ini b/server/settings/numTilesExaminedPerCullStep.ini new file mode 100644 index 000000000..ae4ee13c0 --- /dev/null +++ b/server/settings/numTilesExaminedPerCullStep.ini @@ -0,0 +1 @@ +200 \ No newline at end of file From ebf2902446cc85c35af8a71e5c48196412c06c68 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Tue, 28 May 2019 15:09:43 -0700 Subject: [PATCH 04/10] Don't spawn non-cursed Eve near donkey town. --- documentation/changeLog.txt | 3 +++ server/server.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index bc602ec87..133dad711 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -36,6 +36,9 @@ Server Fixes potentially clear in an uneven sequence, based on their order in the database. Thus, partial ruins are possible. +--Don't spawn non-cursed Eve near donkey town. + + diff --git a/server/server.cpp b/server/server.cpp index 25ce33799..bc3aa45f8 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -5486,7 +5486,17 @@ int processLoggedInPlayer( Socket *inSock, // else starts at civ outskirts (lone Eve) SimpleVector otherPeoplePos( numPlayers ); + + + // consider players to be near Eve location that match + // Eve's curse status + char seekingCursed = false; + + if( inCurseStatus.curseLevel > 0 ) { + seekingCursed = true; + } + for( int i=0; ivogMode ) { continue; } + + if( seekingCursed && player->curseStatus.curseLevel <= 0 ) { + continue; + } + else if( ! seekingCursed && + player->curseStatus.curseLevel > 0 ) { + continue; + } + GridPos p = { player->xs, player->ys }; otherPeoplePos.push_back( p ); } From 10e9b49dca89cd9e50895a883a0e98c9ab9e0f89 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Tue, 28 May 2019 15:29:56 -0700 Subject: [PATCH 05/10] Always reset mother's birth cool down if baby does /DIE, whether ever held or not. --- documentation/changeLog.txt | 2 ++ server/server.cpp | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index 133dad711..5f154284c 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -38,6 +38,8 @@ Server Fixes --Don't spawn non-cursed Eve near donkey town. +--Always reset mother's birth cool down if baby does /DIE, whether ever held + or not. diff --git a/server/server.cpp b/server/server.cpp index bc3aa45f8..ed7eecbf1 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -10210,7 +10210,21 @@ int main() { LiveObject *parentO = getLiveObject( parentID ); - if( parentO != NULL && nextPlayer->everHeldByParent ) { + // CHANGE: + // Reset mother's cool-down whenever baby suicides + // Otherwise, if DIE baby acts quick enough + // they can cycle through all families, putting + // each mother on cooldown, and end up as Eve + // intentionally + // + // Old: only if she picked up baby one time. + // (also, with instant map load, it's easy + // for baby to run away before being picked + // up by a mother that wants the baby) + // + //if( parentO != NULL && + // nextPlayer->everHeldByParent ) { + if( parentO != NULL ) { // mother picked up this SID baby at least // one time // mother can have another baby right away From b33eae6c249103b32b4c0163bb5fe1e57c1d3a35 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Tue, 28 May 2019 15:49:03 -0700 Subject: [PATCH 06/10] Mother's birth cool-down instantly resets when her most-recent baby dies of any cause. --- documentation/changeLog.txt | 3 +++ server/server.cpp | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index 5f154284c..e0ebb7213 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -41,6 +41,9 @@ Server Fixes --Always reset mother's birth cool down if baby does /DIE, whether ever held or not. +--Mother's birth cool-down instantly resets when her most-recent baby dies of + any cause. + diff --git a/server/server.cpp b/server/server.cpp index ed7eecbf1..e5b448634 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -10225,8 +10225,6 @@ int main() { //if( parentO != NULL && // nextPlayer->everHeldByParent ) { if( parentO != NULL ) { - // mother picked up this SID baby at least - // one time // mother can have another baby right away parentO->birthCoolDown = 0; } @@ -13520,6 +13518,27 @@ int main() { &playerIndicesToSendUpdatesAbout ); } + + if( nextPlayer->parentID != -1 ) { + + LiveObject *parentO = + getLiveObject( nextPlayer->parentID ); + + if( parentO != NULL ) { + + if( parentO->babyIDs->getElementIndex( nextPlayer->id ) + == parentO->babyIDs->size() - 1 ) { + + // this mother's most-recent baby just died + + // mother can have another baby right away + parentO->birthCoolDown = 0; + } + } + } + + + newDeleteUpdates.push_back( getUpdateRecord( nextPlayer, true ) ); From c731371c800d43ac9386bc0941e25528bf4f95d6 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Tue, 28 May 2019 17:49:02 -0700 Subject: [PATCH 07/10] Added script for forcing a server shutdown. --- scripts/forceOneServerShutdown.ini | 1 + 1 file changed, 1 insertion(+) create mode 100755 scripts/forceOneServerShutdown.ini diff --git a/scripts/forceOneServerShutdown.ini b/scripts/forceOneServerShutdown.ini new file mode 100755 index 000000000..dcef81a7a --- /dev/null +++ b/scripts/forceOneServerShutdown.ini @@ -0,0 +1 @@ +cd ~/checkout/OneLife/server; echo 1 > settings/forceShutdownMode.ini; sleep 2; git checkout settings/forceShutdownMode.ini \ No newline at end of file From 7292535f9fca5333bff52f3ba9038b530ea77273 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Wed, 29 May 2019 10:01:26 -0700 Subject: [PATCH 08/10] Max birth cool-down for mother is 3 minutes instead of 5 (mean 1.2 minutes instead of 2 minutes). --- documentation/changeLog.txt | 2 ++ server/server.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index e0ebb7213..b4406c856 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -44,6 +44,8 @@ Server Fixes --Mother's birth cool-down instantly resets when her most-recent baby dies of any cause. +--Max birth cool-down for mother is 3 minutes instead of 5 (mean 1.2 minutes + instead of 2 minutes). diff --git a/server/server.cpp b/server/server.cpp index e5b448634..d7e99dcfa 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -906,8 +906,8 @@ static double pickBirthCooldownSeconds() { // v is in [0..1], the value range of Kumaraswamy - // put max at 5 minutes - return v * 5 * 60; + // put max at 3 minutes + return v * 3 * 60; } From acc2bec02ea414f1ce4cf6165945bec497c74346 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Wed, 29 May 2019 13:07:08 -0700 Subject: [PATCH 09/10] Ancient stone walls are left standing during 8-hour-no-look map culling. --- documentation/changeLog.txt | 3 +++ server/map.cpp | 39 +++++++++++++++++++++++++----- server/settings/noCullItemList.ini | 7 ++++++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 server/settings/noCullItemList.ini diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index b4406c856..b4d4b39f3 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -47,6 +47,9 @@ Server Fixes --Max birth cool-down for mother is 3 minutes instead of 5 (mean 1.2 minutes instead of 2 minutes). +--Ancient stone walls are left standing during 8-hour-no-look map culling. + + Version 234 2019-May-25 diff --git a/server/map.cpp b/server/map.cpp index 0a5a2b75e..887f9fbf1 100644 --- a/server/map.cpp +++ b/server/map.cpp @@ -7686,6 +7686,8 @@ static int longTermCullingSeconds = 3600 * 12; static int minActivePlayersForLongTermCulling = 15; +static SimpleVector noCullItemList; + void stepMapLongTermCulling( int inNumCurrentPlayers ) { @@ -7704,6 +7706,13 @@ void stepMapLongTermCulling( int inNumCurrentPlayers ) { minActivePlayersForLongTermCulling = SettingsManager::getIntSetting( "minActivePlayersForLongTermCulling", 15 ); + + SimpleVector *list = + SettingsManager::getIntSettingMulti( "noCullItemList" ); + + noCullItemList.deleteAll(); + noCullItemList.push_back_other( list ); + delete list; } @@ -7729,8 +7738,13 @@ void stepMapLongTermCulling( int inNumCurrentPlayers ) { if( result <= 0 ) { // restart the iterator back at the beginning DB_Iterator_init( &db, &tileCullingIterator ); + continue; } - else if( valueToInt( value ) > 0 ) { + + + int tileID = valueToInt( value ); + + if( tileID > 0 ) { // next value int s = valueToInt( &( tileKey[8] ) ); @@ -7745,10 +7759,14 @@ void stepMapLongTermCulling( int inNumCurrentPlayers ) { if( curTime - lastLookTime > longTermCullingSeconds ) { // stale - clearAllContained( x, y ); + + if( noCullItemList.getElementIndex( tileID ) == -1 ) { + // not on our no-cull list + clearAllContained( x, y ); - // put proc-genned map value in there - setMapObject( x, y, getTweakedBaseMap( x, y ) ); + // put proc-genned map value in there + setMapObject( x, y, getTweakedBaseMap( x, y ) ); + } } } } @@ -7769,8 +7787,12 @@ void stepMapLongTermCulling( int inNumCurrentPlayers ) { if( result <= 0 ) { // restart the iterator back at the beginning DB_Iterator_init( &floorDB, &floorCullingIterator ); + continue; } - else if( valueToInt( value ) > 0 ) { + + int floorID = valueToInt( value ); + + if( floorID > 0 ) { // next value int x = valueToInt( floorKey ); @@ -7780,7 +7802,12 @@ void stepMapLongTermCulling( int inNumCurrentPlayers ) { if( curTime - lastLookTime > longTermCullingSeconds ) { // stale - setMapFloor( x, y, 0 ); + + if( noCullItemList.getElementIndex( floorID ) == -1 ) { + // not on our no-cull list + + setMapFloor( x, y, 0 ); + } } } } diff --git a/server/settings/noCullItemList.ini b/server/settings/noCullItemList.ini new file mode 100644 index 000000000..6d25c2e9c --- /dev/null +++ b/server/settings/noCullItemList.ini @@ -0,0 +1,7 @@ +895 +896 +897 +983 +984 +996 +997 From c3fa18db0aab879a93a98e8fc9f2601252acdb06 Mon Sep 17 00:00:00 2001 From: Jason Rohrer Date: Wed, 29 May 2019 18:11:24 -0700 Subject: [PATCH 10/10] Preparing for binary client v235 --- documentation/changeLog.txt | 2 +- gameSource/game.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/changeLog.txt b/documentation/changeLog.txt index b4d4b39f3..bb784a55a 100644 --- a/documentation/changeLog.txt +++ b/documentation/changeLog.txt @@ -4,7 +4,7 @@ http://onehouronelife.com/updateLog.php -Version 235 ??? +Version 235 2019-May-29 --Fixed one cause of rubber-banding player movement in client. No need to navigate all the way back to start of a new path sent by server if we're diff --git a/gameSource/game.cpp b/gameSource/game.cpp index 8619f9974..8d67f9906 100644 --- a/gameSource/game.cpp +++ b/gameSource/game.cpp @@ -1,4 +1,4 @@ -int versionNumber = 234; +int versionNumber = 235; int dataVersionNumber = 0; int binVersionNumber = versionNumber;