mirror of
https://github.com/collinsmith/riiablo.git
synced 2025-02-21 20:18:14 +07:00
Created Attributes class (see #36)
This commit is contained in:
parent
d4858781c9
commit
93f578373f
118
core/src/com/riiablo/item/Attributes.java
Normal file
118
core/src/com/riiablo/item/Attributes.java
Normal file
@ -0,0 +1,118 @@
|
||||
package com.riiablo.item;
|
||||
|
||||
import com.badlogic.gdx.utils.Bits;
|
||||
import com.riiablo.Riiablo;
|
||||
import com.riiablo.codec.excel.ItemStatCost;
|
||||
|
||||
public class Attributes extends PropertyList {
|
||||
|
||||
/** *
|
||||
* magic + rune + sockets + set are additive to each other, then applied to base
|
||||
*
|
||||
* attributes list
|
||||
* magic props (magic + rune + socket)
|
||||
* set props
|
||||
* set attrs (applied only to character attrs)
|
||||
*/
|
||||
|
||||
final PropertyList attrs = new PropertyList();
|
||||
final Bits modified = new Bits(512);
|
||||
|
||||
public Attributes() {}
|
||||
|
||||
public void apply(PropertyList list) {
|
||||
modified.clear();
|
||||
attrs.clear();
|
||||
attrs.addAll(this);
|
||||
|
||||
for (Stat.Instance stat : list) {
|
||||
Stat.Instance existing = attrs.get(stat.hash);
|
||||
if (existing != null) {
|
||||
System.out.println("stat " + existing + " + " + stat);
|
||||
existing.add(stat);
|
||||
modified.set(stat.stat);
|
||||
} else {
|
||||
attrs.add(stat);
|
||||
}
|
||||
}
|
||||
|
||||
for (Stat.Instance stat : list) {
|
||||
op(stat, stat.entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void op(Stat.Instance stat, ItemStatCost.Entry entry) {
|
||||
switch (entry.op) {
|
||||
case 1:
|
||||
// adds opstat.base * statvalue / 100 to the opstat.
|
||||
break;
|
||||
case 2:
|
||||
// adds (statvalue * basevalue) / (2 ^ param) to the opstat, this does not work properly
|
||||
// with any stat other then level because of the way this is updated, it is only refreshed
|
||||
// when you re-equip the item, your character is saved or you level up, similar to passive
|
||||
// skills, just because it looks like it works in the item description does not mean it
|
||||
// does, the game just recalculates the information in the description every frame, while
|
||||
// the values remain unchanged serverside.
|
||||
break;
|
||||
case 3:
|
||||
// this is a percentage based version of op #2, look at op #2 for information about the
|
||||
// formula behind it, just remember the stat is increased by a percentage rather then by
|
||||
// adding an integer.
|
||||
break;
|
||||
case 4:
|
||||
// this works the same way op #2 works, however the stat bonus is added to the item and not
|
||||
// to the player (so that +defense per level properly adds the defense to the armor and not
|
||||
// to the character directly!)
|
||||
break;
|
||||
case 5:
|
||||
// this works like op #4 but is percentage based, it is used for percentage based increase
|
||||
// of stats that are found on the item itself, and not stats that are found on the
|
||||
// character.
|
||||
break;
|
||||
case 6:
|
||||
// like for op #7, however this adds a plain bonus to the stat, and just like #7 it also
|
||||
// doesn't work so I won't bother to explain the arithmetic behind it either.
|
||||
break;
|
||||
case 7:
|
||||
// this is used to increase a stat based on the current daytime of the game world by a
|
||||
// percentage, there is no need to explain the arithmetics behind it because frankly enough
|
||||
// it just doesn't work serverside, it only updates clientside so this op is essentially
|
||||
// useless.
|
||||
break;
|
||||
case 8:
|
||||
// hardcoded to work only with maxmana, this will apply the proper amount of mana to your
|
||||
// character based on CharStats.txt for the amount of energy the stat added (doesn't work
|
||||
// for non characters)
|
||||
break;
|
||||
case 9:
|
||||
// hardcoded to work only with maxhp and maxstamina, this will apply the proper amount of
|
||||
// maxhp and maxstamina to your character based on CharStats.txt for the amount of vitality
|
||||
// the stat added (doesn't work for non characters)
|
||||
break;
|
||||
case 10:
|
||||
// doesn't do anything, this has no switch case in the op function.
|
||||
break;
|
||||
case 11:
|
||||
// adds opstat.base * statvalue / 100 similar to 1 and 13, the code just does a few more checks
|
||||
break;
|
||||
case 12:
|
||||
// doesn't do anything, this has no switch case in the op function.
|
||||
break;
|
||||
case 13:
|
||||
// adds opstat.base * statvalue / 100 to the value of opstat, this is useable only on items
|
||||
// it will not apply the bonus to other unit types (this is why it is used for
|
||||
// +% durability, +% level requirement, +% damage, +% defense [etc]).
|
||||
int op_base = entry.op_base.isEmpty() ? 1 : 1;
|
||||
for (String op_stat : entry.op_stat) {
|
||||
if (op_stat.isEmpty()) break;
|
||||
System.out.println("op_stat=");
|
||||
int statId = Riiablo.files.ItemStatCost.index(op_stat);
|
||||
Stat.Instance mod = attrs.get(statId);
|
||||
if (mod == null) continue;
|
||||
mod.value = mod.value * (op_base * (stat.value + 100)) / 100;
|
||||
modified.set(statId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -134,7 +134,7 @@ public class Item extends Actor implements Disposable {
|
||||
public int runewordData;
|
||||
public String inscription;
|
||||
|
||||
public PropertyList props;
|
||||
public Attributes props;
|
||||
public PropertyList stats[];
|
||||
|
||||
public ItemEntry base;
|
||||
@ -186,7 +186,7 @@ public class Item extends Actor implements Disposable {
|
||||
typeEntry = Riiablo.files.ItemTypes.get(base.type);
|
||||
type = Type.get(typeEntry);
|
||||
|
||||
props = new PropertyList();
|
||||
props = new Attributes();
|
||||
props.put(Stat.item_levelreq, base.levelreq);
|
||||
if (base instanceof Weapons.Entry) {
|
||||
Weapons.Entry weapon = getBase();
|
||||
@ -319,6 +319,22 @@ public class Item extends Actor implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(getName());
|
||||
PropertyList magicProps = stats[MAGIC_PROPS];
|
||||
PropertyList runeProps = stats[RUNE_PROPS];
|
||||
if (magicProps != null) {
|
||||
PropertyList magicPropsAggregate = magicProps.copy();
|
||||
for (Item socket : socketed) {
|
||||
if (socket.type.is(Type.GEM) || socket.type.is(Type.RUNE)) {
|
||||
magicPropsAggregate.addAll(socket.stats[base.gemapplytype]);
|
||||
} else {
|
||||
magicPropsAggregate.addAll(socket.stats[MAGIC_PROPS]);
|
||||
}
|
||||
}
|
||||
if (runeProps != null) magicPropsAggregate.addAll(runeProps);
|
||||
props.apply(magicPropsAggregate);
|
||||
}
|
||||
|
||||
//System.out.println(getName() + " : " + Arrays.toString(stats) + " : " + Integer.toBinaryString(listsFlags));
|
||||
}
|
||||
|
||||
@ -926,8 +942,14 @@ public class Item extends Actor implements Disposable {
|
||||
|
||||
//if ((flags & COMPACT) == 0) {
|
||||
Stat.Instance prop;
|
||||
if ((prop = props.get(Stat.armorclass)) != null)
|
||||
add(new Label(Riiablo.string.lookup("ItemStats1h") + " " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
|
||||
if ((prop = props.get(Stat.armorclass)) != null) {
|
||||
Table table = new Table();
|
||||
table.add(new Label(Riiablo.string.lookup("ItemStats1h") + " ", font, Riiablo.colors.white));
|
||||
table.add(new Label(Integer.toString(prop.value), font, props.modified.get(Stat.armorclass) ? Riiablo.colors.blue : Riiablo.colors.white));
|
||||
table.pack();
|
||||
add(table).space(SPACING).row();
|
||||
setDebug(true, true);
|
||||
}
|
||||
if (Item.this.type.is(Type.WEAP)) {
|
||||
if ((prop = props.get(Stat.maxdamage)) != null) // TODO: Conditional 2 handed if barbarian, etc
|
||||
add(new Label(Riiablo.string.lookup("ItemStats1l") + " " + props.get(Stat.mindamage).value + " to " + prop.value, font, Riiablo.colors.white)).center().space(SPACING).row();
|
||||
@ -972,10 +994,10 @@ public class Item extends Actor implements Disposable {
|
||||
}
|
||||
if (runeProps != null) magicPropsAggregate.addAll(runeProps);
|
||||
magicPropsAggregate.reduce();
|
||||
System.out.println(Item.this.getName());
|
||||
for (Stat.Instance stat : magicPropsAggregate.props.values()) {
|
||||
System.out.println(stat);
|
||||
}
|
||||
//System.out.println(Item.this.getName());
|
||||
//for (Stat.Instance stat : magicPropsAggregate.props.values()) {
|
||||
// System.out.println(stat);
|
||||
//}
|
||||
|
||||
Array<Stat.Instance> aggregate = magicPropsAggregate.toArray();
|
||||
aggregate.sort();
|
||||
|
@ -9,7 +9,9 @@ import com.riiablo.codec.excel.ItemStatCost;
|
||||
import com.riiablo.codec.excel.Properties;
|
||||
import com.riiablo.codec.util.BitStream;
|
||||
|
||||
public class PropertyList {
|
||||
import java.util.Iterator;
|
||||
|
||||
public class PropertyList implements Iterable<Stat.Instance> {
|
||||
private static final String TAG = "PropertyList";
|
||||
|
||||
private static final int[] ATTRIBUTES = {Stat.strength, Stat.energy, Stat.dexterity, Stat.vitality};
|
||||
@ -36,6 +38,11 @@ public class PropertyList {
|
||||
return new PropertyList(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Stat.Instance> iterator() {
|
||||
return props.values();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
props.clear();
|
||||
}
|
||||
@ -77,14 +84,19 @@ public class PropertyList {
|
||||
return props.values().toArray();
|
||||
}
|
||||
|
||||
public void add(Stat.Instance stat) {
|
||||
assert stat.stat == 0 || stat.hash != 0;
|
||||
Stat.Instance existing = props.get(stat.hash);
|
||||
if (existing != null) {
|
||||
existing.add(stat);
|
||||
} else {
|
||||
props.put(stat.hash, stat);
|
||||
}
|
||||
}
|
||||
|
||||
public PropertyList addAll(PropertyList other) {
|
||||
for (IntMap.Entry<Stat.Instance> entry : other.props) {
|
||||
Stat.Instance existing = props.get(entry.key);
|
||||
if (existing != null) {
|
||||
existing.add(entry.value);
|
||||
} else {
|
||||
props.put(entry.key, entry.value);
|
||||
}
|
||||
for (Stat.Instance stat : other.props.values()) {
|
||||
add(stat);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
@ -486,6 +486,18 @@ public class Stat {
|
||||
hash = Stat.hash(stat, param);
|
||||
}
|
||||
|
||||
Instance(Instance src) {
|
||||
this.stat = src.stat;
|
||||
this.param = src.param;
|
||||
this.hash = src.hash;
|
||||
this.entry = src.entry;
|
||||
this.value = src.value;
|
||||
}
|
||||
|
||||
Instance copy() {
|
||||
return new Instance(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Instance o) {
|
||||
return o.entry.descpriority - this.entry.descpriority;
|
||||
|
Loading…
Reference in New Issue
Block a user