# How to handle a different kinds of weapon in a single component and system in entity system?

A weapon can be used as melee or range weapon, it can be thrown, toss, fired, shoot, cast (a projectile) or use to slash, bash, stab . How do I apply these to entity-system? my first approach is to create an enum class of WeaponType, a melee or range.

public enum WeaponType {
MELEE,
RANGE
}

public interface Weapon {
void use();
}


Then I've create a weapon component and add weapon type data, to determine its type. For melee a weapon, it needs to have a method that handles different kind of "attack motion" like slash, bash, stab. For range weapon, it needs to have a container, factory and a method that handles different kinds of "projectile motion" like shoot, fire, throw, toss etc.. Now the problem is how could I create a method for different kinds of projectile motion, remember I am specifically using Ashley ECS framework

public class WeaponComponent implements Component {
public Weapon weapon;
public WeaponType type;
// if weapon type is melee, use the below data
public Container container // holds the created projectile
public Factory factory // creates a different kinds of projectile object
}

// or create seperately???

public class MeleeWeaponComponent implements Component {
... different kinds of method also like slash, bash, stab
}

public class RangeWeaponComponent implements Component {
... Factory and Container
... different kinds of projectile motion?
}


In this idea, I can use abstract or interface but I think abstraction or is not recommended.

[Combined data suggestion] by @Ryanwhite and me

• Blue line is area of effect angle covered
• Green line is distance covered
• Red point is the target point

public class WeaponComponent implements Component {
public Ray ray // to handle collisions
public float aoe; // 0.5 for melee, more than 0.5 for other weapon
public float aoeAngleCovered;
public float aoeAngle
public Ammo[] // 0 for melee, 1 or more for other weapon
}

• Although i do not understand your question very well, i will try to help. You can use a RayCast for weapons, this allows all weapons to use one set of attributes, so range etc. Now you would have a melee weapon use the range, but set it to set 0.5. This would give the melee weapon a low range, making it seem like its melee (This would be played with allot btw) then from this your weapons all use the same attributes. It saves on creating methods for different types of weapons. Most games use a system like this, as it is really easy to create new weapons on the fly. As for stab and slash 1/2 – Ryan white Aug 15 '16 at 8:18
• 2/2 and slash just use different animations, and if the player uses that melee type, i.e right clicks a knife to stab, the damage would be different but the animation longer. – Ryan white Aug 15 '16 at 8:18
• @Ryanwhite Thank you for your answer, you should also put that as answer. Actually your on the right path you answered 2/3 of it, the last part is how do I create an abstract of weapon class so I could override each weapon usage, but I think abstraction is not recommended in ECS – ronscript Aug 15 '16 at 8:55
• @Ryanwhite I've also updated the title of this question to "How to handle a different kinds of weapon in a single component and system in entity system?" – ronscript Aug 15 '16 at 8:58
• I am not familiar with the Ashley ECS framework. Does it allow more than one component of the same type on an entity? – Philipp Aug 15 '16 at 9:01

You can use a RayCast for weapons, this allows all weapons to use one set of attributes, so range etc. Now you would have a melee weapon use the range, but set it to set 0.5. This would give the melee weapon a low range, making it seem like its melee (This would be played with allot btw) then from this your weapons all use the same attributes. It saves on creating methods for different types of weapons. Most games use a system like this, as it is really easy to create new weapons on the fly. As for stab and slash and slash just use different animations, and if the player uses that melee type, i.e right clicks a knife to stab, the damage would be different but the animation longer.

The above is the original comment i made

To expand on this comment, You can have one set of variables, say range and damage and ammo, then set the variables according to the weapon. For melee just set the ammo to something like -1 (Should cause it to just be unlimited) and the damage for each mouse click to be different, and play different animations.

The raycast will handle most of the calculation for you, you just gotta tell it what to do haha.

Hope this helps

Edit

[Combined data suggestion] by @Ryanwhite and @ronscript

Blue line is area of effect angle covered
Green line is distance covered
Red point is the target point


public class WeaponComponent implements Component {
public Ray ray // to handle collisions
public float aoe; // This would be the range of different weapons, you could stagger them for range drop etc.
public float aoeAngleCovered;
public float aoeAngle
public Ammo[] // Set ammo to 0 and give exception to melee weapons to ignore ammo.
}

• I've edited the article and combine your answer into a components, now it seems you answered it accurately 3/3. – ronscript Aug 15 '16 at 9:25
• Ok cool thank you, btw for range i think 0.5 is what we used, but you will have to tweak it for your use. – Ryan white Aug 15 '16 at 9:27
• I will mark this as answer later, I will edit your answer and combine my idea as well – ronscript Aug 15 '16 at 9:28
• well i hope you get everything working ok :) – Ryan white Aug 15 '16 at 9:29
• If you have time, can you edit your answer and use my updated details above? thanks :). Cause i'll be leaving now and come back later, so if you could not make, it i'll be the one to do it – ronscript Aug 15 '16 at 9:40

(Do note: this answer looks at the problem from a completely different angle.)

Looking at it another, more abstract way: Ranged weapons are just emitters for projectiles (or, in the case of spears, can be projectiles themselves). Meelee weapons and projectiles are physical objects (or have parts) which cause damage upon colliding with damageable entities (like npcs or crates).

Under a system like that, the swinging animation of a blade causing the blade edge to connect/collide with an damageable entity like an enemy is enough to cause damage.

Similarly, different modes of attack could be mapped to different actions/inputs, e.g. firing a rifle vs. stabbing with the bayonet.

A spear could be used to stab by playing the stab animation (which would thrust it forward), or thrown by removing it from the players inventory and spawning it in the world near the players hand, accelerated towards the direction of view (with a slight angle upwards to compensate for the ballistic curve).

Similarly, armor could be an entity attached to other entities, which cancels or changes a weapons/projectiles attack animation upon collision with a weapon.

Ofc, using ray casts for everything is a lot easier, both in difficulty and ease of computation.

• I like the theory behind a system like this, but it leads to allot of complications. But i do like the idea, and i always wanted to experiment with it. – Ryan white Sep 1 '16 at 7:59