Compare commits

..

2 Commits

Author SHA1 Message Date
OMGeeky
c9b92e41cd code-analysis workflow 2023-02-03 20:58:17 +01:00
OMGeeky
58773c1522 code-analysis workflow 2023-02-03 20:56:50 +01:00
296 changed files with 5115 additions and 534077 deletions

74
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "Code Quality Analysis"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '32 9 * * 1' # This cron job will run at 9:32 AM every week on Monday
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java', 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@@ -3,8 +3,8 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gpl.rpg.AndorsTrail"
android:versionCode="70"
android:versionName="0.8.5"
android:versionCode="69"
android:versionName="0.8.4.1"
android:installLocation="auto"
>

View File

@@ -28,11 +28,11 @@ public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_FASTSPEED = false;
public static final boolean DEVELOPMENT_VALIDATEDATA = false;
public static final boolean DEVELOPMENT_DEBUGMESSAGES = false;
public static final String CURRENT_VERSION_DISPLAY = "0.8.5";
public static final String CURRENT_VERSION_DISPLAY = "0.8.4.1";
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED || !IS_RELEASE_VERSION;
public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 71;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 69;
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
private WorldContext world = new WorldContext();

View File

@@ -78,7 +78,7 @@ public final class AndorsTrailPreferences {
dest.dpadTransparency = Integer.parseInt(prefs.getString("dpadtransparency", Integer.toString(DPAD_TRANSPARENCY_50_PERCENT)));
dest.dpadMinimizeable = prefs.getBoolean("dpadMinimizeable", true);
dest.optimizedDrawing = prefs.getBoolean("optimized_drawing", false);
dest.highQualityFilters = prefs.getBoolean("high_quality_filters", false);
dest.highQualityFilters = prefs.getBoolean("high_quality_filters", true);
dest.enableUiAnimations = prefs.getBoolean("enableUiAnimations", true);
dest.displayOverwriteSavegame = Integer.parseInt(prefs.getString("display_overwrite_savegame", Integer.toString(CONFIRM_OVERWRITE_SAVEGAME_ALWAYS)));
dest.quickslotsPosition = Integer.parseInt(prefs.getString("quickslots_placement", Integer.toString(QUICKSLOTS_POSITION_HORIZONTAL_CENTER_BOTTOM)));

View File

@@ -134,9 +134,8 @@ public final class WorldSetup {
onSceneLoadedListener = null;
if (o == null) return;
if (loadResult == Savegames.LoadSavegameResult.success
|| loadResult == Savegames.LoadSavegameResult.editDetected) {
o.onSceneLoaded(loadResult);
if (loadResult == Savegames.LoadSavegameResult.success) {
o.onSceneLoaded();
} else {
o.onSceneLoadFailed(loadResult);
}
@@ -162,7 +161,7 @@ public final class WorldSetup {
public static interface OnSceneLoadedListener {
void onSceneLoaded(Savegames.LoadSavegameResult loadResult);
void onSceneLoaded();
void onSceneLoadFailed(Savegames.LoadSavegameResult loadResult);
}
public interface OnResourcesLoadedListener {

View File

@@ -141,18 +141,13 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On
@Override
public void onSceneLoaded(Savegames.LoadSavegameResult loadResult) {
public void onSceneLoaded() {
synchronized (semaphore) {
if (progressDialog != null) progressDialog.dismiss();
loaded =true;
}
if (loadResult == Savegames.LoadSavegameResult.editDetected) {
showLoadingWarnDialog(R.string.dialog_loading_warning_edit);
}else{
startActivity(new Intent(this, MainActivity.class));
this.finish();
}
startActivity(new Intent(this, MainActivity.class));
this.finish();
}
@Override
@@ -170,19 +165,6 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On
}
}
private void showLoadingWarnDialog(int messageResourceID) {
final CustomDialog d = CustomDialogFactory.createDialog(this, getResources().getString(R.string.dialog_loading_warning_title), null, getResources().getString(messageResourceID), null, true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);
CustomDialogFactory.setDismissListener(d, new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
startActivity(new Intent(LoadingActivity.this, MainActivity.class));
LoadingActivity.this.finish();
}
});
CustomDialogFactory.show(d);
}
private void showLoadingFailedDialog(int messageResourceID) {
final CustomDialog d = CustomDialogFactory.createDialog(this, getResources().getString(R.string.dialog_loading_failed_title), null, getResources().getString(messageResourceID), null, true);
CustomDialogFactory.addDismissButton(d, android.R.string.ok);

View File

@@ -1,8 +1,5 @@
package com.gpl.rpg.AndorsTrail.context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionTypeCollection;
import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
@@ -15,10 +12,6 @@ import com.gpl.rpg.AndorsTrail.model.quest.QuestCollection;
import com.gpl.rpg.AndorsTrail.resource.ConversationLoader;
import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public final class WorldContext {
//Objectcollections
@@ -69,13 +62,4 @@ public final class WorldContext {
public void resetForNewGame() {
maps.resetForNewGame();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public String createHash() throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("MD5");
this.maps.createHash(digest);
this.model.createHash(digest);
byte[] hash = digest.digest();
return ByteUtils.toHexString(hash);
}
}

View File

@@ -7,7 +7,7 @@ import com.gpl.rpg.AndorsTrail.util.ConstRange;
import com.gpl.rpg.AndorsTrail.util.Range;
public final class Constants {
public static final int PERCENT_EXP_LOST_WHEN_DIED = 20;
public static final int PERCENT_EXP_LOST_WHEN_DIED = 30;
public static final int LEVELUP_EFFECT_HEALTH = 5;
public static final int LEVELUP_EFFECT_ATK_CH = 5;
public static final int LEVELUP_EFFECT_ATK_DMG = 1;

View File

@@ -3,7 +3,6 @@ package com.gpl.rpg.AndorsTrail.model;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -13,8 +12,6 @@ import java.util.Map.Entry;
import java.util.Set;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.RequiresApi;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
@@ -22,7 +19,6 @@ import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.model.quest.Quest;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.HashMapHelper;
public final class GameStatistics {
@@ -218,21 +214,4 @@ public final class GameStatistics {
dest.writeInt(startLives);
dest.writeBoolean(unlimitedSaves);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(deaths));
for (Entry<String, Integer> e : killedMonstersByTypeID.entrySet()) {
digest.update(ByteUtils.toBytes(e.getKey()));
digest.update(ByteUtils.toBytes(e.getValue()));
}
for (Entry<String, Integer> e : usedItems.entrySet()) {
digest.update(ByteUtils.toBytes(e.getKey()));
digest.update(ByteUtils.toBytes(e.getValue()));
}
digest.update(ByteUtils.toBytes(spentGold));
digest.update(ByteUtils.toBytes(startLives));
digest.update(ByteUtils.toBytes(unlimitedSaves));
}
}

View File

@@ -3,10 +3,8 @@ package com.gpl.rpg.AndorsTrail.model;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.Coord;
public final class InterfaceData {
@@ -53,12 +51,4 @@ public final class InterfaceData {
}
dest.writeUTF(selectedTabHeroInfo);
}
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(isMainActivityVisible));
digest.update(ByteUtils.toBytes(isInCombat));
if(selectedPosition != null){
selectedPosition.createHash(digest);
}
}
}

View File

@@ -1,17 +1,12 @@
package com.gpl.rpg.AndorsTrail.model;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
public final class ModelContainer {
@@ -54,14 +49,4 @@ public final class ModelContainer {
statistics.writeToParcel(dest);
worldData.writeToParcel(dest);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
player.createHash(digest);
digest.update(ByteUtils.toBytes(currentMaps.map.name));
uiSelections.createHash(digest);
statistics.createHash(digest);
worldData.createHash(digest);
}
}

View File

@@ -1,14 +1,8 @@
package com.gpl.rpg.AndorsTrail.model;
import android.os.Build;
import android.support.annotation.RequiresApi;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
@@ -62,13 +56,4 @@ public final class WorldData {
dest.writeLong(e.getValue());
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(worldTime));
for (Map.Entry<String, Long> e: timers.entrySet() ) {
digest.update(ByteUtils.toBytes(e.getKey()));
digest.update(ByteUtils.toBytes(e.getValue()));
}
}
}

