function rom_reload() { exec($Con::File); } $lualogic_rom_maxheight = (2/5)*256; package lualogic_rom_update { function fxDtsBrick::onPlant(%brick) { parent::onPlant(%brick); lualogic_rom_updatebrick(%brick); } function fxDtsBrick::onLoadPlant(%brick) { parent::onLoadPlant(%brick); lualogic_rom_updatebrick(%brick); } function fxDTSBrick::onDeath(%brick) { parent::onDeath(%brick); %brick.lualogic_rom_delete = 1; lualogic_rom_updatebrick(%brick); } function fxDTSBrick::onRemove(%brick) { parent::onRemove(%brick); %brick.lualogic_rom_delete = 1; lualogic_rom_updatebrick(%brick, 1); } function fxDtsBrick::setRaycasting(%brick, %val) { parent::setRaycasting(%brick, %val); lualogic_rom_updatebrick(%brick); } }; schedule(0, 0, activatePackage, lualogic_rom_update); function lualogic_rom_updatebrick(%brick, %instant) { cancel(%brick.lualogic_rom_updatebrick_schedule); if(%instant) lualogic_rom_updatebrick_final(%brick); else %brick.lualogic_rom_updatebrick_schedule = schedule(100, 0, lualogic_rom_updatebrick_final, %brick); } function lualogic_rom_updatebrick_final(%brick) { if(!isObject(%brick)) return; if(%brick.lualogic_rom_delete) { if(%brick.lualogic_rom_deletedone) return; %brick.lualogic_rom_deletedone = 1; } // update any roms below %box = %brick.getWorldBox(); %boxl = getWords(%box, 0, 2); %boxlz = getWord(%boxl, 2); %boxh = getWords(%box, 3, 5); %boxs = vectorSub(%boxh, %boxl); %boxc = vectorAdd(%boxl, vectorScale(%boxs, 0.5)); %boxc = getWords(%boxc, 0, 1) SPC (%boxlz - $lualogic_rom_maxheight/2); %boxs = getWords(%boxs, 0, 1) SPC $lualogic_rom_maxheight; %boxs = vectorSub(%boxs, 0.5 SPC 0.5 SPC 0.1); initContainerBoxSearch(%boxc, %boxs, $TypeMasks::FxBrickAlwaysObjectType); while(%tbrick = containerSearchNext()) { %tdata = %tbrick.getDatablock(); if(%tdata.isLogicRom) { %rommaxz = getWord(%tbrick.getPosition(), 2) + (%tdata.brickSizeZ/10) + ((%tdata.logicRomZ$="" ? 1 : %tdata.logicRomZ)/5) - 0.1; if(%boxlz <= %rommaxz) { lualogic_rom_updatedata(%tbrick); } } } // if rom, update if(%brick.lualogic_rom_delete) return; if(%brick.getDatablock().isLogicRom) { lualogic_rom_updatedata(%brick); } } function lualogic_rom_updatedata(%brick) { cancel(%brick.lualogic_rom_updatedata_schedule); %brick.lualogic_rom_updatedata_schedule = schedule(1000, 0, lualogic_rom_updatedata_final, %brick); } function lualogic_rom_min(%a, %b) { return %a<%b ? %a : %b; } function lualogic_rom_max(%a, %b) { return %a>%b ? %a : %b; } function lualogic_rom_updatedata_final(%brick) { if(!isObject(%brick) || %brick.lualogic_rom_delete) return; // compute rom stud box %data = %brick.getDatablock(); %rx = (%brick.angleId%2==0) ? %data.logicRomX : %data.logicRomY; %ry = (%brick.angleId%2==0) ? %data.logicRomY : %data.logicRomX; %rz = (%data.logicRomZ$="") ? 1 : %data.logicRomZ; %rpos = vectorAdd(%brick.getPosition(), 0 SPC 0 SPC (%rz/10 + 1/10)); %rxc = getWord(%rpos, 0)* 4; %ryc = getWord(%rpos, 1)* 4; %rzc = getWord(%rpos, 2)*10; %rxl = %rxc - (%rx-1); %ryl = %ryc - (%ry-1); %rzl = %rzc - (%rz-1); %rxh = %rxc + (%rx-1); %ryh = %ryc + (%ry-1); %rzh = %rzc + (%rz-1); // generate box by brick's rom volume %boxs = vectorScale((%rx/4 - 1/4) SPC (%ry/4 - 1/4) SPC (%rz/10 - 1/10), 2); // for each brick in the scan box, add all of its volume to data array initContainerBoxSearch(%rpos, %boxs, $TypeMasks::FxBrickObjectType); while(isObject(%tbrick = containerSearchNext())) { if(%tbrick.isRaycasting()) { // compute target stud box %tdata = %tbrick.getDatablock(); %tx = (%tbrick.angleId%2==0) ? %tdata.brickSizeX : %tdata.brickSizeY; %ty = (%tbrick.angleId%2==0) ? %tdata.brickSizeY : %tdata.brickSizeX; %tz = %tdata.brickSizeZ; %tpos = %tbrick.getPosition(); %txl = getWord(%tpos, 0)* 4 - (%tx-1); %tyl = getWord(%tpos, 1)* 4 - (%ty-1); %tzl = getWord(%tpos, 2)*10 - (%tz-1); %txh = getWord(%tpos, 0)* 4 + (%tx-1); %tyh = getWord(%tpos, 1)* 4 + (%ty-1); %tzh = getWord(%tpos, 2)*10 + (%tz-1); // add each stud within volume overlap to array for(%x=lualogic_rom_max(%rxl, %txl); %x<=lualogic_rom_min(%rxh, %txh); %x+=2) { %xc = %x - %rxc; for(%y=lualogic_rom_max(%ryl, %tyl); %y<=lualogic_rom_min(%ryh, %tyh); %y+=2) { %yc = %y - %ryc; switch(%brick.angleId%4) { case 0: %xcr = %xc; %ycr = %yc; case 1: %xcr = -%yc; %ycr = %xc; case 2: %xcr = -%xc; %ycr = -%yc; case 3: %xcr = %yc; %ycr = -%xc; } for(%z=lualogic_rom_max(%rzl, %tzl); %z<=lualogic_rom_min(%rzh, %tzh); %z+=2) { %zc = %z - %rzc; %data_array[%xcr+0, %ycr+0, %zc+0] = 1; } } } } } // stringify array %data_str = ""; %rxd = %data.logicRomX - 1; %ryd = %data.logicRomY - 1; %rzd = (%data.logicRomZ$="" ? 1 : %data.logicRomZ) - 1; for(%z=-%rzd; %z<= %rzd; %z+=2) { %plane_str = ""; for(%y= %ryd; %y>=-%ryd; %y-=2) { %line_str = ""; for(%x=-%rxd; %x<= %rxd; %x+=2) { if(%data_array[%x+0, %y+0, %z+0]) { %line_str = %line_str @ "1"; } else { %line_str = %line_str @ "0"; } } %plane_str = %plane_str @ %line_str; } %data_str = %data_str @ %plane_str; } // send output //talk("rom" SPC %brick SPC %data_str); lualogic_sendinput(%brick, 1, %data_str); }