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.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. */

View File

@ -31,7 +31,7 @@ import java.util.stream.Collectors;
import lombok.Getter;
import lombok.val;
public class World implements Iterable<Player> {
public final class World implements Iterable<Player> {
@Getter private final GameServer server;
@Getter private final Player host;
@Getter private final List<Player> players;
@ -42,12 +42,12 @@ public class World implements Iterable<Player> {
private int nextPeerId = 0;
private int worldLevel;
private boolean isMultiplayer;
@Getter private boolean isMultiplayer, timeLocked = false;
private long lastUpdateTime;
@Getter private int tickCount = 0;
@Getter private boolean isPaused = false;
@Getter private long currentWorldTime = 0;
@Getter private long currentWorldTime;
public World(Player player) {
this(player, false);
@ -118,10 +118,6 @@ public class World implements Iterable<Player> {
return this.getPlayers().size();
}
public boolean isMultiplayer() {
return isMultiplayer;
}
/**
* 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)
if (this.tickCount % 60 == 0) {
this.getHost().updatePlayerGameTime(currentWorldTime);
this.getHost().updatePlayerGameTime(this.currentWorldTime);
}
this.tickCount++;
@ -438,13 +434,13 @@ public class World implements Iterable<Player> {
/** Returns the in-game world time in real milliseconds. */
public long getWorldTime() {
if (!this.isPaused) {
if (!this.isPaused && !this.timeLocked) {
var newUpdateTime = System.currentTimeMillis();
this.currentWorldTime += (newUpdateTime - lastUpdateTime);
this.lastUpdateTime = newUpdateTime;
}
return currentWorldTime;
return this.currentWorldTime;
}
/** 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.
*/
public void changeTime(int time, int days) {
// Check if the time is locked.
if (this.timeLocked) return;
// Calculate time differences.
var currentTime = this.getGameTime();
var diff = time - currentTime;
@ -526,6 +525,18 @@ public class World implements Iterable<Player> {
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
public Iterator<Player> 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);
}
}