Cannon mounts
The cannons of Create Big Cannons driven by a computer: turn them to an angle at the speed of their shafts, fire, and assemble or disassemble them to reload.
The Cannon Mount and the Fixed Cannon Mount are blocks of Create Big Cannons. Without that mod, there is no such block, and peripheral.find("cannon_mount") returns nil.
A Cannon Mount carries a cannon of Create Big Cannons: its shafts turn it around and raise it, a redstone signal on one face assembles it, on another fires it. A computer connected to the mount does all of that from a program: it turns the cannon to the angles asked, fires, takes the cannon apart to reload it and puts it back together. Enough for a turret that follows a target, a battery that fires in turn, or an artillery piece that reloads itself.
The Cannon Mount has the peripheral type cannon_mount. The Fixed Cannon Mount, the one that holds a cannon on a contraption or a ship, has the type fixed_cannon_mount and most of the same methods (each method says which mounts have it). Against the computer a mount is called by its side ("front"...); on a Data Cable (Minicomputer and newer) it gets a name such as cannon_mount@12,64,-30.
local gun = peripheral.find("cannon_mount")
if not gun.assembled() then
gun.assemble()
end
gun.aim(270, 10) -- towards the east, barrel raised 10 degrees
while not gun.on_target() do
sleep(0.1)
end
gun.fire()Every method reads the block again when it is called. When the mount is gone, the call stops the program with cannon mount removed; when its chunk is not loaded, with peripheral is not loaded. A method that needs a cannon (aim, fire, set_fire_rate) stops it with no cannon assembled on the cannon mount while there is none.
Also a kinetic block. The Cannon Mount is a Create machine, so the wrapped mount also has the methods of Create kinetic blocks; but its two shafts are inside it, and speed() says nothing about them: read cannon_mount.shaft_speeds() instead. While an autocannon is assembled on it, the mount also takes items like an inventory (Inventories): rounds pushed into it (inventory.push()) go into the breech.
gun.assembled() | true while the mount carries an assembled cannon, false when the cannon is blocks (or there is none). Both mounts have it. |
gun.cannon() | What the mount carries: "big_cannon" (fired with fire), "autocannon" (fired with set_fire_rate), or "other" for a cannon of an addon of Big Cannons. nil while no cannon is assembled. Both mounts have it. |
gun.strength() | The "Cannon Strength" of Engineer's Goggles: the propellant the cannon takes before it may burst, counted like Big Cannons counts it (a Powder Charge is 1). It depends on the material of the barrel and on the breech. Both mounts have it. |
gun.fire_rate() | How fast the autocannon fires now, in rounds per minute, as Engineer's Goggles show it; 0 while it does not fire. Both mounts have it. |
gun.yaw() | On a Cannon Mount, where the cannon points around the vertical: 0 south, 90 west, 180 north, 270 east. Without a cannon, the way the mount faces. On a Fixed Cannon Mount, the yaw adjustment of its value box, from -45 to 45 degrees, positive to the right of the cannon. |
gun.pitch() | On a Cannon Mount, the angle of the barrel above the horizontal, negative below; 0 without a cannon. On a Fixed Cannon Mount, the pitch adjustment of its value box, from -45 to 45 degrees, positive upwards. |
gun.pitch_limits() | How low and how high the cannon may point on this mount, in degrees: min is negative (below the horizontal). Big Cannons sets them by cannon and by mount. aim keeps the pitch asked between them. Cannon Mount only. |
gun.shaft_speeds() | The speed of the shaft that turns the mount around (yaw, under it) and of the one that raises it (pitch, on its sides), in RPM, 0 when one stands still or its network is overstressed. A computer turns the mount only as fast as these shafts: RPM × 0.75 degrees per second. Cannon Mount only. |
gun.aim(yaw, pitch) | On a Cannon Mount, takes the mount over and turns the cannon towards these angles at the speed of its shafts (see above), then holds it there. The call returns at once: cannon_mount.on_target() tells when the cannon is there. Calling aim again changes the target, even while the mount turns. Needs an assembled cannon. |
gun.target() | The angles of the last aim, the pitch as kept within the limits; nil when no computer holds the mount (never aimed, released, or the cannon disassembled since). Cannon Mount only. |
gun.on_target() | true once the cannon has reached the angles of the last aim; false while it turns, or when no computer holds the mount. Cannon Mount only. |
gun.release() | Gives the mount back to its shafts: they turn it again as before, a Sequenced Gearshift too. Does nothing when no computer holds it. Cannon Mount only. |
gun.fire() | Fires the big cannon once, like a redstone pulse on the firing face of the mount: Big Cannons ignites the charges and sends the shell, at the end of the tick. Several calls in one tick give one shot; an empty barrel does nothing. On an autocannon, stops the program with an autocannon fires at a rate: set_fire_rate(1..15). Both mounts have it. |
gun.set_fire_rate(rate) | Gives the autocannon the redstone signal strength rate on its firing face: it fires on and on, as long as it has rounds, until set_fire_rate(0). A redstone change on the firing face replaces the rate. On a big cannon, stops the program with only an autocannon has a fire rate: fire() shoots a big cannon. Both mounts have it. |
gun.assemble() | Assembles the cannon placed on the mount, like a rising redstone signal on its assembly face. Does nothing when it is already assembled. When Big Cannons refuses, stops the program with its reason (cannot assemble the cannon: Cannon must have exactly one opening...); with nothing to assemble, with no cannon to assemble on the cannon mount. A mount assembles or disassembles once per tick: a second call in the same tick says to wait (sleep(0)). Both mounts have it. |
gun.disassemble() | Puts the cannon back as blocks, pointing the way it was assembled, and ends the computer's hold on the mount. That is how a big cannon is reloaded. Does nothing when there is no cannon. Both mounts have it. |
Angles
The angles are those of Big Cannons, the ones Engineer's Goggles show on the mount:
- yaw, where the cannon points around the vertical, from 0 to 360 degrees, like the F3 screen: 0 is south, 90 west, 180 north, 270 east;
- pitch, how far the barrel is raised: positive above the horizontal, negative below. How far it may go depends on the cannon and on the mount:
cannon_mount.pitch_limits().
The yaw towards a target comes from the difference of coordinates (target minus cannon), with math.atan2:
local function yaw_to(dx, dz)
return math.floor(math.atan2(-dx, dz) * 180 / math.pi + 0.5) % 360
end
print(yaw_to(0, -10)) -- north
print(yaw_to(10, 0)) -- east
print(yaw_to(-5, 5)) -- south-west180 270 45
The pitch that reaches a distance depends on the shell, on the propellant and on the barrel: the simplest is to try a few angles, note where the shells land, and keep a table of pitches by distance in the program.
How a computer turns the mount
The shafts give the speed, the computer the direction. aim takes the mount over: its shafts no longer turn it by themselves, the computer turns it towards the angles asked, the shortest way, as fast as its shafts would, whichever way they turn. Big Cannons turns a mount by RPM × 0.75 degrees per second: 24 degrees per second for shafts at 32 RPM, a half turn in under a second at 256 RPM. Without rotation, or with an overstressed network, the mount does not move: cannon_mount.shaft_speeds() tells why.
It holds until released. Once on target, the mount stays there, however its shafts turn, even after the program ends: until cannon_mount.release() gives it back to its shafts, or the cannon is disassembled. After a server restart, a program aims again: until then the mount holds still, and goes back to its shafts the next time their speed changes.
The Fixed Cannon Mount has no shafts: its two value boxes turn the cannon up to 45 degrees from where the mount faces. On it, aim sets those boxes, like a player, and the cannon is there at once.
Firing and reloading
A big cannon fires with cannon_mount.fire(), like a redstone pulse on the firing face of the mount: one shot of what the barrel holds, at most once per tick. It is loaded while it is blocks, not while it is assembled: a reloading program disassembles it (cannon_mount.disassemble()), lets a Cannon Loader push the shell and its charges in, then assembles it again.
An autocannon fires on and on as long as its firing face gets a redstone signal, faster with a stronger signal: cannon_mount.set_fire_rate() gives it that signal strength, 0 to stop.
Redstone still works next to the computer: a signal change on the firing face of the mount sets the autocannon's rate to that signal; on the assembly face, a signal that comes assembles the cannon and a signal that goes disassembles it.
State
gun.assembled()
true while the mount carries an assembled cannon, false when the cannon is blocks (or there is none). Both mounts have it.
- boolean
- true while a cannon is assembled on the mount
gun.cannon()
What the mount carries: "big_cannon" (fired with fire), "autocannon" (fired with set_fire_rate), or "other" for a cannon of an addon of Big Cannons. nil while no cannon is assembled. Both mounts have it.
- string
- "big_cannon" or "autocannon", nil when no cannon is assembled
local kind = gun.cannon()
if kind == "autocannon" then
gun.set_fire_rate(10)
elseif kind == "big_cannon" then
gun.fire()
endSee also cannon_mount.assembled()
gun.strength()
The "Cannon Strength" of Engineer's Goggles: the propellant the cannon takes before it may burst, counted like Big Cannons counts it (a Powder Charge is 1). It depends on the material of the barrel and on the breech. Both mounts have it.
- number
- how much propellant the big cannon takes without risk; nil for an autocannon or without cannon
See also cannon_mount.fire()
gun.fire_rate()
How fast the autocannon fires now, in rounds per minute, as Engineer's Goggles show it; 0 while it does not fire. Both mounts have it.
- number
- rounds per minute of the autocannon now; nil for a big cannon or without cannon
See also cannon_mount.set_fire_rate()
Aiming
gun.yaw()
On a Cannon Mount, where the cannon points around the vertical: 0 south, 90 west, 180 north, 270 east. Without a cannon, the way the mount faces. On a Fixed Cannon Mount, the yaw adjustment of its value box, from -45 to 45 degrees, positive to the right of the cannon.
- number
- the yaw of the cannon in degrees, 0 to 360 (Cannon Mount); the yaw adjustment (Fixed Cannon Mount)
print(string.format("yaw %.1f, pitch %.1f", gun.yaw(), gun.pitch()))See also cannon_mount.pitch() cannon_mount.aim()
gun.pitch()
On a Cannon Mount, the angle of the barrel above the horizontal, negative below; 0 without a cannon. On a Fixed Cannon Mount, the pitch adjustment of its value box, from -45 to 45 degrees, positive upwards.
- number
- how far the barrel is raised, in degrees (Cannon Mount); the pitch adjustment (Fixed Cannon Mount)
gun.pitch_limits()
How low and how high the cannon may point on this mount, in degrees: min is negative (below the horizontal). Big Cannons sets them by cannon and by mount. aim keeps the pitch asked between them. Cannon Mount only.
- table
- {min=, max=}, the lowest and highest pitch of the cannon; nil without cannon
local limits = gun.pitch_limits()
print("from " .. limits.min .. " to " .. limits.max .. " degrees")See also cannon_mount.aim()
gun.shaft_speeds()
The speed of the shaft that turns the mount around (yaw, under it) and of the one that raises it (pitch, on its sides), in RPM, 0 when one stands still or its network is overstressed. A computer turns the mount only as fast as these shafts: RPM × 0.75 degrees per second. Cannon Mount only.
- table
- {yaw=, pitch=}, the speeds of the two shafts of the mount, in RPM
local s = gun.shaft_speeds()
if s.yaw == 0 or s.pitch == 0 then
print("the mount needs rotation to turn")
endSee also cannon_mount.aim()
gun.aim(yaw, pitch)
On a Cannon Mount, takes the mount over and turns the cannon towards these angles at the speed of its shafts (see above), then holds it there. The call returns at once: cannon_mount.on_target() tells when the cannon is there. Calling aim again changes the target, even while the mount turns. Needs an assembled cannon.
yawnumber- the yaw to turn to, in degrees (any number: 450 is 90)
pitchnumber- the pitch to turn to, in degrees, kept within the cannon's limits
On a Fixed Cannon Mount, sets its two value boxes to these angles, in whole degrees kept between -45 and 45, at the end of the tick. The cannon is there at once.
A turret that follows a target given by another computer (a network message with the yaw and the pitch):
local gun = peripheral.find("cannon_mount")
while true do
local m = net.receive()
gun.aim(m.data.yaw, m.data.pitch)
while not gun.on_target() do
sleep(0.1)
end
gun.fire()
endSee also cannon_mount.on_target() cannon_mount.release() cannon_mount.yaw()
gun.target()
The angles of the last aim, the pitch as kept within the limits; nil when no computer holds the mount (never aimed, released, or the cannon disassembled since). Cannon Mount only.
- table
- {yaw=, pitch=}, the angles the mount turns to; nil while its shafts drive it
See also cannon_mount.aim()
gun.on_target()
true once the cannon has reached the angles of the last aim; false while it turns, or when no computer holds the mount. Cannon Mount only.
- boolean
- true when the cannon points where aim asked
See also cannon_mount.aim()
gun.release()
Gives the mount back to its shafts: they turn it again as before, a Sequenced Gearshift too. Does nothing when no computer holds it. Cannon Mount only.
See also cannon_mount.aim()
Firing
gun.fire()
Fires the big cannon once, like a redstone pulse on the firing face of the mount: Big Cannons ignites the charges and sends the shell, at the end of the tick. Several calls in one tick give one shot; an empty barrel does nothing. On an autocannon, stops the program with an autocannon fires at a rate: set_fire_rate(1..15). Both mounts have it.
gun.set_fire_rate(rate)
Gives the autocannon the redstone signal strength rate on its firing face: it fires on and on, as long as it has rounds, until set_fire_rate(0). A redstone change on the firing face replaces the rate. On a big cannon, stops the program with only an autocannon has a fire rate: fire() shoots a big cannon. Both mounts have it.
ratenumber- 0 to stop, 1 to 15 for faster and faster fire
gun.set_fire_rate(15)
sleep(3)
gun.set_fire_rate(0)See also cannon_mount.fire_rate()
Assembly
Assembles the cannon placed on the mount, like a rising redstone signal on its assembly face. Does nothing when it is already assembled. When Big Cannons refuses, stops the program with its reason (cannot assemble the cannon: Cannon must have exactly one opening...); with nothing to assemble, with no cannon to assemble on the cannon mount. A mount assembles or disassembles once per tick: a second call in the same tick says to wait (sleep(0)). Both mounts have it.
See also cannon_mount.disassemble() cannon_mount.assembled()
Puts the cannon back as blocks, pointing the way it was assembled, and ends the computer's hold on the mount. That is how a big cannon is reloaded. Does nothing when there is no cannon. Both mounts have it.
A big cannon that reloads itself: a Cannon Loader behind it pushes a shell and its charges in while the redstone output at the back of the computer runs it.
local gun = peripheral.find("cannon_mount")
while true do
gun.disassemble()
rs.set("back", true) -- the loader runs
sleep(8)
rs.set("back", false)
sleep(0.5)
gun.assemble()
gun.aim(180, 30)
while not gun.on_target() do
sleep(0.1)
end
gun.fire()
sleep(1)
endSee also cannon_mount.assemble()