Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion battle/attack/AtkModelEnemy.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class AtkModelEnemy extends AtkModelEntity {
protected AtkModelEnemy(EEnemy ent, float d0) {
super(ent, d0, 1);
String[] arr = { "KB", "STOP", "SLOW", "WEAK", "WARP", "CURSE", "SNIPER", "SEAL", "POISON", "BOSS",
"POIATK", "ARMOR", "SPEED", "DMGCUT", "DMGCAP" };
"POIATK", "ARMOR", "BONECRUSH", "SPEED", "DMGCUT", "DMGCAP" };
cursed = new Proc[data.getAtkCount()];
for (int i = 0; i < cursed.length; i++) {
cursed[i] = data.getAtkModel(i).getProc().clone();
Expand Down
2 changes: 1 addition & 1 deletion battle/attack/AtkModelEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ protected void setProc(int ind, Proc proc) {
String[] par = {
"CRIT", "WAVE", "KB", "WARP", "STOP", "SLOW", "WEAK", "POISON", "MOVEWAVE", "CURSE", "SNIPER",
"BOSS", "SEAL", "BREAK", "SUMMON", "SATK", "POIATK", "VOLC", "ARMOR", "SPEED", "MINIWAVE", "SHIELDBREAK",
"MINIVOLC", "METALKILL", "BLAST"
"MINIVOLC", "METALKILL", "BLAST", "BONECRUSH"
};

for (String s0 : par)
Expand Down
8 changes: 8 additions & 0 deletions battle/attack/AttackAb.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ protected void process() {
else
proc.ARMOR.time *= (100 - imus.IMUARMOR.block) / 100.0;
}
if (proc.BONECRUSH.time > 0 && imus.IMUBONE.block != 0 && checkAIImmunity(proc.BONECRUSH.mult, imus.IMUBONE.smartImu, imus.IMUBONE.block < 0)) {
if (imus.IMUBONE.block > 0)
blocked = true;
if (imus.IMUBONE.block == 100)
proc.BONECRUSH.clear();
else
proc.BONECRUSH.time *= (100 - imus.IMUBONE.block) / 100.0;
}
if (proc.SPEED.time > 0 && imus.IMUSPEED.block != 0) {
boolean b;
if (proc.SPEED.type != 2)
Expand Down
2 changes: 1 addition & 1 deletion battle/attack/ContVolcano.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private void updateProc() {
}
performed[1] = performed[3] = true;
}
String[] cursep = {"KB", "STOP", "SLOW", "WEAK", "WARP", "CURSE", "SNIPER", "SEAL", "POISON", "BOSS", "POIATK", "ARMOR", "SPEED", "DMGCUT", "DMGCAP"};
String[] cursep = {"KB", "STOP", "SLOW", "WEAK", "WARP", "CURSE", "SNIPER", "SEAL", "POISON", "BOSS", "POIATK", "ARMOR", "SPEED", "DMGCUT", "DMGCAP", "BONECRUSH"};
if (v.attacker.status[P_CURSE][0] > 0 || v.attacker.status[P_SEAL][0] > 0 && performed[2]) {
performed[2] = false;
for (String s : cursep)
Expand Down
39 changes: 37 additions & 2 deletions battle/entity/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,11 @@ public void getEff(int t) {
EffAnim<GuardEff> eff = effas().A_E_GUARD;
effs[id] = eff.getEAnim(GuardEff.BREAK);
CommonStatic.setSE(SE_BARRIER_ABI);
} else if (t == P_BONECRUSH) {
int id = A_BONECRUSH;
EffAnim<BoneEff> eff = effas().A_BONECRUSH;
BoneEff index = status[P_BONECRUSH][1] >= 0 ? BoneEff.DEBUFF : BoneEff.BUFF;
effs[id] = eff.getEAnim(index);
}
}

Expand Down Expand Up @@ -487,6 +492,11 @@ private void checkEff() {
effs[id] = null;
}

if (status[P_BONECRUSH][0] == 0) {
byte id = A_BONECRUSH;
effs[id] = null;
}

if (status[P_SPEED][0] == 0) {
byte id = dire == -1 ? A_SPEED : A_E_SPEED;
effs[id] = null;
Expand Down Expand Up @@ -2014,6 +2024,20 @@ private void processProcs(AttackAb atk) {
anim.getEff(INV);
}

if (!isBase && atk.getProc().BONECRUSH.time > 0) {
int res = checkAIImmunity(atk.getProc().BONECRUSH.mult, getProc().IMUBONE.smartImu, getProc().IMUBONE.mult < 0) ? getProc().IMUBONE.mult : 0;

if (res < 100) {
int val = (int) (atk.getProc().BONECRUSH.time * time);
status[P_BONECRUSH][0] = val * (100 - res) / 100;
status[P_BONECRUSH][1] = atk.getProc().BONECRUSH.mult;
status[P_BONECRUSH][2] = atk.getProc().BONECRUSH.single ? 1 : 0;

anim.getEff(P_BONECRUSH);
} else
anim.getEff(INV);
}

if (atk.getProc().SPEED.time > 0) {
int res = getProc().IMUSPEED.mult;
int speed = data.getSpeed();
Expand Down Expand Up @@ -2131,8 +2155,17 @@ public void postUpdate() {
if (status[P_ARMOR][0] > 0) {
damage = (long) (damage * (100 + status[P_ARMOR][1]) / 100.0);
}
if (!isBase && damage > 0 && kbTime <= 0 && kbTime != -1 && (ext <= damage * hb || health < damage))
interrupt(INT_HB, KB_DIS[INT_HB]);
if (!isBase && damage > 0 && kbTime <= 0 && kbTime != -1 && (ext <= damage * hb || health < damage)) {
if (status[P_BONECRUSH][0] > 0) {
damage = (long) (damage * (100 + status[P_BONECRUSH][1]) / 100.0);
if (status[P_BONECRUSH][2] == 1) {
status[P_BONECRUSH][0] = 0;
}
}
if (damage != 0) {
interrupt(INT_HB, KB_DIS[INT_HB]);
}
}
if (damage > 0 && isBase && basis.activeGuard == 1) {
anim.getEff(GUARD_HOLD);
} else {
Expand Down Expand Up @@ -2633,6 +2666,8 @@ private void updateProc() {
status[P_ARMOR][0]--;
if (status[P_SPEED][0] > 0)
status[P_SPEED][0]--;
if (status[P_BONECRUSH][0] > 0)
status[P_BONECRUSH][0]--;
if (status[P_BSTHUNT][0] > 0)
status[P_BSTHUNT][0]--;
// update tokens
Expand Down
40 changes: 31 additions & 9 deletions util/Data.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public static class ARMOR extends ProcItem {
@Order(2)
public int mult;
}

@JsonClass(noTag = NoTag.LOAD)
public static class BURROW extends ProcItem {
@Order(0)
Expand Down Expand Up @@ -227,6 +226,8 @@ public ProcItem clear() {
for (Field f : fs)
if (f.getType() == int.class)
f.set(this, 0);
else if (f.getType() == boolean.class)
f.set(this, false);
else if (IntType.class.isAssignableFrom(f.getType()))
f.set(this, (f.getType().getDeclaredConstructor().newInstance()));
else if (f.getType() == Identifier.class)
Expand Down Expand Up @@ -475,6 +476,18 @@ public static class SPEED extends ProcItem {
public int type;
}

@JsonClass(noTag = NoTag.LOAD)
public static class BONECRUSH extends ProcItem {
@Order(0)
public int prob;
@Order(1)
public int time;
@Order(2)
public int mult;
@Order(3)
public boolean single;
}

@JsonClass(noTag = NoTag.LOAD)
public static class STRONG extends ProcItem {
@Order(0)
Expand Down Expand Up @@ -883,13 +896,17 @@ public static Proc load(int[][] data) {
public final BLAST BLAST = new BLAST();
@Order(61)
public final IMU IMUBLAST = new IMU();
@Order(61)
public final MINIVOLC MINIDEATHSURGE = new MINIVOLC(); // TODO: implement this as a normal ability?
@Order(62)
public final MULT MONEYBACK = new MULT();
public final BONECRUSH BONECRUSH = new BONECRUSH();
@Order(63)
public final MULT CANONCHARGE = new MULT();
public final IMUAD IMUBONE = new IMUAD();
@Order(64)
public final MINIVOLC MINIDEATHSURGE = new MINIVOLC(); // TODO: implement this as a normal ability?
@Order(65)
public final MULT MONEYBACK = new MULT();
@Order(66)
public final MULT CANONCHARGE = new MULT();
@Order(67)
public final PROB IMUATKANY = new PROB();

@Override
Expand Down Expand Up @@ -1265,7 +1282,9 @@ public static Proc genProc(JsonElement elem) {
public static final int P_HPREGEN = 59;
public static final int P_BLAST = 60;
public static final int P_IMUBLAST = 61;
public static final byte PROC_TOT = 62;
public static final int P_BONECRUSH = 62;
public static final int P_IMUBONE = 63;
public static final byte PROC_TOT = 64;
public static final byte PROC_WIDTH = 6;

public static final boolean[] procSharable = {
Expand Down Expand Up @@ -1330,7 +1349,9 @@ public static Proc genProc(JsonElement elem) {
true, //adrenaline
true, //hp regen
false, //blast
true //imu.blast
true, //imu.blast
true, //mini death surge
false //bone crush
};

/**
Expand All @@ -1342,7 +1363,7 @@ public static Proc genProc(JsonElement elem) {
* Procs in this list are removed when an unit is hit and has a barrier or Aku shield active
*/
public static final byte[] REMOVABLE_PROC = {
P_STOP, P_SLOW, P_WEAK, P_CURSE, P_SEAL, P_POISON, P_ARMOR, P_SPEED
P_STOP, P_SLOW, P_WEAK, P_CURSE, P_SEAL, P_POISON, P_ARMOR, P_SPEED, P_BONECRUSH
};

public static final byte WT_WAVE = 1;
Expand Down Expand Up @@ -1553,8 +1574,9 @@ public static Proc genProc(JsonElement elem) {
public static final byte A_DMGCAP = 64;
public static final byte A_E_DMGCAP = 65;
public static final byte A_E_GREEN_GUARD = 66;
public static final byte A_BONECRUSH = 67;
public static final byte[] A_POIS = { A_POI0, A_POI1, A_POI2, A_POI3, A_POI4, A_POI5, A_POI6, A_POI7 };
public static final byte A_TOT = 67;
public static final byte A_TOT = 68;

// atk type index used in filter page
public static final byte ATK_SINGLE = 0;
Expand Down
2 changes: 2 additions & 0 deletions util/Res.java
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ private static void readAbiIcon() {
aux.icon[1][P_SPEED] = new VImg("./org/page/icons/Speed.png");
aux.icon[1][P_SPEEDUP] = new VImg("./org/page/icons/Speed.png");
aux.icon[1][P_HPREGEN] = new VImg("./org/page/icons/Barrier.png");
aux.icon[1][P_BONECRUSH] = new VImg("./org/page/icons/BoneCrush.png");
aux.icon[1][P_IMUBONE] = new VImg("./org/page/icons/BoneCrushX.png");
CommonStatic.getConfig().icon = false;
}

Expand Down
1 change: 1 addition & 0 deletions util/lang/AnimTypeLocale.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class AnimTypeLocale {
Collections.addAll(TYPES, EffAnim.DmgCap.values());
Collections.addAll(TYPES, EffAnim.GuardEff.values());
Collections.addAll(TYPES, EffAnim.BlastEff.values());
Collections.addAll(TYPES, EffAnim.BoneEff.values());
}

public static void read() {
Expand Down
11 changes: 11 additions & 0 deletions util/lang/Editors.java
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,8 @@ else if (t.mult == 0)

map().put("IMUARMOR", imuad);

map().put("IMUBONE", imuad);

map().put("IMUSPEED", imuad);

map().put("BARRIER", new EditControl<>(Proc.BARRIER.class, (t) -> {
Expand Down Expand Up @@ -733,6 +735,15 @@ else if (t.mult == 0)
map().put("BLAST", new EditControl<>(Proc.BLAST.class, (t) -> {
t.prob = Math.max(0, Math.min(100, t.prob));
}));

map().put("BONECRUSH", new EditControl<>(Proc.BONECRUSH.class, (t) -> {
t.prob = MathUtil.clip(t.prob, 0, 100);
if (t.prob == 0) {
t.mult = t.time = 0;
} else {
t.time = Math.max(1, t.time);
}
}));
}

private static void setComponentVisibility(EditorGroup egg, boolean boo, int... fields) {
Expand Down
4 changes: 4 additions & 0 deletions util/lang/assets/animation_type.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,9 @@
"START": "Start",
"EXPLODE": "Explode",
"DUMMY": "Dummy"
},
"BoneEff": {
"BUFF": "parry",
"DEBUFF": "bonecrush"
}
}
48 changes: 48 additions & 0 deletions util/lang/assets/proc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1440,5 +1440,53 @@
"tooltip": "Set from 1 to 99 to reduce duration amongst all units. Set to 100 to completely block slow. Set negative to increase the effect."
}
}
},
"BONECRUSH": {
"abbr_name": "bone crush",
"full_name": "Bone Crush",
"tooltip": "Changes damage from attacks that cause hitbacks",
"format": "(prob)% chance to inflict [(mult<0){parry}(mult>0){bone crush}], changing damage by (mult)% for (_dispTime(time))[(single){, only triggers once}]",
"class": {
"prob": {
"name": "chance",
"tooltip": null
},
"time": {
"name": "duration",
"tooltip": ""
},
"mult": {
"name": "percent",
"tooltip": "Damage multiplier, -50% means half damage from hb, 100% means double"
},
"single": {
"name": "only trigger once",
"tooltip": "When on, the proc is removed after it triggers once"
}
}
},
"IMUBONE": {
"abbr_name": "Imu. BoneCrush",
"full_name": "Immune/Resistant to Bone Crush",
"tooltip": null,
"format": ["[(mult!=0&block!=100){[(mult==100){Immune}(mult<100&mult>0){Resistant}(mult<0){Weak}] to Bone Crush",
"[(mult<100&mult>0){ (_left)Decreases duration by (mult)%(_right)}(mult<0){ (_left)Increases duration by (_abs(mult))%(_right)}]",
"[(block!=0&block<100){ & }]}][(block!=0){Bone Crush [(block==100){blocker}(block<100&block>0){absorber}(block<0){increaser}]",
"[(block<100&block>0){ (_left)Decreases duration by (block)%(_right)}(block<0){ (_left)Increases duration by (_abs(block))%(_right)}]}]",
"[(smartImu!=0){. Only affects [(smartImu>0){bone crush}(smartImu<0){parry}]}]"],
"class": {
"mult": {
"name": "percent",
"tooltip": "Set negative to make this unit weak to the effect"
},
"block": {
"name": "Blocker",
"tooltip": "Set from 1 to 99 to reduce damage. Set to 100 to completely block bone crush. Set negative to increase the effect."
},
"smartImu": {
"name": "Ignore",
"tooltip": "0 = Resist buffs and debuffs, 1 = Only resistant to debuffs, -1 = Only resistant to buffs"
}
}
}
}
24 changes: 24 additions & 0 deletions util/pack/EffAnim.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ public String path() {
}
}

public enum BoneEff implements EffType<BoneEff> {
BUFF("buff"), DEBUFF("debuff");

private final String path;

BoneEff(String str) {
path = str;
}

@Override
public String path() {
return path;
}
}

public enum BarrierEff implements EffType<BarrierEff> {
BREAK("_breaker"), DESTR("_destruction"), NONE("");

Expand Down Expand Up @@ -285,6 +300,8 @@ public static class EffAnimStore {
public EffAnim<BlastEff> A_BLAST;
@Order(81)
public EffAnim<BlastEff> A_E_BLAST;
@Order(82)
public EffAnim<BoneEff> A_BONECRUSH;

public EffAnim<?>[] values() {
Field[] fld = FieldOrder.getDeclaredFields(EffAnimStore.class);
Expand Down Expand Up @@ -654,6 +671,13 @@ private static void readCustom(String[] stfs) {
effas.A_DMGCAP.rev = true;

effas.A_E_DMGCAP = new EffAnim<>(dmgcap, vdmgcap, icdmgcap, DmgCap.values());

String root = "./org/battle/";
String bonecrush = root + "bonecrush/bonecrush";
VImg vbonecrush = new VImg(bonecrush+".png");
ImgCut icbonecrush = ImgCut.newIns(bonecrush+".imgcut");
effas.A_BONECRUSH = new EffAnim<>(bonecrush, vbonecrush, icbonecrush, BoneEff.values());
effas.A_BONECRUSH.rev = true;
}

private final VImg vimg;
Expand Down