Merge pull request #10 from NutAndor/test_brimhaven

Test brimhaven
This commit is contained in:
Nut
2020-05-01 11:10:42 +02:00
committed by GitHub
77 changed files with 702 additions and 263 deletions

View File

@@ -3,8 +3,8 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gpl.rpg.AndorsTrail"
android:versionCode="51"
android:versionName="0.7.9"
android:versionCode="52"
android:versionName="0.7.10"
android:installLocation="auto"
>
<uses-sdk
@@ -22,9 +22,8 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:name=".AndorsTrailApplication"
android:label="@string/app_name"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -23,6 +23,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="@string/iteminfo_effect_set_damage_modifier"
android:id="@+id/abilitymodifierinfo_set_damage_modifier"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:text="@string/iteminfo_effect_increase_critical_skill"
android:id="@+id/abilitymodifierinfo_change_critical_skill"

View File

@@ -2544,7 +2544,7 @@
{
"rewardType":"removeQuestProgress",
"rewardID":"quest_burhczyd_nd",
"value":84
"value":83
}
]
},

View File

@@ -152,7 +152,7 @@
},
{
"rewardType":"dropList",
"rewardID":"gold20"
"rewardID":"gold100"
}
]
},

View File

@@ -249,7 +249,8 @@
"requires":[
{
"requireType":"wear",
"requireID":"lifetaker"
"requireID":"lifetaker",
"value":1
}
]
},
@@ -266,6 +267,7 @@
{
"requireType":"wear",
"requireID":"lifetaker",
"value":1,
"negate":true
}
]

View File

@@ -347,7 +347,7 @@
},
{
"rewardType":"dropList",
"rewardID":"gold20"
"rewardID":"gold50"
}
]
},

View File

@@ -113,18 +113,31 @@
]
},
{
"id":"gold20",
"id":"gold100",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":20,
"max":20
"min":100,
"max":100
}
}
]
},
{
"id":"gold20",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":20,
"max":20
}
}
]
},
{
"id":"canine",
"items":[
@@ -216,8 +229,8 @@
"itemID":"gold",
"chance":"100",
"quantity":{
"min":10,
"max":10
"min":100,
"max":100
}
},
{
@@ -228,6 +241,14 @@
"max":1
}
},
{
"itemID":"ironsword2",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"gem1",
"chance":"5",

View File

@@ -1291,6 +1291,14 @@
"min":5,
"max":5
}
},
{
"itemID":"gloves_critical",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
@@ -1756,6 +1764,14 @@
"min":1,
"max":1
}
},
{
"itemID":"robe_protector",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},

View File

@@ -32,13 +32,11 @@
"increaseAttackCost":4,
"increaseAttackChance":25
},
"hitEffect":{
"killEffect":{
"increaseCurrentAP":{
"min":1,
"max":1
}
},
"killEffect":{
"max":3
},
"conditionsSource":[
{
"condition":"rage_minor",
@@ -102,6 +100,7 @@
"max":40
},
"increaseAttackCost":14,
"setNonWeaponDamageModifier":320,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0

View File

@@ -24,6 +24,7 @@
"max":7
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":104,
"increaseAttackChance":30,
"increaseCriticalSkill":0,
"increaseBlockChance":0,
@@ -120,6 +121,7 @@
"max":8
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":195,
"increaseAttackChance":12
},
"hitEffect":{

View File

@@ -35,6 +35,7 @@
},
"increaseReequipCost":0,
"increaseAttackCost":4,
"setNonWeaponDamageModifier":96,
"increaseAttackChance":15,
"increaseCriticalSkill":10,
"increaseBlockChance":2,
@@ -117,6 +118,7 @@
},
"increaseMaxHP":0,
"increaseAttackCost":5,
"setNonWeaponDamageModifier":113,
"increaseAttackChance":19,
"increaseCriticalSkill":10,
"increaseBlockChance":0,
@@ -167,6 +169,7 @@
"max":4
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":101,
"increaseAttackChance":9,
"increaseBlockChance":11
}

View File

@@ -82,6 +82,7 @@
"max":6
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":102,
"increaseAttackChance":20,
"increaseBlockChance":0
},
@@ -108,6 +109,7 @@
"max":11
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":130,
"increaseAttackChance":15
}
},
@@ -123,6 +125,7 @@
"max":13
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":130,
"increaseAttackChance":15,
"increaseCriticalSkill":4,
"setCriticalMultiplier":1.5
@@ -150,6 +153,7 @@
"max":3
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":10,
"increaseCriticalSkill":1,
"increaseBlockChance":7,
@@ -168,6 +172,7 @@
"max":4
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":105,
"increaseAttackChance":17,
"increaseCriticalSkill":9,
"setCriticalMultiplier":2.5
@@ -196,6 +201,7 @@
"max":9
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":130,
"increaseAttackChance":15,
"increaseBlockChance":4
}
@@ -215,6 +221,7 @@
"max":3
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":135,
"increaseAttackChance":8,
"increaseBlockChance":1
},
@@ -261,6 +268,7 @@
"max":14
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":135,
"increaseAttackChance":8,
"increaseCriticalSkill":10,
"setCriticalMultiplier":2.0
@@ -880,6 +888,7 @@
"max":5
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":15,
"increaseCriticalSkill":8,
"increaseBlockChance":5,
@@ -898,6 +907,7 @@
"max":28
},
"increaseAttackCost":13,
"setNonWeaponDamageModifier":320,
"increaseAttackChance":22,
"increaseCriticalSkill":1,
"increaseBlockChance":-5,

View File

@@ -1,4 +1,27 @@
[
{
"id":"gloves_critical",
"iconID":"items_armours_3:35",
"name":"Assassin's gloves",
"displaytype":"rare",
"category":"hnd_cloth",
"equipEffect":{
"increaseCriticalSkill":4,
"increaseBlockChance":1
}
},
{
"id":"robe_protector",
"iconID":"items_japozero:117",
"name":"Robe of the protector",
"displaytype":"ordinary",
"category":"bdy_clth",
"equipEffect":{
"increaseAttackChance":2,
"increaseCriticalSkill":2,
"increaseBlockChance":7
}
},
{
"id":"dagger_shadow_priests",
"iconID":"items_weapons:17",
@@ -13,6 +36,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":101,
"increaseAttackChance":20,
"increaseCriticalSkill":20,
"setCriticalMultiplier":3.0
@@ -31,6 +55,7 @@
"max":4
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":112,
"increaseAttackChance":15
}
},
@@ -47,6 +72,7 @@
"max":7
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":122,
"increaseAttackChance":12
}
},
@@ -63,6 +89,7 @@
"max":6
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":150,
"increaseAttackChance":9
}
},
@@ -79,6 +106,7 @@
"max":6
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":14
}
},
@@ -95,6 +123,7 @@
"max":10
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":184,
"increaseAttackChance":5
}
},
@@ -111,6 +140,7 @@
"max":4
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":100,
"increaseAttackChance":24
}
},
@@ -127,6 +157,7 @@
"max":7
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":97,
"increaseAttackChance":32
}
},
@@ -143,6 +174,7 @@
"max":11
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":145,
"increaseAttackChance":20
}
},
@@ -159,6 +191,7 @@
"max":7
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":119,
"increaseAttackChance":26,
"increaseBlockChance":3
}
@@ -176,6 +209,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":96,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0
@@ -194,6 +228,7 @@
"max":6
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":20
}
},
@@ -210,6 +245,7 @@
"max":5
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":93,
"increaseAttackChance":14,
"increaseBlockChance":5
}
@@ -227,6 +263,7 @@
"max":21
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":161,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0
@@ -245,6 +282,7 @@
"max":17
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":130,
"increaseAttackChance":21
}
},
@@ -261,6 +299,7 @@
"max":26
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":187,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0

View File

@@ -58,6 +58,7 @@
"max":5
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":112,
"increaseAttackChance":10
}
},
@@ -71,6 +72,7 @@
"category":"lsword",
"equipEffect":{
"increaseAttackCost":5,
"setNonWeaponDamageModifier":120,
"increaseAttackChance":-50
}
},
@@ -97,6 +99,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":102,
"increaseAttackChance":-30
},
"hitEffect":{
@@ -160,6 +163,7 @@
},
"increaseMaxHP":-20,
"increaseAttackCost":4,
"setNonWeaponDamageModifier":96,
"increaseAttackChance":40
},
"hitEffect":{

View File

@@ -84,6 +84,8 @@
"max":11
},
"increaseAttackCost":8,
"setNonWeaponDamageModifier":210,
"increaseAttackChance":15,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0
@@ -101,6 +103,7 @@
"max":11
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":162,
"increaseAttackChance":10,
"increaseCriticalSkill":10,
"setCriticalMultiplier":3.0

View File

@@ -14,6 +14,7 @@
},
"increaseMaxHP":5,
"increaseAttackCost":5,
"setNonWeaponDamageModifier":131,
"increaseAttackChance":21
},
"hitEffect":{
@@ -39,6 +40,7 @@
"category":"dagger",
"equipEffect":{
"increaseAttackCost":4,
"setNonWeaponDamageModifier":107,
"increaseAttackChance":15,
"increaseBlockChance":5
},
@@ -68,6 +70,7 @@
},
"increaseMaxAP":2,
"increaseAttackCost":5,
"setNonWeaponDamageModifier":123,
"increaseAttackChance":25,
"increaseBlockChance":5,
"addedConditions":[
@@ -92,6 +95,7 @@
"max":6
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":21,
"increaseBlockChance":5
},
@@ -121,6 +125,7 @@
},
"increaseMaxAP":2,
"increaseAttackCost":7,
"setNonWeaponDamageModifier":185,
"increaseAttackChance":25,
"increaseCriticalSkill":10,
"setCriticalMultiplier":2.0
@@ -220,6 +225,7 @@
"max":7
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":95,
"increaseAttackChance":50,
"increaseBlockChance":5,
"addedConditions":[
@@ -334,6 +340,7 @@
"max":12
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":140,
"increaseAttackChance":9
}
},
@@ -361,6 +368,7 @@
"max":15
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":160,
"increaseAttackChance":15,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0

View File

@@ -11,6 +11,7 @@
"max":2
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":129,
"increaseAttackChance":10
}
},

View File

@@ -25,7 +25,8 @@
"baseMarketCost":0,
"category":"dagger",
"equipEffect":{
"increaseAttackCost":5
"increaseAttackCost":5,
"setNonWeaponDamageModifier":128
}
},
{

View File

@@ -299,6 +299,7 @@
"max":4
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":155,
"increaseAttackChance":8,
"increaseCriticalSkill":1,
"increaseBlockChance":-2,
@@ -318,6 +319,7 @@
},
"increaseMaxHP":2,
"increaseAttackCost":7,
"setNonWeaponDamageModifier":155,
"increaseAttackChance":23,
"increaseCriticalSkill":4,
"increaseDamageResistance":-1,
@@ -342,6 +344,7 @@
"max":6
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":116,
"increaseAttackChance":9,
"increaseCriticalSkill":1,
"increaseBlockChance":-5,
@@ -360,6 +363,7 @@
"max":6
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":126,
"increaseAttackChance":12,
"increaseCriticalSkill":1,
"increaseBlockChance":3,
@@ -378,6 +382,7 @@
"max":4
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":118,
"increaseAttackChance":12,
"increaseCriticalSkill":6,
"increaseBlockChance":-5,
@@ -396,6 +401,7 @@
"max":8
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":12,
"increaseCriticalSkill":1,
"increaseBlockChance":-5,
@@ -414,6 +420,7 @@
"max":6
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":21,
"increaseCriticalSkill":1,
"increaseBlockChance":-4,
@@ -432,6 +439,7 @@
"max":5
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":185,
"increaseAttackChance":13,
"increaseCriticalSkill":1,
"increaseBlockChance":11,
@@ -452,6 +460,7 @@
},
"increaseMaxHP":4,
"increaseAttackCost":6,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":10,
"increaseCriticalSkill":2,
"increaseBlockChance":15,
@@ -471,6 +480,7 @@
"max":7
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":180,
"increaseAttackChance":28,
"increaseCriticalSkill":7,
"increaseBlockChance":-6,
@@ -491,6 +501,7 @@
"max":4
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":124,
"increaseAttackChance":12,
"increaseCriticalSkill":13,
"increaseBlockChance":-4,
@@ -521,6 +532,7 @@
},
"increaseMaxHP":5,
"increaseAttackCost":6,
"setNonWeaponDamageModifier":150,
"increaseAttackChance":19,
"increaseCriticalSkill":2,
"increaseBlockChance":5,
@@ -542,6 +554,7 @@
},
"increaseMaxHP":-4,
"increaseAttackCost":5,
"setNonWeaponDamageModifier":122,
"increaseAttackChance":35,
"increaseCriticalSkill":5,
"increaseBlockChance":-7,
@@ -582,6 +595,7 @@
},
"increaseMaxHP":-3,
"increaseAttackCost":7,
"setNonWeaponDamageModifier":187,
"increaseAttackChance":23,
"increaseCriticalSkill":10,
"increaseBlockChance":-4,
@@ -613,6 +627,7 @@
},
"increaseMaxHP":-2,
"increaseAttackCost":6,
"setNonWeaponDamageModifier":173,
"increaseAttackChance":32,
"increaseCriticalSkill":3,
"increaseBlockChance":12,
@@ -648,6 +663,7 @@
"max":5
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":5,
"increaseBlockChance":-2
},
@@ -674,6 +690,7 @@
"max":3
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":121,
"increaseAttackChance":6,
"increaseBlockChance":-1
}
@@ -691,6 +708,7 @@
},
"increaseMaxHP":1,
"increaseAttackCost":6,
"setNonWeaponDamageModifier":163,
"increaseAttackChance":12,
"increaseBlockChance":2
}
@@ -707,6 +725,7 @@
"max":8
},
"increaseAttackCost":8,
"setNonWeaponDamageModifier":218,
"increaseAttackChance":23,
"increaseCriticalSkill":5,
"increaseBlockChance":-17,
@@ -727,6 +746,7 @@
},
"increaseMaxHP":2,
"increaseAttackCost":7,
"setNonWeaponDamageModifier":164,
"increaseAttackChance":21,
"increaseCriticalSkill":5,
"setCriticalMultiplier":1.5
@@ -745,6 +765,7 @@
"max":17
},
"increaseAttackCost":8,
"setNonWeaponDamageModifier":320,
"increaseAttackChance":14,
"increaseBlockChance":-7,
"increaseDamageResistance":-1,
@@ -768,6 +789,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":99,
"increaseAttackChance":8,
"increaseBlockChance":-7
}
@@ -784,6 +806,7 @@
"max":3
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":104,
"increaseAttackChance":17,
"increaseCriticalSkill":8,
"increaseBlockChance":-7,
@@ -805,6 +828,7 @@
"max":4
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":98,
"increaseAttackChance":5,
"increaseCriticalSkill":9,
"increaseBlockChance":-8,
@@ -829,6 +853,7 @@
"max":3
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":6
}
},
@@ -844,6 +869,7 @@
"max":4
},
"increaseAttackCost":8,
"setNonWeaponDamageModifier":190,
"increaseAttackChance":12,
"increaseBlockChance":-3
}
@@ -860,6 +886,7 @@
"max":6
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":12,
"increaseCriticalSkill":6,
"increaseBlockChance":-5,
@@ -880,6 +907,7 @@
"max":2
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":173,
"increaseAttackChance":7,
"increaseCriticalSkill":10,
"increaseBlockChance":-5,
@@ -909,6 +937,7 @@
"max":4
},
"increaseAttackCost":8,
"setNonWeaponDamageModifier":191,
"increaseAttackChance":10,
"increaseBlockChance":8
}
@@ -925,6 +954,7 @@
"max":13
},
"increaseAttackCost":10,
"setNonWeaponDamageModifier":202,
"increaseAttackChance":25,
"increaseBlockChance":-6,
"increaseDamageResistance":-1
@@ -942,6 +972,7 @@
},
"increaseMaxHP":2,
"increaseAttackCost":6,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":10,
"increaseCriticalSkill":7,
"increaseBlockChance":-5,
@@ -962,6 +993,7 @@
"max":4
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":175,
"increaseAttackChance":16,
"increaseCriticalSkill":10,
"increaseBlockChance":-5,
@@ -991,6 +1023,7 @@
},
"increaseMaxHP":1,
"increaseAttackCost":5,
"setNonWeaponDamageModifier":110,
"increaseAttackChance":23,
"increaseCriticalSkill":10,
"increaseBlockChance":-4,
@@ -1010,6 +1043,7 @@
"max":5
},
"increaseAttackCost":8,
"setNonWeaponDamageModifier":209,
"increaseAttackChance":24,
"increaseBlockChance":9
}
@@ -1029,6 +1063,7 @@
},
"increaseMaxHP":3,
"increaseAttackCost":6,
"setNonWeaponDamageModifier":150,
"increaseAttackChance":32,
"increaseCriticalSkill":10,
"increaseBlockChance":-5,