View File

@@ -1,15 +1,10 @@
package com.gpl.rpg.AndorsTrail.model.ability;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
public final class ActorCondition {
public static final int MAGNITUDE_REMOVE_ALL = -99;
@@ -50,12 +45,4 @@ public final class ActorCondition {
dest.writeInt(magnitude);
dest.writeInt(duration);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(conditionType.conditionTypeID));
digest.update(ByteUtils.toBytes(magnitude));
digest.update(ByteUtils.toBytes(duration));
}
}

View File

@@ -1,12 +1,8 @@
package com.gpl.rpg.AndorsTrail.model.actor;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
@@ -17,7 +13,6 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemContainer;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForMonster;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.CoordRect;
import com.gpl.rpg.AndorsTrail.util.Range;
@@ -198,28 +193,4 @@ public final class Monster extends Actor {
dest.writeBoolean(false);
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(getMonsterTypeID()));
digest.update(ByteUtils.toBytes(attackCost));
digest.update(ByteUtils.toBytes(attackChance));
digest.update(ByteUtils.toBytes(criticalSkill));
digest.update(ByteUtils.toBytes(criticalMultiplier));
damagePotential.createHash(digest);
digest.update(ByteUtils.toBytes(blockChance));
digest.update(ByteUtils.toBytes(damageResistance));
ap.createHash(digest);
health.createHash(digest);
position.createHash(digest);
for (ActorCondition c: conditions){
c.createHash(digest);
}
digest.update(ByteUtils.toBytes(moveCost));
digest.update(ByteUtils.toBytes(forceAggressive));
if (shopItems != null) {
shopItems.createHash(digest);
}
}
}

View File

