From 32e7d80a1f80ad9e26d4ad279fb75cd018ea4d49 Mon Sep 17 00:00:00 2001 From: Fabio Ticconi Date: Sun, 25 Feb 2018 12:36:27 +0100 Subject: [PATCH 1/6] reset snapshot version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 76493e4..18b49a0 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ com.github.fabio-t alone-rl - 0.2.6 + 0.3.0-SNAPSHOT jar AloneRL From dd9a47d8457556271fb32925958c630b98bc7597 Mon Sep 17 00:00:00 2001 From: Fabio Ticconi Date: Tue, 27 Feb 2018 22:39:36 +0100 Subject: [PATCH 2/6] using tergen 0.1.1 to have proper rivers --- alone-rl.iml | 2 +- pom.xml | 2 +- .../java/com/github/fabioticconi/alone/screens/MapScreen.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/alone-rl.iml b/alone-rl.iml index 942698b..e8ac48a 100644 --- a/alone-rl.iml +++ b/alone-rl.iml @@ -15,7 +15,7 @@ - + diff --git a/pom.xml b/pom.xml index 18b49a0..feddf25 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ com.github.fabio-t terrain-generator - 0.1.0 + 0.1.1 diff --git a/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java b/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java index b3becb2..a39ed15 100644 --- a/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java +++ b/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java @@ -59,7 +59,7 @@ void regenerate() final HeightMap heightMap = new HeightMap().size(Options.MAP_SIZE_X, Options.MAP_SIZE_Y) .island(0.85f) - .rivers(0.8f, 0.03f, 0.001f); + .rivers(0.8f, 0.03f, 0.001f, 1); heightMap.fractalNoise .seed(seed) From 3d8ef6e79fd56dcef0352aec3c8a17a1b4de4ef0 Mon Sep 17 00:00:00 2001 From: Fabio Ticconi Date: Wed, 28 Feb 2018 10:08:25 +0100 Subject: [PATCH 3/6] #34: added bow and two arrow types --- data/items.yml | 40 ++++++++++++++++++- .../fabioticconi/alone/screens/MapScreen.java | 7 ++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/data/items.yml b/data/items.yml index 13bc993..671f38e 100644 --- a/data/items.yml +++ b/data/items.yml @@ -143,7 +143,45 @@ stone-spear: damageType: POINT damage: 4 sprite: - c: 244 + c: 124 + col: + red: 141 + green: 104 + blue: 21 + alpha: 255 + +arrow: + name: an arrow + weapon: + damageType: POINT + damage: 2 + sprite: + c: 196 + col: + red: 141 + green: 104 + blue: 21 + alpha: 255 + +stone-arrow: + name: a stone-tip arrow + weapon: + damageType: POINT + damage: 3 + sprite: + c: 26 + col: + red: 141 + green: 104 + blue: 21 + alpha: 255 + +bow: + name: a simple bow + wearable: + where: HANDS + sprite: + c: '(' col: red: 141 green: 104 diff --git a/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java b/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java index a39ed15..adf2dc1 100644 --- a/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java +++ b/src/main/java/com/github/fabioticconi/alone/screens/MapScreen.java @@ -57,9 +57,10 @@ void regenerate() final int seed = (int) (System.currentTimeMillis() / 1000); final float freq = 3f / Math.max(Options.MAP_SIZE_X, Options.MAP_SIZE_Y); - final HeightMap heightMap = new HeightMap().size(Options.MAP_SIZE_X, Options.MAP_SIZE_Y) - .island(0.85f) - .rivers(0.8f, 0.03f, 0.001f, 1); + final HeightMap heightMap = new HeightMap() + .size(Options.MAP_SIZE_X, Options.MAP_SIZE_Y) + .island(0.85f) + .rivers(0.8f, 0.03f, 0.001f, 1); heightMap.fractalNoise .seed(seed) From 8ce4b0ad87e8bc8786d7d8c156b9762fe794e8ee Mon Sep 17 00:00:00 2001 From: Fabio Ticconi Date: Wed, 28 Feb 2018 10:38:46 +0100 Subject: [PATCH 4/6] #34: started implementing shooting mechanic --- data/crafting.yml | 18 +- data/items.yml | 4 +- .../fabioticconi/alone/messages/ShootMsg.java | 51 +++++ .../alone/systems/ShootSystem.java | 189 ++++++++++++++++++ 4 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/github/fabioticconi/alone/messages/ShootMsg.java create mode 100644 src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java diff --git a/data/crafting.yml b/data/crafting.yml index df53828..8c05fa2 100644 --- a/data/crafting.yml +++ b/data/crafting.yml @@ -3,7 +3,7 @@ sharp-stone: sources: stone tools: stone -small-sharp-stone: +stone-knife: sources: sharp-stone tools: stone @@ -16,5 +16,17 @@ stone-axe: tools: stone stone-spear: - sources: [small-sharp-stone, trunk, vine] - tools: stone + sources: [stone-knife, trunk, vine] + tools: [stone-axe, stone-knife] + +arrow: + source: branch + tools: stone-knife + +stone-arrow: + source: [stone-knife, branch, vine] + tools: stone-knife + +bow: + source: [trunk, vine] + tools: [stone-axe, stone-knife] diff --git a/data/items.yml b/data/items.yml index 671f38e..83c8786 100644 --- a/data/items.yml +++ b/data/items.yml @@ -90,8 +90,8 @@ sharp-stone: blue: 88 alpha: 255 -small-sharp-stone: - name: a small, sharp stone +stone-knife: + name: a stone knife wearable: where: HANDS weapon: diff --git a/src/main/java/com/github/fabioticconi/alone/messages/ShootMsg.java b/src/main/java/com/github/fabioticconi/alone/messages/ShootMsg.java new file mode 100644 index 0000000..99c3a93 --- /dev/null +++ b/src/main/java/com/github/fabioticconi/alone/messages/ShootMsg.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015-2018 Fabio Ticconi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package com.github.fabioticconi.alone.messages; + +import com.github.fabioticconi.alone.constants.Side; + +import java.awt.*; + +/** + * Author: Fabio Ticconi + * Date: 01/11/17 + */ +public class ShootMsg extends AbstractMessage +{ + public final String item; + public final Side at; + + public ShootMsg(final String item, final Side at) + { + this.item = item; + this.at = at; + } + + @Override + public String format() + { + fgCol = Color.RED; + + return String.format("%s %s %s towards %s", + actor, + thirdPerson ? "shoots" : "shoot", + item.toLowerCase(), + at.toString()); + } +} diff --git a/src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java new file mode 100644 index 0000000..fa3021b --- /dev/null +++ b/src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2015-2018 Fabio Ticconi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package com.github.fabioticconi.alone.systems; + +import com.artemis.ComponentMapper; +import com.github.fabioticconi.alone.components.*; +import com.github.fabioticconi.alone.components.actions.ActionContext; +import com.github.fabioticconi.alone.components.attributes.Agility; +import com.github.fabioticconi.alone.components.attributes.Strength; +import com.github.fabioticconi.alone.constants.Side; +import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.messages.CannotMsg; +import com.github.fabioticconi.alone.messages.ShootMsg; +import com.github.fabioticconi.alone.utils.Coords; +import net.mostlyoriginal.api.system.core.PassiveSystem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import rlforj.math.Point; + +import java.util.EnumSet; +import java.util.List; + +/** + * Author: Fabio Ticconi + * Date: 28/02/18 + */ +public class ShootSystem extends PassiveSystem +{ + static final Logger log = LoggerFactory.getLogger(ThrowSystem.class); + + ComponentMapper mInventory; + ComponentMapper mSpeed; + ComponentMapper mTarget; + ComponentMapper mPos; + ComponentMapper mPath; + ComponentMapper mStrength; + ComponentMapper mAgility; + ComponentMapper mName; + ComponentMapper mEquip; + + StaminaSystem sStamina; + BumpSystem sBump; + ItemSystem sItem; + MessageSystem msg; + MapSystem map; + + public ActionContext shootAt(final int actorId) + { + final ShootAction a = new ShootAction(); + + a.actorId = actorId; + + return a; + } + + public class ShootAction extends ActionContext + { + public List path; + + @Override + public boolean tryAction() + { + final Target t = mTarget.get(actorId); + + if (t == null) + { + msg.send(actorId, new CannotMsg("shoot", "without a target")); + + return false; + } + + final Position p = mPos.get(actorId); + + if (p.equals(t.pos)) + { + msg.send(actorId, new CannotMsg("shoot", "here!")); + + return false; + } + + final Inventory inventory = mInventory.get(actorId); + + if (inventory == null) + return false; + + // FIXME: bow is not a weapon, and arrows are a special type of weapon so we can't use this + // function + + final int weaponId = sItem.getWeapon(actorId, EnumSet.allOf(WeaponType.class), true); + + if (weaponId < 0) + { + msg.send(actorId, new CannotMsg("shoot", "without a weapon equipped")); + + return false; + } + + // shooting point-blank + if (Coords.distanceChebyshev(p.x, p.y, t.pos.x, t.pos.y) == 1) + { + // TODO the arrow must be shot + } + else + { + path = map.getLineOfSight(p.x, p.y, t.pos.x, t.pos.y); + + if (path == null || path.size() < 2) + { + log.warn("path not found or empty"); + + return false; + } + + // first index is the current position + path.remove(0); + } + + // TODO: add only arrow + targets.add(weaponId); + + // target position is not included + path.add(new Point(t.pos.x, t.pos.y)); + + delay = 0.5f; + cost = 1.5f; + + msg.send(actorId, new ShootMsg(mName.get(weaponId).name, Side.getSide(p.x, p.y, t.pos.x, t.pos.y))); + + return true; + } + + @Override + public void doAction() + { + if (targets.size() != 1) + return; + + final int arrowId = targets.get(0); + + final Point p2 = path.get(0); + + if (map.isFree(p2.x, p2.y)) + { + final Inventory inventory = mInventory.get(actorId); + + // we are throwing away the arrow, so we don't have it anymore + inventory.items.removeValue(arrowId); + + // how long does it take the arrow to move one step? + final float cooldown = 0.01f; // faster than throwing + + mSpeed.create(arrowId).set(cooldown); + mPath.create(arrowId).set(cooldown, path); + mPos.create(arrowId).set(p2.x, p2.y); + + // strength and agility of shooter are passed on to arrow. + // effects: the arrow will hit more likely with high agility, and do more damage with high strength. + mStrength.create(arrowId).value = mStrength.get(actorId).value; + mAgility.create(arrowId).value = mAgility.get(actorId).value; + + // at this point it really happened: the weapon is flying at its new position. + // it's an obstacle, so it will bump against whatever it finds + map.obstacles.set(arrowId, p2.x, p2.y); + } + else + { + // TODO: must shoot at point-blank + } + + sStamina.consume(actorId, cost); + } + } +} From 48b71eb7a7fd07d01fcfe192300e0db66cb14db3 Mon Sep 17 00:00:00 2001 From: Fabio Ticconi Date: Fri, 2 Mar 2018 23:18:27 +0100 Subject: [PATCH 5/6] #34: finished shooting mechanic via throwing hack. Throwing is a bit buggy though --- data/crafting.yml | 6 +- data/items.yml | 7 + .../fabioticconi/alone/components/Ammo.java | 40 ++++ .../fabioticconi/alone/components/Armour.java | 16 +- .../fabioticconi/alone/components/Weapon.java | 8 +- .../{WeaponType.java => DamageType.java} | 5 +- .../alone/screens/PlayScreen.java | 8 +- .../alone/systems/AttackSystem.java | 22 +- .../alone/systems/CrushSystem.java | 4 +- .../alone/systems/ItemSystem.java | 42 ++-- .../alone/systems/ShootSystem.java | 189 ------------------ .../alone/systems/ThrowSystem.java | 29 ++- .../alone/systems/TreeSystem.java | 4 +- 13 files changed, 145 insertions(+), 235 deletions(-) create mode 100644 src/main/java/com/github/fabioticconi/alone/components/Ammo.java rename src/main/java/com/github/fabioticconi/alone/constants/{WeaponType.java => DamageType.java} (94%) delete mode 100644 src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java diff --git a/data/crafting.yml b/data/crafting.yml index 8c05fa2..31f287f 100644 --- a/data/crafting.yml +++ b/data/crafting.yml @@ -20,13 +20,13 @@ stone-spear: tools: [stone-axe, stone-knife] arrow: - source: branch + sources: branch tools: stone-knife stone-arrow: - source: [stone-knife, branch, vine] + sources: [stone-knife, branch, vine] tools: stone-knife bow: - source: [trunk, vine] + sources: [trunk, vine] tools: [stone-axe, stone-knife] diff --git a/data/items.yml b/data/items.yml index 83c8786..0855fe6 100644 --- a/data/items.yml +++ b/data/items.yml @@ -155,6 +155,8 @@ arrow: weapon: damageType: POINT damage: 2 + ammo: + usableBy: bow sprite: c: 196 col: @@ -168,6 +170,8 @@ stone-arrow: weapon: damageType: POINT damage: 3 + ammo: + usableBy: bow sprite: c: 26 col: @@ -180,6 +184,9 @@ bow: name: a simple bow wearable: where: HANDS + weapon: + damageType: SHOOTER + damage: 1 sprite: c: '(' col: diff --git a/src/main/java/com/github/fabioticconi/alone/components/Ammo.java b/src/main/java/com/github/fabioticconi/alone/components/Ammo.java new file mode 100644 index 0000000..6724db5 --- /dev/null +++ b/src/main/java/com/github/fabioticconi/alone/components/Ammo.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015-2018 Fabio Ticconi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +package com.github.fabioticconi.alone.components; + +import com.artemis.Component; + +/** + * Author: Fabio Ticconi + * Date: 02/03/18 + */ +public class Ammo extends Component +{ + public String usableBy; + + public Ammo() + { + + } + + public Ammo(final String usableBy) + { + this.usableBy = usableBy; + } +} diff --git a/src/main/java/com/github/fabioticconi/alone/components/Armour.java b/src/main/java/com/github/fabioticconi/alone/components/Armour.java index 12577b5..ff2dce4 100644 --- a/src/main/java/com/github/fabioticconi/alone/components/Armour.java +++ b/src/main/java/com/github/fabioticconi/alone/components/Armour.java @@ -19,7 +19,7 @@ package com.github.fabioticconi.alone.components; import com.artemis.Component; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; import java.util.EnumMap; @@ -29,22 +29,22 @@ */ public class Armour extends Component { - // TODO we can improve this by using a primitive float array and WeaponType ordinals as indeces. + // TODO we can improve this by using a primitive float array and DamageType ordinals as indeces. // which is what EnumMap does internally. We'd avoid autoboxing. - public final EnumMap defences; + public final EnumMap defences; public Armour() { - this.defences = new EnumMap<>(WeaponType.class); + this.defences = new EnumMap<>(DamageType.class); } public void set(final float slash, final float point, final float blunt, final float natural) { - this.defences.put(WeaponType.SLASH, slash); - this.defences.put(WeaponType.POINT, point); - this.defences.put(WeaponType.BLUNT, blunt); + this.defences.put(DamageType.SLASH, slash); + this.defences.put(DamageType.POINT, point); + this.defences.put(DamageType.BLUNT, blunt); // a generic type for animal attacks - this.defences.put(WeaponType.NATURAL, natural); + this.defences.put(DamageType.NATURAL, natural); } } diff --git a/src/main/java/com/github/fabioticconi/alone/components/Weapon.java b/src/main/java/com/github/fabioticconi/alone/components/Weapon.java index ffae2e5..981c090 100644 --- a/src/main/java/com/github/fabioticconi/alone/components/Weapon.java +++ b/src/main/java/com/github/fabioticconi/alone/components/Weapon.java @@ -19,7 +19,7 @@ package com.github.fabioticconi.alone.components; import com.artemis.Component; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; /** * Author: Fabio Ticconi @@ -27,7 +27,7 @@ */ public class Weapon extends Component { - public WeaponType damageType; + public DamageType damageType; public float damage; public Weapon() @@ -35,12 +35,12 @@ public Weapon() } - public Weapon(final WeaponType damageType, final float damage) + public Weapon(final DamageType damageType, final float damage) { set(damageType, damage); } - public void set(final WeaponType damageType, final float damage) + public void set(final DamageType damageType, final float damage) { this.damageType = damageType; this.damage = damage; diff --git a/src/main/java/com/github/fabioticconi/alone/constants/WeaponType.java b/src/main/java/com/github/fabioticconi/alone/constants/DamageType.java similarity index 94% rename from src/main/java/com/github/fabioticconi/alone/constants/WeaponType.java rename to src/main/java/com/github/fabioticconi/alone/constants/DamageType.java index 8861d7d..cf3e8fe 100644 --- a/src/main/java/com/github/fabioticconi/alone/constants/WeaponType.java +++ b/src/main/java/com/github/fabioticconi/alone/constants/DamageType.java @@ -22,10 +22,11 @@ * Author: Fabio Ticconi * Date: 04/11/17 */ -public enum WeaponType +public enum DamageType { SLASH, POINT, BLUNT, - NATURAL + NATURAL, + SHOOTER } diff --git a/src/main/java/com/github/fabioticconi/alone/screens/PlayScreen.java b/src/main/java/com/github/fabioticconi/alone/screens/PlayScreen.java index cb00f04..f56eb45 100644 --- a/src/main/java/com/github/fabioticconi/alone/screens/PlayScreen.java +++ b/src/main/java/com/github/fabioticconi/alone/screens/PlayScreen.java @@ -26,8 +26,8 @@ import com.github.fabioticconi.alone.Main; import com.github.fabioticconi.alone.components.*; import com.github.fabioticconi.alone.components.attributes.Sight; +import com.github.fabioticconi.alone.constants.DamageType; import com.github.fabioticconi.alone.constants.Side; -import com.github.fabioticconi.alone.constants.WeaponType; import com.github.fabioticconi.alone.messages.AbstractMessage; import com.github.fabioticconi.alone.messages.CannotMsg; import com.github.fabioticconi.alone.messages.Msg; @@ -193,7 +193,7 @@ else if (keys.get(KeyEvent.VK_T)) { keys.clear(); - final int weaponId = sItems.getWeapon(playerId, EnumSet.allOf(WeaponType.class), true); + final int weaponId = sItems.getWeapon(playerId, EnumSet.allOf(DamageType.class), true); if (weaponId < 0) { @@ -204,6 +204,10 @@ else if (keys.get(KeyEvent.VK_T)) return 0f; } + + Main.pause(); + + screen.select(LookScreen.class); } else if (keys.get(KeyEvent.VK_W)) { diff --git a/src/main/java/com/github/fabioticconi/alone/systems/AttackSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/AttackSystem.java index cf7f624..cc8dfc9 100644 --- a/src/main/java/com/github/fabioticconi/alone/systems/AttackSystem.java +++ b/src/main/java/com/github/fabioticconi/alone/systems/AttackSystem.java @@ -25,7 +25,7 @@ import com.github.fabioticconi.alone.components.attributes.Agility; import com.github.fabioticconi.alone.components.attributes.Skin; import com.github.fabioticconi.alone.components.attributes.Strength; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; import com.github.fabioticconi.alone.messages.DamageMsg; import com.github.fabioticconi.alone.messages.KillMsg; import com.github.fabioticconi.alone.messages.MissMsg; @@ -35,6 +35,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.EnumSet; import java.util.Random; /** @@ -137,23 +138,28 @@ public void doAction() if (r.nextFloat() < toHit) { - float damage = cStrength.value + 2f; - float armour = tSkin.value; - - // assuming the actor is unharmed, we use a generic "natural" attack - WeaponType dmgType = WeaponType.NATURAL; + float damage = cStrength.value + 2f; + float armour = tSkin.value; + DamageType dmgType = DamageType.NATURAL; // the weapon damage is added to the strength-based one, so that creatures // wielding weapons can overcome stronger, unharmed creatures - final int weaponId = sItem.getWeapon(actorId); + final int weaponId = sItem.getWeapon(actorId, EnumSet.allOf(DamageType.class), true); if (weaponId >= 0) { final Weapon w = mWeapon.get(weaponId); damage += w.damage; dmgType = w.damageType; } + // or maybe we ARE a weapon (eg, if thrown or shot) + else if (mWeapon.has(actorId)) + { + final Weapon w = mWeapon.get(actorId); + damage += w.damage; + dmgType = w.damageType; + } - final int armourId = sItem.getArmour(targetId); + final int armourId = sItem.getArmour(targetId, true); if (armourId >= 0) { final Armour a = mArmour.get(armourId); diff --git a/src/main/java/com/github/fabioticconi/alone/systems/CrushSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/CrushSystem.java index bcab54e..7d4e288 100644 --- a/src/main/java/com/github/fabioticconi/alone/systems/CrushSystem.java +++ b/src/main/java/com/github/fabioticconi/alone/systems/CrushSystem.java @@ -25,7 +25,7 @@ import com.github.fabioticconi.alone.components.Weapon; import com.github.fabioticconi.alone.components.actions.ActionContext; import com.github.fabioticconi.alone.components.attributes.Strength; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; import com.github.fabioticconi.alone.messages.CannotMsg; import com.github.fabioticconi.alone.messages.CrushMsg; import net.mostlyoriginal.api.system.core.PassiveSystem; @@ -77,7 +77,7 @@ public boolean tryAction() if (targetId < 0 || !mCrush.has(targetId)) return false; - final int hammerId = sItem.getWeapon(actorId, EnumSet.of(WeaponType.BLUNT), true); + final int hammerId = sItem.getWeapon(actorId, EnumSet.of(DamageType.BLUNT), true); if (hammerId < 0) { diff --git a/src/main/java/com/github/fabioticconi/alone/systems/ItemSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/ItemSystem.java index 6d675e8..c85da37 100644 --- a/src/main/java/com/github/fabioticconi/alone/systems/ItemSystem.java +++ b/src/main/java/com/github/fabioticconi/alone/systems/ItemSystem.java @@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fabioticconi.alone.components.*; import com.github.fabioticconi.alone.components.actions.ActionContext; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; import com.github.fabioticconi.alone.messages.CannotMsg; import com.github.fabioticconi.alone.messages.DropMsg; import com.github.fabioticconi.alone.messages.EquipMsg; @@ -58,6 +58,7 @@ public class ItemSystem extends PassiveSystem ComponentMapper mArmour; ComponentMapper mName; ComponentMapper mObstacle; + ComponentMapper mAmmo; MessageSystem msg; MapSystem map; @@ -176,6 +177,8 @@ public int makeItem(final String tag) edit.add(template.crushable); if (template.cuttable != null) edit.add(template.cuttable); + if (template.ammo != null) + edit.add(template.ammo); return id; } @@ -209,11 +212,6 @@ public EquipAction equip(final int actorId, final int targetId) return a; } - public int getArmour(final int entityId) - { - return getArmour(entityId, true); - } - public int getArmour(final int entityId, final boolean onlyEquipped) { final Inventory items = mInventory.get(entityId); @@ -233,7 +231,7 @@ public int getArmour(final int entityId, final boolean onlyEquipped) continue; } - // we might only want an equipped weapon + // we might only want a worn armour if (!mArmour.has(itemId) || (onlyEquipped && !mEquip.has(itemId))) continue; @@ -268,17 +266,36 @@ public int getItem(final int entityId, final String tag, final boolean onlyEquip return -1; } - public int getWeapon(final int entityId) + public int getAmmo(final int entityId, final String usableBy) { - return getWeapon(entityId, true); + final Inventory items = mInventory.get(entityId); + + if (items == null) + return -1; + + final int[] data = items.items.getData(); + for (int i = 0, size = items.items.size(); i < size; i++) + { + final int itemId = data[i]; + + if (!mAmmo.has(itemId)) + continue; + + final Ammo ammo = mAmmo.get(itemId); + + if (ammo.usableBy.equals(usableBy)) + return itemId; + } + + return -1; } public int getWeapon(final int entityId, final boolean onlyEquipped) { - return getWeapon(entityId, EnumSet.allOf(WeaponType.class), onlyEquipped); + return getWeapon(entityId, EnumSet.allOf(DamageType.class), onlyEquipped); } - public int getWeapon(final int entityId, final EnumSet weaponTypes, final boolean onlyEquipped) + public int getWeapon(final int entityId, final EnumSet damageTypes, final boolean onlyEquipped) { final Inventory items = mInventory.get(entityId); @@ -296,7 +313,7 @@ public int getWeapon(final int entityId, final EnumSet weaponTypes, final Weapon weapon = mWeapon.get(itemId); - if (weaponTypes.contains(weapon.damageType)) + if (damageTypes.contains(weapon.damageType)) return itemId; } @@ -314,6 +331,7 @@ public static class ItemTemplate public Obstacle obstacle; public Crushable crushable; public Cuttable cuttable; + public Ammo ammo; } public class GetAction extends ActionContext diff --git a/src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java deleted file mode 100644 index fa3021b..0000000 --- a/src/main/java/com/github/fabioticconi/alone/systems/ShootSystem.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2015-2018 Fabio Ticconi - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -package com.github.fabioticconi.alone.systems; - -import com.artemis.ComponentMapper; -import com.github.fabioticconi.alone.components.*; -import com.github.fabioticconi.alone.components.actions.ActionContext; -import com.github.fabioticconi.alone.components.attributes.Agility; -import com.github.fabioticconi.alone.components.attributes.Strength; -import com.github.fabioticconi.alone.constants.Side; -import com.github.fabioticconi.alone.constants.WeaponType; -import com.github.fabioticconi.alone.messages.CannotMsg; -import com.github.fabioticconi.alone.messages.ShootMsg; -import com.github.fabioticconi.alone.utils.Coords; -import net.mostlyoriginal.api.system.core.PassiveSystem; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import rlforj.math.Point; - -import java.util.EnumSet; -import java.util.List; - -/** - * Author: Fabio Ticconi - * Date: 28/02/18 - */ -public class ShootSystem extends PassiveSystem -{ - static final Logger log = LoggerFactory.getLogger(ThrowSystem.class); - - ComponentMapper mInventory; - ComponentMapper mSpeed; - ComponentMapper mTarget; - ComponentMapper mPos; - ComponentMapper mPath; - ComponentMapper mStrength; - ComponentMapper mAgility; - ComponentMapper mName; - ComponentMapper mEquip; - - StaminaSystem sStamina; - BumpSystem sBump; - ItemSystem sItem; - MessageSystem msg; - MapSystem map; - - public ActionContext shootAt(final int actorId) - { - final ShootAction a = new ShootAction(); - - a.actorId = actorId; - - return a; - } - - public class ShootAction extends ActionContext - { - public List path; - - @Override - public boolean tryAction() - { - final Target t = mTarget.get(actorId); - - if (t == null) - { - msg.send(actorId, new CannotMsg("shoot", "without a target")); - - return false; - } - - final Position p = mPos.get(actorId); - - if (p.equals(t.pos)) - { - msg.send(actorId, new CannotMsg("shoot", "here!")); - - return false; - } - - final Inventory inventory = mInventory.get(actorId); - - if (inventory == null) - return false; - - // FIXME: bow is not a weapon, and arrows are a special type of weapon so we can't use this - // function - - final int weaponId = sItem.getWeapon(actorId, EnumSet.allOf(WeaponType.class), true); - - if (weaponId < 0) - { - msg.send(actorId, new CannotMsg("shoot", "without a weapon equipped")); - - return false; - } - - // shooting point-blank - if (Coords.distanceChebyshev(p.x, p.y, t.pos.x, t.pos.y) == 1) - { - // TODO the arrow must be shot - } - else - { - path = map.getLineOfSight(p.x, p.y, t.pos.x, t.pos.y); - - if (path == null || path.size() < 2) - { - log.warn("path not found or empty"); - - return false; - } - - // first index is the current position - path.remove(0); - } - - // TODO: add only arrow - targets.add(weaponId); - - // target position is not included - path.add(new Point(t.pos.x, t.pos.y)); - - delay = 0.5f; - cost = 1.5f; - - msg.send(actorId, new ShootMsg(mName.get(weaponId).name, Side.getSide(p.x, p.y, t.pos.x, t.pos.y))); - - return true; - } - - @Override - public void doAction() - { - if (targets.size() != 1) - return; - - final int arrowId = targets.get(0); - - final Point p2 = path.get(0); - - if (map.isFree(p2.x, p2.y)) - { - final Inventory inventory = mInventory.get(actorId); - - // we are throwing away the arrow, so we don't have it anymore - inventory.items.removeValue(arrowId); - - // how long does it take the arrow to move one step? - final float cooldown = 0.01f; // faster than throwing - - mSpeed.create(arrowId).set(cooldown); - mPath.create(arrowId).set(cooldown, path); - mPos.create(arrowId).set(p2.x, p2.y); - - // strength and agility of shooter are passed on to arrow. - // effects: the arrow will hit more likely with high agility, and do more damage with high strength. - mStrength.create(arrowId).value = mStrength.get(actorId).value; - mAgility.create(arrowId).value = mAgility.get(actorId).value; - - // at this point it really happened: the weapon is flying at its new position. - // it's an obstacle, so it will bump against whatever it finds - map.obstacles.set(arrowId, p2.x, p2.y); - } - else - { - // TODO: must shoot at point-blank - } - - sStamina.consume(actorId, cost); - } - } -} diff --git a/src/main/java/com/github/fabioticconi/alone/systems/ThrowSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/ThrowSystem.java index 0f84a67..973095a 100644 --- a/src/main/java/com/github/fabioticconi/alone/systems/ThrowSystem.java +++ b/src/main/java/com/github/fabioticconi/alone/systems/ThrowSystem.java @@ -24,7 +24,7 @@ import com.github.fabioticconi.alone.components.attributes.Agility; import com.github.fabioticconi.alone.components.attributes.Strength; import com.github.fabioticconi.alone.constants.Side; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; import com.github.fabioticconi.alone.messages.CannotMsg; import com.github.fabioticconi.alone.messages.ThrowMsg; import com.github.fabioticconi.alone.utils.Coords; @@ -53,6 +53,7 @@ public class ThrowSystem extends PassiveSystem ComponentMapper mAgility; ComponentMapper mName; ComponentMapper mEquip; + ComponentMapper mWeapon; StaminaSystem sStamina; BumpSystem sBump; @@ -73,6 +74,8 @@ public class ThrowAction extends ActionContext { public List path; + float cooldown; + @Override public boolean tryAction() { @@ -99,7 +102,7 @@ public boolean tryAction() if (inventory == null) return false; - final int weaponId = sItem.getWeapon(actorId, EnumSet.allOf(WeaponType.class), true); + int weaponId = sItem.getWeapon(actorId, EnumSet.allOf(DamageType.class), true); if (weaponId < 0) { @@ -108,6 +111,27 @@ public boolean tryAction() return false; } + cooldown = 0.06f; + + final Weapon weapon = mWeapon.get(weaponId); + + if (weapon.damageType == DamageType.SHOOTER) + { + final Name bowName = mName.get(weaponId); + + // the ammo will be thrown at the next step, not the bow + weaponId = sItem.getAmmo(actorId, bowName.tag); + + cooldown = 0.04f; + + if (weaponId < 0) + { + msg.send(actorId, new CannotMsg("shoot", "with only ".concat(bowName.name))); + + return false; + } + } + // it's close enough to strike, so we transform this in a bump action if (Coords.distanceChebyshev(p.x, p.y, t.pos.x, t.pos.y) == 1) { @@ -163,7 +187,6 @@ public void doAction() // how long does it take the object to move one step? // TODO should be based on thrower's strength and weapon characteristics, maybe - final float cooldown = 0.05f; mSpeed.create(weaponId).set(cooldown); mPath.create(weaponId).set(cooldown, path); diff --git a/src/main/java/com/github/fabioticconi/alone/systems/TreeSystem.java b/src/main/java/com/github/fabioticconi/alone/systems/TreeSystem.java index 0945322..ccde487 100644 --- a/src/main/java/com/github/fabioticconi/alone/systems/TreeSystem.java +++ b/src/main/java/com/github/fabioticconi/alone/systems/TreeSystem.java @@ -24,7 +24,7 @@ import com.github.fabioticconi.alone.components.Speed; import com.github.fabioticconi.alone.components.actions.ActionContext; import com.github.fabioticconi.alone.components.attributes.Strength; -import com.github.fabioticconi.alone.constants.WeaponType; +import com.github.fabioticconi.alone.constants.DamageType; import com.github.fabioticconi.alone.messages.CannotMsg; import com.github.fabioticconi.alone.messages.CutMsg; import net.mostlyoriginal.api.system.core.PassiveSystem; @@ -75,7 +75,7 @@ public boolean tryAction() if (!mCuttable.has(treeId)) return false; - final int axeId = sItem.getWeapon(actorId, EnumSet.of(WeaponType.SLASH), false); + final int axeId = sItem.getWeapon(actorId, EnumSet.of(DamageType.SLASH), false); if (axeId < 0) { From 9a0eabf44501e7a903e2fe0286dd2f80f1fe929a Mon Sep 17 00:00:00 2001 From: Fabio Ticconi Date: Sat, 3 Mar 2018 10:51:14 +0100 Subject: [PATCH 6/6] another middle release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index feddf25..f7ef509 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ com.github.fabio-t alone-rl - 0.3.0-SNAPSHOT + 0.2.7 jar AloneRL