Skip to content

Commit

Permalink
Merge pull request #1 from Akka0/development
Browse files Browse the repository at this point in the history
Updated
  • Loading branch information
Akka0 authored May 6, 2022
2 parents 3d3f36c + 81998b9 commit 833ea1b
Show file tree
Hide file tree
Showing 20 changed files with 353 additions and 151 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ mongod.exe
/*.sh
language/
languages/
gacha_mappings.js
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ There is a dummy user named "Server" in every player's friends list that you can
| kick | kick \<player> | server.kick | Both side | Kicks the specified player from the server. (WIP) | k |
| killall | killall [playerUid] [sceneId] | server.killall | Both side | Kills all entities in the current scene or specified scene of the corresponding player. | |
| list | list | | Both side | Lists online players. | |
| permission | permission <add\|remove> \<username> \<permission> | * | Both side | Grants or removes a permission for a user. | |
| permission | permission <add\|remove> \<UID> \<permission> | * | Both side | Grants or removes a permission for a user. | |
| position | position | | Client only | Sends your current coordinates. | pos |
| reload | reload | server.reload | Both side | Reloads the server config | |
| resetconst | resetconst [all] | player.resetconstellation | Client only | Resets the constellation level on your currently selected character, will need to relog after using the command to see any changes. | resetconstellation |
Expand Down
2 changes: 1 addition & 1 deletion README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ chmod +x gradlew
| kick | kick \<uid> | server.kick | 均可使用 | 从服务器中踢出指定玩家 (WIP) | k |
| killall | killall [uid] [场景ID] | server.killall | 均可使用 | 杀死指定玩家世界中所在或指定场景的全部生物 | |
| list | list | | 均可使用 | 列出在线玩家 | |
| permission | permission <add\|remove> <用户名> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | |
| permission | permission <add\|remove> <UID> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | |
| position | position | | 仅客户端 | 获取当前坐标 | pos |
| reload | reload | server.reload | 均可使用 | 重载服务器配置 | |
| resetconst | resetconst [all] | player.resetconstellation | 仅客户端 | 重置当前角色的命座,重新登录即可生效 | resetconstellation |
Expand Down
2 changes: 1 addition & 1 deletion data/gacha_records.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<!-- This file could be generated automatically using `java -jar grasscutter.jar -gachamap` -->
<!-- You can also modify the file manually to customize it -->
<!-- Otherwise you may onle see number IDs in the gacha record -->
<script type="text/javascript" src="/gcstatic/mappings.js"></script>
<script type="text/javascript" src="/gacha/mappings"></script>
<script>
mappings['default'] = mappings['en-us']; // make en-us as default/fallback option
</script>
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/emu/grasscutter/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ public static class GameServerOptions {
public int ServerAvatarId = 10000007;
public int[] WelcomeEmotes = {2007, 1002, 4010};
public String WelcomeMotd = "Welcome to Grasscutter emu";
public String WelcomeMailContent = "Hi there!\r\nFirst of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! \r\n\r\nCheck out our:\r\n<type=\"browser\" text=\"Discord\" href=\"https://discord.gg/T5vZU6UyeG\"/> <type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
public String WelcomeMailTitle = "Welcome to Grasscutter!";
public String WelcomeMailSender = "Lawnmower";
public String WelcomeMailContent = "Hi there!\r\nFirst of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! \r\n\r\nCheck out our:\r\n<type=\"browser\" text=\"Discord\" href=\"https://discord.gg/T5vZU6UyeG\"/>";
public Mail.MailItem[] WelcomeMailItems = {
new Mail.MailItem(13509, 1, 1),
new Mail.MailItem(201, 10000, 1),
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/emu/grasscutter/Grasscutter.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static void main(String[] args) throws Exception {
Tools.createGmHandbook(); return;
}
case "-gachamap" -> {
Tools.createGachaMapping(); return;
Tools.createGachaMapping("./gacha_mappings.js"); return;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public final class GiveCommand implements CommandHandler {
Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)"); // Java is a joke of a proglang that doesn't have raw string literals
Pattern refineRegex = Pattern.compile("r(\\d+)");
Pattern amountRegex = Pattern.compile("((?<=x)\\d+|\\d+(?=x))");
Pattern amountRegex = Pattern.compile("((?<=x)\\d+|\\d+(?=x)(?!x\\d))");

private int matchIntOrNeg(Pattern pattern, String arg) {
Matcher match = pattern.matcher(arg);
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/emu/grasscutter/data/GameData.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ public class GameData {
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
private static final IntList scenePointIdList = new IntArrayList();

public static char EJWOA = 's';

public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
Int2ObjectMap<?> map = null;

Expand Down
2 changes: 0 additions & 2 deletions src/main/java/emu/grasscutter/database/DatabaseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,4 @@ public static boolean deleteMail(Mail mail) {
DeleteResult result = DatabaseManager.getDatastore().delete(mail);
return result.wasAcknowledged();
}

public static char AWJVN = 'e';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
package emu.grasscutter.game.managers.MotionManager;

import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.EntityMoveInfoOuterClass;
import emu.grasscutter.net.proto.MotionStateOuterClass.MotionState;
import emu.grasscutter.net.proto.VectorOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
import emu.grasscutter.utils.Position;

import java.util.ArrayList;
import java.lang.Math;

public class MotionManager {

private enum Consumption {
None(0),

// consumers
CLIMB_START(-500),
CLIMBING(-150),
CLIMB_JUMP(-2500),
DASH(-1800),
SPRINT(-360),
FLY(-60),
SWIM_DASH_START(-200),
SWIM_DASH(-200),
SWIMMING(-80),

// restorers
STANDBY(500),
RUN(500),
WALK(500),
STANDBY_MOVE(500);

public final int amount;
Consumption(int amount) {
this.amount = amount;
}
}

private EntityMoveInfoOuterClass.EntityMoveInfo moveInfo;

private MotionState previousState = MotionState.MOTION_STANDBY;
private ArrayList<Position> previousCoordinates = new ArrayList<>();
private final Player player;

private float landSpeed = 0;

public MotionManager(Player player) {
previousCoordinates.add(new Position(0,0,0));
this.player = player;
}

public void handle(GameSession session, GameEntity entity, EntityMoveInfoOuterClass.EntityMoveInfo moveInfo) {
MotionState state = moveInfo.getMotionInfo().getState();
setMoveInfo(moveInfo);
if (state == MotionState.MOTION_LAND_SPEED) {
setLandSpeed(moveInfo.getMotionInfo().getSpeed().getY());
}
if (state == MotionState.MOTION_FALL_ON_GROUND) {
handleFallOnGround(session, entity);
}
}

public void tick() {
if(Grasscutter.getConfig().OpenStamina){
EntityMoveInfoOuterClass.EntityMoveInfo mInfo = moveInfo;
if (mInfo == null) {
return;
}

MotionState state = moveInfo.getMotionInfo().getState();
Consumption consumption = Consumption.None;

boolean isMoving = false;
VectorOuterClass.Vector posVector = moveInfo.getMotionInfo().getPos();
Position currentCoordinates = new Position(posVector.getX(), posVector.getY(), posVector.getZ());

float diffX = currentCoordinates.getX() - previousCoordinates.get(0).getX();
float diffY = currentCoordinates.getY() - previousCoordinates.get(0).getY();
float diffZ = currentCoordinates.getZ() - previousCoordinates.get(0).getZ();

if (Math.abs(diffX) > 0.3 || Math.abs(diffY) > 0.3 || Math.abs(diffZ) > 0.3) {
isMoving = true;
}

if (isMoving) {
// TODO: refactor these conditions.
// CLIMB
if (state == MotionState.MOTION_CLIMB) {
if (previousState != MotionState.MOTION_CLIMB && previousState != MotionState.MOTION_CLIMB_JUMP) {
consumption = Consumption.CLIMB_START;
} else {
consumption = Consumption.CLIMBING;
}
}
// JUMP
if (state == MotionState.MOTION_CLIMB_JUMP) {
if (previousState != MotionState.MOTION_CLIMB_JUMP) {
consumption = Consumption.CLIMB_JUMP;
}
}
if (state == MotionState.MOTION_JUMP) {
if (previousState == MotionState.MOTION_CLIMB) {
consumption = Consumption.CLIMB_JUMP;
}
}
// SWIM
if (state == MotionState.MOTION_SWIM_MOVE) {
consumption = Consumption.SWIMMING;
}
if (state == MotionState.MOTION_SWIM_DASH) {
if (previousState != MotionState.MOTION_SWIM_DASH) {
consumption = Consumption.SWIM_DASH_START;
} else {
consumption = Consumption.SWIM_DASH;
}
}
// DASH
if (state == MotionState.MOTION_DASH) {
if (previousState == MotionState.MOTION_DASH) {
consumption = Consumption.SPRINT;
} else {
consumption = Consumption.DASH;
}
}
// RUN and WALK
if (state == MotionState.MOTION_RUN) {
consumption = Consumption.RUN;
}
if (state == MotionState.MOTION_WALK) {
consumption = Consumption.WALK;
}
// FLY
if (state == MotionState.MOTION_FLY) {
consumption = Consumption.FLY;
}
}
// STAND
if (state == MotionState.MOTION_STANDBY) {
consumption = Consumption.STANDBY;
}
if (state == MotionState.MOTION_STANDBY_MOVE) {
consumption = Consumption.STANDBY_MOVE;
}

GameSession session = player.getSession();
updateStamina(session, consumption.amount);
session.send(new PacketPlayerPropNotify(session.getPlayer(), PlayerProperty.PROP_CUR_PERSIST_STAMINA));

Grasscutter.getLogger().debug(session.getPlayer().getProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA) + " " + state + " " + isMoving + " " + consumption + " " + consumption.amount);

previousState = state;
previousCoordinates.add(currentCoordinates);
if (previousCoordinates.size() > 3) {
previousCoordinates.remove(0);
}
}
}

public void updateStamina(GameSession session, int amount) {
if (amount == 0) {
return;
}
int currentStamina = session.getPlayer().getProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA);
int playerMaxStamina = session.getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA);
int newStamina = currentStamina + amount;
if (newStamina < 0) {
newStamina = 0;
}
if (newStamina > playerMaxStamina) {
newStamina = playerMaxStamina;
}
session.getPlayer().setProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA, newStamina);
}

public void setMoveInfo(EntityMoveInfoOuterClass.EntityMoveInfo moveInfo) {
this.moveInfo = moveInfo;
}

public EntityMoveInfoOuterClass.EntityMoveInfo getMoveInfo() {
return moveInfo;
}

public void handleFallOnGround(GameSession session, GameEntity entity) {
float currentHP = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
float maxHP = entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
float damage = 0;
Grasscutter.getLogger().debug("LandSpeed: " + landSpeed);
if (landSpeed < -23.5) {
damage = (float)(maxHP * 0.33);
}
if (landSpeed < -25) {
damage = (float)(maxHP * 0.5);
}
if (landSpeed < -26.5) {
damage = (float)(maxHP * 0.66);
}
if (landSpeed < -28) {
damage = (maxHP * 1);
}
float newHP = currentHP - damage;
if (newHP < 0) {
newHP = 0;
}
Grasscutter.getLogger().debug("Max: " + maxHP + "\tCurr: " + currentHP + "\tDamage: " + damage + "\tnewHP: " + newHP);
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, newHP);
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
if (newHP == 0) {
entity.getWorld().broadcastPacket(new PacketLifeStateChangeNotify(0, entity, LifeState.LIFE_DEAD));
session.getPlayer().getScene().removeEntity(entity);
entity.onDeath(0);
}
}

public void setLandSpeed(float landSpeed) {
this.landSpeed = landSpeed;
}
}
34 changes: 34 additions & 0 deletions src/main/java/emu/grasscutter/game/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.mail.Mail;
import emu.grasscutter.game.mail.MailHandler;
import emu.grasscutter.game.managers.MotionManager.MotionManager;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.EntityType;
import emu.grasscutter.game.props.PlayerProperty;
Expand Down Expand Up @@ -124,6 +125,8 @@ public class Player {
@Transient private final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler;

private MapMarksManager mapMarksManager;
@Transient private MotionManager motionManager;


@Deprecated
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
Expand Down Expand Up @@ -164,6 +167,7 @@ public Player() {
this.shopLimit = new ArrayList<>();
this.messageHandler = null;
this.mapMarksManager = new MapMarksManager();
this.motionManager = new MotionManager(this);
}

// On player creation
Expand Down Expand Up @@ -191,6 +195,7 @@ public Player(GameSession session) {
this.getRotation().set(0, 307, 0);
this.messageHandler = null;
this.mapMarksManager = new MapMarksManager();
this.motionManager = new MotionManager(this);
}

public int getUid() {
Expand Down Expand Up @@ -977,6 +982,8 @@ public MapMarksManager getMapMarksManager() {
return mapMarksManager;
}

public MotionManager getMotionManager() { return motionManager; }

public synchronized void onTick() {
// Check ping
if (this.getLastPingTime() > System.currentTimeMillis() + 60000) {
Expand Down Expand Up @@ -1005,8 +1012,35 @@ public synchronized void onTick() {
this.resetSendPlayerLocTime();
}
}

scheduleStaminaNotify();
}

private void scheduleStaminaNotify() {
// stamina tick
EntityMoveInfoOuterClass.EntityMoveInfo moveInfo = getMotionManager().getMoveInfo();
if (moveInfo == null) {
return;
}

if (getMotionManager().getMoveInfo().getMotionInfo().getState() == MotionStateOuterClass.MotionState.MOTION_STANDBY) {
if (getProperty(PlayerProperty.PROP_CUR_PERSIST_STAMINA) == getProperty(PlayerProperty.PROP_MAX_STAMINA) ) {
return;
}
}

for (int i = 0; i <= 1000; i+=200) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
getMotionManager().tick();
}
}, i);
}
}


public void resetSendPlayerLocTime() {
this.nextSendPlayerLocTime = System.currentTimeMillis() + 5000;
}
Expand Down
Loading

0 comments on commit 833ea1b

Please sign in to comment.