View File

@@ -11,6 +11,7 @@
"max":1
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":126,
"increaseAttackChance":10
}
},
@@ -26,6 +27,7 @@
"max":7
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":170,
"increaseAttackChance":5
}
},
@@ -41,6 +43,7 @@
"max":1
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":115,
"increaseAttackChance":10
}
},
@@ -56,6 +59,7 @@
"max":1
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":114,
"increaseAttackChance":10
}
},
@@ -71,6 +75,7 @@
"max":7
},
"increaseAttackCost":10,
"setNonWeaponDamageModifier":215,
"increaseAttackChance":5
}
},
@@ -86,6 +91,7 @@
"max":1
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":112,
"increaseAttackChance":10
}
},
@@ -101,6 +107,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":100,
"increaseAttackChance":20
}
},
@@ -116,6 +123,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":101,
"increaseAttackChance":25
}
},
@@ -131,6 +139,7 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":96,
"increaseAttackChance":15
}
},
@@ -146,6 +155,7 @@
"max":3
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":111,
"increaseAttackChance":10
}
},
@@ -161,6 +171,7 @@
"max":4
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":120,
"increaseAttackChance":10
}
},
@@ -176,6 +187,7 @@
"max":10
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":171,
"increaseAttackChance":2
}
},
@@ -191,6 +203,7 @@
"max":10
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":155,
"increaseAttackChance":15
}
},
@@ -206,22 +219,24 @@
"max":7
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":105,
"increaseAttackChance":24
}
},
{
"id":"axe1",
"iconID":"items_weapons:56",
"name":"Woodcutter axe",
"name":"Woodcutter's axe",
"baseMarketCost":24,
"category":"axe",
"equipEffect":{
"increaseAttackDamage":{
"min":1,
"max":3
"min":6,
"max":12
},
"increaseAttackCost":5,
"increaseAttackChance":5
"increaseAttackCost":7,
"increaseAttackChance":5,
"setNonWeaponDamageModifier":187
}
},
{
@@ -236,6 +251,7 @@
"max":5
},
"increaseAttackCost":6,
"setNonWeaponDamageModifier":168,
"increaseAttackChance":5
}
},
@@ -248,6 +264,7 @@
"category":"dagger",
"equipEffect":{
"increaseAttackCost":3,
"setNonWeaponDamageModifier":75,
"increaseAttackChance":20,
"increaseBlockChance":-20
}

View File

@@ -89,6 +89,7 @@
{
"progress":100,
"logText":"I have brought the bread to Mikhail.",
"rewardExperience":30,
"finishesQuest":1
},
{
@@ -106,7 +107,7 @@
{
"progress":100,
"logText":"I have killed the two rats in our garden.",
"rewardExperience":20,
"rewardExperience":30,
"finishesQuest":1
},
{
@@ -134,7 +135,7 @@
{
"progress":100,
"logText":"I have told Leta that Oromir is hiding in Crossglen village.",
"rewardExperience":50,
"rewardExperience":80,
"finishesQuest":1
}
]
@@ -152,7 +153,7 @@
{
"progress":100,
"logText":"I have helped Odair clear out the rats in the supply cave in Crossglen village.",
"rewardExperience":300,
"rewardExperience":400,
"finishesQuest":1
}
]

View File

@@ -566,7 +566,7 @@
"rewardExperience":0
},
{
"progress":170,
"progress":171,
"logText":"My result confirmed his relatively low expectations.",
"rewardExperience":500
},

View File

@@ -138,12 +138,12 @@
<string-array name="preferences_language">
<item>@string/preferences_language_default</item>
<item>English</item>
<item>Deutsch (96%)</item>
<item>Español (90%)</item>
<item>Française (57%)</item>
<item>Deutsch (99%)</item>
<item>Español (91%)</item>
<item>Française (58%)</item>
<item>Italiano (90%)</item>
<item>Magyar (44%)</item>
<item>Polski (94%)</item>
<item>Polski (100%)</item>
<item>Português (78%)</item>
<item>Português Brasil (82%)</item>
<item>Русский язык (100%)</item>

View File

