11 KiB
Raw Blame History

(WIP)

Registering a mod

In order to register any weapon, you need to register your mod first via:

weapons_lib.register_mod("mod_name", rules)

This allows you to define the general rules of your weapons. To do that, it uses a table which can contain the following fields (if you don't want to override anything, just declare an empty table):

  • RELOAD_KEY: (string) the key used to reload weapons that support such function. By default "Q"
    • BEWARE: right now, due to MT limitations (see here), it can't be anything but "Q", which also means that weapons can't be dropped. Changing this value will prevent people from reloading, but it'll also allow them to drop weapons
  • SHOOT_SPEED_MULTIPLIER: (float) how much players are slowed down when using a weapon that features slowness. Default is 0.66

Registering a weapon

Weapons can be registered via:

weapons_lib.register_weapon("mod_name:weapon_name", properties)

properties is a table containing all the properties that will define the weapon. See the following section to learn about all the available properties.

Weapon properties

Being weapons nodes with extra parameters, all MT nodes parameters are supported by default. Some of them, however, act in a peculiar way and it's not possible to override them:

  • range: (int) melee weapons have 4 by default and it can be overridden. All the rest have 0 and it can't be changed
  • node_placement_prediction is always ""
  • callbacks on_use, on_secondary_use, on_place and on_drop are defined by weapons_lib

Then there are the built-in weapons_lib parameters:

  • weapon_type: (string) mandatory. It can be "ranged", "melee" or "support". A ranged weapon can have melee functions, but not viceversa. Not sure if I'll maintain "support", which is currently not implemented
  • magazine: (int, no melee) how many bullets the magazine contains; if -1, it's infinite
  • reload_time: (int, no melee) how much time it takes to reload the weapon
  • sound_reload: (string, no melee) the sound the weapon does when reloading
  • crosshair: (string) the image of the crosshair
  • slow_down_user: (boolean) whether the player should be slowed down when attacking and reloading. Default is false.
    • Beware: changing player's velocity whilst slowed down will break their speed if a fixed value is used. Weapons_lib cannot know if there are any external mods interfering, so either rely on multipliers or be very careful when you perform such changes (meaning don't do it if you think they might have a weapon). Related: wl_slowed_down metadata
  • can_use_weapon: (function(player, <action>)) additional checks about whether the weapon can be used (reloading included). Return true to proceed
    • reloading doesn't pass any action
    • actions with continuous_fire run the check before every bullet/hit
  • can_alter_speed: (function(player)) additional checks about whether to prevent slowing down/speeding up again the player
    • Slowing down is only checked for slow_down_user weapons. Speeding up, however, is checked for all weapons due to async issues (i.e. here)
    • Return true to let wapons_lib alter the speed. Related: wl_slowed_down metadata
  • on_after_hit: (function(hitter, weapon, action, objects_hit, total_damage)) additional behaviour after all the damage has been inflicted to all the targets of a hit
    • objects_hit is a table containing as many tables as the amount of targets hit. Format:
      • ref: the ObjectRef
      • type: "player" or "entity"
      • damage: the damage that it should have been inflicted. weapons_lib cannot know if an external mod altered the damage of the weapon (e.g. via minetest.register_on_punchplayer(..))
    • total_damage: the sum of the damage that should have been inflicted to all the targets. weapons_lib cannot know if an external mod altered the damage of the weapon (e.g. via minetest.register_on_punchplayer(..))
  • on_recovery_end: (function(player, weapon, action)) additional behaviour for when the weapon is ready to be used again
  • on_reload: (function(player, weapon)) additional behaviour when reloading
  • on_reload_end: (function(player, weapon)) additional behaviour when the weapon has successfully finished reloading
  • action1: (table) action on left click
  • action2: (table) action on right click
  • action1_hold: (table, melee only) action on left click if kept pressed for 0.3s. NOT YET IMPLEMENTED, waiting for MT
  • action2_hold: (table, melee only) action on right click if kept pressed for 0.3s. NOT YET IMPLEMENTED, ^
  • action1_air: (table, melee only) action on left click whilst in the air
  • action2_air: (table, melee only) action on right click whilst in the air

Custom parameters are supported as well. It's recommended putting a _ at the beginning of the parameter so to avoid conflicts with upcoming official ones

Actions structure

