投掷器重制【Throwing Redo】

客户端和服务器插件
中文名称 投掷器重制
英文名称 Throwing Redo
作者 帕利格
语言 英语
版本 Minetest Minetest Version: 5.0.0
依赖Mode或插件 默认和耕种(都包括在minetest游戏中,您无需安装它们)
Mode类型 角色
开源协议 代码许可证:MPL-2.0 纹理许可:与PilzAdam(WTFPL)的throwing mod的纹理相同
原始地址 https://forum.minetest.net/viewtopic.php?t=16365
下载地址 https://github.com/minetest-mods/throwing
代码仓库 https://github.com/minetest-mods/throwing

使用更干净的代码进行投掷并提供API以使其可扩展的新实现。

Throwing mod by PilzAdam
Throwing mod by Jeija

这个mod可以无问题地替换上面的两个 throws mod(如果您将其目录命名为 throwing,则项目字符串保持不变)。

该模块已在Eurythmia服务器上进行了积极测试。

物品列表

  • 木弓
  • 石弓
  • 钢弓
  • 青铜弓
  • 梅斯弓
  • 钻石弓

箭头:

  • 箭头
  • 金箭
  • 挖箭
  • 管理员挖箭
  • 传送箭
  • 火炬箭
  • 建立箭头
  • 放下箭头

配置文档

设置如下:

# Trajectory parameters
throwing.vertical_acceleration = -10
throwing.realistic_trajectory = false
throwing.frictional_coefficient = -.5

# How the initial velocity of arrows is computed: simple, strength, or momentum
throwing.velocity_mode = strength
throwing.velocity_factor = 19

# Whether to allow placing an arrow as a node
throwing.allow_arrow_placing = false

# Minimum time between two shots
throwing.bow_cooldown = 0.2

# Whether to enable toolranks for bows
throwing.toolranks = true

轨迹参数

默认情况下,箭头的轨迹是简单的抛物线。您可以使用设置垂直加速度(重力加速度)throwing.vertical_acceleration。

如果要使用空气摩擦的一阶建模的更真实的轨迹,可以将其设置throwing.realistic_trajectory为true。在此模式下,throwing.frictional_coefficient指示箭头上的摩擦力与其速度之间的比率。应该是负面的。随后通过将力除以箭头的“质量”来确定箭头的加速度,参考质量1是中的钢箭头的质量throwing_arrows。通常,摩擦系数应该很小。-1值将已经大大缩短了箭头的范围。默认值为-0.5。

初始速度计算

该mod提供了三种模式来计算射箭后的初始速度:简单,强度和动量。

在简单模式下,箭头的初始速度始终相同。此速度的值由throwing.velocity_factor默认值19 的设置控制。

在强度模式(默认)下,箭头的初始速度仅取决于所使用的弓箭-弓箭越贵,箭头越快。弓箭强度乘以速度因子可计算箭头的速度。作为参考,钢弓throwing_arrows的强度约为1。

最后,动量模式是最现实的。像在强度模式下一样,它根据弓箭强度和箭头的质量计算箭头的速度:箭头越重,射击的速度就越慢。之所以称为动量模式,是因为在这种模式下,弓的强度表示箭头的初始动量,而不是箭头的初始速度。

API

mod API中有两个可用功能:

function throwing.register_bow(name, definition)
--[[
Name: Bow name. If it doesn't contain ":", the "throwing:" prefix will be added.
Definition: definition table, containing:
  * description (highly recommended): description of the bow.
  * texture (essential): texture of the bow, shown in inventory.
  * groups (optional): groups of the item.
  * uses: number of uses of the bow (the default is 50).
  * allow_shot (optional): function(player, itemstack, index, last_run):
    - player: the player using the bow
    - itemstack: the itemstack of the bow
    - index: index of the arrow in the inventory
    - last_run: whether this is the last time this function is called before actually calling `spawn_arrow_entity`.
      Currently, `allow_shot` is actually run twice (once before the delay, and once after).
    - should return true if the shot can be made, and false otherwise
    - the default function checks that the arrow to be thrown is a registered arrow
    - it can return a second return value, which is the new itemstack to replace the arrow after the shot
  * throw_itself (optional): whether the bow should throw itself instead of the arrow next to it in the inventory.
    The default is false.
  * cooldown: bow cooldown. Default is setting throwing.bow_cooldown
  * function spawn_arrow_entity(position, arrow, player): defaults to throwing.spawn_arrow_entity
  * sound: sound to be played when the bow is used
  * delay: delay before throwing the arrow
  * no_toolranks: If true, toolranks support is disabled for this item. Defaults to false.
  * strength: strength of the bow, see above. Defaults to 1.
]]

-- Example:
throwing.register_bow("bow_wood", {
	itemcraft = "default:wood",
	description = "Wooden Bow",
	texture = "throwing_bow_wood.png"
})

itemcraft, craft_quantity, description, tiles, on_hit_sound, on_hit[, on_throw[, groups]]
function throwing.register_arrow(name, definition table)
--[[
Name: Arrow name. If it doesn't contain ":", the "throwing:" prefix will be added.
Definition: definition table, containing:
  * tiles (essential): tiles of the arrow.
  * target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both).
  * allow_protected (optional, defaulting to false): whether the arrow can be throw in a protected area
  * mass (optional, defaulting to 1): the mass of the arrow (see above)
  * on_hit_sound (optional): sound played when the arrow hits a node or an object.
  * on_hit(self, pos, last_pos, node, object, hitter, data) (optional but very useful): callback function:
    - pos: the position of the hit node or object.
    - last_pos: the last air node where the arrow was
    - node and object: hit node or object. Either node or object is nil, depending
      whether the arrow hit a node or an object.
    - hitter: an ObjectRef to the thrower player.
    - data: a data table associated to the entity where you can store what you want
    - self: the arrow entity table (it allows you to hack a lot!)
    - If it fails, it should return:
      false[, reason]
  * on_throw(self, pos, thrower, itemstack, index, data) (optional): callback function: on_throw:
    - pos: the position from where the arrow is throw (which a bit higher than the hitter position)
    - thrower: an ObjectRef to the thrower player
    - next_index: the index next to the arrow in the "main" inventory
    - data: a data table associated to the entity where you can store what you want
    - self: the arrow entity table
    - If the arrow shouldn't be thrown, it should return false.
  * on_throw_sound (optional, there is a default sound, specify "" for no sound): sound to be played when the arrow is throw
  * on_hit_fails(self, pos, thrower, data) (optional): callback function called if the hit failed (e.g. because on_hit returned false or because the area was protected)
]]

-- Example:
throwing.register_arrow("arrow", {
	itemcraft = "default:steel_ingot",
	craft_quantity = 16,
	description = "Arrow",
	tiles = {"throwing_arrow.png", "throwing_arrow.png", "throwing_arrow_back.png", "throwing_arrow_front.png", "throwing_arrow_2.png", "throwing_arrow.png"},
	target = throwing.target_object,
	on_hit_sound = "throwing_arrow",
	on_hit = function(pos, _, _, object, hitter)
		object:punch(hitter, 1, {
			full_punch_interval = 1,
			damage_groups = {fleshy = 3}
		})
	end
})

如果要投掷的物品是使用所注册的箭头throwing.register_arrow,则所使用的实体将是此功能自动注册的实体。否则,如果其定义包含一个throwing_entity字段,则该字段(如果为字符串)将用作实体名称,否则将被称为function(pos, player)必须生成对象并返回相应ObjectRef的。如果该项既不是箭头也不是throwing_entity字段,__builtin:item则将使用相应的项。