@@ -283,18 +283,16 @@
]]></string>
<string name="dialog_newversion_title">Welcome</string>
<string name="dialog_newversion_message">
Thank you for downloading Andor\'s Trail!\n\n
Please note that this version of Andor\'s Trail is a WORK IN PROGRESS, which means that all maps are not yet complete.\n
Please visit the project forums to discuss the game with other players or to help make the game even better (see "about").\n
\n
Thanks for all the feedback!
<string name="dialog_newversion_message">Thank you for downloading Andor\'s Trail!\n\nPlease note that this version of Andor\'s Trail is a WORK IN PROGRESS, which means that all maps are not yet complete.\nPlease visit the project forums to discuss the game with other players or to help make the game even better (see "about").\n\nThanks for all the feedback!
</string>
<string name="dialog_newversion_permission_information">\n\nIn order to save and load your games (and only for this purpose) Andor\'s Trail will ask you for permission to access your storage.</string>
<string name="dialog_permission_information_title">Loading and saving games</string>
<string name="dialog_permission_information">Andor\'s Trail writes saved games to user accessible storage on your device. This allows you to easily back up your saved games or transfer them to a new device. Please visit our forums for more information.\n\nAndor\'s Trail does not use access to your device for any other purpose and does not access the internet. Andor\'s Trail is open source; the sources can be found on github.</string>
<string name="questlog_includecompleted_prompt">Select quests to show</string>
<string name="questlog_includecompleted_hidecompleted">Hide completed quests</string>
<string name="questlog_includecompleted_includecompleted">Include completed quests</string>
<string name="questlog_includecompleted_onlycompleted">Only completed quests</string>
<string name="questlog_includecompleted_hidecompleted">Active quests</string>
<string name="questlog_includecompleted_includecompleted">All quests</string>
<string name="questlog_includecompleted_onlycompleted">Completed quests</string>
<string name="questlog_queststatus">Status: %1$s</string>
<string name="questlog_queststatus_inprogress">In progress</string>
<string name="questlog_queststatus_completed">Completed</string>
@@ -373,7 +371,7 @@
<string name="preferences_language_default">System language</string>
<string name="preferences_language">Language</string>
<string name="preferences_language_description">Select the language. English is used if the system language is not available or content has not ben translated. (Requires restart)</string>
<string name="preferences_language_description">Select the language. English is used if the system language is not available or content has not been translated. (Requires restart)</string>
<string name="inventory_assign">Assign quick slot</string>
<string name="inventory_selectitem">Select item to assign</string>
@@ -563,6 +561,7 @@
<string name="iteminfo_effect_weapon_attack_damage">Attack damage: %1$d</string>
<string name="iteminfo_effect_weapon_attack_damage_minmax">Attack damage: %1$d-%2$d</string>
<string name="iteminfo_effect_increase_attack_damage">Increases attack damage by %1$d</string>
<string name="iteminfo_effect_set_damage_modifier">Damage modifier: %1$d%%</string>
<string name="iteminfo_effect_increase_attack_damage_minmax">Increases attack damage by %1$d-%2$d</string>
<string name="iteminfo_effect_decrease_attack_damage">Lowers attack damage by %1$d</string>
<string name="iteminfo_effect_decrease_attack_damage_minmax">Lowers attack damage by %1$d-%2$d</string>
@@ -613,6 +612,7 @@
<string name="skill_title_fightstyle_dualwield">Fighting style: Dual wield</string>
<string name="skill_title_fightstyle_2hand">Fighting style: Two-handed weapon</string>
<string name="skill_title_fightstyle_weapon_shield">Fighting style: Weapon and shield</string>
<string name="skill_title_fightstyle_unarmed_unarmored">Fighting style: Way of the monk</string>
<string name="skill_title_specialization_dualwield">Specialization: Dual wield</string>
<string name="skill_title_specialization_2hand">Specialization: Two-handed weapon</string>
<string name="skill_title_specialization_weapon_shield">Specialization: Weapon and shield</string>
@@ -624,13 +624,14 @@
<string name="skill_shortdescription_weapon_prof_axe">Better at fighting with axes</string>
<string name="skill_shortdescription_weapon_prof_blunt">Better at fighting with bludgeoning weapons</string>
<string name="skill_shortdescription_weapon_prof_unarmed">Better at fighting without weapons</string>
<string name="skill_shortdescription_armor_prof_shield">Make better use of shields</string>
<string name="skill_shortdescription_armor_prof_shield">Make better use of shields and parrying weapons</string>
<string name="skill_shortdescription_armor_prof_unarmored">Better at fighting without armor</string>
<string name="skill_shortdescription_armor_prof_light">Make better use of light armor</string>
<string name="skill_shortdescription_armor_prof_heavy">Make better use of heavy armor</string>
<string name="skill_shortdescription_fightstyle_dualwield">Wield two weapons at the same time</string>
<string name="skill_shortdescription_fightstyle_2hand">Make better use of weapons that require both hands</string>
<string name="skill_shortdescription_fightstyle_weapon_shield">Better at fighting with weapon and shield</string>
<string name="skill_shortdescription_fightstyle_unarmed_unarmored">Better at fighting unarmed/unarmored</string>
<string name="skill_shortdescription_specialization_dualwield">Expert at dual wielding</string>
<string name="skill_shortdescription_specialization_2hand">Expert at two-handed weapons</string>
<string name="skill_shortdescription_specialization_weapon_shield">Expert at fighting with weapon and shield</string>
@@ -642,7 +643,7 @@
<string name="skill_longdescription_weapon_prof_axe">For each skill level, increases attack chance of axes and greataxes by %1$d %% of the item\'s base attack chance, increases block chance by %2$d %% of the item\'s base block chance, and increases critical skill by %3$d %% of the item\'s base critical skill.</string>
<string name="skill_longdescription_weapon_prof_blunt">For each skill level, increases attack chance of bludgeoning weapons by %1$d %% of the item\'s base attack chance, increases block chance by %2$d %% of the item\'s base block chance, and increases critical skill by %3$d %% of the item\'s base critical skill. This includes clubs, quarterstaves, maces, scepters, war hammers and giant hammers.</string>
<string name="skill_longdescription_weapon_prof_unarmed">When fighting without a weapon and shield, gain %1$d attack chance, %2$d damage potential and %3$d block chance per skill level.</string>
<string name="skill_longdescription_armor_prof_shield">Increase damage resistance by %1$d per skill level while having a shield equipped.</string>
<string name="skill_longdescription_armor_prof_shield">Increase damage resistance by %1$d per skill level while having a shield or parrying weapon equipped.</string>
<string name="skill_longdescription_armor_prof_unarmored">While fighting without having any piece of armor equipped, gain %1$d block chance per skill level. Items made of cloth are not considered as being armor.</string>
<string name="skill_longdescription_armor_prof_light">For every skill level, increases the block chance of every piece of light armor being worn by %1$d %% of their original block chances. Light armors include leather, light metal and hide armors.</string>
<string name="skill_longdescription_armor_prof_heavy">For every skill level, increases the block chance of every piece of heavy armor being worn by %1$d %% of their original block chances. Pieces of heavy armor have their movement penalties reduced by %2$d %% per skill level, and their attack speed penalties reduced by %3$d %% per skill level. Heavy armors include metal armors, chain mail and plate mail.</string>
@@ -656,12 +657,15 @@ With two levels of this skill, %4$d %% of the off-hand\'s weapon\'s qualities ma
<string name="skill_longdescription_fightstyle_2hand">"Gives benefits when using weapons that require both hands to wield, such as two-handed swords, greataxes or giant hammers.
Every skill level increases damage potential of two-handed weapons with %1$d %% of the original damage potential."</string>
<string name="skill_longdescription_fightstyle_weapon_shield">"Gives benefits when fighting with a weapon in the main hand and having a shield equipped in the off-hand.
<string name="skill_longdescription_fightstyle_weapon_shield">"Gives benefits when fighting with a weapon in the main hand and having a shield or parrying weapon equipped in the off-hand.
Every skill level increases the attack chance of weapons with %1$d %% of their original attack chances, and the block chance of shields by %2$d %% of their original block chances."</string>
Every skill level increases the attack chance of weapons in the main hand with %1$d %% of their original attack chances, and the block chance of shields or parrying weapons by %2$d %% of their original block chances."</string>
<string name="skill_longdescription_fightstyle_unarmed_unarmored">"While fighting without having any piece of armor equipped and without using a weapon or shield, gain %1$d attack chance, %2$d block chance, %3$d damage resistance and increase the maximum damage by %4$d per skill level. The skill also gives a critical multiplier of 1 plus 0.%5$d per level.
Items made of cloth are not considered as being armor." </string>
<string name="skill_longdescription_specialization_dualwield">Increases the attack chance of both wielded weapons by an additional %1$d %% of their original attack chances, in addition to the benefits given by the weapon style skill. The block chances of both wielded weapons are also increased by %2$d %% of their original block chances.</string>
<string name="skill_longdescription_specialization_2hand">Increases damage potential of two-handed weapons by an additional %1$d %% of the original damage potential, in addition to the benefits given by the weapon style skill. The attack chances of two-handed weapons are also increased by %2$d %% of their original attack chances.</string>
<string name="skill_longdescription_specialization_weapon_shield">Increases both attack chances and damage potential of weapons. The attack chance is increased by %1$d %% of the original attack chance, and the damage potential is increased by %2$d %% of the original damage potential.</string>
<string name="skill_longdescription_specialization_weapon_shield">Increases both attack chances and damage potential of weapons in the main hand. The attack chance is increased by %1$d %% of the original attack chance, and the damage potential is increased by %2$d %% of the original damage potential.</string>
<string name="skill_longdescription_weapon_prof_pole">For each skill level, increases attack chance when using pole weapons by %1$d %% of the item\'s base attack chance, increases block chance by %2$d %% of the item\'s base block chance, and increases critical skill by %3$d %% of the item\'s base critical skill.</string>
<string name="preferences_quickslots_placement">Quickslot position</string>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" tiledversion="1.1.5" orientation="orthogonal" renderorder="right-down" width="25" height="25" tilewidth="32" tileheight="32" infinite="0" nextobjectid="16">
<map version="1.0" tiledversion="1.1.6" orientation="orthogonal" renderorder="right-down" width="25" height="25" tilewidth="32" tileheight="32" infinite="0" nextobjectid="16">
<properties>
<property name="outdoors" value="1"/>
</properties>
@@ -188,22 +188,22 @@
eJy7J8nA8A6IN3Ki4s1QjCwGUncPSe09SYQYMo0sj6yPWHvAWJhEjMV9hOw4KEwaRg4HDPfisMdEmoHBFIjNpAn7AaQWPWyJscMZqM8FiF2lCfvBWRoz7oj1C7qfsGEzJD/gi3dCdsD8xMwOoZExyJ9BrLjTJSn2UAsPFzvIsQdfHFPDHkJplVh7iLGPHH/gsode6WEo24WvjKOWXfQoGyhJN6N4FFOCAVqdySY=
</data>
</layer>
<layer name="Objects" width="25" height="25">
<layer name="Objects" width="25" height="25" visible="0">
<data encoding="base64" compression="zlib">
eJyNVb1Ow0AMtioVdUIk0EiV4BEYgQkeBmZ2FjaQeAB4FdIdFCidClX6k4mlIqVdQEJMiHMb93yur40li7vj/H3+bF8K4FovAHiK7H5s1rnxScOeTRtQ2nx3fwxmxnieizXy8Ji/7XI8Mr8kmK81Le+hG7u5U44jDVyeYcHh00I5POwCPO6ux8d7EOr/SyJdy011vn8zsd0SHHhP9oT2rcjVgvpIy5XhuTZ+a/y8AvBSB/jesNq4xtOqWyeuAS33zBjZnYm/rNg98qE2TaPse8xwfH3pmtw77Bzz2t9b1kk2Cty5jCO779RdLciRGr8X3o7sPJCdbQFcVJfvojfZeuDpPb7V4xrASQmf6QxszbR3KetFPG2RN8UPxfmXZ3Z5DPZe4/koHPlGgR8nNxifDXc/ZvuUxUoeyUczR7lNBC7nGXtyShQ9q7iIj3LOBI+miev5LXydLswLnbAkZo/p4fXGt4AzzflWcSEmxb+GtiarLGZ1l9p8daQ6ZUptSBuf05bAma7hyj34vl7QnCXit7EvvhWcC2vO+03Y/QLLN2NxEctx+TdmEFku3m85V9y4Luwf9QTfZ8owZxrFrCzqHOp6eh4dTZGvZlQD3g/eF222+FmsYGcCi3Nlnnpp80a5LWol7mg5c9y+8h7p74H5Rh8WflSbc9CZnEEZ+w939yQl
</data>
</layer>
<layer name="Above" width="25" height="25">
<layer name="Above" width="25" height="25" visible="0">
<data encoding="base64" compression="zlib">
eJzFVVsKwkAMXIXS/guC4D28mJ7QG+jXSlvQk9ilBsJ2s500Aeenj3RnMpNAQ5gxnIIK/fT9eCjXElcv8CE671bXyxbsOtt5bV6Ip0+7zA7RuTYh3BrM076TZ+OF+3H5TpsXx/M8X8lnwqOgQUj+LHr/hLX3/DzCZ9HkuxSn+1fl2crPYeWtgXPnOh6eOJek4wELp2YnKJNSNkheazpRqCPc+f6gvrbMWeOjxu25Y8Tjvbc071zHwoVyIGdKPfJe40rNG5bsL7//uuT7C6IoWX0=
</data>
</layer>
<layer name="Above_replace" width="25" height="25">
<layer name="Above_replace" width="25" height="25" visible="0">
<data encoding="base64" compression="zlib">
eJxjYBgFo2AUDAbQIjD07bglSR9/jIJRMApGwShgYAAAUygCsA==
</data>
</layer>
<layer name="Walkable" width="25" height="25">
<layer name="Walkable" width="25" height="25" visible="0">
<data encoding="base64" compression="zlib">
eJzdlNENACEIQ53C/VdgQx1AoJRqLteED3OhT6qnzTFsVyabmvoKp8tC9Ze8XpzHiRWxT99YZX7ZmmWqPCr5M3c46kfy78wazXM7wxtSnw/LUUjxn1cZXl6eF8Lp3C+0x3u7UHXmYLxQBjtPlaHab8TIepA9KqrivwCLg9Kq
</data>
@@ -213,9 +213,9 @@
eJxjYBgFo2AUDAawUWzo2wEynx7+GAWjYBSMglHAwAAA3vsDHQ==
</data>
</layer>
<layer name="Above_replace2" width="25" height="25" visible="0">
<layer name="Above_replace2" width="25" height="25">
<data encoding="base64" compression="zlib">
eJztwQENAAAAwqD3T20ON6AAAHgzCcQAAQ==
eJxjYBgFo2AUjALqgFuSA+2CUTAKRsEoGDkAADcSAPQ=
</data>
</layer>
<layer name="Walkable_replace2" width="25" height="25" visible="0">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" tiledversion="1.0.2" orientation="orthogonal" renderorder="right-down" width="32" height="18" tilewidth="32" tileheight="32" nextobjectid="15">
<map version="1.2" tiledversion="1.2.2" orientation="orthogonal" renderorder="right-down" width="32" height="18" tilewidth="32" tileheight="32" infinite="0" nextlayerid="8" nextobjectid="15">
<properties>
<property name="outdoors" value="1"/>
</properties>
@@ -183,27 +183,27 @@
<tileset firstgid="7449" name="map_window_2" tilewidth="32" tileheight="32" tilecount="128" columns="16">
<image source="../drawable/map_window_2.png" width="512" height="256"/>
</tileset>
<layer name="Ground" width="32" height="18">
<layer id="1" name="Ground" width="32" height="18">
<data encoding="base64" compression="zlib">
eJzbyMnAsBEPluMiDeMzCxfeLYyK6WY/VP1pYVRMFfuB7E0E8DGo+iBpBoZgKA6RJi8M0fFFoNmXiMAgtYlAO5OgOBnNfvS4wYep4W50jB43+DCpZi9noq39hNIIOfYHIaUTetiPnjYTkdIJoXRLDfuxpc0dYoTTLbXspwQTsn8Fje3X5cKOYX6ntf3IGL2sgNk/DQ3Tyn70vAKzHxumhTvQ8wo++0F4JYVuWI5mBiiv/OZE5BVc4Y8eDvgwIfvxpS9c/l9JIFywxRU2TEgdTBwA2axxSQ==
eJy9lDEOwjAMRSO2du1YiRtwmcIFCnfiCqVjYWRnYYLrsJBIiUi/HJu2cYcnVa3l5zh2h8KYgWFbToPLleJejVnN7+Of1Zgsfvt8FXj4+KY2Zu851PN6iLxs7vcfuNjWOo+eE/jxbjhy1I3g3XBMzd1tdP3SjMzxN9GcrOHH2WyjOZHmNoefms0b8y23fwmS/6Ls35U04eza/hj8VwT/GdDy464EP4VGHbgrnN/RL6yhgxxuVz7Fb1dS/cc+cEh+br5S5++FvlB3RSHFhfdfjGFxNw==
</data>
</layer>
<layer name="Objects" width="32" height="18">
<layer id="2" name="Objects" width="32" height="18">
<data encoding="base64" compression="zlib">
eJytVclKA0EQbUbG5aKZUUdGBvQT/AGXP9CrB0XwJHjxoAfxJwQlHyK4gBcXNNEQEMXtIHgJJIoInvQg1rO76EpnJhr0QVPTXd31qmvpUUqpaqxULbZyqlOpnUhLP2xtyLMngfoG22WUDMdHqFIx9w/8sMG8R4a7d1CpPhr9g3ofcE0+xp7+Zjnu/53/J6zmtJwnGRHvW7uWGJOGf4ZsjbU4ZlvkR3zA2dZh+QHY4PwBXZ79/uxtXAOeA3t2orORs0D6W7MH+k3P5uiV1m9obPhaBxvTvvWHgXl3X/0a520+Z/mRh7tAcwKnRvKdOP9clyeR9ZH5F/zGO7iQ/rn8bWH6qBLHmdMbOAMfi4J/SfDzHR8SXSuQsVev/y3/s4gLehFznCmI3GC+buJ/RFzHNDro+yXRtfJi+Fm32AI/A70n7z/q1DD7c0n2rxLtC+oDtTIQ6jnr1ug7F/6Of5n8XDG+bkd67Eb2O20u13eb6HlPM/7zWNe+zL8ruV6LKW9oReQP4JquiP6b+4H/0cQKNg9oHArukuG5J3u1INtH911nFDPeH67XEdO/NVEL/Hbkac8QrQ87/4ay4XF9BbbEXMYljdt9Txj8L+K45L3s+16LnDyJ/4v0CfnNi57gNx49tJ/otb2UON0J/8+CepvlJjlwJd+jJ7T3R98CpURzfzi9mOWT1D+KM7hfIaU+GHjn8iLe6NtTJz+3Yv5ubF8IjrQaAWScsva7+xh8R+i+ADys5xs=
</data>
</layer>
<layer name="Above" width="32" height="18">
<layer id="3" name="Above" width="32" height="18">
<data encoding="base64" compression="zlib">
eJxjYCAeZAiQoBgIbkoyMNwC4s2SED6zFAMDixSqmofsCLaBCIR+xM5AN8DIgSnGhEWMVuCWJKbYYTH8eu4JU89+WBwhg0tQ+x+SGA/kxBs2/8PARxLN+0SG/dj8T0/79+DxP7a0eRlP2iAn3eLzPzaAL20SSrcwkAIsR9JILEtg4BIeO/DJIQPkMIf5H51GB6SGE7EAZOZGIN6EZDd6msDlRlq5CRvYB7UH3a3obsQGSC1H0M3E5V9i3YAtH5HqBhDYh8Mt5MbJVCb88vjyOjY3EmO3LBN+u6cTcBM9ALH+Jhcg+x0AK8hU/w==
</data>
</layer>
<layer name="Walkable" width="32" height="18">
<layer id="4" name="Walkable" width="32" height="18">
<data encoding="base64" compression="zlib">
eJzFk1sOwCAIBD1F738Fb9j0w4QQ6i4LrSSkD7UzYJ3XGDPIJ9Z1hX+Owq6tJMtj+fYd41nlq56Rr9K7LN/f23kKF3m8ra3WH30H8VFvVD4K1Lu/+Nn60Zha/24fO/nZs6IEy2fPcNa3k591VZmKgx/v5Gddd//y13zG7ZTHif1g8wav+Q9b
</data>
</layer>
<objectgroup name="Mapevents">
<objectgroup id="5" name="Mapevents">
<object id="1" name="northeast" type="mapchange" x="672" y="0" width="32" height="32">
<properties>
<property name="map" value="stoutford_ne"/>
@@ -265,7 +265,7 @@
</properties>
</object>
</objectgroup>
<objectgroup name="Spawn" visible="0">
<objectgroup id="6" name="Spawn" visible="0">
<object id="9" name="stoutford_farmer3" type="spawn" x="736" y="160" width="192" height="224"/>
<object id="10" name="stoutford_commoner4" type="spawn" x="384" y="320" width="288" height="64"/>
<object id="11" name="stoutford_guard1" type="spawn" x="928" y="32" width="32" height="32"/>
@@ -275,5 +275,5 @@
</properties>
</object>
</objectgroup>
<objectgroup name="Keys" visible="0"/>
<objectgroup id="7" name="Keys" visible="0"/>
</map>

View File

@@ -30,8 +30,8 @@ public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED;
public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 51;
public static final String CURRENT_VERSION_DISPLAY = "0.7.9";
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 52;
public static final String CURRENT_VERSION_DISPLAY = "0.7.10";
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();

View File