@@ -3,7 +3,6 @@ package com.gpl.rpg.AndorsTrail.model.actor;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -14,8 +13,6 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.SparseIntArray;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
@@ -30,7 +27,6 @@ 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.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.Range;
import com.gpl.rpg.AndorsTrail.util.Size;
@@ -59,11 +55,9 @@ public final class Player extends Actor {
public String id = UUID.randomUUID().toString();
public long savedVersion = 1; // the version get's increased for cheat detection everytime a player with limited saves is saved
public boolean wasEditingDetected;
public String hash;
// Unequipped stats
// Unequipped stats
public static final class PlayerBaseTraits {
public int iconID;
public int maxAP;
@@ -117,7 +111,7 @@ public final class Player extends Actor {
baseTraits.criticalSkill = 0;
baseTraits.criticalMultiplier = 1;
baseTraits.damagePotential.set(1, 1);
baseTraits.blockChance = 9;
baseTraits.blockChance = 0;
baseTraits.damageResistance = 0;
baseTraits.useItemCost = 5;
baseTraits.reequipCost = 5;
@@ -422,13 +416,6 @@ public final class Player extends Actor {
this.id = src.readUTF();
this.savedVersion = src.readLong();
}
if (fileversion >= 71){
this.hash = src.readUTF();
this.wasEditingDetected = src.readBoolean();
}else{
this.hash = "";
this.wasEditingDetected = false;
}
}
public void writeToParcel(DataOutputStream dest) throws IOException {
@@ -487,58 +474,6 @@ public final class Player extends Actor {
}
dest.writeUTF(id);
dest.writeLong(savedVersion);
dest.writeUTF(hash);
dest.writeBoolean(wasEditingDetected);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
//skipping icon ID so that it can be changed without hash difference
digest.update(ByteUtils.toBytes(baseTraits.maxAP));
digest.update(ByteUtils.toBytes(baseTraits.maxHP));
//skipping name so that it can be changed without hash difference
digest.update(ByteUtils.toBytes(moveCost));
digest.update(ByteUtils.toBytes(baseTraits.attackCost));
digest.update(ByteUtils.toBytes(baseTraits.attackChance));
digest.update(ByteUtils.toBytes(baseTraits.criticalSkill));
digest.update(ByteUtils.toBytes(baseTraits.criticalMultiplier));
baseTraits.damagePotential.createHash(digest);
digest.update(ByteUtils.toBytes(baseTraits.blockChance));
digest.update(ByteUtils.toBytes(baseTraits.damageResistance));
digest.update(ByteUtils.toBytes(baseTraits.moveCost));
ap.createHash(digest);
health.createHash(digest);
position.createHash(digest);
for(ActorCondition c : conditions){
c.createHash(digest);
}
lastPosition.createHash(digest);
nextPosition.createHash(digest);
digest.update(ByteUtils.toBytes(level));
digest.update(ByteUtils.toBytes(totalExperience));
inventory.createHash(digest);
digest.update(ByteUtils.toBytes(baseTraits.useItemCost));
digest.update(ByteUtils.toBytes(baseTraits.reequipCost));
for (int i = 0; i<skillLevels.size(); i++){
digest.update(ByteUtils.toBytes(skillLevels.keyAt(i)));
digest.update(ByteUtils.toBytes(skillLevels.valueAt(i)));
}
digest.update(ByteUtils.toBytes(spawnMap));
digest.update(ByteUtils.toBytes(spawnPlace));
for (Entry<String, LinkedHashSet<Integer> > e:questProgress.entrySet() ) {
digest.update(ByteUtils.toBytes(e.getKey()));
for(int progress: e.getValue()){
digest.update(ByteUtils.toBytes(progress));
}
}
digest.update(ByteUtils.toBytes(availableSkillIncreases));
for (Entry<String, Integer> e:alignments.entrySet() ) {
digest.update(ByteUtils.toBytes(e.getKey()));
digest.update(ByteUtils.toBytes(e.getValue()));
}
digest.update(ByteUtils.toBytes(id));
// digest.update(ByteUtils.toBytes(savedVersion));
// digest.update(ByteUtils.toBytes(wasEditingDetected));
}
}

View File

@@ -1,19 +1,14 @@
package com.gpl.rpg.AndorsTrail.model.item;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
public class ItemContainer {
public final ArrayList<ItemEntry> items = new ArrayList<ItemEntry>();
@@ -28,8 +23,7 @@ public class ItemContainer {
return result;
}
public static final class ItemEntry {
public static final class ItemEntry {
public final ItemType itemType;
public int quantity;
public ItemEntry(ItemType itemType, int initialQuantity) {
@@ -48,12 +42,6 @@ public class ItemContainer {
dest.writeUTF(itemType.id);
dest.writeInt(quantity);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(itemType.id));
digest.update(ByteUtils.toBytes(quantity));
}
}
public void addItem(ItemType itemType, int quantity) {
@@ -292,12 +280,4 @@ public class ItemContainer {
e.writeToParcel(dest);
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
for (ItemEntry e :
items) {
e.createHash(digest);
}
}
}

View File

@@ -1,16 +1,11 @@
package com.gpl.rpg.AndorsTrail.model.item;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.Coord;
public final class Loot {
@@ -93,13 +88,4 @@ public final class Loot {
position.writeToParcel(dest);
dest.writeBoolean(isVisible);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(exp));
digest.update(ByteUtils.toBytes(exp));
items.createHash(digest);
position.createHash(digest);
digest.update(ByteUtils.toBytes(isVisible));
}
}

View File

@@ -1,12 +1,8 @@
package com.gpl.rpg.AndorsTrail.model.map;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -92,27 +88,15 @@ public final class MapCollection {
return false;
}
private List<PredefinedMap> getAllSavedMaps(WorldContext world) {
public void writeToParcel(DataOutputStream dest, WorldContext world) throws IOException {
List<PredefinedMap> mapsToExport = new ArrayList<PredefinedMap>();
for(PredefinedMap map : getAllMaps()) {
if (shouldSaveMap(world, map)) mapsToExport.add(map);
}
return mapsToExport;
}
public void writeToParcel(DataOutputStream dest, WorldContext world) throws IOException {
List<PredefinedMap> mapsToExport = getAllSavedMaps(world);
dest.writeInt(mapsToExport.size());
for(PredefinedMap map : mapsToExport) {
dest.writeUTF(map.name);
map.writeToParcel(dest, world);
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
for (PredefinedMap map : getAllMaps()) {
map.createHash(digest);
}
}
}

View File

@@ -1,12 +1,8 @@
package com.gpl.rpg.AndorsTrail.model.map;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -14,7 +10,6 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.CoordRect;
import com.gpl.rpg.AndorsTrail.util.Range;
@@ -145,13 +140,4 @@ public final class MonsterSpawnArea {
m.writeToParcel(dest);
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(isSpawning));
for (Monster m :
monsters) {
m.createHash(digest);
}
}
}

View File

@@ -1,12 +1,8 @@
package com.gpl.rpg.AndorsTrail.model.map;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -20,7 +16,6 @@ import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.map.MapObject.MapObjectType;
import com.gpl.rpg.AndorsTrail.util.ByteUtils;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.CoordRect;
import com.gpl.rpg.AndorsTrail.util.L;
@@ -345,7 +340,6 @@ public final class PredefinedMap {
}
}
} else {
currentColorFilter = null;
activeMapObjectGroups.clear();
activeMapObjectGroups.addAll(initiallyActiveMapObjectGroups);
activateMapObjects();
@@ -366,20 +360,16 @@ public final class PredefinedMap {
}
public boolean shouldSaveMapData(WorldContext world) {
if (this == world.model.currentMaps.map) return true;
return mapDataNeedsToBeSaved();
}
private boolean mapDataNeedsToBeSaved() {
if (!hasResetTemporaryData()) 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;
if (a.isSpawning != a.isSpawningForNewGame) return true;
}
if (!activeMapObjectGroups.containsAll(initiallyActiveMapObjectGroups)
|| !initiallyActiveMapObjectGroups.containsAll(activeMapObjectGroups)) return true;
if (currentColorFilter != null && !currentColorFilter.equals(initialColorFilter)) return true;
if (!activeMapObjectGroups.containsAll(initiallyActiveMapObjectGroups)
|| !initiallyActiveMapObjectGroups.containsAll(activeMapObjectGroups)) return true;
if (currentColorFilter != null) return true;
return false;
}
@@ -408,23 +398,4 @@ public final class PredefinedMap {
dest.writeBoolean(visited);
dest.writeUTF(lastSeenLayoutHash);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public void createHash(MessageDigest digest) {
if (mapDataNeedsToBeSaved()) {
for (MonsterSpawnArea a : spawnAreas) {
a.createHash(digest);
}
for (String g : activeMapObjectGroups) {
digest.update(ByteUtils.toBytes(g));
}
for (Loot l : groundBags) {
l.createHash(digest);
}
digest.update(ByteUtils.toBytes(currentColorFilter));
//skip lastVisitTime since it is too volatile
}
digest.update( ByteUtils.toBytes(visited));
digest.update( ByteUtils.toBytes(lastSeenLayoutHash));
}
}

View File

@@ -12,7 +12,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -21,7 +20,6 @@ import java.util.regex.Pattern;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.os.SystemClock;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
@@ -44,7 +42,6 @@ public final class Savegames {
public static enum LoadSavegameResult {
success
, editDetected
, unknownError
, savegameIsFromAFutureVersion
, cheatingDetected
@@ -81,7 +78,7 @@ public final class Savegames {
}
return true;
} catch (IOException | NoSuchAlgorithmException e) {
} catch (IOException e) {
L.log("Error saving world: " + e.toString());
return false;
}
@@ -213,18 +210,14 @@ public final class Savegames {
}
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException, NoSuchAlgorithmException {
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
DataOutputStream dest = new DataOutputStream(outStream);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
world.model.player.hash = world.createHash();
}
FileHeader.writeToParcel(dest, world.model.player.getName(),
displayInfo, world.model.player.iconID,
world.model.statistics.isDead(),
world.model.statistics.hasUnlimitedSaves(),
world.model.player.id,
world.model.player.savedVersion,
world.model.player.wasEditingDetected);
world.model.player.savedVersion);
world.maps.writeToParcel(dest, world);
world.model.writeToParcel(dest);
dest.close();
@@ -246,15 +239,6 @@ public final class Savegames {
onWorldLoaded(res, world, controllers);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
String worldHash = world.createHash();
if(!worldHash.equals(world.model.player.hash)){
world.model.player.wasEditingDetected = true;
return LoadSavegameResult.editDetected;
}
} catch (NoSuchAlgorithmException ignored) { }
}
return LoadSavegameResult.success;
}
@@ -350,7 +334,6 @@ public final class Savegames {
public final boolean hasUnlimitedSaves;
public final String playerId;
public final long savedVersion;
public final boolean wasEditingDetected;
public String describe() {
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
@@ -395,14 +378,9 @@ public final class Savegames {
this.playerId = "";
this.savedVersion = 0;
}
if (fileversion >= 70){
this.wasEditingDetected = src.readBoolean();
}else{
this.wasEditingDetected = false;
}
}
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion, boolean wasEditingDetected) throws IOException {
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeUTF(playerName);
dest.writeUTF(displayInfo);
@@ -411,7 +389,6 @@ public final class Savegames {
dest.writeBoolean(hasUnlimitedSaves);
dest.writeUTF(playerId);
dest.writeLong(savedVersion);
dest.writeBoolean(wasEditingDetected);
}
}
}

