Implement game time locking

implement for quests
This commit is contained in:
KingRainbow44 2023-05-08 00:11:29 -04:00
parent d32f6982be
commit a4f5d3286d
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
4 changed files with 61 additions and 11 deletions

View File

@ -0,0 +1,20 @@
package emu.grasscutter.game.quest.exec;
import emu.grasscutter.data.excels.quest.QuestData.QuestExecParam;
import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.QuestValueExec;
import emu.grasscutter.game.quest.enums.QuestExec;
import emu.grasscutter.game.quest.handlers.QuestExecHandler;
import java.util.Objects;
@QuestValueExec(QuestExec.QUEST_EXEC_SET_IS_GAME_TIME_LOCKED)
public final class ExecSetGameTimeLocked extends QuestExecHandler {
@Override
public boolean execute(GameQuest quest, QuestExecParam condition, String... paramStr) {
var isLocked = Objects.equals(condition.getParam()[0], "1");
quest.getOwner().getWorld().lockTime(isLocked);
return true;
}
}

View File

@ -510,7 +510,8 @@ public final class Scene {
this.finishLoading(); this.finishLoading();
this.checkPlayerRespawn(); this.checkPlayerRespawn();
if (this.tickCount++ % 10 == 0) broadcastPacket(new PacketSceneTimeNotify(this)); if (this.tickCount++ % 10 == 0)
this.broadcastPacket(new PacketSceneTimeNotify(this));
} }
/** Validates a player's current position. Teleports the player if the player is out of bounds. */ /** Validates a player's current position. Teleports the player if the player is out of bounds. */

View File

@ -31,7 +31,7 @@ import java.util.stream.Collectors;
import lombok.Getter; import lombok.Getter;
import lombok.val; import lombok.val;
public class World implements Iterable<Player> { public final class World implements Iterable<Player> {
@Getter private final GameServer server; @Getter private final GameServer server;
@Getter private final Player host; @Getter private final Player host;
@Getter private final List<Player> players; @Getter private final List<Player> players;
@ -42,12 +42,12 @@ public class World implements Iterable<Player> {
private int nextPeerId = 0; private int nextPeerId = 0;
private int worldLevel; private int worldLevel;
private boolean isMultiplayer; @Getter private boolean isMultiplayer, timeLocked = false;
private long lastUpdateTime; private long lastUpdateTime;
@Getter private int tickCount = 0; @Getter private int tickCount = 0;
@Getter private boolean isPaused = false; @Getter private boolean isPaused = false;
@Getter private long currentWorldTime = 0; @Getter private long currentWorldTime;
public World(Player player) { public World(Player player) {
this(player, false); this(player, false);
@ -118,10 +118,6 @@ public class World implements Iterable<Player> {
return this.getPlayers().size(); return this.getPlayers().size();
} }
public boolean isMultiplayer() {
return isMultiplayer;
}
/** /**
* Gets the next entity ID for the specified entity type. * Gets the next entity ID for the specified entity type.
* *
@ -427,7 +423,7 @@ public class World implements Iterable<Player> {
// store updated world time every 60 seconds. (in-game hour) // store updated world time every 60 seconds. (in-game hour)
if (this.tickCount % 60 == 0) { if (this.tickCount % 60 == 0) {
this.getHost().updatePlayerGameTime(currentWorldTime); this.getHost().updatePlayerGameTime(this.currentWorldTime);
} }
this.tickCount++; this.tickCount++;
@ -438,13 +434,13 @@ public class World implements Iterable<Player> {
/** Returns the in-game world time in real milliseconds. */ /** Returns the in-game world time in real milliseconds. */
public long getWorldTime() { public long getWorldTime() {
if (!this.isPaused) { if (!this.isPaused && !this.timeLocked) {
var newUpdateTime = System.currentTimeMillis(); var newUpdateTime = System.currentTimeMillis();
this.currentWorldTime += (newUpdateTime - lastUpdateTime); this.currentWorldTime += (newUpdateTime - lastUpdateTime);
this.lastUpdateTime = newUpdateTime; this.lastUpdateTime = newUpdateTime;
} }
return currentWorldTime; return this.currentWorldTime;
} }
/** Returns the current in game days world time in in-game minutes (0-1439) */ /** Returns the current in game days world time in in-game minutes (0-1439) */
@ -512,6 +508,9 @@ public class World implements Iterable<Player> {
* @param days The number of days to add. * @param days The number of days to add.
*/ */
public void changeTime(int time, int days) { public void changeTime(int time, int days) {
// Check if the time is locked.
if (this.timeLocked) return;
// Calculate time differences. // Calculate time differences.
var currentTime = this.getGameTime(); var currentTime = this.getGameTime();
var diff = time - currentTime; var diff = time - currentTime;
@ -526,6 +525,18 @@ public class World implements Iterable<Player> {
player -> player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK)); player -> player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK));
} }
/**
* Locks the world time.
*
* @param locked True if the world time should be locked.
*/
public void lockTime(boolean locked) {
this.timeLocked = locked;
// Broadcast the state change.
this.broadcastPacket(new PacketClientLockGameTimeNotify(this));
}
@Override @Override
public Iterator<Player> iterator() { public Iterator<Player> iterator() {
return this.getPlayers().iterator(); return this.getPlayers().iterator();

View File

@ -0,0 +1,18 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.world.World;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.ClientLockGameTimeNotifyOuterClass.ClientLockGameTimeNotify;
public final class PacketClientLockGameTimeNotify extends BasePacket {
public PacketClientLockGameTimeNotify(World world) {
super(PacketOpcodes.ClientLockGameTimeNotify);
var packet = ClientLockGameTimeNotify.newBuilder()
.setIsLock(world.isTimeLocked())
.build();
this.setData(packet);
}
}