@@ -4,13 +4,18 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import android.*;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View;
@@ -106,7 +111,7 @@ public final class Dialogs {
if (!params.containsKey("x")) return null;
int x = params.getInt("x");
int y = params.getInt("y");
return world.model.currentMap.getMonsterAt(x, y);
return world.model.currentMaps.map.getMonsterAt(x, y);
}
public static void showMonsterEncounter(final MainActivity currentActivity, final ControllerContext context, final Monster monster) {
@@ -318,26 +323,47 @@ public final class Dialogs {
showDialogAndPause(d, controllerContext);
}
public static void showNewVersion(final Activity currentActivity) {
public static void showNewVersion(final Activity currentActivity, final OnDismissListener onDismiss) {
// new AlertDialog.Builder(new ContextThemeWrapper(currentActivity, R.style.AndorsTrailStyle))
// .setTitle(R.string.dialog_newversion_title)
// .setMessage(R.string.dialog_newversion_message)
// .setNeutralButton(android.R.string.ok, null)
// .show();
String text = currentActivity.getResources().getString(R.string.dialog_newversion_message);
if (!hasPermissions(currentActivity)) {
text += currentActivity.getResources().getString(R.string.dialog_newversion_permission_information);
}
final Dialog d = CustomDialogFactory.createDialog(currentActivity,
currentActivity.getResources().getString(R.string.dialog_newversion_title),
null,
currentActivity.getResources().getString(R.string.dialog_newversion_message),
text,
null,
true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
CustomDialogFactory.setDismissListener(d, new OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
if (onDismiss != null) onDismiss.onDismiss(arg0);
}
});
CustomDialogFactory.show(d);
}
@TargetApi(23)
private static boolean hasPermissions(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (activity.getApplicationContext().checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| activity.getApplicationContext().checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public static boolean showSave(final Activity mainActivity, final ControllerContext controllerContext, final WorldContext world) {
if (world.model.uiSelections.isInCombat) {
Toast.makeText(mainActivity, R.string.menu_save_saving_not_allowed_in_combat, Toast.LENGTH_SHORT).show();

View File

@@ -7,6 +7,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,6 +43,7 @@ import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.quest.Quest;
import com.gpl.rpg.AndorsTrail.model.quest.QuestLogEntry;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
@@ -76,11 +78,15 @@ public final class ConversationActivity
setContentView(R.layout.conversation);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setFinishOnTouchOutside(false);
}
replyGroup = new RadioGroup(this);
replyGroup.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, ListView.LayoutParams.WRAP_CONTENT));
statementList = (ListView) findViewById(R.id.conversation_statements);
statementList.addFooterView(replyGroup);
listAdapter = new StatementContainerAdapter(this, conversationHistory, world.tileManager);
listAdapter = new StatementContainerAdapter(this, conversationHistory, world.tileManager, world.model.currentMaps.tiles);
statementList.setAdapter(listAdapter);
nextButton = (Button) findViewById(R.id.conversation_next);
@@ -344,10 +350,12 @@ public final class ConversationActivity
private static final class StatementContainerAdapter extends ArrayAdapter<ConversationStatement> {
private final TileManager tileManager;
private final TileCollection tiles;
public StatementContainerAdapter(Context context, ArrayList<ConversationStatement> items, TileManager tileManager) {
public StatementContainerAdapter(Context context, ArrayList<ConversationStatement> items, TileManager tileManager, TileCollection tiles) {
super(context, 0, items);
this.tileManager = tileManager;
this.tiles = tiles;
}
@Override
@@ -362,7 +370,7 @@ public final class ConversationActivity
if (statement.hasActor()) {
final Resources res = getContext().getResources();
if (statement.isPlayerActor) tileManager.setImageViewTileForPlayer(res, tv, statement.iconID);
else tileManager.setImageViewTileForMonster(res, tv, statement.iconID);
else tileManager.setImageViewTileForMonster(res, tv, statement.iconID, tiles);
tv.setText(statement.actorName + ": " + statement.text, BufferType.SPANNABLE);
Spannable sp = (Spannable) tv.getText();

View File

@@ -93,7 +93,7 @@ public final class DisplayWorldMapActivity extends AndorsTrailBaseActivity {
}
WorldMapSegment segment = world.maps.worldMapSegments.get(worldMapSegmentName);
map = segment.maps.get(world.model.currentMap.name);
map = segment.maps.get(world.model.currentMaps.map.name);
if (map == null) {
this.finish();
return;

View File

@@ -6,6 +6,7 @@ import java.util.Collection;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
@@ -304,6 +305,9 @@ public final class MainActivity
t = Toast.makeText(this, msg, duration);
lastToast = new WeakReference<Toast>(t);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && t.getView().isShown()) {
t.cancel();
}
t.setText(msg);
t.setDuration(duration);
}

View File

@@ -41,7 +41,7 @@ public final class MonsterEncounterActivity extends AndorsTrailBaseActivity {
TextView tv = (TextView) findViewById(R.id.monsterencounter_title);
tv.setText(monster.getName());
world.tileManager.setImageViewTile(getResources(), tv, monster);
world.tileManager.setImageViewTile(getResources(), tv, monster, world.model.currentMaps.tiles);
tv = (TextView) findViewById(R.id.monsterencounter_description);
tv.setText(getString(R.string.dialog_monsterencounter_message, difficulty));

View File

@@ -79,7 +79,7 @@ public final class MonsterInfoActivity extends AndorsTrailBaseActivity {
private void updateTitle(Monster monster) {
monsterinfo_title.setText(monster.getName());
world.tileManager.setImageViewTile(getResources(), monsterinfo_title, monster);
world.tileManager.setImageViewTile(getResources(), monsterinfo_title, monster, world.model.currentMaps.tiles);
monsterinfo_difficulty.setText(getMonsterDifficultyResource(controllers, monster));
}

View File

@@ -148,6 +148,7 @@ public final class SkillInfoActivity extends AndorsTrailBaseActivity {
case fightstyleDualWield: return R.string.skill_title_fightstyle_dualwield;
case fightstyle2hand: return R.string.skill_title_fightstyle_2hand;
case fightstyleWeaponShield: return R.string.skill_title_fightstyle_weapon_shield;
case fightstyleUnarmedUnarmored: return R.string.skill_title_fightstyle_unarmed_unarmored;
case specializationDualWield: return R.string.skill_title_specialization_dualwield;
case specialization2hand: return R.string.skill_title_specialization_2hand;
case specializationWeaponShield: return R.string.skill_title_specialization_weapon_shield;
@@ -198,6 +199,12 @@ public final class SkillInfoActivity extends AndorsTrailBaseActivity {
case fightstyleDualWield: return res.getString(R.string.skill_longdescription_fightstyle_dualwield, SkillCollection.DUALWIELD_EFFICIENCY_LEVEL0, SkillCollection.DUALWIELD_EFFICIENCY_LEVEL1, SkillCollection.DUALWIELD_LEVEL1_OFFHAND_AP_COST_PERCENT, SkillCollection.DUALWIELD_EFFICIENCY_LEVEL2);
case fightstyle2hand: return res.getString(R.string.skill_longdescription_fightstyle_2hand, SkillCollection.PER_SKILLPOINT_INCREASE_FIGHTSTYLE_2HAND_DMG_PERCENT);
case fightstyleWeaponShield: return res.getString(R.string.skill_longdescription_fightstyle_weapon_shield, SkillCollection.PER_SKILLPOINT_INCREASE_FIGHTSTYLE_WEAPON_AC_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_FIGHTSTYLE_SHIELD_BC_PERCENT);
case fightstyleUnarmedUnarmored: return res.getString(R.string.skill_longdescription_fightstyle_unarmed_unarmored,
SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_AC,
SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_BC,
SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_DR,
SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_DMG_MAX,
SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_CM_PERCENT);
case specializationDualWield: return res.getString(R.string.skill_longdescription_specialization_dualwield, SkillCollection.PER_SKILLPOINT_INCREASE_SPECIALIZATION_DUALWIELD_AC_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_SPECIALIZATION_DUALWIELD_BC_PERCENT);
case specialization2hand: return res.getString(R.string.skill_longdescription_specialization_2hand, SkillCollection.PER_SKILLPOINT_INCREASE_SPECIALIZATION_2HAND_DMG_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_SPECIALIZATION_2HAND_AC_PERCENT);
case specializationWeaponShield: return res.getString(R.string.skill_longdescription_specialization_weapon_shield, SkillCollection.PER_SKILLPOINT_INCREASE_SPECIALIZATION_WEAPON_AC_PERCENT, SkillCollection.PER_SKILLPOINT_INCREASE_SPECIALIZATION_WEAPON_DMG_PERCENT);

View File

@@ -10,9 +10,13 @@ import com.gpl.rpg.AndorsTrail.activity.fragment.StartScreenActivity_NewGame.Gam
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.CloudsAnimatorView;
import com.gpl.rpg.AndorsTrail.view.CustomDialogFactory;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -109,34 +113,30 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
toggleUiVisibility();
app.getWorldSetup().startResourceLoader(res);
checkAndRequestPermissions();
}
private static final int READ_EXTERNAL_STORAGE_REQUEST=1;
private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2;
@TargetApi(23)
private void checkAndRequestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
}
if (getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
this.requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.storage_permissions_mandatory, Toast.LENGTH_LONG).show();
((AndorsTrailApplication)getApplication()).discardWorld();
finish();
final Dialog d = CustomDialogFactory.createDialog(this,
getResources().getString(R.string.dialog_permission_information_title),
getResources().getDrawable(android.R.drawable.ic_dialog_info),
getResources().getString(R.string.dialog_permission_information),
null,
true);
final Activity activity = this;
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
CustomDialogFactory.setDismissListener(d, new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
StartScreenActivity_MainMenu.checkAndRequestPermissions(activity);
}
});
CustomDialogFactory.show(d);
}
}
private void toggleUiVisibility() {
ui_visible = !ui_visible;
int visibility = ui_visible ? View.VISIBLE : View.GONE;

View File

@@ -116,43 +116,43 @@ public final class HeroinfoActivity_Quests extends Fragment {
groupList.clear();
childList.clear();
for (Quest q : world.quests.getAllQuests()) {
for (String questProgressID : player.getAllQuestProgressIDs()) {
Quest q = world.quests.getQuest(questProgressID);
if (q == null) continue; // This should not happen
if (!q.showInLog) continue; // Do not show
if (player.hasAnyQuestProgress(q.questID)) {
boolean isCompleted = q.isCompleted(player);
boolean isCompleted = q.isCompleted(player);
int v = world.model.uiSelections.selectedQuestFilter;
if (v == 0) { // Hide completed quests
if (isCompleted) continue;
} else if (v == 1) { // Include completed quests
// Always show.
} else if (v == 2) { // Only completed quests
if (!isCompleted) continue;
}
int statusResId;
if (isCompleted) {
statusResId = R.string.questlog_queststatus_completed;
} else {
statusResId = R.string.questlog_queststatus_inprogress;
}
Map<String, Object> item = new HashMap<String, Object>();
item.put(mn_questName, q.name);
item.put(mn_questStatus, getString(R.string.questlog_queststatus, getString(statusResId)));
groupList.add(item);
List<Map<String, ?>> logItemList = new ArrayList<Map<String, ?>>();
for (QuestLogEntry e : q.stages) {
if (e.logtext.length() <= 0) continue; // Do not show if displaytext is empty.
if (player.hasExactQuestProgress(q.questID, e.progress)) {
item = new HashMap<String, Object>();
item.put(mn_logText, e.logtext);
logItemList.add(item);
}
}
childList.add(logItemList);
int v = world.model.uiSelections.selectedQuestFilter;
if (v == 0) { // Active quests
if (isCompleted) continue;
} else if (v == 1) { // All quests
// Always show.
} else if (v == 2) { // Completed quests
if (!isCompleted) continue;
}
int statusResId;
if (isCompleted) {
statusResId = R.string.questlog_queststatus_completed;
} else {
statusResId = R.string.questlog_queststatus_inprogress;
}
Map<String, Object> item = new HashMap<String, Object>();
item.put(mn_questName, q.name);
item.put(mn_questStatus, getString(R.string.questlog_queststatus, getString(statusResId)));
groupList.add(item);
List<Map<String, ?>> logItemList = new ArrayList<Map<String, ?>>();
for (QuestLogEntry e : q.stages) {
if (e.logtext.length() <= 0) continue; // Do not show if displaytext is empty.
if (player.hasExactQuestProgress(q.questID, e.progress)) {
item = new HashMap<String, Object>();
item.put(mn_logText, e.logtext);
logItemList.add(item);
}
}
childList.add(logItemList);
}
questlog_contents_adapter.notifyDataSetChanged();
}

View File

@@ -1,11 +1,15 @@
package com.gpl.rpg.AndorsTrail.activity.fragment;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@@ -140,6 +144,12 @@ public class StartScreenActivity_MainMenu extends Fragment {
} else if (AndorsTrailApplication.DEVELOPMENT_FORCE_CONTINUEGAME) {
continueGame(false, Savegames.SLOT_QUICKSAVE, null);
}
// if it is a new version we first fire a welcome screen in onResume
// and afterwards check the permissions
if (!isNewVersion()) {
checkAndRequestPermissions(getActivity());
}
return root;
}
@@ -171,13 +181,34 @@ public class StartScreenActivity_MainMenu extends Fragment {
setButtonState(playerName, displayInfo, iconID, isDead);
if (isNewVersion()) {
Dialogs.showNewVersion(getActivity());
Dialogs.showNewVersion(getActivity(), new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
setCurrentVersionForVersionCheck();
checkAndRequestPermissions(getActivity());
}
});
}
boolean hasSavegames = !Savegames.getUsedSavegameSlots().isEmpty();
startscreen_load.setEnabled(hasSavegames);
}
private static final int READ_EXTERNAL_STORAGE_REQUEST=1;
private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2;
@TargetApi(23)
public static void checkAndRequestPermissions(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_REQUEST);
}
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST);
}
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
@@ -246,17 +277,21 @@ public class StartScreenActivity_MainMenu extends Fragment {
CustomDialogFactory.show(d);
}
private static final String versionCheck = "lastversion";
private boolean isNewVersion() {
final String v = "lastversion";
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
int lastversion = s.getInt(v, 0);
int lastversion = s.getInt(versionCheck, 0);
if (lastversion >= AndorsTrailApplication.CURRENT_VERSION) return false;
Editor e = s.edit();
e.putInt(v, AndorsTrailApplication.CURRENT_VERSION);
e.commit();
return true;
}
private void setCurrentVersionForVersionCheck() {
SharedPreferences s = getActivity().getSharedPreferences(Constants.PREFERENCE_MODEL_LASTRUNVERSION, Activity.MODE_PRIVATE);
Editor e = s.edit();
e.putInt(versionCheck, AndorsTrailApplication.CURRENT_VERSION);
e.commit();
}
@Override

View File