View File

@@ -1,17 +1,6 @@
package com.gpl.rpg.AndorsTrail.util;
import android.os.Build;
import android.support.annotation.RequiresApi;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public final class ByteUtils {
private static int bytes;
public static String toHexString(byte[] bytes) { return toHexString(bytes, bytes.length); }
public static String toHexString(byte[] bytes, int numBytes) {
if (bytes == null) return "";
@@ -32,57 +21,4 @@ public final class ByteUtils {
array[i] ^= mask[i];
}
}
public static byte[] toBytes(long l){
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
bytes = Long.BYTES;
}else{
bytes = 8;
}
ByteBuffer buffer = ByteBuffer.allocate(bytes);
buffer.putLong(l);
return buffer.array();
}
public static byte[] toBytes(int i){
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
bytes = Integer.BYTES;
}else{
bytes = 4;
}
ByteBuffer buffer = ByteBuffer.allocate(bytes);
buffer.putInt(i);
return buffer.array();
}
public static byte[] toBytes(float f) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
bytes = Float.BYTES;
}else{
bytes = 4;
}
ByteBuffer buffer = ByteBuffer.allocate(bytes);
buffer.putFloat(f);
return buffer.array();
}
public static byte[] toBytes(boolean bool){
byte b;
if(bool){
b = 0;
}else{
b = 1;
}
return new byte[] {b};
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static byte[] toBytes(String x) {
if (x == null) {
return new byte[]{};
}
return x.getBytes(StandardCharsets.UTF_8);
}
}

View File

@@ -3,7 +3,6 @@ package com.gpl.rpg.AndorsTrail.util;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
public final class Coord {
public int x;
@@ -48,9 +47,4 @@ public final class Coord {
dest.writeInt(x);
dest.writeInt(y);
}
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(x));
digest.update(ByteUtils.toBytes(y));
}
}

View File

@@ -1,11 +1,8 @@
package com.gpl.rpg.AndorsTrail.util;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
public final class Range {
public int max;
@@ -102,9 +99,4 @@ public final class Range {
dest.writeInt(max);
dest.writeInt(current);
}
public void createHash(MessageDigest digest) {
digest.update(ByteUtils.toBytes(max));
digest.update(ByteUtils.toBytes(current));
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,46 +21,6 @@ Visit our forums on www.andorstrail.com for help, hints, tips and general discus
Changelog:
v0.8.5
New quest 'Ratdom' with 139 new maps and 2 sub quests
The loss of XP in case of death is now 20% instead of 30%
Having raw meat cooked
Translation updates and many minor bug fixes and enhancements
v0.8.4.1
Export/Import: The worldmap, which consists of many small png files, is handled now as a zip file.
Translation updates and many minor bug fixes and map enhancements
v0.8.3
New quest "The Dead are Walking" with 38 new maps
Export/Import function for savegames
v0.8.2
Fix of a lost traveler in certain conditions
Support of older mobiles again
v0.8.1
New city Sullengard
71 new maps and 6 new quests
Monster kill count
Controller support
Translations updated
Engine changes to support actual Android Studio
v0.7.17
Fix of unloadable savegames in certain conditions
v0.7.16
New quest 'Delivery'
Fix of Killed-by-Kamelio bug, postman bug and typos
Translations updated (Chinese 99%)
v0.7.15
Fix of a notification crash bug
Fix of missing scout and of a non disappearing Ortholion and Ehrenfest in certain conditions
Various small changes and bug fixes
Translations updated
v0.7.14
2 new quests:
"Climbing up is forbidden"

View File

@@ -1,56 +1,6 @@
I put both (release notes + forum announcement) into this source, so it will be easier to maintain them parallel:
APK 70 (0.8.5) Ratdom
Release notes
=============
* The new Ratdom area with 3 quests and 139 new maps
* Translation updates and many minor bug fixes and enhancements
Forum announcement //2023-01-29
==================
Hello adventurers,
we have another new version for you (v0.8.5 beta) 8-)
[list]We have a huge new area with 139 new maps and 3 new quests:
A big quest in a rat world and two other small quests you will find on your way.
This section is more for high-level players: the quests Lodar, Charwood, Colonel Lutarc and the starter quests Prohibited Substance and Rat Infestation are mandatory.
Do you have these and also 9000 gold pieces with you, then you can dive into the new adventure.
Just go home and take a nap - it's not really going to be refreshing...
You will find many new maps arranged as a maze. This area looks and feels different than the rest of Andor's path. It will also be a challenge for the high-level players who just run through new areas with no effort.
(The scope took a long time to create, so don't expect to finish it in a few hours.)
A rat named Clevred will accompany you even though you don't see it. It's small enough to hide in your pocket or carry around. But he will talk to you, sometimes randomly, sometimes giving advice.
[/list]
[list]The loss of XP in case of death is now 20% instead of 30%[/list]
[list]It is now possible to have your raw meat cooked by Gison's son Gael and in Remgard.[/list]
[list]We added the new Polished ring of the Protector in Remgard, and flipped the places of sale of the Guardian and Protector rings.[/list]
[list]Several other adjustments, not worth to list them all here[/list]
[list]And as always, we've fixed some minor bugs and updated the translations.[/list]
Here is is the link on our server: [url]https://andorstrail.com/static/AndorsTrail_v0.8.5.apk[/url]
Google Play, F-Droid and Itch will follow soon.
Have fun!
PS
I might be too harsh, so we added an early exit to the quest so you can come out and complete the quest even if you didn't actually reach the end.
APK 69 (0.8.4.1) //Mostly harmless
Release notes

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 187 KiB

View File

@@ -6,23 +6,6 @@
{
"text":"Please show me your wares.",
"nextPhraseID":"S"
},
{
"text":"Do you have a pickaxe by chance?",
"nextPhraseID":"ratdom_audir",
"requires":[
{
"requireType":"questProgress",
"requireID":"ratdom_quest",
"value":80
},
{
"requireType":"questProgress",
"requireID":"ratdom_quest",
"value":82,
"negate":true
}
]
}
]
},

View File

