Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve 'playerHeight' command #3841

Merged
merged 14 commits into from
Apr 19, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ public Vector3f getVelocity() {
return velocity;
}

public float getPlayerHeight(){ return height; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The member height is public in CharacterMovementComponent, so there should be no need for this getter method.

See CharacterMovementComponent.java#L39


public void setVelocity(Vector3f newVelocity) {
velocity.set(newVelocity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
import org.terasology.entitySystem.entity.EntityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.logic.characters.CharacterImpulseEvent;
import org.terasology.logic.common.DisplayNameComponent;
import org.terasology.logic.characters.CharacterComponent;
import org.terasology.logic.characters.GazeMountPointComponent;
import org.terasology.logic.characters.CharacterMovementComponent;
import org.terasology.logic.characters.CharacterTeleportEvent;
import org.terasology.logic.characters.GazeMountPointComponent;
import org.terasology.logic.characters.CharacterImpulseEvent;
import org.terasology.logic.characters.MovementMode;
import org.terasology.logic.common.DisplayNameComponent;
import org.terasology.logic.location.Location;
import org.terasology.logic.location.LocationComponent;
import org.terasology.math.geom.Quat4f;
Expand All @@ -46,6 +47,8 @@

import java.util.Optional;

import static java.lang.Math.pow;

@RegisterSystem
@Share(MovementDebugCommands.class)
public class MovementDebugCommands extends BaseComponentSystem {
Expand Down Expand Up @@ -233,22 +236,48 @@ public String stepHeight(@Sender EntityRef client, @CommandParam("height") float
return "";
}

private float getJumpSpeed(float amount){
double d = (double)amount;
return (float) pow(d,0.6) * 9.36f ;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default jumpSpeed seems to be 10 (and that's the maximum at the same time o.O ). thus, I would assume that setting the player height to the default should result in the default jump speed, but substituting amount by 1.6 yiels a value ~12.4 (≠10).

This is how the jump speed is adjusted according to this function, for amount in the interval from 0 to 5:
image
see Wolfram Alpha

see CharacterMovementComponent.java#L53-L54

}

private float getInteractionRange(float amount){
double d = (double)amount;
return (float) pow(d,0.6) * 3.9f ;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default interaction range seems to be 5 (see CharacterComponent.java#L37). With this formula the interaction range for height of 1.6 is 5.17055 (≠ 5).

This is what the plot looks like:
image
see Wolfram Alpha

}

private float getRunFactor(float amount){
return 0.15f + (0.64f * amount) - (0.006f * amount * amount);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The run factor seems to be a value in the range from 0 to 10, with 1.5 being the default.

Again, calculating the new run factor with the default height of 1.6 yields a value of 1.15864 (≠1.5).

This is how the run factor scales with the given function for amount between 0 and 5. The curve looks almost linear, to be hones:
image
see Wolfram Alpha

}

@Command(shortDescription = "Sets the height of the player", runOnServer = true,
requiredPermission = PermissionManager.CHEAT_PERMISSION)
public String playerHeight(@Sender EntityRef client, @CommandParam("height") float amount) {
skaldarnar marked this conversation as resolved.
Show resolved Hide resolved
try {
ClientComponent clientComp = client.getComponent(ClientComponent.class);
CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class);
if (move != null) {
CharacterComponent charComp = clientComp.character.getComponent(CharacterComponent.class);
EntityRef player = clientComp.character;
GazeMountPointComponent gazeMountPointComponent = player.getComponent(GazeMountPointComponent.class);

float ratio = amount / 1.6f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe 1.6f is the default height of the player? Ideally, we don't have to copy around these magic numbers and loose track of where they came from.

The best shot could be to define constants in CharacterMovementComponent which can be reused here.


if (move != null && gazeMountPointComponent != null) {
float prevHeight = move.height;

move.height = amount;
gazeMountPointComponent.translate.y = amount;
move.jumpSpeed = getJumpSpeed(amount);
move.stepHeight = 0.35f * ratio;
move.distanceBetweenFootsteps = ratio;
move.runFactor = getRunFactor(amount);
charComp.interactionRange = getInteractionRange(amount);

Location.removeChild(player, gazeMountPointComponent.gazeEntity);
Location.attachChild(player, gazeMountPointComponent.gazeEntity, gazeMountPointComponent.translate, new Quat4f(Quat4f.IDENTITY));
player.saveComponent(gazeMountPointComponent);
clientComp.character.saveComponent(move);
LocationComponent loc = client.getComponent(LocationComponent.class);
Vector3f currentPosition = loc.getWorldPosition();
clientComp.character
.send(new CharacterTeleportEvent(new Vector3f(currentPosition.getX(), currentPosition.getY() + (amount - prevHeight) / 2, currentPosition.getZ())));
physics.removeCharacterCollider(clientComp.character);
physics.getCharacterCollider(clientComp.character);

return "Height of player set to " + amount + " (was " + prevHeight + ")";
}
return "";
Expand Down