@@ -1091,6 +1091,7 @@ checkpoint_level()
1091
1091
mtmp -> female = poly_gender ();
1092
1092
initedog (mtmp ); /* mark as tame */
1093
1093
mtmp -> mtame = 127 ;
1094
+ mtmp -> mlstmv = monstermoves ; /* indicate what this level's "local time" is */
1094
1095
/* Setting the movement value is very important, so that the other
1095
1096
games know whether they should yield to us this turn. */
1096
1097
mtmp -> movement = youmonst .movement ;
@@ -1157,6 +1158,123 @@ uncheckpoint_level()
1157
1158
return 0 ; /* successful */
1158
1159
}
1159
1160
1161
+ /* Looks at the current level, to deduce what its local time is. We
1162
+ rely on the facts that a) nothing on the level can be dated in the
1163
+ future, and b) any other players on the level are flagged with
1164
+ their current times, so that if there are other players there, the
1165
+ times will line up exactly (to within a turn, anyway). */
1166
+ static long
1167
+ calculate_objchain_local_time (ochain )
1168
+ struct obj * ochain ;
1169
+ {
1170
+ struct obj * otmp ;
1171
+ long localtime = 0L ;
1172
+ for (otmp = ochain ; otmp ; otmp = otmp -> nobj ) {
1173
+ if (age_is_relative (otmp )) continue ;
1174
+ if (otmp -> age > localtime ) localtime = otmp -> age ;
1175
+ /* Age has a different meaning inside ice boxes. */
1176
+ if (Has_contents (otmp ) && otmp -> otyp != ICE_BOX ) {
1177
+ long t = calculate_objchain_local_time (otmp -> cobj );
1178
+ if (t > localtime ) localtime = t ;
1179
+ }
1180
+ }
1181
+ return localtime ;
1182
+ }
1183
+ static long
1184
+ calculate_level_local_time ()
1185
+ {
1186
+ struct monst * mtmp ;
1187
+ long localtime = -1L ;
1188
+ long t ;
1189
+
1190
+ for (mtmp = fmon ; mtmp ; mtmp = mtmp -> nmon ) {
1191
+ if (DEADMONSTER (mtmp )) continue ;
1192
+ if (mtmp -> mlstmv > localtime ) localtime = mtmp -> mlstmv ;
1193
+ if (mtmp -> minvent ) {
1194
+ t = calculate_objchain_local_time (mtmp -> minvent );
1195
+ if (t > localtime ) localtime = t ;
1196
+ }
1197
+ if (mtmp -> mw && mtmp -> mw -> age > localtime ) localtime = mtmp -> mw -> age ;
1198
+ }
1199
+ t = calculate_objchain_local_time (fobj );
1200
+ if (t > localtime ) localtime = t ;
1201
+ t = calculate_objchain_local_time (level .buriedobjlist , FALSE);
1202
+ if (t > localtime ) localtime = t ;
1203
+ if (localtime == -1 ) {
1204
+ /* no monsters or items on the level; this is rather unlikely, but
1205
+ theoretically possible, and in this case we can choose the time
1206
+ we like for the level's local time, so set it to our own local
1207
+ time */
1208
+ localtime = monstermoves ;
1209
+ }
1210
+ return localtime ;
1211
+ }
1212
+
1213
+ static void
1214
+ time_dilate_objchain (ochain , dtime )
1215
+ struct obj * ochain ;
1216
+ long dtime ;
1217
+ {
1218
+ struct obj * otmp ;
1219
+ for (otmp = ochain ; otmp ; otmp = otmp -> nobj ) {
1220
+ if (age_is_relative (otmp )) continue ;
1221
+ otmp -> age += dtime ;
1222
+ /* Age has a different meaning inside ice boxes. */
1223
+ if (Has_contents (otmp ) && otmp -> otyp != ICE_BOX )
1224
+ time_dilate_objchain (otmp -> cobj , dtime );
1225
+ }
1226
+ }
1227
+ static void
1228
+ time_dilate_monchain (mchain , dtime )
1229
+ struct monst * mchain ;
1230
+ long dtime ;
1231
+ {
1232
+ struct monst * mtmp ;
1233
+ for (mtmp = mchain ; mtmp ; mtmp = mtmp -> nmon ) {
1234
+ if (DEADMONSTER (mtmp )) continue ;
1235
+ mtmp -> mlstmv += dtime ;
1236
+ if (mtmp -> minvent ) time_dilate_objchain (mtmp -> minvent , dtime );
1237
+ /* Assume monsters don't wield containers. */
1238
+ if (mtmp -> mw && !age_is_relative (mtmp -> mw )) mtmp -> mw -> age += dtime ;
1239
+ }
1240
+ }
1241
+
1242
+ /* Adjusts all timestamps saved in lockfile 0 by the given amount. */
1243
+ static void
1244
+ time_dilation (dtime )
1245
+ long dtime ;
1246
+ {
1247
+ /* nothing relevant in flags */
1248
+ /* timestamps in struct you */
1249
+ u .ucleansed += dtime ;
1250
+ u .usleep += dtime ;
1251
+ /* timers */
1252
+ adjust_nonlocal_timers (dtime );
1253
+ /* nothing relevant in light sources */
1254
+ /* inventory */
1255
+ time_dilate_objchain (invent , dtime );
1256
+ /* migration */
1257
+ time_dilate_objchain (migrating_objs , dtime );
1258
+ time_dilate_monchain (migrating_mons , dtime );
1259
+ /* nothing relevant in monster statistics */
1260
+ /* nothing relevant in dungeons or level chains */
1261
+ /* time handling */
1262
+ moves += dtime ;
1263
+ monstermoves += dtime ;
1264
+ /* nothing relevant in quest status */
1265
+ /* nothing relevant in spells (perhaps surprisingly, spell
1266
+ knowledge is relative not absolute) */
1267
+ /* nothing relevant in artifacts */
1268
+ /* nothing relevant in oracularities */
1269
+ /* stuck/steed are not multiplayer-safe, so needn't be adjusted */
1270
+ /* nothing relevant in tutorial flags (TODO: the tutorial is currently
1271
+ based on local time, when it should be based on character time,
1272
+ but we can't fix that here) */
1273
+ /* nothing relevant in character name */
1274
+ /* nothing relevant in fruitnames */
1275
+ /* nothing relevant in Plane of Water status */
1276
+ }
1277
+
1160
1278
#ifdef INSURANCE
1161
1279
void
1162
1280
save_currentstate ()
@@ -1504,16 +1622,20 @@ boolean at_stairs, falling, portal;
1504
1622
(void ) close (fd );
1505
1623
}
1506
1624
1507
- /* We must release the lock before anything that could print
1508
- messages, to avoid panicking other processes; the error
1509
- on level file removal above is OK, though, because it can
1510
- only happen if someone's gone around deleting files while
1511
- we have them locked, which would crash those processes
1512
- anyway. */
1513
1625
if (iflags .multiplayer ) {
1626
+ /* We must release the lock before anything that could print
1627
+ messages, to avoid panicking other processes; the error
1628
+ on level file removal above is OK, though, because it can
1629
+ only happen if someone's gone around deleting files while
1630
+ we have them locked, which would crash those processes
1631
+ anyway. */
1514
1632
Strcpy (lock , iflags .mp_lock_name );
1515
1633
set_levelfile_name (lock , new_ledger );
1516
1634
unlock_file (lock );
1635
+
1636
+ /* We also need to adjust for local time, before doing
1637
+ anything that might depend on timers. */
1638
+ time_dilation (calculate_level_local_time () - monstermoves );
1517
1639
}
1518
1640
1519
1641
/* do this prior to level-change pline messages */
0 commit comments