@@ -2414,7 +2414,7 @@
},
{
"id":"achieve_road_10",
"message":"This must be the great Duleian Road! I have heard so much about it - and now I am really here!",
"message":"This must be the great Duleian Road! I have heard so much of it - and now I am really here!",
"rewards":[
{
"rewardType":"questProgress",

View File

@@ -1659,10 +1659,6 @@
{
"text":"To each his own, I guess.",
"nextPhraseID":"gael_20_5"
},
{
"text":"Cooked meat? Who cooks your meat?",
"nextPhraseID":"gael_cook"
}
]
},

View File

@@ -290,7 +290,7 @@
},
{
"id":"gorwath_exit",
"message":"I will go now and prepare a present for lovely Arensia. When we get married, you will of course be invited.",
"message":"I will go now and prepare a present for lovely Arensia.",
"replies":[
{
"text":"OK. Bye.",
@@ -300,16 +300,12 @@
},
{
"id":"gorwath_exit_1",
"message":"Before we go our separate ways, please take this ring that I found behind those haystacks over there.",
"message":"And when we get married, you will of course be invited.",
"rewards":[
{
"rewardType":"removeSpawnArea",
"rewardID":"gorwath",
"mapName":"crossglen"
},
{
"rewardType":"dropList",
"rewardID":"gorwath_dl"
}
]
},

View File

@@ -463,7 +463,7 @@
},
{
"id":"haunted_forest_discovery_script_10",
"message":"As you enter this dark place, you suspect that you are getting closer to the sounds heard by Gabriel as the moaning is much louder now.",
"message":"As you enter this dark place, you suspect that you are getting closer to the sounds heard by Gabriel as the moaning is much loader now.",
"rewards":[
{
"rewardType":"questProgress",
@@ -599,7 +599,7 @@
},
{
"id":"road5_daw_20",
"message":"Now you begin to notice that the moaning heard by Gabriel is a little louder here.",
"message":"Now you begin to notice that the moaning heard by Gabriel is a little loader here.",
"replies":[
{
"text":"I must be getting closer to the source. It's time to press on.",

View File

@@ -52,10 +52,6 @@
{
"text":"Are there any rooms available?",
"nextPhraseID":"kendelow_room_1"
},
{
"text":"Actually, I am wondering if it would be possible if I could cook some meat in your kitchen?",
"nextPhraseID":"kendelow_meat"
}
]
},

View File

@@ -2,16 +2,6 @@
{
"id":"mikhail_start_select",
"replies":[
{
"nextPhraseID":"ratdom_mikhail",
"requires":[
{
"requireType":"questProgress",
"requireID":"ratdom_nondisplay",
"value":1
}
]
},
{
"nextPhraseID":"mikhail_start_select2",
"requires":[
@@ -565,16 +555,6 @@
"replies":[
{
"text":"OK, I understand. I can rest here if I get hurt, and I should check my inventory for useful items.",
"nextPhraseID":"mikhail_rats_start3a"
}
]
},
{
"id":"mikhail_rats_start3a",
"message":"One more thing: Look at that basket on the floor over there. It belongs to Andor and he might have left something useful inside.",
"replies":[
{
"text":"N",
"nextPhraseID":"mikhail_default"
}
]

View File

@@ -6587,7 +6587,7 @@
"nextPhraseID":"X"
},
{
"text":"May the Shadow be with your soul.",
"text":"May the shadow be with your soul.",
"nextPhraseID":"elm3_corpse_3b"
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -45,10 +45,10 @@
},
{
"id":"loneford13_pitchfork",
"message":"A new pitchfork is pinned in this haystack.",
"message":"A new pitchfork pinned in this haystack.",
"replies":[
{
"text":"Time to prove that I'm the child of farmer!",
"text":"Time to prove that I'm a son of farmer!",
"nextPhraseID":"loneford13_pitchfork_selector2",
"requires":[
{
@@ -107,7 +107,7 @@
"message":"After several minutes of intense pulling you finally pull out the new pitchfork from the haystack.",
"replies":[
{
"text":"I'm a child of a farmer!",
"text":"I'm the son of a farmer!",
"nextPhraseID":"X"
},
{
@@ -4135,27 +4135,15 @@
"nextPhraseID":"parents_argue_10",
"requires":[
{
"requireType":"questProgress",
"requireType":"questLatestProgress",
"requireID":"andor",
"value":100
},
{
"requireType":"questProgress",
"requireID":"andor",
"value":110,
"negate":true
},
{
"requireType":"questProgress",
"requireID":"sullengard_hidden",
"value":26,
"negate":true
},
{
"requireType":"questProgress",
"requireID":"ratdom_nondisplay",
"value":1,
"negate":true
}
]
}

View File

@@ -1,945 +0,0 @@
[
{
"id":"container_gold_200_500",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":200,
"max":500
}
}
]
},
{
"id":"container_gold_3_10",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":3,
"max":10
}
},
{
"itemID":"club3",
"chance":"5",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"container_gold_30_200",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":30,
"max":200
}
},
{
"itemID":"club3",
"chance":"5",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"container_rock_1",
"items":[
{
"itemID":"rock",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"club3",
"chance":"5",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"drop_ratdom_gruil",
"items":[
{
"itemID":"gem1",
"chance":"50",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"drop_ratdom_kriih",
"items":[
{
"itemID":"gem1",
"chance":"50",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":200,
"max":500
}
},
{
"itemID":"boots_coward",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"daggr_curv",
"chance":"50",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"stiletto",
"chance":"25",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"drink_lowyn3",
"chance":"50",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"drop_ratdom_mara",
"items":[
{
"itemID":"bread",
"chance":"100",
"quantity":{
"min":1,
"max":2
}
}
]
},
{
"id":"drop_ratdom_tharal",
"items":[
{
"itemID":"health_minor2",
"chance":"50",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_531_loot1",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":200,
"max":400
}
}
]
},
{
"id":"ratdom_531_loot2",
"items":[
{
"itemID":"gold",
"chance":"50",
"quantity":{
"min":10,
"max":40
}
},
{
"itemID":"gem2",
"chance":"50",
"quantity":{
"min":2,
"max":4
}
},
{
"itemID":"gem3",
"chance":"50",
"quantity":{
"min":2,
"max":4
}
},
{
"itemID":"gem5",
"chance":"50",
"quantity":{
"min":2,
"max":4
}
}
]
},
{
"id":"ratdom_567_loot1",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":200,
"max":400
}
}
]
},
{
"id":"ratdom_567_loot2",
"items":[
{
"itemID":"gold",
"chance":"50",
"quantity":{
"min":10,
"max":40
}
},
{
"itemID":"gem2",
"chance":"50",
"quantity":{
"min":2,
"max":4
}
},
{
"itemID":"gem3",
"chance":"50",
"quantity":{
"min":2,
"max":4
}
},
{
"itemID":"gem5",
"chance":"50",
"quantity":{
"min":2,
"max":4
}
}
]
},
{
"id":"ratdom_616_loot1",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":50,
"max":100
}
}
]
},
{
"id":"ratdom_618_loot1",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":50,
"max":100
}
}
]
},
{
"id":"ratdom_618_loot2",
"items":[
{
"itemID":"gem2",
"chance":"50",
"quantity":{
"min":1,
"max":3
}
},
{
"itemID":"gem3",
"chance":"50",
"quantity":{
"min":1,
"max":3
}
},
{
"itemID":"gem4",
"chance":"50",
"quantity":{
"min":1,
"max":3
}
}
]
},
{
"id":"ratdom_artefact",
"items":[
{
"itemID":"ratdom_artefact",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_bone_collector_container",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":3,
"max":10
}
}
]
},
{
"id":"ratdom_bone_collector_container2",
"items":[
{
"itemID":"gem2",
"chance":"100",
"quantity":{
"min":1,
"max":2
}
}
]
},
{
"id":"ratdom_drop_compass_bwm",
"items":[
{
"itemID":"ratdom_compass_bwm",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_drop_compass_tour",
"items":[
{
"itemID":"ratdom_compass_tour",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_ff_guard",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":2,
"max":9
}
}
]
},
{
"id":"ratdom_ff_guard_loot1",
"items":[
{
"itemID":"sullengrad_finest",
"chance":"100",
"quantity":{
"min":20,
"max":30
}
}
]
},
{
"id":"ratdom_ff_guard_loot2",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":120,
"max":330
}
}
]
},
{
"id":"ratdom_fraedro",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":200,
"max":500
}
},
{
"itemID":"ratdom_fraedro_key",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_goldhunter_drop",
"items":[
{
"itemID":"ratdom_rat_skelett_leg",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":30,
"max":200
}
}
]
},
{
"id":"ratdom_king_rah",
"items":[
{
"itemID":"ratdom_rat_sword",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_kriih",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":200,
"max":500
}
}
]
},
{
"id":"ratdom_librarian",
"items":[
{
"itemID":"ratdom_torch",
"chance":"50",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"gold",
"chance":"50",
"quantity":{
"min":30,
"max":80
}
},
{
"itemID":"ratdom_book",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_library_container",
"items":[
{
"itemID":"ratdom_rat_skelett_back",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_maze_mole",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":1,
"max":5
}
}
]
},
{
"id":"ratdom_maze_mole_food",
"items":[
{
"itemID":"ratdom_maze_mole_food",
"chance":"66",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"gold",
"chance":"33",
"quantity":{
"min":1,
"max":2
}
}
]
},
{
"id":"ratdom_mz_center",
"items":[
{
"itemID":"gem1",
"chance":"50",
"quantity":{
"min":1,
"max":2
}
},
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":10,
"max":30
}
},
{
"itemID":"ratdom_rat_skelett_leg",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_rat_pub_owner",
"items":[
{
"itemID":"snake_meat_cooked",
"chance":"100",
"quantity":{
"min":5,
"max":10
}
},
{
"itemID":"guynmart_wine",
"chance":"100",
"quantity":{
"min":5,
"max":5
}
},
{
"itemID":"charwood_cheddar",
"chance":"100",
"quantity":{
"min":2,
"max":2
}
},
{
"itemID":"ferm-garlic",
"chance":"80",
"quantity":{
"min":1,
"max":3
}
},
{
"itemID":"mead",
"chance":"100",
"quantity":{
"min":5,
"max":5
}
}
]
},
{
"id":"ratdom_skeleton_gold",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":50,
"max":120
}
}
]
},
{
"id":"ratdom_startitems2",
"items":[
{
"itemID":"bone",
"chance":"100",
"quantity":{
"min":2,
"max":10
}
}
]
},
{
"id":"ratdom_drop_torch",
"items":[
{
"itemID":"ratdom_torch",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_troll",
"items":[
{
"itemID":"gold",
"chance":"60",
"quantity":{
"min":1,
"max":5
}
},
{
"itemID":"club3",
"chance":"5",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_troll_loot_1",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":1000,
"max":5000
}
},
{
"itemID":"gem2",
"chance":"100",
"quantity":{
"min":1,
"max":3
}
}
]
},
{
"id":"ratdom_troll_loot_2",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":1000,
"max":5000
}
},
{
"itemID":"gem1",
"chance":"100",
"quantity":{
"min":1,
"max":3
}
}
]
},
{
"id":"ratdom_troll_9",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":1000,
"max":5000
}
},
{
"itemID":"club3",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_uglybrute",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":1,
"max":50
}
},
{
"itemID":"club3",
"chance":"75",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"ratdom_rat_warden",
"items":[
{
"itemID":"ratdom_compass_tour",
"chance":"100",
"quantity":{
"min":5,
"max":5
}
}
]
},
{
"id":"ratdom_rat_warden2",
"items":[
{
"itemID":"ratdom_compass_tour",
"chance":"100",
"quantity":{
"min":5,
"max":5
}
},
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":1,
"max":5
}
}
]
},
{
"id":"ratdom_water_container",
"items":[
{
"itemID":"gold",
"chance":"100",
"quantity":{
"min":80,
"max":200
}
}
]
},
{
"id":"well_water",
"items":[
{
"itemID":"well_water",
"chance":"100",
"quantity":{
"min":1,
"max":3
}
}
]
},
{
"id":"whootibarfag",
"items":[
{
"itemID":"ratdom_compass_bwm",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
},
{
"itemID":"ratdom_torch",
"chance":"100",
"quantity":{
"min":1,
"max":5
}
},
{
"itemID":"handcarved_snowball",
"chance":"100",
"quantity":{
"min":100,
"max":150
}
}
]
},
{
"id":"one_cooked_meat",
"items":[
{
"itemID":"meat_cooked",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
},
{
"id":"five_cooked_meat",
"items":[
{
"itemID":"meat_cooked",
"chance":"100",
"quantity":{
"min":5,
"max":5
}
}
]
},
{
"id":"ten_cooked_meat",
"items":[
{
"itemID":"meat_cooked",
"chance":"100",
"quantity":{
"min":10,
"max":10
}
}
]
},
{
"id":"twenty_cooked_meat",
"items":[
{
"itemID":"meat_cooked",
"chance":"100",
"quantity":{
"min":20,
"max":20
}
}
]
},
{
"id":"gorwath_dl",
"items":[
{
"itemID":"kids_ring",
"chance":"100",
"quantity":{
"min":1,
"max":1
}
}
]
}
]

View File

@@ -635,7 +635,7 @@
}
},
{
"itemID":"ring_protector",
"itemID":"ring_guardian",
"chance":"100",
"quantity":{
"min":1,

View File

@@ -1790,7 +1790,7 @@
}
},
{
"itemID":"ring_guardian",
"itemID":"ring_protector",
"chance":"100",
"quantity":{
"min":1,
@@ -1859,7 +1859,7 @@
}
},
{
"itemID":"ring_protector",
"itemID":"ring_guardian",
"chance":"100",
"quantity":{
"min":1,

View File

@@ -406,7 +406,7 @@
}
},
{
"itemID":"polished_ring_protector",
"itemID":"ring_protector",
"chance":"100",
"quantity":{
"min":1,

View File

@@ -1,9 +0,0 @@
[
{
"id":"bigtorch",
"name":"Big torch",
"actionType":"equip",
"size":"large",
"inventorySlot":"weapon"
}
]

View File

@@ -52,7 +52,7 @@
"displaytype":"extraordinary",
"hasManualPrice":1,
"baseMarketCost":11155,
"category":"shld_mtl_li",
"category":"shld_wd_li",
"description":"This shield calls for death, and yours will do.",
"equipEffect":{
"increaseAttackChance":-5,

View File

@@ -1,288 +0,0 @@
[
{
"id":"handcarved_snowball",
"iconID":"items_misc:4",
"name":"Hand carved snowball",
"hasManualPrice":1,
"baseMarketCost":10,
"category":"other"
},
{
"id":"ratdom_artefact",
"iconID":"items_consumables:23",
"name":"Rat's artifact",
"displaytype":"extraordinary",
"hasManualPrice":1,
"baseMarketCost":3000,
"category":"food",
"description":"A hard, dry cheese wheel that seems to last almost forever.",
"useEffect":{
"conditionsSource":[
{
"condition":"food",
"magnitude":2,
"duration":400,
"chance":"100"
}
]
}
},
{
"id":"ratdom_book",
"iconID":"items_books:0",
"name":"Nasty looking book",
"displaytype":"extraordinary",
"hasManualPrice":1,
"baseMarketCost":300,
"category":"other",
"description":"-> Enslavement <- \nand how to do it right.\n\n[As you scan the pages, you decide that this is not appropriate reading for you]"
},
{
"id":"ratdom_compass_bwm",
"iconID":"items_reterski_1:9",
"name":"Blue rat necklace",
"displaytype":"rare",
"hasManualPrice":1,
"baseMarketCost":3000,
"category":"neck",
"description":"This necklace will guide you the shortest way towards the sky.\nWatch out for blue shields.",
"equipEffect":{
"addedConditions":[
{
"condition":"confusion",
"magnitude":1
}
]
}
},
{
"id":"ratdom_compass_tour",
"iconID":"items_reterski_1:10",
"name":"Orange rat necklace",
"displaytype":"rare",
"hasManualPrice":1,
"baseMarketCost":5000,
"category":"neck",
"description":"This necklace will guide you a long way through the caves from Crossglen entrance unto every worthy place.\nWatch out for orange shields, but don't neglect the yellow shields.",
"equipEffect":{
"addedConditions":[
{
"condition":"confusion",
"magnitude":1
}
]
}
},
{
"id":"ratdom_fraedro_key",
"iconID":"items_japozero:387",
"name":"Fraedro's key",
"displaytype":"quest",
"category":"other",
"description":"A tiny golden key"
},
{
"id":"ratdom_maze_mole_food",
"iconID":"items_consumables:25",
"name":"Nutritious snake meat",
"hasManualPrice":1,
"baseMarketCost":120,
"category":"food",
"useEffect":{
"conditionsSource":[
{
"condition":"food",
"magnitude":4,
"duration":10,
"chance":"100"
},
{
"condition":"foodp",
"magnitude":5,
"duration":9,
"chance":"10"
}
]
}
},
{
"id":"ratdom_pickaxe",
"iconID":"items_misc_5:24",
"name":"Pickaxe",
"displaytype":"quest",
"category":"axe",
"equipEffect":{
"increaseAttackDamage":{
"min":1,
"max":2
},
"increaseAttackCost":7,
"increaseAttackChance":-1,
"increaseBlockChance":1
}
},
{
"id":"ratdom_torch",
"iconID":"items_misc:19",
"name":"Ratcave Torch",
"displaytype":"quest",
"category":"bigtorch",
"equipEffect":{
"increaseAttackDamage":{
"min":5,
"max":9
},
"increaseAttackCost":7,
"increaseAttackChance":0,
"increaseBlockChance":1
}
},
{
"id":"ratdom_rat_skelett_back",
"iconID":"items_omgeeky:1",
"name":"Back bones of a rat",
"displaytype":"quest",
"category":"other"
},
{
"id":"ratdom_rat_skelett_leg",
"iconID":"items_omgeeky:2",
"name":"Leg bones of a rat",
"displaytype":"quest",
"category":"other"
},
{
"id":"ratdom_rat_skelett_leg_coll",
"iconID":"items_omgeeky:2",
"name":"Leg bone of a rat",
"displaytype":"quest",
"category":"other",
"description":"The most precious bone of the instrument maker's bone collection"
},
{
"id":"ratdom_rat_skelett_skull",
"iconID":"items_omgeeky:0",
"name":"Rat skull",
"displaytype":"quest",
"category":"other"
},
{
"id":"ratdom_rat_skelett_tail",
"iconID":"items_omgeeky:3",
"name":"Tail bones of a rat",
"displaytype":"quest",
"category":"other"
},
{
"id":"ratdom_rat_skelett_ribs",
"iconID":"items_misc_3:150",
"name":"Rib bones of a rat",
"displaytype":"quest",
"category":"other"
},
{
"id":"ratdom_rat_sword",
"iconID":"items_weapons_3:0",
"name":"Rat King Rah's sword",
"displaytype":"extraordinary",
"baseMarketCost":2000,
"category":"2hsword",
"equipEffect":{
"increaseAttackDamage":{
"min":3,
"max":7
},
"increaseMaxHP":-6,
"increaseAttackCost":5,
"increaseAttackChance":20,
"increaseCriticalSkill":4,
"increaseBlockChance":10,
"setCriticalMultiplier":2.0,
"setNonWeaponDamageModifier":125
},
"hitEffect":{
"conditionsTarget":[
{
"condition":"head_wound",
"magnitude":1,
"duration":3,
"chance":"8"
}
]
}
},
{
"id":"ratdom_wells_ball",
"iconID":"items_misc:0",
"name":"Shimmering globe",
"displaytype":"quest",
"category":"other"
},
{
"id":"snake_meat_cooked",
"iconID":"items_consumables:27",
"name":"Cooked snake meat",
"hasManualPrice":1,
"baseMarketCost":90,
"category":"food",
"useEffect":{
"conditionsSource":[
{
"condition":"food",
"magnitude":4,
"duration":8,
"chance":"100"
}
]
}
},
{
"id":"well_water",
"iconID":"items_omi2:13",
"name":"Bottle of well water",
"displaytype":"extraordinary",
"hasManualPrice":1,
"baseMarketCost":126,
"category":"healing",
"description":"As if freshly drawn from the well",
"useEffect":{
"increaseCurrentHP":{
"min":5,
"max":20
}
}
},
{
"id":"kids_ring",
"iconID":"items_rings_1:17",
"name":"Kid's ring",
"displaytype":"ordinary",
"category":"ring",
"description":"Part of Andor's training equipment.",
"equipEffect":{
"increaseAttackDamage":{
"min":1,
"max":1
},
"increaseAttackChance":8
}
},
{
"id":"polished_ring_protector",
"iconID":"items_rings_1:20",
"name":"Polished ring of the protector",
"displaytype":"rare",
"hasManualPrice":0,
"baseMarketCost":3744,
"category":"ring",
"equipEffect":{
"increaseAttackDamage":{
"min":1,
"max":4
},
"increaseMaxHP":4,
"increaseAttackChance":20,
"increaseBlockChance":17
}
}
]

View File

@@ -21,7 +21,7 @@
"name":"Orchard apples",
"displaytype":"rare",
"hasManualPrice":1,
"baseMarketCost":50,
"baseMarketCost":35,
"category":"food",
"description":"A sweet, deliciously tasting snack for those on the move.",
"useEffect":{
@@ -31,10 +31,6 @@
"magnitude":2,
"duration":10,
"chance":"100"
},
{
"condition":"fatigue_minor",
"chance":"10"
}
]
}
@@ -45,7 +41,7 @@
"name":"Deebo's apple juice",
"displaytype":"rare",
"hasManualPrice":1,
"baseMarketCost":97,
"baseMarketCost":45,
"category":"food",
"description":"A desireable choice of many Sullengard residence.",
"useEffect":{
@@ -55,12 +51,6 @@
"magnitude":2,
"duration":12,
"chance":"100"
},
{
"condition":"vulnerability",
"magnitude":-99,
"duration":2,
"chance":"30"
}
]
}
@@ -71,7 +61,7 @@
"name":"Deebo's apple cider",
"displaytype":"rare",
"hasManualPrice":1,
"baseMarketCost":80,
"baseMarketCost":50,
"category":"food",
"description":"A nice seasonal drink for those slightly colder nights.",
"useEffect":{
@@ -81,11 +71,6 @@
"magnitude":2,
"duration":14,
"chance":"100"
},
{
"condition":"nausea",
"magnitude":-99,
"chance":"35"
}
]
}
@@ -422,9 +407,9 @@
"max":4
},
"increaseAttackCost":6,
"increaseAttackChance":8,
"increaseCriticalSkill":10,
"increaseBlockChance":5,
"increaseAttackChance":12,
"increaseCriticalSkill":12,
"increaseBlockChance":-3,
"increaseDamageResistance":-1,
"setCriticalMultiplier":2.0,
"setNonWeaponDamageModifier":150