Actions are tables containing info about how they should work. Actions also support custom parameters: it's recommended putting a _ at the beginning of the parameter so to avoid conflicts with upcoming official ones.

  • type: (string) mandatory. It can be "raycast" (), "bullet" (🥏), "zoom" (🔎), "punch" (👊) or "custom" (TODO: "parry")
  • damage (float) 🥏👊 how much damage deals
  • delay: (float) 🥏👊 how much time it should pass between being able to rerun the action
  • range: (float) range of the action
  • fov: (int) 🔎 fov when zooming (TODO: convert it into a zoom_data table with overlay HUD etc?)
  • bullet: (table) 🥏 the properties of the physical bullet shot with this action. See the Bullets structure section down below
  • loading_time: (float) 🥏👊 how much time before actually running the action. NOT YET IMPLEMENTED, waiting for MT
  • attack_on_release: (bool) 🥏👊🔎 whether it should attack when the action key is released. NOT YET IMPLEMENTED, waiting for MT
  • knockback: (int) 🥏👊 how much knockback the action should inflict
  • ammo_per_use: (int) 🥏 how much ammo is needed to run the action
  • continuous_fire: (bool) 🥏 whether it should keep firing when holding down the action key (waiting delay seconds between a shot and another). Default is false
  • decrease_damage_with_distance: (bool) 👊 whether damage should decrease as the distance from the target increases. Default is false
  • pierce: (bool) 🥏👊 whether the hit should stop on the first person or continue. Default is false
  • physics_override: (table or string) 🥏👊🔎 how the player physics should change when running the action. Physics is restored when the recovery phase ends
    • It takes either a Minetest physics table or the string "FREEZE", which will block the player
    • If this parameter is declared, slow_down_user won't get called
  • sound: (string) 🥏👊 the sound to play when the action is run
  • trail: (table) 👊 the trail the action should leave. Fields are:
    • image: (string) the particle to spawn
    • amount: (int) how many particles to draw along the line
    • size: (int) the size of each particle
  • on_use: (function(player, weapon, action, <pointed_thing>)) 🥏👊 additional behaviour when the action is successfully run
    • pointed_thing is only passed with custom and punch action types
    • if continuous_fire is on, the callback is run repeatedly
    • a must for "custom" type to actually do something
  • on_hit: (function(hitter, target, weapon, action, hit_point, damage, knockback)) 🥏👊 additional behaviour when hitting a player or an entity
    • It must return the damage that will be inflicted (int) and the knockback (int or nil)
    • hit_point only works with type "raycast" at the moment, waiting for MT
  • on_end: (function(player, weapon, action)) 🥏👊 additional behaviour for when the action reaches its end

TODO: physics_override con zoom al momento prob dà problemi TODO: explosion

Bullets structure

TODO

  • remove_on_contact: (boolean) whether the bullet should cause an explosion when hitting something. It needs explosion

Metadata

Weapons communicate their state through players metadata:

  • wl_weapon_state: (int) communicates the state of the weapon
    • 0: free
    • 1: loading, NOT YET IMPLEMENTED
    • 2: shooting
    • 3: recovering
    • 4: reloading
    • 5: parrying, NOT YET IMPLEMENTED
  • wl_zooming: (int) whether the player is in zoom state (1) or not (0)
  • wl_is_speed_locked: (int) whether the player's speed is altered by a weapon (physics_override)
  • wl_slowed_down: (int) whether the player is currently slowed down by a weapon (shooting, reloading etc)
    • reset_state(..) forces it to 0
    • in case of slowing down weapons impeding the alteration of speed (can_alter_speed returning false), this metadata remains stuck to its latest value until the alteration is possible again. Beware of any manual speed alterations you could have in the meanwhile (e.g. calling a set_physics_override in a mod) and be sure to manually set this value once the conditions stopping can_alter_speed from happening aren't satisfied anymore

Utils

  • weapons_lib.is_weapon(i_name): whether the item i_name is a registered weapon
  • weapons_lib.refill(p_name, weapon): instantly refills the magazine of weapon for p_name. If the weapon was reloading, it instantly completes the process
  • weapons_lib.deactivate_zoom(p_name): disables the zoom state of the player, if any
  • weapons_lib.reset_state(player): resets the weapon state of player, instantly completing any ongoing action and setting wl_slowed_down to 0
  • weapons_lib.apply_damage(hitter, targets, weapon, action): useful for "custom" actions to deal damage
    • targets is a table of tables, one per target hit. Format of these single tables is {object = ObjRef, hit_point = intersection_point}. hit_point is optional
    • weapon is the node representing the weapon

Getters

  • weapons_lib.get_weapon_by_name(w_name): returns the table of the weapon w_name, if any
  • weapons_lib.get_magazine(p_name, w_name): returns the current magazine of p_name's weapon w_name, if any