@@ -272,27 +272,39 @@ public final class ActorStatsController {
actor.damagePotential.addToMax(effects.increaseMaxDamage * multiplier);
actor.blockChance += effects.increaseBlockChance * multiplier;
actor.damageResistance += effects.increaseDamageResistance * multiplier;
if (actor.attackChance < 0) actor.attackChance = 0;
if (actor.damagePotential.max < 0) actor.damagePotential.set(0, 0);
}
public void recalculatePlayerStats(Player player) {
player.weaponDamage.set(0,0);
player.resetStatsToBaseTraits();
player.recalculateLevelExperience();
controllers.itemController.applyInventoryEffects(player);
controllers.skillController.applySkillEffects(player);
applyEffectsFromCurrentConditions(player);
ItemController.recalculateHitEffectsFromWornItems(player);
ItemController.applyDamageModifier(player);
capActorHealthAtMax(player);
capActorAPAtMax(player);
lowCapActorAttackChance(player);
lowCapActorDamagePotential(player);
}
public void recalculateMonsterCombatTraits(Monster monster) {
monster.resetStatsToBaseTraits();
applyEffectsFromCurrentConditions(monster);
capActorHealthAtMax(monster);
capActorAPAtMax(monster);
lowCapActorAttackChance(monster);
lowCapActorDamagePotential(monster);
}
private void lowCapActorAttackChance(Actor actor) {
if (actor.attackChance < 0) actor.attackChance = 0;
}
private void lowCapActorDamagePotential(Actor actor) {
if (actor.damagePotential.max < 0) actor.damagePotential.set(0, 0);
}
private void recalculateActorCombatTraits(Actor actor) {
if (actor.isPlayer) recalculatePlayerStats((Player) actor);
else recalculateMonsterCombatTraits((Monster) actor);
@@ -545,6 +557,11 @@ public final class ActorStatsController {
}
}
public void addPlayerWeaponDamage(Player player, int increaseMinDamage, int increaseMaxDamage) {
player.weaponDamage.add(increaseMinDamage, true);
player.weaponDamage.addToMax(increaseMaxDamage);
}
public static enum LevelUpSelection {
health
,attackChance

View File

@@ -25,6 +25,8 @@ import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea;
import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection;
import com.gpl.rpg.AndorsTrail.util.Coord;
import static java.lang.Math.max;
public final class CombatController implements VisualEffectCompletedCallback {
private final ControllerContext controllers;
private final WorldContext world;
@@ -109,10 +111,10 @@ public final class CombatController implements VisualEffectCompletedCallback {
}
public void setCombatSelection(Coord p) {
Monster m = world.model.currentMap.getMonsterAt(p);
Monster m = world.model.currentMaps.map.getMonsterAt(p);
if (m != null) {
setCombatSelection(m, p);
} else if (world.model.currentTileMap.isWalkable(p)) {
} else if (world.model.currentMaps.tileMap.isWalkable(p)) {
setCombatSelection(null, p);
}
}
@@ -128,7 +130,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
public boolean canExitCombat() { return getAdjacentAggressiveMonster() == null; }
private Monster getAdjacentAggressiveMonster() {
return MovementController.getAdjacentAggressiveMonster(world.model.currentMap, world.model.player);
return MovementController.getAdjacentAggressiveMonster(world.model.currentMaps.map, world.model.player);
}
public void executeMoveAttack(int dx, int dy) {
@@ -155,7 +157,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
private void executeFlee(int dx, int dy) {
// avoid monster fields when fleeing
if (!controllers.movementController.findWalkablePosition(dx, dy, AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_DEFENSIVE)) return;
Monster m = world.model.currentMap.getMonsterAt(world.model.player.nextPosition);
Monster m = world.model.currentMaps.map.getMonsterAt(world.model.player.nextPosition);
if (m != null) return;
executeCombatMove(world.model.player.nextPosition);
}
@@ -198,11 +200,11 @@ public final class CombatController implements VisualEffectCompletedCallback {
public void playerKilledMonster(Monster killedMonster) {
final Player player = world.model.player;
Loot loot = world.model.currentMap.getBagOrCreateAt(killedMonster.position);
Loot loot = world.model.currentMaps.map.getBagOrCreateAt(killedMonster.position);
killedMonster.createLoot(loot, player);
controllers.monsterSpawnController.remove(world.model.currentMap, killedMonster);
controllers.effectController.addSplatter(world.model.currentMap, killedMonster);
controllers.monsterSpawnController.remove(world.model.currentMaps.map, killedMonster);
controllers.effectController.addSplatter(world.model.currentMaps.map, killedMonster);
controllers.actorStatsController.addActorAP(player, player.getSkillLevel(SkillCollection.SkillID.cleave) * SkillCollection.PER_SKILLPOINT_INCREASE_CLEAVE_AP);
controllers.actorStatsController.addActorHealth(player, player.getSkillLevel(SkillCollection.SkillID.eater) * SkillCollection.PER_SKILLPOINT_INCREASE_EATER_HEALTH);
@@ -216,7 +218,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
controllers.actorStatsController.applyOnDeathEffectsToPlayer(player, killedMonster);
if (!loot.hasItemsOrGold()) {
world.model.currentMap.removeGroundLoot(loot);
world.model.currentMaps.map.removeGroundLoot(loot);
} else if (world.model.uiSelections.isInCombat) {
killedMonsterBags.add(loot);
}
@@ -305,7 +307,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
private void beginMonsterTurn(boolean isFirstRound) {
controllers.actorStatsController.setActorMinAP(world.model.player);
world.model.uiSelections.isPlayersCombatTurn = false;
for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) {
for (MonsterSpawnArea a : world.model.currentMaps.map.spawnAreas) {
for (Monster m : a.monsters) {
controllers.actorStatsController.setActorMaxAP(m);
}
@@ -323,7 +325,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
if (shouldAttackWithMonsterInCombat(currentActiveMonster, playerPosition)) return MonsterAction.attack;
}
for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) {
for (MonsterSpawnArea a : world.model.currentMaps.map.spawnAreas) {
for (Monster m : a.monsters) {
if (!m.isAgressive(world.model.player)) continue;
@@ -387,7 +389,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
}
final Monster movingMonster = currentActiveMonster;
controllers.monsterMovementController.moveMonsterToNextPositionDuringCombat(currentActiveMonster, world.model.currentMap, new VisualEffectController.VisualEffectCompletedCallback(){
controllers.monsterMovementController.moveMonsterToNextPositionDuringCombat(currentActiveMonster, world.model.currentMaps.map, new VisualEffectController.VisualEffectCompletedCallback(){
@Override
public void onVisualEffectCompleted(int callbackValue) {
combatActionListeners.onMonsterMovedDuringCombat(movingMonster);
@@ -484,13 +486,29 @@ public final class CombatController implements VisualEffectCompletedCallback {
if (target.isImmuneToCriticalHits()) return false;
return true;
}
private static float getAverageDamagePerHit(Actor attacker, Actor target) {
float result = (float) (getAttackHitChance(attacker, target)) * attacker.getDamagePotential().average() / 100;
if (hasCriticalAttack(attacker, target)) {
result += (float) attacker.getEffectiveCriticalChance() * result * attacker.getCriticalMultiplier() / 100;
// see this post for explenations about the calculation: https://andorstrail.com/viewtopic.php?f=3&t=6661
// if you change code here make sure to run the tests in CombatControllerTest.java
public static float getAverageDamagePerHit(final Actor attacker, final Actor target) {
final int numPossibleOutcomes = attacker.getDamagePotential().max - attacker.getDamagePotential().current + 1;
float avgNonCriticalDamage = 0;
for (int n = 0; n < numPossibleOutcomes; n++) {
avgNonCriticalDamage += max(0, (float) n + attacker.getDamagePotential().current - target.getDamageResistance()) / numPossibleOutcomes;
}
result -= target.getDamageResistance();
return result;
float avgCriticalDamage = 0;
float effectiveCriticalChance = 0;
if (hasCriticalAttack(attacker, target)) {
effectiveCriticalChance = attacker.getEffectiveCriticalChance();
}
if (effectiveCriticalChance > 0) {
for (int n = 0; n < numPossibleOutcomes; n++) {
avgCriticalDamage += max(0, Math.floor((n + attacker.getDamagePotential().current) * attacker.getCriticalMultiplier()) - target.getDamageResistance()) / numPossibleOutcomes;
}
}
float avgDamagePerSuccessfulStrike = (1 - effectiveCriticalChance / 100) * avgNonCriticalDamage + effectiveCriticalChance * avgCriticalDamage / 100;
return (float)getAttackHitChance(attacker, target) * avgDamagePerSuccessfulStrike / 100;
}
private static float getAverageDamagePerTurn(Actor attacker, Actor target) {
return getAverageDamagePerHit(attacker, target) * attacker.getAttacksPerTurn();
@@ -577,7 +595,7 @@ public final class CombatController implements VisualEffectCompletedCallback {
world.model.worldData.tickWorldTime();
controllers.gameRoundController.resetRoundTimers();
controllers.actorStatsController.applyConditionsToPlayer(world.model.player, false);
controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMap, true);
controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMaps.map, true);
}
public void monsterSteppedOnPlayer(Monster m) {

View File

@@ -0,0 +1,30 @@
package com.gpl.rpg.AndorsTrail.controller;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import org.junit.Test;
import static org.junit.Assert.*;
public class CombatControllerTest {
@Test
public void getAverageDamagePerHit() throws Exception {
Actor attacker = new Actor(null, false, false);
attacker.attackChance = 100;
attacker.damagePotential.set(5, 3);
Actor target = new Actor(null, false, false);
target.damageResistance = 3;
target.blockChance = 50;
float averageDamagePerHit = CombatController.getAverageDamagePerHit(attacker, target);
assertEquals(0.5, averageDamagePerHit, 0.01);
attacker.criticalSkill = 30;
attacker.criticalMultiplier = 2.5f;
averageDamagePerHit = CombatController.getAverageDamagePerHit(attacker, target);
assertEquals(1.038, averageDamagePerHit, 0.01);
}
}

View File

@@ -130,7 +130,7 @@ public final class ConversationController {
private void changeMapFilter(Resources res, String mapName, String effectID) {
PredefinedMap map = findMapForScriptEffect(mapName);
map.currentColorFilter = effectID;
if (world.model.currentMap == map) {
if (world.model.currentMaps.map == map) {
controllers.mapController.applyCurrentMapReplacements(res, true);
}
}
@@ -141,7 +141,7 @@ public final class ConversationController {
}
private PredefinedMap findMapForScriptEffect(String mapName) {
if (mapName == null) return world.model.currentMap;
if (mapName == null) return world.model.currentMaps.map;
return world.maps.findPredefinedMap(mapName);
}
@@ -153,8 +153,8 @@ public final class ConversationController {
private void spawnAll(String mapName, String areaId) {
PredefinedMap map = findMapForScriptEffect(mapName);
LayeredTileMap tileMap = null;
if (map == world.model.currentMap) {
tileMap = world.model.currentTileMap;
if (map == world.model.currentMaps.map) {
tileMap = world.model.currentMaps.tileMap;
}
for (MonsterSpawnArea area : map.spawnAreas) {
if (!area.areaID.equals(areaId)) continue;
@@ -174,12 +174,12 @@ public final class ConversationController {
private void addAlignmentReward(Player player, String faction, int delta) {
player.addAlignment(faction, delta);
MovementController.refreshMonsterAggressiveness(world.model.currentMap, world.model.player);
MovementController.refreshMonsterAggressiveness(world.model.currentMaps.map, world.model.player);
}
private void setAlignmentReward(Player player, String faction, int delta) {
player.setAlignment(faction, delta);
MovementController.refreshMonsterAggressiveness(world.model.currentMap, world.model.player);
MovementController.refreshMonsterAggressiveness(world.model.currentMaps.map, world.model.player);
}
private void addQuestProgressReward(Player player, String questID, int questProgress, ScriptEffectResult result) {
@@ -241,11 +241,11 @@ public final class ConversationController {
result.actorConditions.add(e);
}
private static void applyReplyEffect(final WorldContext world, final Reply reply) {
private static void applyReplyEffect(final WorldContext world, final Reply reply, ControllerContext controllers) {
if (!reply.hasRequirements()) return;
for (Requirement requirement : reply.requires) {
requirementFulfilled(world, requirement);
requirementFulfilled(world, requirement, controllers);
}
}
@@ -270,6 +270,7 @@ public final class ConversationController {
result = player.isLatestQuestProgress(requirement.requireID, requirement.value);
break;
case wear:
case wearRemove:
result = player.inventory.isWearing(requirement.requireID, requirement.value);
break;
case inventoryKeep:
@@ -316,7 +317,7 @@ public final class ConversationController {
return requirement.negate ? !result : result;
}
public static void requirementFulfilled(WorldContext world, Requirement requirement) {
public static void requirementFulfilled(WorldContext world, Requirement requirement, ControllerContext controllers) {
Player p = world.model.player;
switch (requirement.requireType) {
case inventoryRemove:
@@ -326,6 +327,10 @@ public final class ConversationController {
} else {
p.inventory.removeItem(requirement.requireID, requirement.value);
}
break;
case wearRemove:
controllers.itemController.removeEquippedItem(requirement.requireID, requirement.value);
break;
}
}
@@ -357,7 +362,7 @@ public final class ConversationController {
public String getCurrentPhraseID() { return currentPhraseID; }
public void playerSelectedReply(final Resources res, Reply r) {
applyReplyEffect(world, r);
applyReplyEffect(world, r, controllers);
proceedToPhrase(res, r.nextPhrase, true, true);
}
@@ -383,7 +388,7 @@ public final class ConversationController {
if (currentPhrase == null) currentPhrase = new Phrase("(phrase \"" + phraseID + "\" not implemented yet)", null, null, null);
}
if (this.currentPhrase.switchToNPC != null) {
setCurrentNPC(world.model.currentMap.findSpawnedMonster(this.currentPhrase.switchToNPC));
setCurrentNPC(world.model.currentMaps.map.findSpawnedMonster(this.currentPhrase.switchToNPC));
}
}
@@ -414,7 +419,7 @@ public final class ConversationController {
if (currentPhrase.message == null) {
for (Reply r : currentPhrase.replies) {
if (!canSelectReply(world, r)) continue;
applyReplyEffect(world, r);
applyReplyEffect(world, r, controllers);
proceedToPhrase(res, r.nextPhrase, applyScriptEffects, displayPhraseMessage);
return;
}
@@ -440,7 +445,7 @@ public final class ConversationController {
listener.onConversationEnded();
return;
}
controllers.monsterSpawnController.remove(world.model.currentMap, npc);
controllers.monsterSpawnController.remove(world.model.currentMaps.map, npc);
listener.onConversationEndedWithRemoval(npc);
}

View File

@@ -74,7 +74,7 @@ public final class GameRoundController implements TimedMessageTask.Callback {
public void onNewFullRound() {
controllers.mapController.resetMapsNotRecentlyVisited();
controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMap, true);
controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMaps.map, true);
controllers.actorStatsController.applyConditionsToPlayer(world.model.player, true);
gameRoundListeners.onNewFullRound();
}
@@ -87,19 +87,19 @@ public final class GameRoundController implements TimedMessageTask.Callback {
public void onNewPlayerRound() {
world.model.worldData.tickWorldTime();
controllers.actorStatsController.applyConditionsToPlayer(world.model.player, false);
controllers.actorStatsController.applySkillEffectsForNewRound(world.model.player, world.model.currentMap);
controllers.mapController.handleMapEvents(world.model.currentMap, world.model.player.position, MapObject.MapObjectEvaluationType.afterEveryRound);
controllers.actorStatsController.applySkillEffectsForNewRound(world.model.player, world.model.currentMaps.map);
controllers.mapController.handleMapEvents(world.model.currentMaps.map, world.model.player.position, MapObject.MapObjectEvaluationType.afterEveryRound);
}
public void onNewMonsterRound() {
controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMap, false);
controllers.actorStatsController.applyConditionsToMonsters(world.model.currentMaps.map, false);
}
private void onNewTick() {
controllers.monsterMovementController.moveMonsters();
controllers.monsterSpawnController.maybeSpawn(world.model.currentMap, world.model.currentTileMap);
controllers.monsterSpawnController.maybeSpawn(world.model.currentMaps.map, world.model.currentMaps.tileMap);
controllers.monsterMovementController.attackWithAgressiveMonsters();
controllers.effectController.updateSplatters(world.model.currentMap);
controllers.mapController.handleMapEvents(world.model.currentMap, world.model.player.position, MapObject.MapObjectEvaluationType.continuously);
controllers.effectController.updateSplatters(world.model.currentMaps.map);
controllers.mapController.handleMapEvents(world.model.currentMaps.map, world.model.player.position, MapObject.MapObjectEvaluationType.continuously);
gameRoundListeners.onNewTick();
}
}

View File

@@ -19,6 +19,8 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import static java.lang.Math.min;
public final class ItemController {
private final ControllerContext controllers;
@@ -33,7 +35,7 @@ public final class ItemController {
public void dropItem(ItemType type, int quantity) {
if (world.model.player.inventory.getItemQuantity(type.id) < quantity) return;
world.model.player.inventory.removeItem(type.id, quantity);
world.model.currentMap.itemDropped(type, quantity, world.model.player.position);
world.model.currentMaps.map.itemDropped(type, quantity, world.model.player.position);
}
public void equipItem(ItemType type, Inventory.WearSlot slot) {
@@ -175,8 +177,12 @@ public final class ItemController {
// The stats for off-hand weapons will be added later in SkillController.applySkillEffectsFromFightingStyles
if (SkillController.isDualWielding(mainHandItem, type)) return;
}
if (type.effects_equip != null && type.effects_equip.stats != null)
controllers.actorStatsController.applyAbilityEffects(player, type.effects_equip.stats, 1);
if (type.effects_equip != null && type.effects_equip.stats != null) {
controllers.actorStatsController.applyAbilityEffects(player, type.effects_equip.stats, 1);
if (type.isWeapon()) {
controllers.actorStatsController.addPlayerWeaponDamage(player, type.effects_equip.stats.increaseMinDamage, type.effects_equip.stats.increaseMaxDamage);
}
}
}
public static void recalculateHitEffectsFromWornItems(Player player) {
@@ -239,8 +245,8 @@ public final class ItemController {
public boolean removeLootBagIfEmpty(final Loot loot) {
if (loot.hasItemsOrGold()) return false;
world.model.currentMap.removeGroundLoot(loot);
controllers.mapController.mapLayoutListeners.onLootBagRemoved(world.model.currentMap, loot.position);
world.model.currentMaps.map.removeGroundLoot(loot);
controllers.mapController.mapLayoutListeners.onLootBagRemoved(world.model.currentMaps.map, loot.position);
return true; // The bag was removed.
}
@@ -383,4 +389,41 @@ public final class ItemController {
}
}
public int removeEquippedItem(String itemTypeID, int count) {
int removed = 0;
final Player player = world.model.player;
for (Inventory.WearSlot slot : Inventory.WearSlot.values()) {
ItemType type = player.inventory.getItemTypeInWearSlot(slot);
if (type != null && type.id.equals(itemTypeID)) {
player.inventory.setItemTypeInWearSlot(slot, null);
controllers.actorStatsController.removeConditionsFromUnequippedItem(player, type);
controllers.actorStatsController.recalculatePlayerStats(player);
removed++;
if (removed >= count) {
break;
}
}
}
return removed;
}
public static void applyDamageModifier(Player player) {
ItemType itemType = player.inventory.getItemTypeInWearSlot(Inventory.WearSlot.weapon);
int modifier1 = -1;
int modifier2 = -1;
if (itemType != null) modifier1 = itemType.effects_equip.stats.setNonWeaponDamageModifier;
itemType = player.inventory.getItemTypeInWearSlot(Inventory.WearSlot.shield);
if (itemType != null && itemType.isWeapon()) modifier2 = itemType.effects_equip.stats.setNonWeaponDamageModifier;
int modifier = 100;
if (modifier1 >= 0 && modifier2 >= 0) modifier = Math.min(modifier1, modifier2);
else if (modifier1 <= 0 && modifier2 >= 0) modifier = modifier2;
else if (modifier2 <= 0 && modifier1 >= 0) modifier = modifier1;
if (modifier != 100) {
final int minBaseDamage = player.damagePotential.current - player.weaponDamage.current;
final int maxBaseDamage = player.damagePotential.max - player.weaponDamage.max;
player.damagePotential.add(Math.round(minBaseDamage * ((modifier - 100)/100f)), true);
player.damagePotential.addToMax(Math.round(maxBaseDamage * ((modifier - 100)/100f)));
}
}
}

View File

@@ -146,20 +146,20 @@ public final class MapController {
for (PredefinedMap m : world.maps.getAllMaps()) {
m.resetTemporaryData();
}
controllers.monsterSpawnController.spawnAll(world.model.currentMap, world.model.currentTileMap);
controllers.monsterSpawnController.spawnAll(world.model.currentMaps.map, world.model.currentMaps.tileMap);
world.model.worldData.tickWorldTime(20);
controllers.gameRoundController.resetRoundTimers();
}
public void rest(MapObject area) {
lotsOfTimePassed();
world.model.player.setSpawnPlace(world.model.currentMap.name, area.id);
world.model.player.setSpawnPlace(world.model.currentMaps.map.name, area.id);
worldEventListeners.onPlayerRested();
}
public boolean canEnterKeyArea(MapObject area) {
if (ConversationController.canFulfillRequirement(world, area.enteringRequirement)) {
ConversationController.requirementFulfilled(world, area.enteringRequirement);
ConversationController.requirementFulfilled(world, area.enteringRequirement, controllers);
return true;
}
worldEventListeners.onPlayerSteppedOnKeyArea(area);
@@ -168,7 +168,7 @@ public final class MapController {
public void resetMapsNotRecentlyVisited() {
for (PredefinedMap m : world.maps.getAllMaps()) {
if (m == world.model.currentMap) continue;
if (m == world.model.currentMaps.map) continue;
if (m.isRecentlyVisited()) continue;
if (m.hasResetTemporaryData()) continue;
m.resetTemporaryData();
@@ -176,12 +176,12 @@ public final class MapController {
}
public void applyCurrentMapReplacements(final Resources res, boolean updateWorldmap) {
if (!applyReplacements(world.model.currentMap, world.model.currentTileMap)) return;
if (!applyReplacements(world.model.currentMaps.map, world.model.currentMaps.tileMap)) return;
world.maps.worldMapRequiresUpdate = true;
if (!updateWorldmap) return;
WorldMapController.updateWorldMap(world, res);
mapLayoutListeners.onMapTilesChanged(world.model.currentMap, world.model.currentTileMap);
mapLayoutListeners.onMapTilesChanged(world.model.currentMaps.map, world.model.currentMaps.tileMap);
}
private boolean applyReplacements(PredefinedMap map, LayeredTileMap tileMap) {
@@ -190,7 +190,7 @@ public final class MapController {
for(ReplaceableMapSection replacement : tileMap.replacements) {
if (replacement.isApplied) continue;
if (!satisfiesCondition(replacement)) continue;
else ConversationController.requirementFulfilled(world, replacement.requirement);
else ConversationController.requirementFulfilled(world, replacement.requirement, controllers);
tileMap.applyReplacement(replacement);
for (ReplaceableMapSection impactedReplacement : tileMap.replacements) {
if (impactedReplacement.isApplied && impactedReplacement.replacementArea.intersects(replacement.replacementArea)) {

View File

@@ -27,7 +27,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
public void moveMonsters() {
long currentTime = System.currentTimeMillis();
for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) {
for (MonsterSpawnArea a : world.model.currentMaps.map.spawnAreas) {
for (Monster m : a.monsters) {
if (m.nextActionTime <= currentTime) {
moveMonster(m, a);
@@ -37,7 +37,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
}
public void attackWithAgressiveMonsters() {
for (MonsterSpawnArea a : world.model.currentMap.spawnAreas) {
for (MonsterSpawnArea a : world.model.currentMaps.map.spawnAreas) {
for (Monster m : a.monsters) {
if (!m.isAgressive(world.model.player)) continue;
if (!m.isAdjacentTo(world.model.player)) continue;
@@ -75,8 +75,8 @@ public final class MonsterMovementController implements EvaluateWalkable {
}
private void moveMonster(final Monster m, final MonsterSpawnArea area) {
PredefinedMap map = world.model.currentMap;
LayeredTileMap tileMap = world.model.currentTileMap;
PredefinedMap map = world.model.currentMaps.map;
LayeredTileMap tileMap = world.model.currentMaps.tileMap;
m.nextActionTime = System.currentTimeMillis() + getMillisecondsPerMove(m);
if (m.movementDestination != null && m.position.equals(m.movementDestination)) {
// Monster has been moving and arrived at the destination.
@@ -159,7 +159,7 @@ public final class MonsterMovementController implements EvaluateWalkable {
@Override
public boolean isWalkable(CoordRect r, Monster m) {
return monsterCanMoveTo(null, world.model.currentMap, world.model.currentTileMap, r, m.area.ignoreAreas);
return monsterCanMoveTo(null, world.model.currentMaps.map, world.model.currentMaps.tileMap, r, m.area.ignoreAreas);
}
public void moveMonsterToNextPosition(final Monster m, final PredefinedMap map) {

View File

@@ -7,6 +7,7 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailPreferences;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerMovementListeners;
import com.gpl.rpg.AndorsTrail.model.MapBundle;
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
@@ -56,7 +57,7 @@ public final class MovementController implements TimedMessageTask.Callback {
protected void onPostExecute(Void result) {
super.onPostExecute(result);
stopMovement();
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position);
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMaps.map, world.model.player.position);
controllers.gameRoundController.resume();
}
@@ -83,7 +84,7 @@ public final class MovementController implements TimedMessageTask.Callback {
}
final ModelContainer model = world.model;
if (model.currentMap != null) model.currentMap.updateLastVisitTime();
if (model.currentMaps.map != null) model.currentMaps.map.updateLastVisitTime();
model.player.position.set(place.position.topLeft);
model.player.position.x += Math.min(offset_x, place.position.size.width-1);
model.player.position.y += Math.min(offset_y, place.position.size.height-1);
@@ -103,19 +104,28 @@ public final class MovementController implements TimedMessageTask.Callback {
public void prepareMapAsCurrentMap(PredefinedMap newMap, Resources res, boolean spawnMonsters) {
final ModelContainer model = world.model;
model.currentMap = newMap;
cacheCurrentMapData(res, newMap);
MapBundle newMaps = new MapBundle();
newMaps.map = newMap;
LayeredTileMap mapTiles = TMXMapTranslator.readLayeredTileMap(res, world.tileManager.tileCache, newMaps.map);
mapTiles.changeColorFilter(newMaps.map.currentColorFilter);
TileCollection cachedTiles = world.tileManager.loadTilesFor(newMaps.map, mapTiles, world, res);
newMaps.tileMap = mapTiles;
newMaps.tiles = cachedTiles;
world.tileManager.cacheAdjacentMaps(res, world, newMaps.map);
world.model.currentMaps = newMaps;
//Apply replacements before spawning, so that MonsterSpawnArea's isActive variable is up to date.
controllers.mapController.applyCurrentMapReplacements(res, false);
if (spawnMonsters) {
if (!newMap.isRecentlyVisited()) {
controllers.monsterSpawnController.spawnAll(newMap, model.currentTileMap);
controllers.monsterSpawnController.spawnAll(newMap, model.currentMaps.tileMap);
}
}
controllers.mapController.prepareScriptsOnCurrentMap();
newMap.visited = true;
newMap.updateLastVisitTime();
moveBlockedActors(newMap, model.currentTileMap);
moveBlockedActors(newMap, model.currentMaps.tileMap);
refreshMonsterAggressiveness(newMap, model.player);
controllers.effectController.updateSplatters(newMap);
WorldMapController.updateWorldMap(world, res);
@@ -131,7 +141,7 @@ public final class MovementController implements TimedMessageTask.Callback {
if (!findWalkablePosition(dx, dy)) return;
Monster m = world.model.currentMap.getMonsterAt(world.model.player.nextPosition);
Monster m = world.model.currentMaps.map.getMonsterAt(world.model.player.nextPosition);
if (m != null) {
controllers.mapController.steppedOnMonster(m, world.model.player.nextPosition);
return;
@@ -196,14 +206,14 @@ public final class MovementController implements TimedMessageTask.Callback {
,player.position.y + dy
);
if (!world.model.currentTileMap.isWalkable(player.nextPosition)) return false;
if (!world.model.currentMaps.tileMap.isWalkable(player.nextPosition)) return false;
// allow player to enter every field when he is NORMAL
// prevent player from entering "non-monster-fields" when he is AGGRESSIVE
// prevent player from entering "monster-fields" when he is DEFENSIVE
if (aggressiveness == AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_NORMAL) return true;
Monster m = world.model.currentMap.getMonsterAt(player.nextPosition);
Monster m = world.model.currentMaps.map.getMonsterAt(player.nextPosition);
if (m != null && !m.isAgressive(player)) return true; // avoid MOVEMENTAGGRESSIVENESS settings for NPCs
if (aggressiveness == AndorsTrailPreferences.MOVEMENTAGGRESSIVENESS_AGGRESSIVE && m == null) return false;
@@ -225,7 +235,7 @@ public final class MovementController implements TimedMessageTask.Callback {
public void moveToNextIfPossible() {
final Player player = world.model.player;
final PredefinedMap currentMap = world.model.currentMap;
final PredefinedMap currentMap = world.model.currentMaps.map;
final Coord newPosition = player.nextPosition;
for (MapObject o : currentMap.eventObjects) {
@@ -251,7 +261,7 @@ public final class MovementController implements TimedMessageTask.Callback {
if (!world.model.uiSelections.isInCombat) {
//currentMap can be outdated due to mapchange events processed above.
Loot loot = world.model.currentMap.getBagAt(newPosition);
Loot loot = world.model.currentMaps.map.getBagAt(newPosition);
if (loot != null) controllers.itemController.playerSteppedOnLootBag(loot);
}
}
@@ -262,7 +272,7 @@ public final class MovementController implements TimedMessageTask.Callback {
public void respawnPlayer(Resources res) {
placePlayerAt(res, MapObject.MapObjectType.rest, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0);
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position);
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMaps.map, world.model.player.position);
}
public void respawnPlayerAsync() {
placePlayerAsyncAt(MapObject.MapObjectType.rest, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0);
@@ -311,16 +321,6 @@ public final class MovementController implements TimedMessageTask.Callback {
return null;
}
private void cacheCurrentMapData(final Resources res, final PredefinedMap nextMap) {
LayeredTileMap mapTiles = TMXMapTranslator.readLayeredTileMap(res, world.tileManager.tileCache, nextMap);
mapTiles.changeColorFilter(nextMap.currentColorFilter);
TileCollection cachedTiles = world.tileManager.loadTilesFor(nextMap, mapTiles, world, res);
world.model.currentTileMap = mapTiles;
world.tileManager.currentMapTiles = cachedTiles;
world.tileManager.cacheAdjacentMaps(res, world, nextMap);
}
private int movementDx;
private int movementDy;
public void startMovement(int dx, int dy, Coord destination) {

View File

@@ -307,6 +307,15 @@ public final class SkillController {
ItemType mainHandItem = player.inventory.getItemTypeInWearSlot(Inventory.WearSlot.weapon);
ItemType offHandItem = player.inventory.getItemTypeInWearSlot(Inventory.WearSlot.shield);
final int skillLevelFightStyleUnarmedUnarmored = player.getSkillLevel(SkillID.fightstyleUnarmedUnarmored);
if (skillLevelFightStyleUnarmedUnarmored > 0 && isUnarmored(player) && mainHandItem == null && offHandItem == null) {
player.blockChance += SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_BC * skillLevelFightStyleUnarmedUnarmored;
player.damageResistance += SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_DR * skillLevelFightStyleUnarmedUnarmored;
player.attackChance += SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_AC * skillLevelFightStyleUnarmedUnarmored;
player.damagePotential.addToMax(SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_DMG_MAX * skillLevelFightStyleUnarmedUnarmored);
player.criticalMultiplier = 1 + ((float)SkillCollection.PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_CM_PERCENT / 100) * skillLevelFightStyleUnarmedUnarmored;
}
if (isWielding2HandItem(mainHandItem, offHandItem)) {
int skillLevelFightStyle = player.getSkillLevel(SkillID.fightstyle2hand);
int skillLevelSpecialization = player.getSkillLevel(SkillID.specialization2hand);
@@ -386,6 +395,11 @@ public final class SkillController {
if (itemType.effects_equip == null) return;
player.damagePotential.addToMax(getPercentage(itemType.effects_equip.stats.increaseMaxDamage, percentForPositiveValues, percentForNegativeValues));
player.damagePotential.add(getPercentage(itemType.effects_equip.stats.increaseMinDamage, percentForPositiveValues, percentForNegativeValues), false);
if (itemType.isWeapon()) {
player.weaponDamage.addToMax(getPercentage(itemType.effects_equip.stats.increaseMaxDamage, percentForPositiveValues, percentForNegativeValues));
player.weaponDamage.add(getPercentage(itemType.effects_equip.stats.increaseMinDamage, percentForPositiveValues, percentForNegativeValues), false);
}
}
private static void addPercentCriticalSkill(Player player, ItemType itemType, int percentForPositiveValues, int percentForNegativeValues) {

View File

@@ -41,7 +41,7 @@ public final class WorldMapController {
public static final int WORLDMAP_DISPLAY_TILESIZE = WORLDMAP_SCREENSHOT_TILESIZE;
public static void updateWorldMap(final WorldContext world, final Resources res) {
updateWorldMap(world, world.model.currentMap, world.model.currentTileMap, world.tileManager.currentMapTiles, res);
updateWorldMap(world, world.model.currentMaps.map, world.model.currentMaps.tileMap, world.model.currentMaps.tiles, res);
}
private static void updateWorldMap(
@@ -303,7 +303,7 @@ public final class WorldMapController {
}
public static boolean displayWorldMap(Context context, WorldContext world) {
String worldMapSegmentName = world.maps.getWorldMapSegmentNameForMap(world.model.currentMap.name);
String worldMapSegmentName = world.maps.getWorldMapSegmentNameForMap(world.model.currentMaps.map.name);
if (worldMapSegmentName == null) {
Toast.makeText(context, context.getResources().getString(R.string.display_worldmap_not_available), Toast.LENGTH_LONG).show();
return false;

View File

@@ -0,0 +1,11 @@
package com.gpl.rpg.AndorsTrail.model;
import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
public final class MapBundle {
public PredefinedMap map;
public LayeredTileMap tileMap;
public TileCollection tiles;
}

View File

@@ -9,6 +9,7 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.map.LayeredTileMap;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
public final class ModelContainer {
@@ -17,8 +18,7 @@ public final class ModelContainer {
public final CombatLog combatLog = new CombatLog();
public final GameStatistics statistics;
public final WorldData worldData;
public PredefinedMap currentMap;
public LayeredTileMap currentTileMap;
public MapBundle currentMaps = new MapBundle();;
public ModelContainer(int startLives, boolean unlimitedSaves) {
player = new Player();
@@ -31,13 +31,13 @@ public final class ModelContainer {
public ModelContainer(DataInputStream src, WorldContext world, ControllerContext controllers, int fileversion) throws IOException {
this.player = Player.newFromParcel(src, world, controllers, fileversion);
this.currentMap = world.maps.findPredefinedMap(src.readUTF());
this.currentMaps.map = world.maps.findPredefinedMap(src.readUTF());
this.uiSelections = new InterfaceData(src, fileversion);
if (uiSelections.selectedPosition != null) {
this.uiSelections.selectedMonster = currentMap.getMonsterAt(uiSelections.selectedPosition);
this.uiSelections.selectedMonster = currentMaps.map.getMonsterAt(uiSelections.selectedPosition);
}
this.statistics = new GameStatistics(src, world, fileversion);
this.currentTileMap = null;
this.currentMaps.tileMap = null;
if (fileversion >= 40) {
this.worldData = new WorldData(src, fileversion);
} else {
@@ -47,7 +47,7 @@ public final class ModelContainer {
public void writeToParcel(DataOutputStream dest) throws IOException {
player.writeToParcel(dest);
dest.writeUTF(currentMap.name);
dest.writeUTF(currentMaps.map.name);
uiSelections.writeToParcel(dest);
statistics.writeToParcel(dest);
worldData.writeToParcel(dest);

View File

@@ -55,6 +55,7 @@ public final class SkillCollection {
,specialization2hand
,specializationWeaponShield
,weaponProficiencyPole
,fightstyleUnarmedUnarmored
}
// should be in the same number &U order as in arrays.xml
@@ -117,6 +118,11 @@ public final class SkillCollection {
public static final int PER_SKILLPOINT_INCREASE_SPECIALIZATION_2HAND_AC_PERCENT = 20;
public static final int PER_SKILLPOINT_INCREASE_FIGHTSTYLE_WEAPON_AC_PERCENT = 25;
public static final int PER_SKILLPOINT_INCREASE_FIGHTSTYLE_SHIELD_BC_PERCENT = 25;
public static final int PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_BC = 5;
public static final int PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_DR = 1;
public static final int PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_AC = 12;
public static final int PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_DMG_MAX = 4;
public static final int PER_SKILLPOINT_INCREASE_UNARMED_UNARMORED_CM_PERCENT = 25;
public static final int PER_SKILLPOINT_INCREASE_SPECIALIZATION_WEAPON_AC_PERCENT = 50;
public static final int PER_SKILLPOINT_INCREASE_SPECIALIZATION_WEAPON_DMG_PERCENT = 20;
public static final int DUALWIELD_EFFICIENCY_LEVEL2 = 100;
@@ -223,6 +229,9 @@ public final class SkillCollection {
initializeSkill(new SkillInfo(SkillID.fightstyleWeaponShield, 2, SkillInfo.LevelUpType.alwaysShown, SkillCategory.specialty, new SkillLevelRequirement[] {
SkillLevelRequirement.requireExperienceLevels(15, 0)
}, position++));
initializeSkill(new SkillInfo(SkillID.fightstyleUnarmedUnarmored, 3, SkillInfo.LevelUpType.alwaysShown, SkillCategory.specialty, new SkillLevelRequirement[] {
SkillLevelRequirement.requireExperienceLevels(15, 0)
}, position++));
initializeSkill(new SkillInfo(SkillID.specializationDualWield, 1, SkillInfo.LevelUpType.alwaysShown, SkillCategory.specialty, new SkillLevelRequirement[] {
SkillLevelRequirement.requireExperienceLevels(45, 0)
,SkillLevelRequirement.requireOtherSkill(SkillID.fightstyleDualWield, 2)

View File

@@ -12,6 +12,7 @@ public final class AbilityModifierTraits {
public final int increaseBlockChance;
public final int increaseMinDamage;
public final int increaseMaxDamage;
public final int setNonWeaponDamageModifier;
public final int increaseCriticalSkill;
public final float setCriticalMultiplier;
public final int increaseDamageResistance;
@@ -27,6 +28,7 @@ public final class AbilityModifierTraits {
, int increaseBlockChance
, int increaseMinDamage
, int increaseMaxDamage
, int setNonWeaponDamageModifier
, int increaseCriticalSkill
, float setCriticalMultiplier
, int increaseDamageResistance
@@ -41,6 +43,7 @@ public final class AbilityModifierTraits {
this.increaseBlockChance = increaseBlockChance;
this.increaseMinDamage = increaseMinDamage;
this.increaseMaxDamage = increaseMaxDamage;
this.setNonWeaponDamageModifier = setNonWeaponDamageModifier;
this.increaseCriticalSkill = increaseCriticalSkill;
this.setCriticalMultiplier = setCriticalMultiplier;
this.increaseDamageResistance = increaseDamageResistance;

View File

@@ -3,8 +3,12 @@ package com.gpl.rpg.AndorsTrail.model.actor;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.UUID;
@@ -19,6 +23,7 @@ import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
import com.gpl.rpg.AndorsTrail.model.item.DropListCollection;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.quest.Quest;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForPlayer;
import com.gpl.rpg.AndorsTrail.util.Coord;
@@ -40,8 +45,9 @@ public final class Player extends Actor {
public int useItemCost;
public int reequipCost;
public int totalExperience;
public final Range weaponDamage = new Range();
private final HashMap<String, HashSet<Integer> > questProgress = new HashMap<String, HashSet<Integer> >();
private final LinkedHashMap<String, HashSet<Integer> > questProgress = new LinkedHashMap<String, HashSet<Integer> >();
private String spawnMap;
private String spawnPlace;
private final HashMap<String, Integer> alignments = new HashMap<String, Integer>();
@@ -117,6 +123,7 @@ public final class Player extends Actor {
this.ap.set(baseTraits.maxAP, baseTraits.maxAP);
this.health.set(baseTraits.maxHP, baseTraits.maxHP);
this.conditions.clear();
this.weaponDamage.set(0, 0);
Loot startItems = new Loot();
dropLists.getDropList(DropListCollection.DROPLIST_STARTITEMS).createRandomLoot(startItems, this);
@@ -139,6 +146,9 @@ public final class Player extends Actor {
public boolean hasAnyQuestProgress(String questID) {
return questProgress.containsKey(questID);
}
public Collection<String> getAllQuestProgressIDs() {
return new ArrayList<String>(this.questProgress.keySet());
}
public boolean isLatestQuestProgress(String questID, int progress) {
if (!questProgress.containsKey(questID)) return false;
if (!questProgress.get(questID).contains(progress)) return false;
@@ -343,16 +353,30 @@ public final class Player extends Actor {
this.spawnPlace = src.readUTF();
if (fileversion > 13) {
LinkedHashMap<String, HashSet<Integer> > questProgress = new LinkedHashMap<String, HashSet<Integer> >();
final int numQuests = src.readInt();
for(int i = 0; i < numQuests; ++i) {
final String questID = src.readUTF();
this.questProgress.put(questID, new HashSet<Integer>());
questProgress.put(questID, new HashSet<Integer>());
final int numProgress = src.readInt();
for(int j = 0; j < numProgress; ++j) {
int progress = src.readInt();
this.questProgress.get(questID).add(progress);
questProgress.get(questID).add(progress);
}
}
// questprogress is randomly sorted until 52 so sort it by quest order
if (fileversion < 52) {
for (Quest q : world.quests.getAllQuests()) {
final HashSet<Integer> questSteps = questProgress.get(q.questID);
if (questSteps != null) {
this.questProgress.put(q.questID, questSteps);
}
}
} else {
this.questProgress.putAll(questProgress);
}
}
this.availableSkillIncreases = 0;

View File

@@ -56,16 +56,7 @@ public final class Inventory extends ItemContainer {
wear[slot.ordinal()] = type;
}
public boolean isWearing(String itemTypeID) {
for(int i = 0; i < NUM_WORN_SLOTS; ++i) {
if (wear[i] == null) continue;
if (wear[i].id.equals(itemTypeID)) return true;
}
return false;
}
public boolean isWearing(String itemTypeID, int minNumber) {
if (minNumber == 0) return isWearing(itemTypeID);
for(int i = 0; i < NUM_WORN_SLOTS; ++i) {
if (wear[i] == null) continue;
if (wear[i].id.equals(itemTypeID)) minNumber--;

View File

@@ -64,6 +64,16 @@ public final class PredefinedMap {
assert(size.height > 0);
this.isOutdoors = isOutdoors;
this.initialColorFilter = colorFilter;
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
for (int i = 0; i < spawnAreas.length; i++) {
for (int j = i + 1; j < spawnAreas.length; j++) {
if (spawnAreas[i].areaID.equals(spawnAreas[j].areaID)) {
L.log("WARNING: duplicate areaID " + spawnAreas[i].areaID + " in map " + this.name);
}
}
}
}
}
public final boolean isOutside(final Coord p) { return isOutside(p.x, p.y); }
@@ -351,7 +361,7 @@ public final class PredefinedMap {
public boolean shouldSaveMapData(WorldContext world) {
if (!hasResetTemporaryData()) return true;
if (this == world.model.currentMap) return true;
if (this == world.model.currentMaps.map) return true;
if (!groundBags.isEmpty()) return true;
for (MonsterSpawnArea a : spawnAreas) {
if (this.visited && a.isUnique) return true;

View File

@@ -20,6 +20,7 @@ public final class Requirement {
,factionScore
,random
,factionScoreEquals
,wearRemove
}
public final RequirementType requireType;
@@ -68,6 +69,8 @@ public final class Requirement {
return requireID != null;
case inventoryKeep:
case inventoryRemove:
case wear:
case wearRemove:
case usedItem:
return requireID != null && value >= 0;
case killedMonster:
@@ -83,10 +86,8 @@ public final class Requirement {
return chance != null;
case timerElapsed:
return requireID != null && value >= 0;
case wear:
case factionScore:
case factionScoreEquals:
return requireID != null;
default:
return false;
}

View File

@@ -325,7 +325,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.monsters_man1, "monsters_man1", sz1x1, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_men, "monsters_men", new Size(9, 1), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_men2, "monsters_men2", new Size(10, 1), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_misc, "monsters_misc", new Size(12, 1), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_misc, "monsters_misc", new Size(13, 1), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_rats, "monsters_rats", new Size(5, 1), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_redshrike1, "monsters_redshrike1", sz7x1, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_rltiles1, "monsters_rltiles1", new Size(20, 8), sz1x1, mTileSize);
@@ -356,6 +356,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.monsters_unknown, "monsters_unknown", sz1x1, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_arulirs, "monsters_arulirs", new Size(8, 2), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_fatboy73, "monsters_fatboy73", new Size(20, 12), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_giantbasilisk, "monsters_giantbasilisk", sz1x1, sz2x2, mTileSize);
/*INSERT_NPCS_TILESETS_HERE*/
loader.prepareTileset(R.drawable.map_bed_1, "map_bed_1", mapTileSize, sz1x1, mTileSize);
@@ -404,6 +405,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.map_shop_1, "map_shop_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_sign_ladder_1, "map_sign_ladder_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_table_1, "map_table_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_table_2, "map_table_2", new Size(14, 8), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_trail_1, "map_trail_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_transition_1, "map_transition_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_transition_2, "map_transition_2", mapTileSize, sz1x1, mTileSize);

View File

@@ -125,6 +125,7 @@ public final class ResourceParserUtils {
,o.optInt(JsonFieldNames.AbilityModifierTraits.increaseBlockChance, 0)
,increaseAttackDamage != null ? increaseAttackDamage.current : 0
,increaseAttackDamage != null ? increaseAttackDamage.max : 0
, o.optInt(JsonFieldNames.AbilityModifierTraits.setNonWeaponDamageModifier, 100)
,o.optInt(JsonFieldNames.AbilityModifierTraits.increaseCriticalSkill, 0)
,(float)o.optDouble(JsonFieldNames.AbilityModifierTraits.setCriticalMultiplier, 0)
,o.optInt(JsonFieldNames.AbilityModifierTraits.increaseDamageResistance, 0)

View File

@@ -30,6 +30,7 @@ public final class JsonFieldNames {
public static final String increaseCriticalSkill = "increaseCriticalSkill";
public static final String setCriticalMultiplier = "setCriticalMultiplier";
public static final String increaseAttackDamage = "increaseAttackDamage";
public static final String setNonWeaponDamageModifier = "setNonWeaponDamageModifier";
public static final String increaseBlockChance = "increaseBlockChance";
public static final String increaseDamageResistance = "increaseDamageResistance";
}

View File

@@ -98,7 +98,6 @@ public final class TileManager {
public final TileCache tileCache = new TileCache();
public TileCollection preloadedTiles;// = new TileCollection(116);
public TileCollection currentMapTiles;
public TileCollection adjacentMapTiles;
private final HashSet<Integer> preloadedTileIDs = new HashSet<Integer>();
@@ -177,9 +176,9 @@ public final class TileManager {
public void setImageViewTile(Resources res, TextView textView, Monster monster) { setImageViewTileForMonster(res, textView, monster.iconID); }
public void setImageViewTile(Resources res, TextView textView, Monster monster, TileCollection tiles) { setImageViewTileForMonster(res, textView, monster.iconID, tiles); }
public void setImageViewTile(Resources res, TextView textView, Player player) { setImageViewTileForPlayer(res, textView, player.iconID); }
public void setImageViewTileForMonster(Resources res, TextView textView, int iconID) { setImageViewTile(res, textView, currentMapTiles.getBitmap(iconID)); }
public void setImageViewTileForMonster(Resources res, TextView textView, int iconID, TileCollection tiles) { setImageViewTile(res, textView, tiles.getBitmap(iconID)); }
public void setImageViewTileForPlayer(Resources res, TextView textView, int iconID) { setImageViewTile(res, textView, preloadedTiles.getBitmap(iconID)); }
public void setImageViewTile(Resources res, TextView textView, ActorConditionType conditionType) { setImageViewTile(res, textView, preloadedTiles.getBitmap(conditionType.iconID)); }
public void setImageViewTile(Resources res, TextView textView, ActorConditionType conditionType, boolean immunityOverlay) { setImageViewTile(res, textView, preloadedTiles.getBitmap(conditionType.iconID), immunityOverlay); }
@@ -249,9 +248,9 @@ public final class TileManager {
}
}
public void setImageViewTile(Resources res, ImageView imageView, Monster monster) { setImageViewTileForMonster(res, imageView, monster.iconID); }
public void setImageViewTile(Resources res, ImageView imageView, Monster monster, TileCollection tiles) { setImageViewTileForMonster(res, imageView, monster.iconID, tiles); }
public void setImageViewTile(Resources res, ImageView imageView, Player player) { setImageViewTileForPlayer(res, imageView, player.iconID); }
public void setImageViewTileForMonster(Resources res, ImageView imageView, int iconID) { setImageViewTile(res, imageView, currentMapTiles.getBitmap(iconID)); }
public void setImageViewTileForMonster(Resources res, ImageView imageView, int iconID, TileCollection tiles) { setImageViewTile(res, imageView, tiles.getBitmap(iconID)); }
public void setImageViewTileForPlayer(Resources res, ImageView imageView, int iconID) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(iconID)); }
// public void setImageViewTile(Resources res, ImageView imageView, ActorConditionType conditionType) { setImageViewTile(res, imageView, preloadedTiles.getBitmap(conditionType.iconID)); }
public void setImageViewTile(Context ctx, ImageView imageView, ActorConditionType conditionType, boolean immunityOverlay) { setImageViewTile(ctx, imageView, preloadedTiles.getBitmap(conditionType.iconID), immunityOverlay); }

View File

@@ -29,7 +29,7 @@ public class LegacySavegamesContentAdaptations {
for (MonsterSpawnArea newarea : fields5Map.spawnAreas) {
if (newarea.areaID.equals("guynmart_robber1")) {
controllers.monsterSpawnController.spawnAllInArea(fields5Map,
(world.model.currentMap == fields5Map ? world.model.currentTileMap : null),
(world.model.currentMaps.map == fields5Map ? world.model.currentMaps.tileMap : null),
newarea, true);
break;
}

View File

@@ -233,7 +233,7 @@ public final class Savegames {
private static void onWorldLoaded(Resources res, WorldContext world, ControllerContext controllers) {
controllers.actorStatsController.recalculatePlayerStats(world.model.player);
controllers.mapController.resetMapsNotRecentlyVisited();
controllers.movementController.prepareMapAsCurrentMap(world.model.currentMap, res, false);
controllers.movementController.prepareMapAsCurrentMap(world.model.currentMaps.map, res, false);
controllers.gameRoundController.resetRoundTimers();
}

View File

@@ -8,7 +8,7 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
public class ListOfListeners<T> {
private final ArrayList<WeakReference<T>> listeners = new ArrayList<WeakReference<T>>();
public final void add(T listener) {
public synchronized final void add(T listener) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
for (WeakReference<T> ref : listeners) {
if (ref.get() == listener) {
@@ -18,7 +18,7 @@ public class ListOfListeners<T> {
}
listeners.add(new WeakReference<T>(listener));
}
public final void remove(T listenerToRemove) {
public synchronized final void remove(T listenerToRemove) {
for (int i = listeners.size()-1; i >= 0; --i) {
T listener = listeners.get(i).get();
if (listener == null || listener == listenerToRemove) {
@@ -26,32 +26,32 @@ public class ListOfListeners<T> {
}
}
}
public final void clear() {
public synchronized final void clear() {
listeners.clear();
}
protected final void callAllListeners(Function<T> e) {
protected synchronized final void callAllListeners(Function<T> e) {
for (int i = listeners.size()-1; i >= 0; --i) {
T listener = listeners.get(i).get();
if (listener == null) listeners.remove(i);
else e.call(listener);
}
}
protected final <Arg1> void callAllListeners(Function1<T, Arg1> e, Arg1 arg) {
protected synchronized final <Arg1> void callAllListeners(Function1<T, Arg1> e, Arg1 arg) {
for (int i = listeners.size()-1; i >= 0; --i) {
T listener = listeners.get(i).get();
if (listener == null) listeners.remove(i);
else e.call(listener, arg);
}
}
protected final <Arg1, Arg2> void callAllListeners(Function2<T, Arg1, Arg2> e, Arg1 arg1, Arg2 arg2) {
protected synchronized final <Arg1, Arg2> void callAllListeners(Function2<T, Arg1, Arg2> e, Arg1 arg1, Arg2 arg2) {
for (int i = listeners.size()-1; i >= 0; --i) {
T listener = listeners.get(i).get();
if (listener == null) listeners.remove(i);
else e.call(listener, arg1, arg2);
}
}
protected final <Arg1, Arg2, Arg3> void callAllListeners(Function3<T, Arg1, Arg2, Arg3> e, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
protected synchronized final <Arg1, Arg2, Arg3> void callAllListeners(Function3<T, Arg1, Arg2, Arg3> e, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
for (int i = listeners.size()-1; i >= 0; --i) {
T listener = listeners.get(i).get();
if (listener == null) listeners.remove(i);

View File

@@ -19,6 +19,7 @@ public final class AbilityModifierInfoView extends LinearLayout {
private final TextView abilitymodifierinfo_change_attack_cost;
private final TextView abilitymodifierinfo_change_attack_chance;
private final TextView abilitymodifierinfo_change_attack_damage;
private final TextView abilitymodifierinfo_set_damage_modifier;
private final TextView abilitymodifierinfo_change_critical_skill;
private final TextView abilitymodifierinfo_change_critical_multiplier;
private final TextView abilitymodifierinfo_change_block_chance;
@@ -38,6 +39,7 @@ public final class AbilityModifierInfoView extends LinearLayout {
abilitymodifierinfo_change_attack_cost = (TextView) findViewById(R.id.abilitymodifierinfo_change_attack_cost);
abilitymodifierinfo_change_attack_chance = (TextView) findViewById(R.id.abilitymodifierinfo_change_attack_chance);
abilitymodifierinfo_change_attack_damage = (TextView) findViewById(R.id.abilitymodifierinfo_change_attack_damage);
abilitymodifierinfo_set_damage_modifier = (TextView) findViewById(R.id.abilitymodifierinfo_set_damage_modifier);
abilitymodifierinfo_change_critical_skill = (TextView) findViewById(R.id.abilitymodifierinfo_change_critical_skill);
abilitymodifierinfo_change_critical_multiplier = (TextView) findViewById(R.id.abilitymodifierinfo_change_critical_multiplier);
abilitymodifierinfo_change_block_chance = (TextView) findViewById(R.id.abilitymodifierinfo_change_block_chance);
@@ -89,6 +91,12 @@ public final class AbilityModifierInfoView extends LinearLayout {
}
abilitymodifierinfo_change_attack_damage.setVisibility(View.VISIBLE);
}
if (isWeapon) {
final int nonWeaponDamageModifier = traits.setNonWeaponDamageModifier > 0 ? traits.setNonWeaponDamageModifier : 100;
abilitymodifierinfo_set_damage_modifier.setText(res.getString(R.string.iteminfo_effect_set_damage_modifier, nonWeaponDamageModifier));
abilitymodifierinfo_set_damage_modifier.setVisibility(View.VISIBLE);
}
}
private void displayIfNonZero(int statChange, TextView textView, int stringresource_increase, int stringresource_decrease) {

View File

@@ -197,7 +197,7 @@ public final class CombatView extends RelativeLayout implements CombatSelectionL
currentMonster = null;
if (selectedMonster != null) {
monsterBar.setVisibility(View.VISIBLE);
world.tileManager.setImageViewTile(res, monsterInfo, selectedMonster);
world.tileManager.setImageViewTile(res, monsterInfo, selectedMonster, world.model.currentMaps.tiles);
updateMonsterHealth(selectedMonster);
currentMonster = selectedMonster;
}

View File

@@ -167,8 +167,8 @@ public final class MainView extends SurfaceView
sh.setFixedSize(surfaceSize.width, surfaceSize.height);
}
if (model.currentMap != null) {
onPlayerEnteredNewMap(model.currentMap, model.player.position);
if (model.currentMaps.map != null) {
onPlayerEnteredNewMap(model.currentMaps.map, model.player.position);
} else {
redrawAll(RedrawAllDebugReason.SurfaceChanged);
}
@@ -506,8 +506,8 @@ public final class MainView extends SurfaceView
movingSpritesRedrawTick.start();
synchronized (holder) {
currentMap = map;
currentTileMap = model.currentTileMap;
tiles = world.tileManager.currentMapTiles;
currentTileMap = model.currentMaps.tileMap;
tiles = world.model.currentMaps.tiles;
movingSprites = 0;
Size visibleNumberOfTiles = new Size(
Math.min(screenSizeTileCount.width, currentMap.size.width)

View File

@@ -155,6 +155,7 @@ public final class SkillListAdapter extends ArrayAdapter<SkillInfo> {
case fightstyleDualWield: return R.string.skill_shortdescription_fightstyle_dualwield;
case fightstyle2hand: return R.string.skill_shortdescription_fightstyle_2hand;
case fightstyleWeaponShield: return R.string.skill_shortdescription_fightstyle_weapon_shield;
case fightstyleUnarmedUnarmored: return R.string.skill_shortdescription_fightstyle_unarmed_unarmored;
case specializationDualWield: return R.string.skill_shortdescription_specialization_dualwield;
case specialization2hand: return R.string.skill_shortdescription_specialization_2hand;
case specializationWeaponShield: return R.string.skill_shortdescription_specialization_weapon_shield;