View File

@@ -36,10 +36,10 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":101,
"increaseAttackChance":20,
"increaseCriticalSkill":20,
"setCriticalMultiplier":3.0,
"setNonWeaponDamageModifier":101
"setCriticalMultiplier":3.0
}
},
{
@@ -55,8 +55,8 @@
"max":4
},
"increaseAttackCost":5,
"increaseAttackChance":15,
"setNonWeaponDamageModifier":112
"setNonWeaponDamageModifier":112,
"increaseAttackChance":15
}
},
{
@@ -72,8 +72,8 @@
"max":7
},
"increaseAttackCost":5,
"increaseAttackChance":12,
"setNonWeaponDamageModifier":122
"setNonWeaponDamageModifier":122,
"increaseAttackChance":12
}
},
{
@@ -89,8 +89,8 @@
"max":6
},
"increaseAttackCost":6,
"increaseAttackChance":9,
"setNonWeaponDamageModifier":150
"setNonWeaponDamageModifier":150,
"increaseAttackChance":9
}
},
{
@@ -106,8 +106,8 @@
"max":6
},
"increaseAttackCost":5,
"increaseAttackChance":14,
"setNonWeaponDamageModifier":115
"setNonWeaponDamageModifier":115,
"increaseAttackChance":14
}
},
{
@@ -123,8 +123,8 @@
"max":10
},
"increaseAttackCost":7,
"increaseAttackChance":5,
"setNonWeaponDamageModifier":184
"setNonWeaponDamageModifier":184,
"increaseAttackChance":5
}
},
{
@@ -140,8 +140,8 @@
"max":4
},
"increaseAttackCost":4,
"increaseAttackChance":24,
"setNonWeaponDamageModifier":100
"setNonWeaponDamageModifier":100,
"increaseAttackChance":24
}
},
{
@@ -157,8 +157,8 @@
"max":7
},
"increaseAttackCost":4,
"increaseAttackChance":32,
"setNonWeaponDamageModifier":97
"setNonWeaponDamageModifier":97,
"increaseAttackChance":32
}
},
{
@@ -174,8 +174,8 @@
"max":11
},
"increaseAttackCost":6,
"increaseAttackChance":20,
"setNonWeaponDamageModifier":145
"setNonWeaponDamageModifier":145,
"increaseAttackChance":20
}
},
{
@@ -191,9 +191,9 @@
"max":7
},
"increaseAttackCost":5,
"setNonWeaponDamageModifier":119,
"increaseAttackChance":26,
"increaseBlockChance":3,
"setNonWeaponDamageModifier":119
"increaseBlockChance":3
}
},
{
@@ -209,10 +209,10 @@
"max":2
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":96,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0,
"setNonWeaponDamageModifier":96
"setCriticalMultiplier":3.0
}
},
{
@@ -228,8 +228,8 @@
"max":6
},
"increaseAttackCost":5,
"increaseAttackChance":20,
"setNonWeaponDamageModifier":115
"setNonWeaponDamageModifier":115,
"increaseAttackChance":20
}
},
{
@@ -245,9 +245,9 @@
"max":5
},
"increaseAttackCost":4,
"setNonWeaponDamageModifier":93,
"increaseAttackChance":14,
"increaseBlockChance":5,
"setNonWeaponDamageModifier":93
"increaseBlockChance":5
}
},
{
@@ -263,10 +263,10 @@
"max":21
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":161,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0,
"setNonWeaponDamageModifier":161
"setCriticalMultiplier":3.0
}
},
{
@@ -282,8 +282,8 @@
"max":17
},
"increaseAttackCost":6,
"increaseAttackChance":21,
"setNonWeaponDamageModifier":130
"setNonWeaponDamageModifier":130,
"increaseAttackChance":21
}
},
{
@@ -299,10 +299,10 @@
"max":26
},
"increaseAttackCost":7,
"setNonWeaponDamageModifier":187,
"increaseAttackChance":20,
"increaseCriticalSkill":5,
"setCriticalMultiplier":3.0,
"setNonWeaponDamageModifier":187
"setCriticalMultiplier":3.0
}
},
{

View File

@@ -986,7 +986,7 @@
"id":"elm_miner4a",
"name":"Prim guard skeleton",
"iconID":"monsters_omi2:19",
"maxHP":364,
"maxHP":104,
"moveCost":4,
"unique":1,
"monsterClass":"undead",

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More