Fire Projectile (Power Type)
Fires one or more projectiles upon pressing the specified Key with customizable projectile-firing ability with configurable visuals, behavior, and actions…
Fires one or more projectiles upon pressing the specified Key with customizable projectile-firing ability with configurable visuals, behavior, and actions on hit/miss.
Type ID: apoli:fire_projectile
Fields
| Field | Type | Default | Description |
|---|---|---|---|
entity_type | Identifier | The ID of the entity type that will be fired. | |
texture_location | Identifier or keyword | optional | If specified, the texture used for the projectile and the entity_type will be ignored. The projectile is then Apoli’s own entity, which can also wear a Bedrock model. The keywords held_item and offhand_item throw the shooter’s item instead — see Throwing what you are holding. |
cooldown | Integer or Expression | 1 | Interval of ticks this power needs to recharge before the power can be triggered again. |
hud_render | Hud Render | optional | Determines how the cooldown of this power is visualized on the HUD. |
count | Integer | 1 | The amount of projectiles to fire each use. |
interval | Integer | 0 | Determines the interval for firing multiple projectiles consecutively (in ticks). If set to 0, it will fire all the projectiles at the same tick. |
start_delay | Integer | 0 | Determines how long the start of the firing process is delayed (in ticks). |
speed | Float | 1.5 | The speed applied to the fired projectile. |
offset_x, offset_y, offset_z | Float | 0 | Where the projectile spawns, relative to the shooter’s eyes. Read through space, so local puts offset_z: 1.5 a block and a half in front of wherever they are looking — the muzzle of a cannon rather than a point due south of it. |
space | Space | world | How the spawn offset is read. local is relative to the shooter’s facing, world to the world axes. |
max_distance | Float or Expression | 0 | Removes the projectile once it has travelled this far, in blocks. 0 leaves it to fly until it hits something or expires. Apoli’s own shots keep drifting on inertia, so speed alone does not bound their range. |
divergence | Float | 1.0 | How much each projectile fired is affected by random spread. |
sound | Identifier | optional | If set, the sound with this ID will be played when the power is used. |
tag | NBT | optional | NBT data of the entity. |
allow_conditional_cancelling | Boolean | false | Determines if extra projectiles will no longer be fired as soon as the entity no longer meets this power’s condition. |
block_action_cancels_miss_action | Boolean | false | Determines if the block_action_on_hit action will cancel the bientity_action_on_miss action. |
entity_action_before_firing | Entity Action | optional | If specified, the entity action to execute on the entity firing the projectile just prior to the projectile being created. |
bientity_action_after_firing | Bi-entity Action | optional | If specified, the bi-entity action to execute with the projectile owner the actor, and the projectile as the target as soon as the projectile is created. |
block_action_on_hit | Block Action | optional | If specified, the block action to execute on the block the projectile lands on upon having it land on it. |
bientity_action_on_miss | Bi-entity Action | optional | If specified, the bi-entity action to execute with the projectile owner as the actor, and the projectile as the target upon missing. |
bientity_action_on_hit | Bi-entity Action | optional | If specified, the bi-entity action to execute with the projectile as the actor, and the hit entity as the target upon hitting an entity. |
owner_target_bientity_action_on_hit | Bi-entity Action | optional | If specified, the bi-entity action to execute with the projectile owner as the actor, and the hit entity as the target upon hitting an entity. |
tick_bientity_action | Bi-entity Action | optional | If specified, the bi-entity action with the projectile owner as the actor, and the projectile as the target that is run each tick of the projectile’s lifespan. |
block_condition | Block Condition | optional | If specified, the block condition that the block targeted by the block_action_on_hit field must meet in order for that to run. |
bientity_condition | Bi-entity Condition | optional | If specified, the bi-entity condition with the projectile as the actor and the target as the target for the projectile to actually hit the target instead of pass through. |
owner_bientity_condition | Bi-entity Condition | optional | If specified, the bi-entity condition with the projectile owner as the actor and the target as the target for the projectile to actually hit the target instead of pass through. |
key | Key | optional | Which active key this power should respond to. If none is specified, this power will use the primary active power key. |
projectile_action | Entity Action Type | optional | If specified, this entity action will be executed on the projectile or entity that will be launched. |
shooter_action | Entity Action Type | optional | If specified, this entity action will be executed on the entity that has the power. |
reflective | Boolean | false | When true, the projectile bounces off blocks instead of stopping on them. See Bouncing off walls. |
max_bounces | Integer | 4 | How many times a reflective projectile may bounce before the next block hit stops it. -1 bounces forever, which needs max_distance or a tick_bientity_action to end the shot. |
bounce_speed | Float | 1.0 | The fraction of its speed the projectile keeps after each bounce. 1.0 loses nothing, 0.6 is a rubber ball, values above 1 accelerate it. |
bientity_action_on_bounce | Bi-entity Action | optional | If specified, the bi-entity action to execute with the projectile owner as the actor and the projectile as the target every time it bounces. |
Bouncing off walls
reflective turns a block hit into a rebound: the projectile’s velocity is mirrored through the face it struck, scaled by bounce_speed, and it carries on flying. Entity hits are unaffected — a reflective projectile still hits the first entity it reaches, subject to bientity_condition.
Each bounce still runs block_action_on_hit (honouring block_condition), so a bouncing shot can leave a mark on every wall it kisses. bientity_action_on_miss is held back until the projectile actually stops, so “it missed” means what it says.
Once max_bounces is used up the next block hit ends the shot normally. Give a forever-bouncing projectile (max_bounces: -1) a max_distance so it cannot outlive the player who fired it.
{
"type": "apoli:fire_projectile",
"texture_location": "example:textures/entity/bouncy_orb.png",
"speed": 1.2,
"reflective": true,
"max_bounces": 6,
"bounce_speed": 0.85,
"max_distance": 64,
"bientity_action_on_bounce": {
"type": "apoli:play_sound",
"sound": "minecraft:entity.slime.squish"
}
}
bounce_speedabove1.0compounds — at1.3a projectile is travelling nearly four times its launch speed after six bounces, fast enough to tunnel through a one-block wall between ticks. Pair it with a lowmax_bounces.
Examples
{
"type": "apoli:fire_projectile",
"entity_type": "minecraft:arrow",
"cooldown": 2,
"hud_render": {
"should_render": false
},
"tag": "{pickup:0b}",
"key": {
"key": "key.attack",
"continuous": true
}
} This example will let the player fire arrows very rapidly by holding the left mouse button. They can’t be picked up.
{
"type": "apoli:fire_projectile",
"entity_type": "minecraft:snowball",
"cooldown": 100,
"hud_render": {
"should_render": false
},
"count": 4,
"interval": 5,
"tag": "{Item: {id: 'minecraft:slime_ball', Count: 1b}}",
"key": {
"key": "key.use",
"continuous": false
}
} This example will let the player fire 4 snow balls disguised as slime balls consecutively, with an interval of 5 ticks upon pressing the right mouse button.
Throwing what you are holding
Set texture_location to held_item (or offhand_item) and the projectile carries the shooter’s stack, rendering its real item model — blocks come out as blocks, items as their sprite, exactly the way a thrown snowball or ender pearl renders:
{
"type": "apoli:fire_projectile",
"texture_location": "held_item",
"speed": 1.5
} The stack is read when the projectile spawns, so it keeps looking like that item even if the shooter swaps hands mid-flight. It is a copy for rendering only — nothing is taken from the shooter’s inventory, so pair it with an apoli:consume or apoli:change_slot if the throw should cost the item.
Giving the projectile a model
A projectile spawned by texture_location is Apoli’s own entity, and like a minion or a clone it
renders whatever apoli:custom_model_render geometry it
is holding. Grant the model power to the projectile from projectile_action and it wears the model
instead of the flat texture:
{
"type": "apoli:fire_projectile",
"texture_location": "example:textures/projectile/blank.png",
"speed": 1.8,
"projectile_action": {
"type": "apoli:grant_power",
"power": "example:shuriken_model",
"source": "example:shuriken"
}
} {
"type": "apoli:custom_model_render",
"mode": "geometry",
"model": "example:geo/shuriken.geo.json",
"texture": "example:textures/entity/shuriken.png",
"animations": {
"animation": "example:animations/shuriken.animation.json",
"name": "animation.shuriken.spin",
"loop": true
}
} The model faces the projectile’s direction of travel, and its animations play from the moment it is granted, so a spin or a flame flicker runs for the projectile’s whole flight.
The power is resolved at spawn and the projectile carries it in its own entity data, so it arrives with the spawn packet and every viewer sees the model on the very first frame. Granting or revoking a model power mid-flight still works — the live power is checked when the projectile is not carrying a stamped one.
Pair it with the spawn offset to line the projectile up with whatever fired it:
{
"type": "apoli:fire_projectile",
"texture_location": "example:textures/projectile/blank.png",
"space": "local",
"offset_y": -0.4,
"offset_z": 1.6,
"speed": 2.0,
"projectile_action": { "type": "apoli:grant_power", "power": "example:cannonball_model", "source": "example:cannon" }
}
texture_locationis what selects Apoli’s projectile entity in the first place, so it stays required even when a model covers it — point it at a blank texture. A vanillaentity_typeprojectile renders the way vanilla renders it and ignores model powers.