B Tutorial Module System Making An Item Throwable

Currently viewing this thread:

Scarebear

Recruit
WB
Best answers
0
Preface: As I take a break from refining the new addition to my module, with spectacular help from Somebody, and many others who've written great tutorials, I figured it might be nice to try and give a little something back. No, this is not something overly complicated, rather almost anyone into the basics of development will have grasped, or know how to do this already. I am not bringing something new to the table. However, I haven't seen any actual written tutorial around here truly focusing on this, and I've seen the question raised a few times. If I'm mistaken, then by all means, trash bin this topic. If not, I hope that I can provide a quality reference for those who want more things to throw at their foes.

Introduction: Sometimes, one just needs to be able throw things at an opponent. That satisfying feeling as a peasant, when you've managed to Leonidas a pitch fork into a horseman passing by, or that last ditch attempt to save a friend from an encroaching foe who is out of melee's reach. Yes, things sometimes just need to be thrown. What things you ask? Many. Limited only by your imagination. But, before we get crazy (That comes at the end, I'm looking at you magical maul whom sticks in victims), let's focus on the little more down to earth. Keyword: Little.

Making an item throwable is not all that difficult really. Perhaps, for one item, whether from scratch (Scratch meaning creating an item's entry, not modeling, texturing, etc.) or using a pre-existing one, about 3-5 minutes. That time frame includes testing and things. This tutorial is written under the assumption that you've already setup your module, and that module_items.py is glaring at you from your taskbar.

However, if this is not the case, then I shall direct you to one of the many great guides sitting in the Unofficial Tutorials section:
http://forums.taleworlds.com/index.php/topic,113991.0.html

Anyways, without further ado, let us begin by making some spears and forks to throw.

The Guide:

Our first step is, we need to decide whether or not we want to turn the base item into a throwable, or create our own side versions so that any files relying on those base items won't have their functions changed, nor will AI by default be able to throw them. For this run-through, we're going to do the easier and less complicated route, and create side versions of these items. These are the two files we're going to want open while we work:

Module_items.py (For actually creating our item definitions.)
Module_scripts.py (This is for an ease of testing, where we'll temporarily add the item to a Multiplayer troop.)

So for Module_items.py, let's Ctrl-F (Search or Find) for this without quotes "items_end". Depending on how organized/disorganized your items file may or may not be, or just depending if your building off another module's source (Such as Diplomacy), it's going to be very hard to provide a generic place to insert this upcoming bit of code. So we'll just put it before that for now, then I'll explain what does what to the best of my ability. Quick note: I'm building off of the last Diplomacy Source, so my items may or may not look a little different in some areas. But the purpose of this tutorial is to provide the know-how on making something throwable, therefore breaking module boundaries.

Code:
["spear_thrown", "Spear", [("spear_h_2-15m",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
110 , weight(2.25)|difficulty(3)|spd_rtng(9:cool: | shoot_speed(33) | weapon_length(135)|thrust_damage(58 , pierce)|max_ammo(1),imodbits_polearm ],
["spear_melee", "Spear", [("spear_h_2-15m",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_wooden_parry, itc_staff|itcf_carry_spear,
110 , weight(1)|difficulty(0)|spd_rtng(9:cool: | weapon_length(135)|swing_damage(20 , blunt) | thrust_damage(26 , pierce),imodbits_polearm ],

So, first off, this may look like two items are being created, but in reality, it's one. Sort of. But let me explain the color coding first.

Red = This is your item ID. It's what will be prefixed with itm_ in other .py files, and how it will be referenced throughout your module.
Yellow = This is your item Name. It's what you will see in game when you look at in your inventory or in a shop for example.
Lime Green = This is your Mesh Name. It's essentially what model will be used for it.
Green = These are your item Flags, separated by |'s. This can tell the item what type it is, how it should function, whether it can knock someone down or should have a penalty with a shield, ect.
Orange = This area will dictate what animations are to be used with the item. More than one option can sometimes be found here.
Purple = This your item Value. How much the item will cost.
Blue = This is your item Stats. Such as how fast the projectile will fly, it's damage type or types, etc.
Maroon = This is your item Modifier. Whether there can be heavy, or cracked versions, etc.

Now with the color coding out of the way, I'll explain how these two entries equal one item. So for our spear_thrown, that is our actual item. The one that could be bought from a merchant or used in MP. You'll notice it has the item flag: itp_next_item_as_melee. That means that the next item defined will be used as it's melee version when X (Or whatever your change weapon mode key may be) is pressed. So for that second item, we typically don't want the itp_merchandise flag, so that we can't find it in shops.

We now have some reference, but let's look at how to set up and item to be thrown from scratch:
For sillyness and learning's sake, we're going to make a Maul throwable. So in our Module_items.py, let's Ctrl-F for "maul". Once we have it, let's copy that entry and put it down at the bottom where we're working right before items_end. Right now it should look like this:
Code:
["maul",         "Maul", [("maul_b",0)], itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced, itc_nodachi|itcf_carry_spear,
97 , weight(6)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],

["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],

]
Now, let's change our item ID, so as not to conflict with the original maul. We'll change it to "maul_thrown". Now before we go any further, we're going to want to copy our maul_thrown entry and paste it right below. We should be here:
Code:
["maul_thrown",         "Maul", [("maul_b",0)], itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced, itc_nodachi|itcf_carry_spear,
97 , weight(6)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],
["maul_thrown",         "Maul", [("maul_b",0)], itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced, itc_nodachi|itcf_carry_spear,
97 , weight(6)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],

["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],

]
Now, we'll change our second maul_thrown entry's ID to actually be maul_melee. So we have both our entries, let's begin turning the first one into actually being throwable. We have a lot of item flags we can get rid of for our _thrown entry, let's take a look:

itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced

Quite a few there we don't need, so let's take it down to this:

itp_crush_through|itp_merchandise|itp_can_knock_down |itp_primary

We're not quite done with our flags though, we still need to tell the item it's thrown, and that it has a melee version. We'll do this by adding itp_type_thrown and itp_next_item_as_melee to it's current flags end up like so:

itp_type_thrown|itp_crush_through|itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee

Let's see where we're at right now:
Code:
["maul_thrown",         "Maul", [("maul_b",0)], itp_type_thrown|itp_crush_through|itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee, itc_nodachi|itcf_carry_spear,
97 , weight(6)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],
["maul_melee",         "Maul", [("maul_b",0)], itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced, itc_nodachi|itcf_carry_spear,
97 , weight(6)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],

["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],

]
Next up is fixing the animations used for our maul_thrown. Where you see: itc_nodachi|itcf_carry_spear

We'll change it to simply be: itcf_throw_axe

For reference, there are four default types of throwing animations: itcf_throw_axe, itcf_throw_javelin, itcf_throw_knife, itcf_throw_stone. You can choose the one that best fits your needs. But for now, we'll do the axe as it looks semi-believable with our maul.

Now let's take a look at our difficulty stat. Currently it's 11. That was back when our maul was melee, therefore meaning that it required 11 strength. But now since it's thrown, that means it requires a power throw of 11. So let's drop that down to 3 for testing's sake. We need to add two more stats to our thrown version, then we'll look it over and see if we're done. The two stats we're adding is shoot_speed, and max_ammo. We're also going to remove it's swing damage and change it's thrust damage amount and type.

So for shoot_speed, I tend to do 75 divided by an item's weight. It's been good for me so far for balance and practicality, so let's see what we end up with. 12.5. We can round that up or down, I usually do down. So we'll say 12. This means we're going add the item stat: shoot_speed(12) into our stat array. Max_ammo is rather self explanatory, and we'll put it at 1 for now: max_ammo(1). We can remove the swing damage section entirely and change our thrust damage type to blunt. For finding our damage amount, I usually do an item's main form of damage times it's weight. Obviously for our maul, this is going to be a ridiculous number. But we're just learning, so it's alright. We end up with this as our throwing damage 216. These are quite a few steps, so let's do another check to see what we should look like by now:
Code:
["maul_thrown",         "Maul", [("maul_b",0)], itp_type_thrown|itp_crush_through|itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee, itcf_throw_axe,
97 , weight(6)|difficulty(3)|spd_rtng(83)|shoot_speed(12) | weapon_length(79)| thrust_damage(216 ,  blunt)|max_ammo(1),imodbits_mace ],
["maul_melee",         "Maul", [("maul_b",0)], itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced, itc_nodachi|itcf_carry_spear,
97 , weight(6)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],

["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],

]
We're almost done! Now the last change we have to do is set our maul_melee's weight to 1. After that, if we didn't mess anything up (I'm only human after all beep boop.), then we should be able to save our module_items.py, and move on to the module_scripts.py. This is our final check, the code you can copy/paste if you so choose to do to have a working, throwing maul:
Code:
["maul_thrown",         "Maul", [("maul_b",0)], itp_type_thrown|itp_crush_through|itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee, itcf_throw_axe,
97 , weight(6)|difficulty(3)|spd_rtng(83)|shoot_speed(12) | weapon_length(79)| thrust_damage(216 ,  blunt)|max_ammo(1),imodbits_mace ],
["maul_melee",         "Maul", [("maul_b",0)], itp_crush_through|itp_type_two_handed_wpn|itp_merchandise|itp_can_knock_down |itp_primary|itp_two_handed|itp_wooden_parry|itp_wooden_attack|itp_unbalanced, itc_nodachi|itcf_carry_spear,
97 , weight(1)|difficulty(11)|spd_rtng(83) | weapon_length(79)|swing_damage(36 , blunt) | thrust_damage(0 ,  pierce),imodbits_mace ],

["items_end", "Items End", [("shield_round_a",0)], 0, 0, 1, 0, 0],

]
Module_scripts.py
Our last step is to provide an easy form of testing the item. I prefer MP against bots to do so, so let's jump into module_scripts.py.
Let's Ctrl-F for:
Code:
(item_set_slot, "itm_throwing_axes", slot_item_multiplayer_item_class, multi_item_class_type_throwing_axe),
Somewhere around this code's location (Where ever your OCD pleases if you suffer like I do from it), you'll want to add this line in below it or above it:
Code:
(item_set_slot, "itm_maul_thrown", slot_item_multiplayer_item_class, multi_item_class_type_throwing_axe),
Already half way done. Let's scoot down and Ctrl-F for:
Code:
(call_script, "script_multiplayer_set_item_available_for_troop", "itm_light_throwing_axes", "trp_nord_veteran_multiplayer"),
This is where it gets a little more tricky. The items must be in order by their type, then by value. Like so:
Item with a value of 50
Item with a value of 150
etc.
So since our maul is technically defined as a throwing axe, we need to make sure it's snugly fit the appropriate place for it's value. Since we didn't change it for this learning experience, it's going to come before the itm_light_throwing_axes as it is the cheapest item thus far. We should end up with this if I lost you:
Code:
(call_script, "script_multiplayer_set_item_available_for_troop", "itm_maul_thrown", "trp_nord_veteran_multiplayer"),
(call_script, "script_multiplayer_set_item_available_for_troop", "itm_light_throwing_axes", "trp_nord_veteran_multiplayer"),


If all went well, we should be able to compile now, and host a multiplayer game with the Nord faction, playing as a Veteran and throw our maul at some people. I hope you've enjoyed this tutorial, I'll try and format it better. Before we go, here are some wise words from Somebody:
A couple of notes - two categories of throwing weapons are defined for multiplayer, multi_item_class_type_throwing and multi_item_class_type_throwing_axe. This puts them in different rows.

Also, if you don't care about compatibility with savegames, you can simply put the thrown version before the native melee versions so you don't use up two extra item spaces per weapon. There is no requirement for the item name to have _melee at the end or only 1.0 weight, which is purely for the sake of letting you run faster with it in melee mode I suspect.

As for the difference between itcf_throw_axe, itcf_throw_javelin, itcf_throw_knife, itcf_throw_stone, the difference is mainly in the animation (you can tweak them to have different speeds in module_animation). itcf_throw_axe (and maybe itcf_throw_knife, haven't checked) will also spin the item, while itcf_throw_stone won't leave a projectile behind when it hits something.

A final note regarding shoot_speed - it also affects damage (faster = higher damage when hit) and the range at which AI will start using them. spd_rtng lets you spam them. (Speaking of which, shoot_speed(30) is repeated twice in your war spear code).

As a bonus, here is the complete code for default spears to be throwable using this method.
Code:
#THROWING SPEARS BEGIN#
["pitch_fork_thrown", "Pitch Fork", [("pitch_fork",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
50 , weight(1.5)|difficulty(2)|spd_rtng(87) | shoot_speed(50) | weapon_length(154)|thrust_damage(33 , pierce)|max_ammo(1),imodbits_polearm ],
["pitch_fork_melee", "Pitch Fork", [("pitch_fork",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_penalty_with_shield|itp_wooden_parry,itc_staff,
50 , weight(1)|difficulty(0)|spd_rtng(87) | weapon_length(154)|swing_damage(16 , blunt) | thrust_damage(22 , pierce),imodbits_polearm ],
["military_fork_thrown", "Military Fork", [("military_fork",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
150 , weight(2)|difficulty(3)|spd_rtng(95) | shoot_speed(37) | weapon_length(135)|thrust_damage(60 , pierce)|max_ammo(1),imodbits_polearm ],
["military_fork_melee", "Military Fork", [("military_fork",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_wooden_parry,itc_staff,
150 , weight(1)|difficulty(0)|spd_rtng(95) | weapon_length(135)|swing_damage(15 , blunt) | thrust_damage(30 , pierce),imodbits_polearm ],
["battle_fork_thrown", "Battle Fork", [("battle_fork",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
250 , weight(2.2)|difficulty(4)|spd_rtng(90) | shoot_speed(34) | weapon_length(144)| thrust_damage(77 , pierce)|max_ammo(1),imodbits_polearm ],
["battle_fork_melee", "Battle Fork", [("battle_fork",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_wooden_parry,itc_staff,
250 , weight(1)|difficulty(0)|spd_rtng(90) | weapon_length(144)|swing_damage(15, blunt) | thrust_damage(35 , pierce),imodbits_polearm ],
["boar_spear_thrown", "Boar Spear", [("spear",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
55 , weight(1.5)|difficulty(2)|spd_rtng(90) | shoot_speed(50) | weapon_length(157)|thrust_damage(34 , pierce)|max_ammo(1),imodbits_polearm ],
["boar_spear_melee", "Boar Spear", [("spear",0)], itp_type_polearm| itp_primary|itp_penalty_with_shield|itp_wooden_parry,itc_staff|itcf_carry_spear,
55 , weight(1)|difficulty(0)|spd_rtng(90) | weapon_length(157)|swing_damage(26 , cut) | thrust_damage(23 , pierce),imodbits_polearm ],
["shortened_spear_thrown", "Shortened Spear", [("spear_g_1-9m",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
100 , weight(2.0)|difficulty(3)|spd_rtng(102) | shoot_speed(37) | weapon_length(120)|thrust_damage(50 , pierce)|max_ammo(1),imodbits_polearm ],
["shortened_spear_melee", "Shortened Spear", [("spear_g_1-9m",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_wooden_parry, itc_staff|itcf_carry_spear,
100 , weight(1)|difficulty(0)|spd_rtng(102) | weapon_length(120)|swing_damage(19 , blunt) | thrust_damage(25 , pierce),imodbits_polearm ],
["spear_thrown", "Spear", [("spear_h_2-15m",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
110 , weight(2.25)|difficulty(3)|spd_rtng(98) | shoot_speed(33) | weapon_length(135)|thrust_damage(58 , pierce)|max_ammo(1),imodbits_polearm ],
["spear_melee", "Spear", [("spear_h_2-15m",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_wooden_parry, itc_staff|itcf_carry_spear,
110 , weight(1)|difficulty(0)|spd_rtng(98) | weapon_length(135)|swing_damage(20 , blunt) | thrust_damage(26 , pierce),imodbits_polearm ],
["bamboo_spear_thrown", "Bamboo Spear", [("arabian_spear_a_3m",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
80 , weight(2.0)|difficulty(2)|spd_rtng(88) | shoot_speed(37) | weapon_length(200)|thrust_damage(40 , pierce)|max_ammo(1),imodbits_polearm ],
["bamboo_spear_melee", "Bamboo Spear", [("arabian_spear_a_3m",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_penalty_with_shield|itp_wooden_parry, itc_staff|itcf_carry_spear,
80 , weight(1)|difficulty(0)|spd_rtng(88) | weapon_length(200)|swing_damage(15 , blunt) | thrust_damage(20 , pierce),imodbits_polearm ],
["war_spear_thrown", "War Spear", [("spear_i_2-3m",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
200 , weight(2.5)|difficulty(3)|spd_rtng(95) | shoot_speed(30) | weapon_length(150)| thrust_damage(67 , pierce)|max_ammo(1),imodbits_polearm ],
["war_spear_melee", "War Spear", [("spear_i_2-3m",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_wooden_parry, itc_staff|itcf_carry_spear,
200 , weight(1)|difficulty(0)|spd_rtng(95) | weapon_length(150)|swing_damage(20 , blunt) | thrust_damage(27 , pierce),imodbits_polearm ],
["pike_thrown", "Pike", [("spear_a_3m",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
275 , weight(3.0)|difficulty(4)|spd_rtng(81) | shoot_speed(25) | weapon_length(245)|thrust_damage(78 , pierce)|max_ammo(1),imodbits_polearm ],
["pike_melee", "Pike", [("spear_a_3m",0)], itp_type_polearm| itp_cant_use_on_horseback|itp_primary|itp_penalty_with_shield|itp_wooden_parry|itp_two_handed, itc_cutting_spear,
275 , weight(1)|difficulty(0)|spd_rtng(81) | weapon_length(245)|swing_damage(16 , blunt) | thrust_damage(26 , pierce),imodbits_polearm ],
["ashwood_pike_thrown", "Ashwood Pike", [("pike",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
400 , weight(3.5)|difficulty(5)|spd_rtng(90) | shoot_speed(21) | weapon_length(170)|thrust_damage(101, pierce)|max_ammo(1),imodbits_polearm ],
["ashwood_pike_melee", "Ashwood Pike", [("pike",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_two_handed|itp_wooden_parry, itc_cutting_spear,
400 , weight(1)|difficulty(9)|spd_rtng(90) | weapon_length(170)|swing_damage(19 , blunt) | thrust_damage(29, pierce),imodbits_polearm ],
["awlpike_thrown", "Awlpike", [("awl_pike_b",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
265 , weight(2.25)|difficulty(4)|spd_rtng(92) | shoot_speed(33) | weapon_length(165)|thrust_damage(74 , pierce)|max_ammo(1),imodbits_polearm ],
["awlpike_melee", "Awlpike", [("awl_pike_b",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_penalty_with_shield|itp_wooden_parry, itc_cutting_spear|itcf_carry_spear,
265 , weight(1)|difficulty(0)|spd_rtng(92) | weapon_length(165)|swing_damage(20 , blunt) | thrust_damage(33 , pierce),imodbits_polearm ],
["awlpike_long_thrown", "Long Awlpike", [("awl_pike_a",0)], itp_type_thrown |itp_merchandise|itp_can_knock_down |itp_primary|itp_next_item_as_melee ,itcf_throw_javelin,
270 , weight(2.25)|difficulty(4)|spd_rtng(89) | shoot_speed(33) | weapon_length(185)|thrust_damage(72 , pierce)|max_ammo(1),imodbits_polearm ],
["awlpike_long_melee", "Long Awlpike", [("awl_pike_a",0)], itp_type_polearm|itp_offset_lance| itp_primary|itp_penalty_with_shield|itp_wooden_parry, itc_cutting_spear|itcf_carry_spear,
270 , weight(1)|difficulty(0)|spd_rtng(89) | weapon_length(185)|swing_damage(20 , blunt) | thrust_damage(32 , pierce),imodbits_polearm ],
#THROWING SPEARS END#

A small list of things to remember.
  • When thrown, a spear of any kind has the itp_can_knock_down. This means it has a chance to knock down the target, should they survive. If you don't like it, you can remove that flag.
  • Values were assigned with a VS Bots Coop mentality, and can be changed to your liking easily.
  • Thrown damage was deduced by the item's original Thrust Damage * Original Weight
  • Shoot_speed is how fast or slow the projectile goes, not how fast you can spam them. A shoot_speed of zero means it will literally fall at your feet once thrown. I've deduced my own by 75 / Original Weight. It's worked fairly well for balance.
 

Somebody

Code Pope
Baron
WBWF&S
Best answers
1
A couple of notes - two categories of throwing weapons are defined for multiplayer, multi_item_class_type_throwing and multi_item_class_type_throwing_axe. This puts them in different rows.

Also, if you don't care about compatibility with savegames, you can simply put the thrown version before the native melee versions so you don't use up two extra item spaces per weapon. There is no requirement for the item name to have _melee at the end or only 1.0 weight, which is purely for the sake of letting you run faster with it in melee mode I suspect.

As for the difference between itcf_throw_axe, itcf_throw_javelin, itcf_throw_knife, itcf_throw_stone, the difference is mainly in the animation (you can tweak them to have different speeds in module_animation). itcf_throw_axe (and maybe itcf_throw_knife, haven't checked) will also spin the item, while itcf_throw_stone won't leave a projectile behind when it hits something.

A final note regarding shoot_speed - it also affects damage (faster = higher damage when hit) and the range at which AI will start using them. spd_rtng lets you spam them. (Speaking of which, shoot_speed(30) is repeated twice in your war spear code).
 

Scarebear

Recruit
WB
Best answers
0
Aye, I suppose I should've pointed out that the naming convention was my OCD taking place. Thanks for the notes and clarifications, I'm going to put them in the OP and thanks for catching that goof on my code there.
 

Audustum

Squire
M&BWBWF&S
Best answers
0
You might want to slightly shorten the length stat on the thrown version of the items, or they'll tend to float in front of instead of sticking in front of what they hit, but that's just an aesthetics issue.
 

Einar23

I will test and I think you should pm a moderator to have it moved into Unnoficial tutorials  :mrgreen:
EDIT--Can I switch to melee version of the item? And how?