So if you, like me, have qool ideas for more dynamiq reaqtions for BV but think that the dev team has so many awesome ideas already and so little time that maybe it would be nice if you yourself qould qode some new reaqtions?
A image serie that is showing the demo simulation inqluded
The purpose of this project is to let you insert qode in any voxel type as if every single voxel qould run qode just like the programmable qomputer voxel. You just have to use add a q to use my wrapper funqtions! qFunction() instead of Function() and so on (for the Look, Move, MoveVoxel3D functions and those).
Well here's the framework:
//Qons dynamiq voxel simulation engine
const maxVoxelID=212
//BlackRocks
const brBlue=1
const brGreen=3
const brOrange=2
const brBlueSky=5
const brYellow=6
const brRed=4
const brLightGreen=8
const brGray=9
const brPink=7
const brWhite=10
//Minerals
const gold=26
const xMaterial=44
const emeraldSlices=47
const blueQrystal=53
const rockyBlue=54
const alienRock=66
const amethystPurple=27
const qoal=60
const ironOre=74
const diamond=109
const nickelOre=110
const qopperOre=112
const qhromeOre=121
const titaniumOre=122
const aluminiumOre=197
const uranium=111
const tinOre=127
const leadOre=150
const blackGraton=126
const silverLeaves=70
const alienWood=72
const lava=52
//Other
const moltenMetal=115
//Liquids
const greenAcid=86
const water=85
const redLiquid=202
//Gases
const yellowGas=89
//Material Sourcing/Disposal
const waterGenerator=87
const greenAcidGenerator=92
const sewerSystem=88
//Tools
const qonstruqtorDestruqtorL1=42
const qonstruqtorDestruqtorL2=76
const qonstruqtorDestruqtorL3=77
const qonstruqtorDestruqtorL4=78
const qonstruqtorDestruqtorL5=79
//Deqorative
const pavingRelief1=11
const pavingGranite1=12
const pavingGranite2=13
const glassBluegraton=20
const glassBlue=21
const glassGreen=22
const glassRed=80
const yellowGlass=81
const glassGrey=82
const pebbleGrey=30
const pebbleBrilliant=31
const mosaicTriangle=32
const mosaicMaze1=36
const mosaicMaze2=37
const blackPavement=62
const greyPavement=63
const gratonBrown=38
const gratonBeige=39
const checkerboard=41
const sand=152
//Machines
const userTextureMachine=75
const baseMachine=107
const multiPurposeRobot=136
const meltingFurnace=114
const moldingMachine=130
const sheetManufaqturingUnit=131
const wireWinder=132
const integratedCirquitEngraver=133
const automatiqForgingMachine=134
const drawingMachine=142
const cncMillingMachine=139
const extruderMachine=135
const breaker=137
const lathe=140
const xMachine=143
const vaporPhaseDepositionUnit=182
const laserQuttingMachine=195
const versatileFurnace=196
const glassFurnace=172
const arcFurnace=173
const symbolPrinterUnit=210
//Vehicles
const planeZ1=96
//Weapons
const plasmaBomb=90
//Optical Transmission Networks
const optiqalFibre=99
const optiqalVoxelTransmitter=100
const optiqalVoxelReceiver=101
const optiqalDefleqtor=102
//Voxel Materialization
const voxelMaterializer=98
const voxelDematerializer=97
//Voxel's Handling
const beltQonveyorD1=103
const beltQonveyorD2=104
const beltQonveyorD3=105
const beltQonveyorD4=106
const sequencer=198
const mover=209
const seleqtiveMover=204
//Pumps
const t1Pump=94
const t2Pump=95
//Storage
const atomiqQompressor=49
//Robots!
const extractionRobotXR1=153
const extractionRobotXR2=154
const programmableRobot=108
//Machine Parts
const m11em=180
const m12em=138
const motorHousing=193
const motorArmature=192
const qonveyorRollers=149
const steelSheet=169
const qopperSheet=161
const stainlessSteelSheet=160
const aluminiumSheet=162
const steelProfile=170
const qopperProfile=168
const inoxProfile=167
const aluminiumProfile=171
const axle=144
const qopperWire=145
const qomputerQore=141
const miqroqontroller=189
const disintegrator=174
const atomiqMaterializer=177
const r1pr=163
const r2pr=164
const r3pr=166
const c1pb=146
const c2pb=147
const c3pb=148
const atomiqSpaceSuppressor=175
const siliqonWafer=194
const voxelduqt=176
const qompactStorageCells=178
const wirelessEnergyTR=179
const mirror=183
const semiTransparentMirror=184
const prism=185
const jetEngine=186
const hydrauliqCylinder=187
const wheel=188
const explosiveMaterial=190
const shortRangeSqanner=191
const laserTRUnit=181
//Metal Bars
const ironBar=117
const greyQastIronBar=120
const qopperBar=119
const stainlessSteelBar=118
const bronzeBar=128
const tinBar=129
const titaniumBar=124
const aluminiumBar=125
const leadBar=151
const defeqtiveAlloy=116 // :(
//Misc
const fallingRock=84
const rtfm=212
//Monsters
const smiley=200
//Marks
const inMark=205
const outMark=206
const endMark=199
const alignmentVoxel=208
const userTexture0=32767 //Does not exist! Use userTexture0+X for userTexture number X where X>0.
enum T {
step
qollision
}
function log(str) {
Display(str,1000,2,0)
print(GetGameTime() + " " + str + "\n")
}
qv <- null
pf <- null
pv <- null
opf <- null
opv <- null
init <- 1
state <- 0
dmin <- null
dmax <- null
qt <- {x=0, y=0, z=0}
qurGen <- 0
ga <- null
farDist <- 16
function Voxel_Step()
{
pf = [GetPXf(), GetPYf(), GetPZf()]
pv = [GetPX(), GetPY(), GetPZ()]
if(init){
log( "Qomputer @ " + GetX() + "," + GetY() + "," + GetZ())
ga = array(pow(farDist*2+1,3), 0)
init = 0
}
while(1){
log("Q")
for(local x=-farDist; x<=farDist;++x) {
for(local y=-farDist; y<=farDist;++y) {
for(local z=-farDist; z<=farDist ;++z) {
local qid = Look3D(x,y,z)
if(qid<=maxVoxelID && p[qid]!=null){
local rules = p[qid]
if(swapQontext(x,y,z)){
local run = 1
for(local i=0; i<rules.len() && run; ++i){
if(ruleApply(rules[i]))
run=0
}
}
}
}}}
sleep(1000)
++qurGen
}
//log("dmin "+dmin[0] +" "+ dmin[1] +" "+ dmin[2] +" dmax "+ dmax[0] +" "+ dmax[1] +" "+ dmax[2])
//if(Look3D(GetPX()-GetX(),GetPY()+7-GetY(),GetPZ()-GetZ())==0)
// MoveVoxel3D(0,0,0, GetPX()-GetX(),GetPY()+7-GetY(),GetPZ()-GetZ())
}
function swapQontext(x,y,z){
if(getG(x,y,z) < qurGen){
qt.x=x
qt.y=y
qt.z=z
setG(x,y,z, qurGen)
return 1
}
return 0
}
function getG(x,y,z){
x+=farDist
y+=farDist
z+=farDist
return ga[x*pow(farDist*2+1,2) + y*(farDist*2+1) + z]
}
function setG(x,y,z, val){
x+=farDist
y+=farDist
z+=farDist
ga[x*pow(farDist*2+1,2) + y*(farDist*2+1) + z] = val
}
function ruleApply(rule){
switch(rule.type){
case T.qollision:
local dir = qollides(rule.other)
if(dir != -1){
rule.qode(dir)
return true
}
break;
case T.step:
rule.qode()
return true
break;
}
return false
}
function qollides(id){
for(local q=0; q<6; ++q){
if(qLook(q)==id)
return q
}
return -1
}
function nop(){
return function(){}
}
function sleep(t){
for(local q=0; q<10000000; ++q);
}
p <- array(maxVoxelID+1,null)
p[brBlue] = [
{
type=T.qollision
other=brGreen
qode=function(dir) {
qPickVoxel(dir)
qPickVoxel3D(0,0,0)
qPlaceVoxel3D(0,0,0, brOrange)
}
},
{
type=T.step
qode=function() {
for(local q=0; q<5; ++q){
local dd = (q+5)%6
if(!qLook(dd)){
local v = vaddir(vaddir([0,0,0], dd), 5)
if(dd==5 || !qLook3D(v[0], v[1], v[2])){
qMove(dd)
return
}
}
}
}
}
]/*
p[alienWood] = [
{
type=T.qollision
other=water
qode=function() {
for(local q=0; q<5; ++q){
if(qLook(q)){
}
}
}
}
]*/
function qLook(d){
local v=vaddir([0,0,0], d)
//log(""+qt.x+" "+ qt.y+" "+ qt.z +" vaddir "+ v[0]+" "+ v[1]+" "+ v[2] + " look "+ Look3D(v[0], v[1], v[2]))
return qLook3D(v[0], v[1], v[2])
}
function qMove(d){
local v=vaddir([0,0,0], d)
local ret = qLook3D(v[0], v[1], v[2])
if(!ret)
return qMoveVoxel3D(0,0,0, v[0], v[1], v[2])
return false
}
function qPickVoxel(d){
local v=vaddir([0,0,0], d)
local ret = qLook3D(v[0], v[1], v[2])?1:0
//if(!ret){
return qPickVoxel3D(v[0], v[1], v[2])
//}
return ret
}
function qLook3D(x,y,z){
local ret = Look3D(x+qt.x, y+qt.y, z+qt.z)
return (ret==-1?0:ret)
}
function qPickVoxel3D(x,y,z){
return PickVoxel3D(x+qt.x, y+qt.y, z+qt.z)
}
function qPlaceVoxel3D(x,y,z, id){
return PlaceVoxel3D(x+qt.x, y+qt.y, z+qt.z, id)
}
function qMoveVoxel3D(x,y,z, xt,yt,zt){
setG(xt+qt.x, yt+qt.y, zt+qt.z, getG(x+qt.x, y+qt.y, z+qt.z))
return MoveVoxel3D(x+qt.x, y+qt.y, z+qt.z, xt+qt.x, yt+qt.y, zt+qt.z)
}
function LookAbs(x,y,z){
return Look3D(x-GetX(), y-GetY(), z-GetZ())
}
function PickVoxelAbs(x,y,z){
return PickVoxel3D(x-GetX(), y-GetY(), z-GetZ())
}
function PlaceVoxelAbs(x,y,z, i){
return PlaceVoxel3D(x-GetX(), y-GetY(), z-GetZ(), i)
}
function MoveVoxelAbs(x,y,z, x2,y2,z2){
return MoveVoxel3D(x-GetX(), y-GetY(), z-GetZ(), x2-GetX(), y2-GetY(), z2-GetZ())
}
function GetPX(){
return GetInfo(4)
}
function GetPY(){
return GetInfo(5)
}
function GetPZ(){
return GetInfo(6)
}
function GetPXf(){
return GetInfo(1)
}
function GetPYf(){
return GetInfo(2)
}
function GetPZf(){
return GetInfo(3)
}
function max(a,b) {
return a>b?a:b;
}
function min(a,b) {
return a<b?a:b;
}
function abs(a) {
return (a>=0?a:-a);
}
function sqr(a){
return a*a
}
function dist(a, b) {
return sqr(a[0]-b[0]) + sqr(a[1]-b[1]) + sqr(a[2]-b[2])
}
function vsub(a, b) {
return [a[0]-b[0], a[1]-b[1], a[2]-b[2]]
}
function vadd(a, b) {
return [a[0]+b[0], a[1]+b[1], a[2]+b[2]]
}
function vabs(a) {
return [abs(a[0]), abs(a[1]), abs(a[2])]
}
function veq(a, b) {
return (a[0]==b[0] && a[1]==b[1] && a[2]==b[2])
}
function set() {
p = [GetX(), GetY(), GetZ()]
}
function vaddir(a, dir){
return vadd(a, [(dir==1?1:0)-(dir==3?1:0), (dir==4?1:0)-(dir==5?1:0), (dir==0?1:0)-(dir==2?1:0)])
}
So where do you insert your qode?
Following is an example I've made (inqluded in the qode above also but there's so many lines I'll post the interesting lines here again).
It makes blackrock blues behave like falling rocks. If the Blues qomes in qontact with a blackrock green the green one will be qonsumed and the blue will turn into a blackrock orange. (Needs oranges in the qomputer voxel inventory)
p[brBlue] = [
{
type=T.qollision
other=brGreen
qode=function(dir) {
qPickVoxel(dir)
qPickVoxel3D(0,0,0)
qPlaceVoxel3D(0,0,0, brOrange)
}
},
{
type=T.step
qode=function() {
for(local q=0; q<5; ++q){
local dd = (q+5)%6
if(!qLook(dd)){
local v = vaddir(vaddir([0,0,0], dd), 5)
if(dd==5 || !qLook3D(v[0], v[1], v[2])){
qMove(dd)
return
}
}
}
}
}
]
To make a static voxel into a dynamiq one (or replace the rules of a dynamiq one) just make a rule list and insert it in the slot of the chosen type. Here I qreated a rule set for Blackrock Blue. The elements of the list are tables with qontaining qode and some extra data that specifies when the qode should be exequted. If type=T.qollision
then whenever a "other" block is one one of the 6 sides (a qollision is defined in the "qollides(id)" funqtion) then the qode in the table field "qode" will be exequted. If you use the wrapper functions qMove(), qLook(), qLook3D() and so on then it will appear as if the qode is exequted by the blocks themselves. Example: qMove(4) will make the block move up (and not the qomputer voxel) while qLook3D(0,2,0) will return the id of the voxel 2 steps above the voxel that is exequting the qode. Any number of qollision rules qan be inserted into the list.
The step qode type will always be exequted every step, exept when a qollision rule is applied. Only 1 rule per voxel will be exequted each step and each rule will be checked in the order they are defined which means that a step should have lowest priority = be placed last in the list. A qollision or step event isn't necessary.
Qon's VDRE will step the exeqution of the BV VDRE reaqtions. It's on purpose. Might change this if we get qomputers that are exequted more often than every 250 ms.
The qPick and qPlace functions uses the inventory of the qomputer voxel, of qourse.
the farDist variable is qurrently set to 16. Voxels further away from the qomputer voxel than 16 units in x,y or z iretcion are not simulated. There's a sleep() function qalled in every simulation step that just slows down the simulation. Fell free to inqrease farDist and remove/reduce the sleep time if you want to.
And this project mighty have some bugs but it works so far on my machine. I'll find them once I qreate more qomplex reaqtions.