diff --git a/AndorsTrail/res/layout/itemeffectview.xml b/AndorsTrail/res/layout/itemeffectview.xml index 21f1f943e..db94f3ecd 100644 --- a/AndorsTrail/res/layout/itemeffectview.xml +++ b/AndorsTrail/res/layout/itemeffectview.xml @@ -65,4 +65,29 @@ android:layout_marginLeft="10sp" /> + + + + + diff --git a/AndorsTrail/res/layout/itemeffectview_ondeath.xml b/AndorsTrail/res/layout/itemeffectview_ondeath.xml new file mode 100644 index 000000000..46451619a --- /dev/null +++ b/AndorsTrail/res/layout/itemeffectview_ondeath.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/AndorsTrail/res/layout/itemeffectview_onhitreceived.xml b/AndorsTrail/res/layout/itemeffectview_onhitreceived.xml new file mode 100644 index 000000000..819238cc7 --- /dev/null +++ b/AndorsTrail/res/layout/itemeffectview_onhitreceived.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/AndorsTrail/res/raw/droplists_debug.json b/AndorsTrail/res/raw/droplists_debug.json index 7d70c8ea1..4104c1d3e 100644 --- a/AndorsTrail/res/raw/droplists_debug.json +++ b/AndorsTrail/res/raw/droplists_debug.json @@ -99,7 +99,14 @@ }, { "id": "debuglist2", - "items": [] + "items": [{ + "itemID": "gold", + "quantity": { + "min": 3, + "max": 3 + }, + "chance": 100 + }] }, { "id": "startitems", diff --git a/AndorsTrail/res/raw/itemlist_debug.json b/AndorsTrail/res/raw/itemlist_debug.json index 3e88c13e6..f367ecb5b 100644 --- a/AndorsTrail/res/raw/itemlist_debug.json +++ b/AndorsTrail/res/raw/itemlist_debug.json @@ -170,6 +170,40 @@ "min": 1, "max": 1 } + }, + "hitReceivedEffect" : { + "increaseCurrentHP": { + "min": 1, + "max": 1 + }, + "increaseCurrentAP": { + "min": 1, + "max": 1 + }, + "increaseAttackerCurrentHP": { + "min": 1, + "max": 1 + }, + "increaseAttackerCurrentAP": { + "min": 1, + "max": 1 + }, + "conditionsSource":[ + { + "condition":"chaotic_grip", + "magnitude": 1, + "duration": 5, + "chance":"50" + } + ], + "conditionsTarget":[ + { + "condition":"chaotic_grip", + "magnitude": 1, + "duration": 5, + "chance":"80" + } + ] } } ] diff --git a/AndorsTrail/res/values/strings.xml b/AndorsTrail/res/values/strings.xml index 2e580e59e..22dcd0fea 100644 --- a/AndorsTrail/res/values/strings.xml +++ b/AndorsTrail/res/values/strings.xml @@ -68,6 +68,14 @@ Not enough AP left this round. You fall unconscious, but fortunately wake up alive, dazed and fatigued. You lost %1$d experience. MISS + You taunt %1$s! + You are affected by %1$s. + You are cleared of %1$s. + You are now immunized against %1$s. + %1$s is affected by %2$s. + %1$s is cleared of %2$s. + %1$s is now immunized against %2$s. + Info Equip @@ -304,11 +312,14 @@ On source On target + On attacker When hitting target On every kill When used When equipped - + When hit by attacker + When killed by attacker + Drains %1$s HP Restores %1$s HP Drains %1$s AP diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java index 86ef2b4d8..aadee5fe0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/AndorsTrailApplication.java @@ -14,7 +14,7 @@ import java.util.Locale; public final class AndorsTrailApplication extends Application { - public static final boolean DEVELOPMENT_DEBUGRESOURCES = false; + public static final boolean DEVELOPMENT_DEBUGRESOURCES = true; public static final boolean DEVELOPMENT_FORCE_STARTNEWGAME = false; public static final boolean DEVELOPMENT_FORCE_CONTINUEGAME = false; public static final boolean DEVELOPMENT_DEBUGBUTTONS = true; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java index eb4b2bc0f..63ea37a49 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/DebugInterface.java @@ -89,6 +89,13 @@ public final class DebugInterface { showToast(mainActivity, "DEBUG: hp set to max", Toast.LENGTH_SHORT); } }) + ,new DebugButton("skill", new OnClickListener() { + @Override + public void onClick(View arg0) { + world.model.player.availableSkillIncreases += 10; + showToast(mainActivity, "DEBUG: 10 skill points", Toast.LENGTH_SHORT); + } + }) /* ,new DebugButton("cg", new OnClickListener() { @Override diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java index fc2e41e84..2a18d92d7 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/ItemInfoActivity.java @@ -62,6 +62,8 @@ public final class ItemInfoActivity extends Activity { itemType.effects_use == null ? null : Collections.singletonList(itemType.effects_use), itemType.effects_hit == null ? null : Collections.singletonList(itemType.effects_hit), itemType.effects_kill == null ? null : Collections.singletonList(itemType.effects_kill), + itemType.effects_hitReceived == null ? null : Collections.singletonList(itemType.effects_hitReceived), + null, itemType.isWeapon() ); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java index cf6306240..324a33cf9 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MainActivity.java @@ -29,6 +29,8 @@ import com.gpl.rpg.AndorsTrail.controller.listeners.CombatActionListener; import com.gpl.rpg.AndorsTrail.controller.listeners.CombatTurnListener; import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerMovementListener; import com.gpl.rpg.AndorsTrail.controller.listeners.WorldEventListener; +import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; @@ -191,6 +193,8 @@ public final class MainActivity controllers.movementController.playerMovementListeners.remove(this); controllers.combatController.combatActionListeners.remove(this); controllers.combatController.combatTurnListeners.remove(this); + controllers.actorStatsController.combatActionListeners.remove(this); + controllers.skillController.combatActionListeners.remove(this); controllers.mapController.worldEventListeners.remove(this); } @@ -198,6 +202,8 @@ public final class MainActivity controllers.mapController.worldEventListeners.add(this); controllers.combatController.combatTurnListeners.add(this); controllers.combatController.combatActionListeners.add(this); + controllers.actorStatsController.combatActionListeners.add(this); + controllers.skillController.combatActionListeners.add(this); controllers.movementController.playerMovementListeners.add(this); statusview.subscribe(); quickitemview.subscribe(); @@ -493,5 +499,68 @@ public final class MainActivity public void onPlayerDoesNotHaveEnoughAP() { message(getString(R.string.combat_not_enough_ap)); } + + @Override + public void onPlayerTauntsMonster(Monster attacker) { + message(getString(R.string.combat_taunt_monster, attacker.getName())); + } + + @Override + public void onPlayerReceviesActorCondition(ActorConditionEffect effect) { + StringBuilder sb = new StringBuilder(); + if (effect.isImmunity()) { + sb.append(effect.conditionType.name); + } else if (effect.isRemovalEffect()) { + sb.append(effect.conditionType.name); + } else { + sb.append(effect.conditionType.name); + if (effect.magnitude > 1) { + sb.append(" x"); + sb.append(effect.magnitude); + } + } + if (ActorCondition.isTemporaryEffect(effect.duration)) { + sb.append(' '); + sb.append(getString(R.string.iteminfo_effect_duration, effect.duration)); + } + String msg = sb.toString(); + + if (effect.isImmunity()) { + message(getString(R.string.combat_condition_player_immune, msg)); + } else if (effect.isRemovalEffect()) { + message(getString(R.string.combat_condition_player_clear, msg)); + } else { + message(getString(R.string.combat_condition_player_apply, msg)); + } + } + + @Override + public void onMonsterReceivesActorCondition(ActorConditionEffect effect, Monster target) { + StringBuilder sb = new StringBuilder(); + if (effect.isImmunity()) { + sb.append(effect.conditionType.name); + } else if (effect.isRemovalEffect()) { + sb.append(effect.conditionType.name); + } else { + sb.append(effect.conditionType.name); + if (effect.magnitude > 1) { + sb.append(" x"); + sb.append(effect.magnitude); + } + } + if (ActorCondition.isTemporaryEffect(effect.duration)) { + sb.append(' '); + sb.append(getString(R.string.iteminfo_effect_duration, effect.duration)); + } + String msg = sb.toString(); + + if (effect.isImmunity()) { + message(getString(R.string.combat_condition_monster_immune, target.getName(), msg)); + } else if (effect.isRemovalEffect()) { + message(getString(R.string.combat_condition_monster_clear, target.getName(), msg)); + } else { + message(getString(R.string.combat_condition_monster_apply, target.getName(), msg)); + } + } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java index dc3e39ca8..e129e6a39 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/MonsterInfoActivity.java @@ -87,6 +87,8 @@ public final class MonsterInfoActivity extends Activity { null, monster.getOnHitEffectsAsList(), null, + monster.getOnHitReceivedEffectsAsList(), + monster.getOnDeathEffects(), false); hp.update(monster.getMaxHP(), monster.getCurrentHP()); monsterinfo_max_ap.setText(Integer.toString(monster.getMaxAP())); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java index 19857ec43..ffc1dec2c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/activity/fragment/HeroinfoActivity_Stats.java @@ -12,12 +12,14 @@ import android.widget.Button; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; + import com.gpl.rpg.AndorsTrail.AndorsTrailApplication; import com.gpl.rpg.AndorsTrail.Dialogs; import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.Inventory; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.view.ItemEffectsView; @@ -155,15 +157,17 @@ public final class HeroinfoActivity_Stats extends Fragment { ArrayList effects_hit = new ArrayList(); ArrayList effects_kill = new ArrayList(); + ArrayList effects_hitReceived = new ArrayList(); for (Inventory.WearSlot slot : Inventory.WearSlot.values()) { ItemType type = player.inventory.getItemTypeInWearSlot(slot); if (type == null) continue; if (type.effects_hit != null) effects_hit.add(type.effects_hit); if (type.effects_kill != null) effects_kill.add(type.effects_kill); + if (type.effects_hitReceived != null) effects_hitReceived.add(type.effects_hitReceived); } if (effects_hit.isEmpty()) effects_hit = null; if (effects_kill.isEmpty()) effects_kill = null; - actorinfo_onhiteffects.update(null, null, effects_hit, effects_kill, false); + actorinfo_onhiteffects.update(null, null, effects_hit, effects_kill, effects_hitReceived, null, false); updateStatsTableRow(world.model.statistics.getNumberOfCompletedQuests(world), R.id.heroinfo_gamestats_quests, R.id.heroinfo_gamestats_quests_row); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java index 49db85c4d..9c70430b3 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ActorStatsController.java @@ -7,6 +7,7 @@ import com.gpl.rpg.AndorsTrail.context.ControllerContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.controller.listeners.ActorConditionListeners; import com.gpl.rpg.AndorsTrail.controller.listeners.ActorStatsListeners; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatActionListeners; import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerStatsListeners; import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; @@ -19,6 +20,7 @@ import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.item.Inventory; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; @@ -31,6 +33,7 @@ public final class ActorStatsController { public final ActorConditionListeners actorConditionListeners = new ActorConditionListeners(); public final ActorStatsListeners actorStatsListeners = new ActorStatsListeners(); public final PlayerStatsListeners playerStatsListeners = new PlayerStatsListeners(); + public final CombatActionListeners combatActionListeners = new CombatActionListeners(); public ActorStatsController(ControllerContext controllers, WorldContext world) { this.controllers = controllers; @@ -458,12 +461,22 @@ public final class ActorStatsController { controllers.effectController.startEnqueuedEffect(source.position); } } + + public void applyHitReceivedEffect(Actor source, Actor target, ItemTraits_OnHitReceived effect) { + applyUseEffect(source, target, effect); + if (effect.changedStats_target != null) { + applyStatsModifierEffect(target, effect.changedStats, 1); + controllers.effectController.startEnqueuedEffect(target.position); + } + } private void rollForConditionEffect(Actor actor, ActorConditionEffect conditionEffect) { int chanceRollBias = 0; if (actor.isPlayer) chanceRollBias = SkillController.getActorConditionEffectChanceRollBias(conditionEffect, (Player) actor); if (!Constants.rollResult(conditionEffect.chance, chanceRollBias)) return; + if (actor.isPlayer) combatActionListeners.onPlayerReceviesActorCondition(conditionEffect); + else combatActionListeners.onMonsterReceivesActorCondition(conditionEffect, (Monster)actor); applyActorCondition(actor, conditionEffect); } @@ -510,6 +523,13 @@ public final class ActorStatsController { applyUseEffect(player, null, type.effects_kill); } } + + public void applyOnDeathEffectsToPlayer(Player player, Actor monster) { + ItemTraits_OnUse onDeathEffect = monster.getOnDeathEffects(); + if (onDeathEffect == null) return; + + applyUseEffect(player, null, onDeathEffect); + } public void applySkillEffectsForNewRound(Player player, PredefinedMap currentMap) { int level = player.getSkillLevel(SkillCollection.SkillID.regeneration); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java index 516ced403..de6e01757 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/CombatController.java @@ -18,6 +18,7 @@ import com.gpl.rpg.AndorsTrail.model.actor.Actor; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; import com.gpl.rpg.AndorsTrail.model.actor.Player; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; @@ -208,6 +209,7 @@ public final class CombatController implements VisualEffectCompletedCallback { totalExpThisFight += loot.exp; loot.exp = 0; controllers.actorStatsController.applyKillEffectsToPlayer(player); + controllers.actorStatsController.applyOnDeathEffectsToPlayer(player, killedMonster); if (!loot.hasItemsOrGold()) { world.model.currentMap.removeGroundLoot(loot); @@ -554,10 +556,16 @@ public final class CombatController implements VisualEffectCompletedCallback { private void applyAttackHitStatusEffects(Actor attacker, Actor target) { ItemTraits_OnUse[] onHitEffects = attacker.getOnHitEffects(); - if (onHitEffects == null) return; - - for (ItemTraits_OnUse e : onHitEffects) { - controllers.actorStatsController.applyUseEffect(attacker, target, e); + ItemTraits_OnHitReceived[] onHitReceivedEffects = target.getOnHitReceivedEffects(); + if (onHitEffects != null) { + for (ItemTraits_OnUse e : onHitEffects) { + controllers.actorStatsController.applyUseEffect(attacker, target, e); + } + } + if (onHitReceivedEffects != null) { + for (ItemTraits_OnHitReceived e : onHitReceivedEffects) { + controllers.actorStatsController.applyHitReceivedEffect(target, attacker, e); + } } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java index c109536f8..9674ee83c 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/ItemController.java @@ -175,24 +175,37 @@ public final class ItemController { } public static void recalculateHitEffectsFromWornItems(Player player) { - ArrayList effects = null; + ArrayList effects_onHit = null; + ArrayList effects_onHitReceived = null; for (Inventory.WearSlot slot : Inventory.WearSlot.values()) { ItemType type = player.inventory.getItemTypeInWearSlot(slot); if (type == null) continue; - ItemTraits_OnUse e = type.effects_hit; - if (e == null) continue; + ItemTraits_OnUse eh = type.effects_hit; + ItemTraits_OnHitReceived ehr = type.effects_hitReceived; + if (eh == null && ehr == null) continue; - if (effects == null) effects = new ArrayList(); - effects.add(e); + if (effects_onHit == null) effects_onHit = new ArrayList(); + if (eh != null) effects_onHit.add(eh); + + if (effects_onHitReceived == null) effects_onHitReceived = new ArrayList(); + if (ehr != null) effects_onHitReceived.add(ehr); } - if (effects != null) { - ItemTraits_OnUse[] effects_ = new ItemTraits_OnUse[effects.size()]; - effects_ = effects.toArray(effects_); + if (effects_onHit != null) { + ItemTraits_OnUse[] effects_ = new ItemTraits_OnUse[effects_onHit.size()]; + effects_ = effects_onHit.toArray(effects_); player.onHitEffects = effects_; } else { player.onHitEffects = null; } + + if (effects_onHitReceived != null) { + ItemTraits_OnHitReceived[] effects_ = new ItemTraits_OnHitReceived[effects_onHitReceived.size()]; + effects_ = effects_onHitReceived.toArray(effects_); + player.onHitReceivedEffects = effects_; + } else { + player.onHitReceivedEffects = null; + } } public void consumeNonItemLoot(Loot loot) { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java index eda8e048f..5771a1810 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/MapController.java @@ -188,6 +188,13 @@ public final class MapController { if (!satisfiesCondition(replacement)) continue; else ConversationController.requirementFulfilled(world, replacement.requirement); tileMap.applyReplacement(replacement); + for (ReplaceableMapSection impactedReplacement : tileMap.replacements) { + if (impactedReplacement.isApplied && impactedReplacement.replacementArea.intersects(replacement.replacementArea)) { + //The applied replacement has overwritten changes made by a previously applied replacement. + //This previous replacement must now be considered as unapplied to let it be reapplied later eventually. + impactedReplacement.isApplied = false; + } + } hasUpdated = true; } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java index b7845b2ef..a4a264123 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/SkillController.java @@ -2,6 +2,7 @@ package com.gpl.rpg.AndorsTrail.controller; import com.gpl.rpg.AndorsTrail.context.ControllerContext; import com.gpl.rpg.AndorsTrail.context.WorldContext; +import com.gpl.rpg.AndorsTrail.controller.listeners.CombatActionListeners; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionType; import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection; @@ -20,6 +21,8 @@ import com.gpl.rpg.AndorsTrail.util.ConstRange; public final class SkillController { private final ControllerContext controllers; private final WorldContext world; + public final CombatActionListeners combatActionListeners = new CombatActionListeners(); + public SkillController(ControllerContext controllers, WorldContext world) { this.controllers = controllers; @@ -184,6 +187,7 @@ public final class SkillController { public void applySkillEffectsFromMonsterAttack(AttackResult result, Monster monster) { if (!result.isHit) { if (rollForSkillChance(world.model.player, SkillID.taunt, SkillCollection.PER_SKILLPOINT_INCREASE_TAUNT_CHANCE)) { + combatActionListeners.onPlayerTauntsMonster(monster); controllers.actorStatsController.changeActorAP(monster, -SkillCollection.TAUNT_AP_LOSS, false, false); } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java index a65ba89d5..3b8e4ac19 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListener.java @@ -1,6 +1,7 @@ package com.gpl.rpg.AndorsTrail.controller.listeners; import com.gpl.rpg.AndorsTrail.controller.AttackResult; +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.actor.Monster; public interface CombatActionListener { @@ -13,4 +14,8 @@ public interface CombatActionListener { void onPlayerStartedFleeing(); void onPlayerFailedFleeing(); void onPlayerDoesNotHaveEnoughAP(); + void onPlayerTauntsMonster(Monster attacker); + void onPlayerReceviesActorCondition(ActorConditionEffect conditionEffect); + void onMonsterReceivesActorCondition(ActorConditionEffect conditionEffect, Monster target); + } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java index 0183b1d83..1a931bc27 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/controller/listeners/CombatActionListeners.java @@ -1,6 +1,7 @@ package com.gpl.rpg.AndorsTrail.controller.listeners; import com.gpl.rpg.AndorsTrail.controller.AttackResult; +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.util.ListOfListeners; @@ -41,6 +42,18 @@ public final class CombatActionListeners extends ListOfListeners onPlayerDoesNotHaveEnoughAP = new Function() { @Override public void call(CombatActionListener listener) { listener.onPlayerDoesNotHaveEnoughAP(); } }; + + private final Function1 onPlayerTauntsMonster = new Function1() { + @Override public void call(CombatActionListener listener, Monster attacker) { listener.onPlayerTauntsMonster(attacker); } + }; + + private final Function1 onPlayerReceviesActorCondition = new Function1() { + @Override public void call(CombatActionListener listener, ActorConditionEffect effect) { listener.onPlayerReceviesActorCondition(effect); } + }; + + private final Function2 onMonsterReceivesActorCondition = new Function2() { + @Override public void call(CombatActionListener listener, ActorConditionEffect effect, Monster target) { listener.onMonsterReceivesActorCondition(effect, target); } + }; @Override public void onPlayerAttackMissed(Monster target, AttackResult attackResult) { @@ -86,4 +99,20 @@ public final class CombatActionListeners extends ListOfListeners getOnHitEffectsAsList() { return onHitEffects == null ? null : Arrays.asList(onHitEffects); } - + public ItemTraits_OnHitReceived[] getOnHitReceivedEffects() { return onHitReceivedEffects; } + public List getOnHitReceivedEffectsAsList() { return onHitReceivedEffects == null ? null : Arrays.asList(onHitReceivedEffects); } + public ItemTraits_OnUse getOnDeathEffects() { return onDeathEffects; } + public boolean hasCriticalSkillEffect() { return getCriticalSkill() != 0; } public boolean hasCriticalMultiplierEffect() { float m = getCriticalMultiplier(); return m != 0 && m != 1; } public boolean hasCriticalAttacks() { return hasCriticalSkillEffect() && hasCriticalMultiplierEffect(); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java index 466a713cb..39d549671 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/Monster.java @@ -50,6 +50,8 @@ public final class Monster extends Actor { this.blockChance = monsterType.blockChance; this.damageResistance = monsterType.damageResistance; this.onHitEffects = monsterType.onHitEffects; + this.onHitReceivedEffects = monsterType.onHitReceivedEffects; + this.onDeathEffects = monsterType.onDeathEffects; } public DropList getDropList() { return monsterType.dropList; } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java index 46b097d7f..bfad037df 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/actor/MonsterType.java @@ -1,6 +1,7 @@ package com.gpl.rpg.AndorsTrail.model.actor; import com.gpl.rpg.AndorsTrail.model.item.DropList; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.util.ConstRange; import com.gpl.rpg.AndorsTrail.util.Size; @@ -47,6 +48,8 @@ public final class MonsterType { public final int blockChance; public final int damageResistance; public final ItemTraits_OnUse[] onHitEffects; + public final ItemTraits_OnHitReceived[] onHitReceivedEffects; + public final ItemTraits_OnUse onDeathEffects; public MonsterType( String id @@ -72,6 +75,8 @@ public final class MonsterType { , int blockChance , int damageResistance , ItemTraits_OnUse[] onHitEffects + , ItemTraits_OnHitReceived[] onHitReceivedEffects + , ItemTraits_OnUse onDeathEffects ) { this.id = id; this.name = name; @@ -96,6 +101,8 @@ public final class MonsterType { this.blockChance = blockChance; this.damageResistance = damageResistance; this.onHitEffects = onHitEffects; + this.onHitReceivedEffects = onHitReceivedEffects; + this.onDeathEffects = onDeathEffects; } public static enum AggressionType { diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnHitReceived.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnHitReceived.java new file mode 100644 index 000000000..12372ed53 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnHitReceived.java @@ -0,0 +1,26 @@ +package com.gpl.rpg.AndorsTrail.model.item; + +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; +import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; + +public class ItemTraits_OnHitReceived extends ItemTraits_OnUse { + + public final StatsModifierTraits changedStats_target; + + public ItemTraits_OnHitReceived( + StatsModifierTraits changedStats + , StatsModifierTraits changedStats_target + , ActorConditionEffect[] addedConditions_source + , ActorConditionEffect[] addedConditions_target + ) { + super(changedStats_target, addedConditions_source, addedConditions_target); + this.changedStats_target = changedStats_target; + } + + public int calculateHitReceivedCost() { + int costStats = changedStats == null ? 0 : changedStats.calculateHitCost(); + costStats += changedStats_target == null ? 0 : -changedStats_target.calculateHitCost(); + return costStats; + } + +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnUse.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnUse.java index 6760cb224..0b0af9699 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnUse.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemTraits_OnUse.java @@ -3,7 +3,7 @@ package com.gpl.rpg.AndorsTrail.model.item; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; -public final class ItemTraits_OnUse { +public class ItemTraits_OnUse { public final StatsModifierTraits changedStats; public final ActorConditionEffect[] addedConditions_source; public final ActorConditionEffect[] addedConditions_target; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemType.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemType.java index cd6a82de4..9d69d1ccd 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemType.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/item/ItemType.java @@ -34,6 +34,7 @@ public final class ItemType { public final ItemTraits_OnUse effects_use; public final ItemTraits_OnUse effects_hit; public final ItemTraits_OnUse effects_kill; + public final ItemTraits_OnHitReceived effects_hitReceived; public ItemType( String id @@ -48,6 +49,7 @@ public final class ItemType { , ItemTraits_OnUse effects_use , ItemTraits_OnUse effects_hit , ItemTraits_OnUse effects_kill + , ItemTraits_OnHitReceived effects_hitReceived ) { this.id = id; this.iconID = iconID; @@ -62,6 +64,7 @@ public final class ItemType { this.effects_use = effects_use; this.effects_hit = effects_hit; this.effects_kill = effects_kill; + this.effects_hitReceived = effects_hitReceived; this.hasPersonalizedName = name.contains(Constants.PLACEHOLDER_PLAYERNAME); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java index c85491380..aed27b394 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/model/map/TMXMapTranslator.java @@ -288,7 +288,8 @@ public final class TMXMapTranslator { else if (prop.name.equalsIgnoreCase(LAYERNAME_ABOVE)) layerNames.aboveLayersName = prop.value; else if (prop.name.equalsIgnoreCase(LAYERNAME_WALKABLE)) layerNames.walkableLayersName = prop.value; else if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { - L.log("OPTIMIZE: Map " + map.name + " contains replace area with unknown property \"" + prop.name + "\"."); + if (!requirementPropertiesNames.contains(prop.name)) + L.log("OPTIMIZE: Map " + map.name + " contains replace area with unknown property \"" + prop.name + "\"."); } } MapSection replacementSection = transformMapSection(map, tileCache, position, layersPerLayerName, usedTileIDs, layerNames); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java index 09b671ce7..ad85a91c0 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/ResourceLoader.java @@ -235,7 +235,7 @@ public final class ResourceLoader { loader.prepareTileset(R.drawable.ui_quickslots, "ui_quickslots", sz2x1, sz1x1, mTileSize); loader.prepareTileset(R.drawable.ui_icon_equipment, "ui_icon_equipment", sz1x1, sz1x1, mTileSize); loader.prepareTileset(R.drawable.ui_splatters1, "ui_splatters1", new Size(8, 2), sz1x1, mTileSize); - loader.prepareTileset(R.drawable.ui_icon_skill, "ui_icon_skill", sz1x1, sz1x1, mTileSize); + loader.prepareTileset(R.drawable.ui_icon_immunity, "ui_icon_immunity", sz1x1, sz1x1, mTileSize); loader.prepareTileset(R.drawable.actorconditions_1, "actorconditions_1", new Size(14, 8), sz1x1, mTileSize); loader.prepareTileset(R.drawable.actorconditions_2, "actorconditions_2", sz3x1, sz1x1, mTileSize); diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java index 31cc2a5aa..0cc627f3b 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTraitsParser.java @@ -7,11 +7,13 @@ import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionTypeCollection; import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits; import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.util.ConstRange; import com.gpl.rpg.AndorsTrail.util.L; + import org.json.JSONException; import org.json.JSONObject; @@ -73,6 +75,44 @@ public final class ItemTraitsParser { } } + public ItemTraits_OnHitReceived parseItemTraits_OnHitReceived(JSONObject o) throws JSONException { + if (o == null) return null; + + ConstRange boostCurrentHP = ResourceParserUtils.parseConstRange(o.optJSONObject(JsonFieldNames.ItemTraits_OnHitReceived.increaseCurrentHP)); + ConstRange boostCurrentAP = ResourceParserUtils.parseConstRange(o.optJSONObject(JsonFieldNames.ItemTraits_OnHitReceived.increaseCurrentAP)); + ConstRange boostAttackerCurrentHP = ResourceParserUtils.parseConstRange(o.optJSONObject(JsonFieldNames.ItemTraits_OnHitReceived.increaseAttackerCurrentHP)); + ConstRange boostAttackerCurrentAP = ResourceParserUtils.parseConstRange(o.optJSONObject(JsonFieldNames.ItemTraits_OnHitReceived.increaseAttackerCurrentAP)); + ActorConditionEffect[] addedConditions_source = actorConditionEffectParser_withDuration.parseArray(o.optJSONArray(JsonFieldNames.ItemTraits_OnHitReceived.conditionsSource)); + ActorConditionEffect[] addedConditions_target = actorConditionEffectParser_withDuration.parseArray(o.optJSONArray(JsonFieldNames.ItemTraits_OnHitReceived.conditionsTarget)); + if ( boostCurrentHP == null + && boostCurrentAP == null + && boostAttackerCurrentAP == null + && boostCurrentAP == null + && addedConditions_source == null + && addedConditions_target == null + ) { + if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) { + L.log("OPTIMIZE: Tried to parseItemTraits_OnHitReceived , where hasEffect=" + o.toString() + ", but all data was empty."); + } + return null; + } else { + return new ItemTraits_OnHitReceived( + new StatsModifierTraits( + null + ,boostCurrentHP + ,boostCurrentAP + ) + , new StatsModifierTraits( + null + ,boostAttackerCurrentHP + ,boostAttackerCurrentAP + ) + ,addedConditions_source + ,addedConditions_target + ); + } + } + public ItemTraits_OnEquip parseItemTraits_OnEquip(JSONObject o) throws JSONException { if (o == null) return null; diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java index 5aa26cbc8..e3777ac19 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/ItemTypeParser.java @@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.resource.parsers; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionTypeCollection; import com.gpl.rpg.AndorsTrail.model.item.ItemCategoryCollection; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader; @@ -10,6 +11,7 @@ import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.util.Pair; + import org.json.JSONException; import org.json.JSONObject; @@ -40,7 +42,8 @@ public final class ItemTypeParser extends JsonCollectionParserFor { final ItemTraits_OnUse useEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.useEffect)); final ItemTraits_OnUse hitEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.hitEffect)); final ItemTraits_OnUse killEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.killEffect)); - + final ItemTraits_OnHitReceived hitReceivedEffect = itemTraitsParser.parseItemTraits_OnHitReceived(o.optJSONObject(JsonFieldNames.ItemType.hitReceivedEffect)); + final int baseMarketCost = o.optInt(JsonFieldNames.ItemType.baseMarketCost); final boolean hasManualPrice = o.optInt(JsonFieldNames.ItemType.hasManualPrice, 0) > 0; final ItemType itemType = new ItemType( @@ -56,6 +59,7 @@ public final class ItemTypeParser extends JsonCollectionParserFor { , useEffect , hitEffect , killEffect + , hitReceivedEffect ); return new Pair(id, itemType); } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java index 70fa59a04..4f6f47b64 100644 --- a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/resource/parsers/MonsterTypeParser.java @@ -7,6 +7,7 @@ import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionTypeCollection; import com.gpl.rpg.AndorsTrail.model.actor.MonsterType; import com.gpl.rpg.AndorsTrail.model.item.DropListCollection; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; @@ -49,6 +50,8 @@ public final class MonsterTypeParser extends JsonCollectionParserFor effects_use, Collection effects_hit, Collection effects_kill, + Collection effects_hitreceived, + ItemTraits_OnUse effects_death, boolean isWeapon ) { @@ -85,5 +97,19 @@ public final class ItemEffectsView extends LinearLayout { } else { itemeffect_onkill_title.setVisibility(View.GONE); } + + itemeffect_onhitreceived.update(effects_hitreceived); + if (effects_hitreceived != null) { + itemeffect_onhitreceived_title.setVisibility(View.VISIBLE); + } else { + itemeffect_onhitreceived_title.setVisibility(View.GONE); + } + + itemeffect_ondeath.update(effects_death); + if (effects_death != null) { + itemeffect_ondeath_title.setVisibility(View.VISIBLE); + } else { + itemeffect_ondeath_title.setVisibility(View.GONE); + } } } diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ItemEffectsView_OnDeath.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ItemEffectsView_OnDeath.java new file mode 100644 index 000000000..1f680a9cc --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ItemEffectsView_OnDeath.java @@ -0,0 +1,74 @@ +package com.gpl.rpg.AndorsTrail.view; + +import java.util.ArrayList; +import java.util.Arrays; + +import android.content.Context; +import android.content.res.Resources; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; +import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; + +public final class ItemEffectsView_OnDeath extends LinearLayout { + private final LinearLayout itemeffect_ondeath_ontarget_list; + private final ActorConditionEffectList itemeffect_ondeath_conditions_source; + private final TextView itemeffect_ondeath_target_title; + + public ItemEffectsView_OnDeath(Context context, AttributeSet attr) { + super(context, attr); + setFocusable(false); + setOrientation(LinearLayout.VERTICAL); + inflate(context, R.layout.itemeffectview_ondeath, this); + + itemeffect_ondeath_ontarget_list = (LinearLayout) findViewById(R.id.itemeffect_ondeath_ontarget_list); + itemeffect_ondeath_target_title = (TextView) findViewById(R.id.itemeffect_ondeath_target_title); + itemeffect_ondeath_conditions_source = (ActorConditionEffectList) findViewById(R.id.itemeffect_ondeath_conditions_source); + } + + public void update(ItemTraits_OnUse effects) { + ArrayList sourceEffects = new ArrayList(); + + itemeffect_ondeath_ontarget_list.removeAllViews(); + + boolean sourceHasStatsModifiers = false; + if (effects != null) { + final Context context = getContext(); + final Resources res = getResources(); + if (effects.addedConditions_source != null) sourceEffects.addAll(Arrays.asList(effects.addedConditions_source)); + + if (effects.changedStats != null) { + describeStatsModifierTraits(effects.changedStats, context, res, itemeffect_ondeath_ontarget_list); + if (effects.changedStats.currentAPBoost != null || effects.changedStats.currentHPBoost != null) sourceHasStatsModifiers = true; + } + } + itemeffect_ondeath_conditions_source.update(sourceEffects); + if (sourceEffects.isEmpty() && !sourceHasStatsModifiers) { + itemeffect_ondeath_target_title.setVisibility(View.GONE); + } else { + itemeffect_ondeath_target_title.setVisibility(View.VISIBLE); + } + } + + public static void describeStatsModifierTraits(StatsModifierTraits traits, Context context, Resources res, LinearLayout listView) { + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + + if (traits.currentAPBoost != null) { + final int label = traits.currentAPBoost.max > 0 ? R.string.iteminfo_effect_increase_current_ap : R.string.iteminfo_effect_decrease_current_ap; + final TextView tv = new TextView(context); + tv.setText(res.getString(label, traits.currentAPBoost.toMinMaxAbsString())); + listView.addView(tv, layoutParams); + } + if (traits.currentHPBoost != null) { + final int label = traits.currentHPBoost.max > 0 ? R.string.iteminfo_effect_increase_current_hp : R.string.iteminfo_effect_decrease_current_hp; + final TextView tv = new TextView(context); + tv.setText(res.getString(label, traits.currentHPBoost.toMinMaxAbsString())); + listView.addView(tv, layoutParams); + } + } +} diff --git a/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ItemEffectsView_OnHitReceived.java b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ItemEffectsView_OnHitReceived.java new file mode 100644 index 000000000..911c871e5 --- /dev/null +++ b/AndorsTrail/src/com/gpl/rpg/AndorsTrail/view/ItemEffectsView_OnHitReceived.java @@ -0,0 +1,97 @@ +package com.gpl.rpg.AndorsTrail.view; + +import android.content.Context; +import android.content.res.Resources; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.gpl.rpg.AndorsTrail.R; +import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect; +import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; +import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnHitReceived; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +public final class ItemEffectsView_OnHitReceived extends LinearLayout { + private final LinearLayout itemeffect_onhitreceived_onsource_list; + private final LinearLayout itemeffect_onhitreceived_ontarget_list; + private final ActorConditionEffectList itemeffect_onhitreceived_conditions_source; + private final ActorConditionEffectList itemeffect_onhitreceived_conditions_target; + private final TextView itemeffect_onhitreceived_source_title; + private final TextView itemeffect_onhitreceived_target_title; + + public ItemEffectsView_OnHitReceived(Context context, AttributeSet attr) { + super(context, attr); + setFocusable(false); + setOrientation(LinearLayout.VERTICAL); + inflate(context, R.layout.itemeffectview_onhitreceived, this); + + itemeffect_onhitreceived_onsource_list = (LinearLayout) findViewById(R.id.itemeffect_onhitreceived_onsource_list); + itemeffect_onhitreceived_ontarget_list = (LinearLayout) findViewById(R.id.itemeffect_onhitreceived_ontarget_list); + itemeffect_onhitreceived_source_title = (TextView) findViewById(R.id.itemeffect_onhitreceived_source_title); + itemeffect_onhitreceived_target_title = (TextView) findViewById(R.id.itemeffect_onhitreceived_target_title); + itemeffect_onhitreceived_conditions_source = (ActorConditionEffectList) findViewById(R.id.itemeffect_onhitreceived_conditions_source); + itemeffect_onhitreceived_conditions_target = (ActorConditionEffectList) findViewById(R.id.itemeffect_onhitreceived_conditions_target); + } + + public void update(Collection effects) { + ArrayList sourceEffects = new ArrayList(); + ArrayList targetEffects = new ArrayList(); + + itemeffect_onhitreceived_onsource_list.removeAllViews(); + itemeffect_onhitreceived_ontarget_list.removeAllViews(); + + boolean sourceHasStatsModifiers = false; + boolean targetHasStatsModifiers = false; + if (effects != null) { + final Context context = getContext(); + final Resources res = getResources(); + for (ItemTraits_OnHitReceived t : effects) { + if (t.addedConditions_source != null) sourceEffects.addAll(Arrays.asList(t.addedConditions_source)); + if (t.addedConditions_target != null) targetEffects.addAll(Arrays.asList(t.addedConditions_target)); + + if (t.changedStats != null) { + describeStatsModifierTraits(t.changedStats, context, res, itemeffect_onhitreceived_onsource_list); + if (t.changedStats.currentAPBoost != null || t.changedStats.currentHPBoost != null) sourceHasStatsModifiers = true; + } + if (t.changedStats_target != null) { + describeStatsModifierTraits(t.changedStats_target, context, res, itemeffect_onhitreceived_ontarget_list); + if (t.changedStats_target.currentAPBoost != null || t.changedStats_target.currentHPBoost != null) targetHasStatsModifiers = true; + } + } + } + itemeffect_onhitreceived_conditions_source.update(sourceEffects); + itemeffect_onhitreceived_conditions_target.update(targetEffects); + if (sourceEffects.isEmpty() && !sourceHasStatsModifiers) { + itemeffect_onhitreceived_source_title.setVisibility(View.GONE); + } else { + itemeffect_onhitreceived_source_title.setVisibility(View.VISIBLE); + } + if (targetEffects.isEmpty() && !targetHasStatsModifiers) { + itemeffect_onhitreceived_target_title.setVisibility(View.GONE); + } else { + itemeffect_onhitreceived_target_title.setVisibility(View.VISIBLE); + } + } + + public static void describeStatsModifierTraits(StatsModifierTraits traits, Context context, Resources res, LinearLayout listView) { + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + + if (traits.currentAPBoost != null) { + final int label = traits.currentAPBoost.max > 0 ? R.string.iteminfo_effect_increase_current_ap : R.string.iteminfo_effect_decrease_current_ap; + final TextView tv = new TextView(context); + tv.setText(res.getString(label, traits.currentAPBoost.toMinMaxAbsString())); + listView.addView(tv, layoutParams); + } + if (traits.currentHPBoost != null) { + final int label = traits.currentHPBoost.max > 0 ? R.string.iteminfo_effect_increase_current_hp : R.string.iteminfo_effect_decrease_current_hp; + final TextView tv = new TextView(context); + tv.setText(res.getString(label, traits.currentHPBoost.toMinMaxAbsString())); + listView.addView(tv, layoutParams); + } + } +}