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

Base Attributes #2664

Merged
merged 43 commits into from
Jul 18, 2020
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
efe3c60
Merge pull request #8 from SkriptLang/master
Wealthyturtle Nov 13, 2019
6528e10
Attribute Type
Wealthyturtle Nov 29, 2019
788f098
ExprAttribute
Wealthyturtle Nov 29, 2019
9789540
ExprEntityAttribute
Wealthyturtle Nov 29, 2019
30fac93
Remove Debug Code
Wealthyturtle Nov 29, 2019
275c478
Add Spaces
Wealthyturtle Nov 29, 2019
bcb6d07
Update BukkitClasses.java
Wealthyturtle Nov 29, 2019
301fb84
Delete ExprAttribute.java
Wealthyturtle Nov 29, 2019
66487d1
Update ExprEntityAttribute.java
Wealthyturtle Nov 29, 2019
73292b5
Update english.lang
Wealthyturtle Nov 29, 2019
fed9f13
Update ExprEntityAttribute.java
Wealthyturtle Nov 30, 2019
dccc41b
Update ExprEntityAttribute.java
Wealthyturtle Dec 1, 2019
05496b2
Add Notice
Wealthyturtle Dec 2, 2019
01ee836
Update ExprEntityAttribute.java
Wealthyturtle Dec 29, 2019
7680a8f
Add NPE Check
Wealthyturtle Dec 29, 2019
3e64f69
Attribute Regression Test
Wealthyturtle Dec 29, 2019
d162f90
Use name() instead of toString()
Wealthyturtle Dec 29, 2019
f63d67e
Update BukkitClasses.java
Wealthyturtle Dec 30, 2019
9068b60
Fix Regex
Wealthyturtle Dec 30, 2019
2cb8d44
Update ExprEntityAttribute.java
Wealthyturtle Dec 30, 2019
c10a0c7
Update ExprEntityAttribute.java
Wealthyturtle Dec 30, 2019
cedb8ee
Update ExprEntityAttribute.java
Wealthyturtle Dec 30, 2019
89c2961
Update ExprEntityAttribute.java
Wealthyturtle Jan 10, 2020
0bbc29a
Oops... recursive toString()
Wealthyturtle Jan 10, 2020
478fa25
Improved toString()
Wealthyturtle Jan 10, 2020
92c5c7f
Update ExprEntityAttribute.java
Wealthyturtle Jan 10, 2020
140cc69
Finally Fix Bugs
Wealthyturtle Mar 2, 2020
884b296
Switch to Usage
Wealthyturtle Mar 9, 2020
963eb60
More ChangeMode Support
Wealthyturtle Mar 30, 2020
2246231
Enhanced Regression Test
Wealthyturtle Mar 30, 2020
e77f5c6
Merge branch 'master' into feature/attributes2
Wealthyturtle Mar 30, 2020
75cbaff
Fix Null Case, Whoops
Wealthyturtle Mar 30, 2020
3ef3abf
Add Test for MC 1.11+
Wealthyturtle Mar 31, 2020
e5f8d57
Split Tests
Wealthyturtle Mar 31, 2020
03d83af
Test set/not set
Wealthyturtle Mar 31, 2020
3090069
Update BukkitClasses.java
Wealthyturtle Apr 1, 2020
8bfcfcb
Merge branch 'master' into feature/attributes2
FranKusmiruk May 28, 2020
50e69f5
Merge branch 'master' into feature/attributes2
Wealthyturtle May 29, 2020
4d22194
Merge branch 'master' into feature/attributes2
FranKusmiruk Jul 7, 2020
4f4043b
Update to 1.16 Attributes
Wealthyturtle Jul 17, 2020
f126544
Elaborate on description
Wealthyturtle Jul 17, 2020
715942c
Merge branch 'master' into feature/attributes2
Wealthyturtle Jul 17, 2020
7357ba6
Merge branch 'master' into feature/attributes2
Wealthyturtle Jul 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.bukkit.OfflinePlayer;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
Expand Down Expand Up @@ -1751,6 +1752,37 @@ public String getVariableNamePattern() {
}
}));
}
EnumUtils<Attribute> attributes = new EnumUtils<>(Attribute.class, "attribute types");
Classes.registerClass(new ClassInfo<>(Attribute.class, "attributetype")
.user("attribute ?types?")
.name("Attribute Type")
.description("Represents the type of an attribute. Note that this type does not contain any numerical values."
+ "See <a href='https://minecraft.gamepedia.com/Attribute#Attributes'>attribute types</a> for more info.")
.defaultExpression(new EventValueExpression<>(Attribute.class))
.usage(attributes.getAllNames())
.since("INSERT VERSION")
.parser(new Parser<Attribute>() {
@Override
@Nullable
public Attribute parse(String input, ParseContext context) {
return attributes.parse(input);
}

@Override
public String toString(Attribute a, int flags) {
return attributes.toString(a, flags);
}

@Override
public String toVariableNameString(Attribute a) {
return toString(a, 0);
}

@Override
public String getVariableNamePattern() {
return "[\\sA-Za-z]+";
}
})
.serializer(new EnumSerializer<>(Attribute.class)));
}

}
141 changes: 141 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprEntityAttribute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
*
* Copyright 2011-2017 Peter Güttinger and contributors
*/
package ch.njol.skript.expressions;

import org.bukkit.attribute.Attribute;

import java.util.stream.Stream;

import org.bukkit.attribute.Attributable;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.PropertyExpression;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;

@Name("Entity Attribute")
@Description({"The numerical value of an entity's particular attribute.",
"Note that the movement speed attribute cannot be reliably used for players. For that purpose, use the speed expression instead.",
"Resetting an entity's attribute is only available in Minecraft 1.11 and above."})
@Examples({"on damage of player:",
" send \"You are wounded!\"",
" set victim's attack speed attribute to 2"})
@Since("INSERT VERSION")
public class ExprEntityAttribute extends PropertyExpression<Entity, Number> {

static {
Skript.registerExpression(ExprEntityAttribute.class, Number.class, ExpressionType.COMBINED,
Pikachu920 marked this conversation as resolved.
Show resolved Hide resolved
"%attributetype% [value] of %entities%",
"%entities%'[s] %attributetype% [value]");
}

private static final boolean DEFAULTVALUE_EXISTS = Skript.isRunningMinecraft(1, 11);

Wealthyturtle marked this conversation as resolved.
Show resolved Hide resolved
@Nullable
private Expression<Attribute> attributes;

@SuppressWarnings({"null", "unchecked"})
@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
attributes = (Expression<Attribute>) exprs[matchedPattern];
setExpr((Expression<? extends Entity>) exprs[matchedPattern ^ 1]);
return true;
}

@SuppressWarnings("null")
@Override
protected Number[] get(Event e, Entity[] entities) {
Attribute a = attributes.getSingle(e);
return Stream.of(entities)
.map(ent -> getAttribute(ent, a).getBaseValue())
.toArray(Number[]::new);
}

@Override
@Nullable
public Class<?>[] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.REMOVE_ALL || (mode == ChangeMode.RESET && !DEFAULTVALUE_EXISTS))
return null;
return CollectionUtils.array(Number.class);
}

@SuppressWarnings("null")
@Override
public void change(Event e, @Nullable Object[] delta, ChangeMode mode) {
Attribute a = attributes.getSingle(e);
double d = delta == null ? 0 : ((Number) delta[0]).doubleValue();
for (Entity entity : getExpr().getArray(e)) {
AttributeInstance ai = getAttribute(entity, a);
if(ai != null) {
switch(mode) {
case ADD:
ai.setBaseValue(ai.getBaseValue() + d);
break;
case SET:
ai.setBaseValue(d);
break;
case DELETE:
ai.setBaseValue(0);
break;
case RESET:
ai.setBaseValue(ai.getDefaultValue());
break;
case REMOVE:
ai.setBaseValue(ai.getBaseValue() - d);
break;
case REMOVE_ALL:
assert false;
}
}
}
}

@Override
public Class<? extends Number> getReturnType() {
return Number.class;
}

@SuppressWarnings("null")
@Override
public String toString(@Nullable Event e, boolean debug) {
return "entity " + getExpr().toString(e, debug) + "'s " + (attributes == null ? "" : attributes.toString(e, debug)) + "attribute";
}

@Nullable
private static AttributeInstance getAttribute(Entity e, @Nullable Attribute a) {
if (a != null && e instanceof Attributable) {
return ((Attributable) e).getAttribute(a);
}
return null;
}

}
16 changes: 16 additions & 0 deletions src/main/resources/lang/english.lang
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,22 @@ genes:
weak: weak
aggressive: aggressive, savage, wild

# -- Attribute Types --
attribute types:
generic_armor: generic armor, armor attribute
generic_armor_toughness: generic armor toughness, armor toughness attribute
generic_attack_damage: generic attack damage, attack damage attribute
generic_attack_knockback: generic attack knockback, attack knockback attribute
generic_attack_speed: generic attack speed, attack speed attribute
generic_flying_speed: generic flying speed, flying speed attribute
generic_follow_range: generic follow range, follow range attribute
generic_knockback_resistance: generic knockback resistance, knockback resistance attribute
generic_luck: generic luck, luck attribute
generic_max_health: generic max health, max health attribute
generic_movement_speed: generic movement speed, movement speed attribute
horse_jump_strength: horse jump strength, horse jump strength attribute
zombie_spawn_reinforcements: zombie spawn reinforcements, zombie spawn reinforcements attribute

# -- Boolean --
boolean:
true:
Expand Down
21 changes: 21 additions & 0 deletions src/test/skript/tests/regressions/2664-attributes.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
test "attributes 1":
spawn cow at location(0, 64, 0, world "world")
set {_m} to last spawned cow
assert movement speed attribute of {_m} is set with "attribute get failed"
set movement speed attribute of {_m} to 3.14
assert movement speed attribute of {_m} is 3.14 with "attribute set failed"
add 5 to movement speed attribute of {_m}
assert movement speed attribute of {_m} is 8.14 with "attribute add failed"
remove 4 from movement speed attribute of {_m}
assert movement speed attribute of {_m} is 4.14 with "attribute remove ##1 failed"
remove 10 from movement speed attribute of {_m}
assert movement speed attribute of {_m} is -5.86 with "attribute remove ##2 failed" # Negative attribute values should be safe
delete movement speed attribute of {_m}
assert movement speed attribute of {_m} is 0 with "attribute delete failed"

test "attributes 2" when minecraft version is not "1.9.4":
# Test the Reset ChangeMode only on versions that have it
spawn cow at location(0, 65, 0, world "world")
set {_m} to last spawned cow
reset movement speed attribute of {_m}
assert movement speed attribute of {_m} is set with "attribute reset failed" # No need to compare with a fixed constant