datablock StaticShapeData(LuaLogic_RobotShapeData) { shapeFile = $LuaLogic::Path @ "bricks/special/cube.dts"; }; datablock fxDTSBrickData(LogicGate_RobotController_Data) { brickFile = $LuaLogic::Path @ "bricks/blb/RobotController.blb"; category = "Logic Bricks"; subCategory = "Special"; uiName = "Robot Controller"; iconName = $LuaLogic::Path @ "icons/Robot Controller"; hasPrint = 1; printAspectRatio = "Logic"; orientationFix = 3; isLogic = true; isLogicGate = true; //isLogicInput = true; logicInit = lualogic_readfile($LuaLogic::Path @ "bricks/special/robot-init.lua" ); logicUpdate = lualogic_readfile($LuaLogic::Path @ "bricks/special/robot-update.lua"); logicInput = lualogic_readfile($LuaLogic::Path @ "bricks/special/robot-input.lua" ); logicUIName = "Robot Controller"; logicUIDesc = "Creates and controls a mobile robot that can detect and place bricks"; numLogicPorts = 22; logicPortType[0] = 1; logicPortPos[0] = "15 -3 0"; logicPortDir[0] = 3; logicPortUIName[0] = "ColorIn0"; logicPortType[1] = 1; logicPortPos[1] = "13 -3 0"; logicPortDir[1] = 3; logicPortUIName[1] = "ColorIn1"; logicPortType[2] = 1; logicPortPos[2] = "11 -3 0"; logicPortDir[2] = 3; logicPortUIName[2] = "ColorIn2"; logicPortType[3] = 1; logicPortPos[3] = "9 -3 0"; logicPortDir[3] = 3; logicPortUIName[3] = "ColorIn3"; logicPortType[4] = 1; logicPortPos[4] = "7 -3 0"; logicPortDir[4] = 3; logicPortUIName[4] = "ColorIn4"; logicPortType[5] = 1; logicPortPos[5] = "5 -3 0"; logicPortDir[5] = 3; logicPortUIName[5] = "ColorIn5"; logicPortType[6] = 1; logicPortPos[6] = "1 -3 0"; logicPortDir[6] = 3; logicPortUIName[6] = "Destroy Brick"; logicPortCauseUpdate[6] = true; logicPortType[7] = 1; logicPortPos[7] = "-1 -3 0"; logicPortDir[7] = 3; logicPortUIName[7] = "Plant Brick"; logicPortCauseUpdate[7] = true; logicPortType[8] = 1; logicPortPos[8] = "-5 -3 0"; logicPortDir[8] = 3; logicPortUIName[8] = "Move Down"; logicPortCauseUpdate[8] = true; logicPortType[9] = 1; logicPortPos[9] = "-7 -3 0"; logicPortDir[9] = 3; logicPortUIName[9] = "Move Up"; logicPortCauseUpdate[9] = true; logicPortType[10] = 1; logicPortPos[10] = "-9 -3 0"; logicPortDir[10] = 3; logicPortUIName[10] = "Move Right"; logicPortCauseUpdate[10] = true; logicPortType[11] = 1; logicPortPos[11] = "-11 -3 0"; logicPortDir[11] = 3; logicPortUIName[11] = "Move Left"; logicPortCauseUpdate[11] = true; logicPortType[12] = 1; logicPortPos[12] = "-13 -3 0"; logicPortDir[12] = 3; logicPortUIName[12] = "Move Backward"; logicPortCauseUpdate[12] = true; logicPortType[13] = 1; logicPortPos[13] = "-15 -3 0"; logicPortDir[13] = 3; logicPortUIName[13] = "Move Forward"; logicPortCauseUpdate[13] = true; logicPortType[14] = 0; logicPortPos[14] = "15 3 0"; logicPortDir[14] = 1; logicPortUIName[14] = "ColorOut0"; logicPortType[15] = 0; logicPortPos[15] = "13 3 0"; logicPortDir[15] = 1; logicPortUIName[15] = "ColorOut1"; logicPortType[16] = 0; logicPortPos[16] = "11 3 0"; logicPortDir[16] = 1; logicPortUIName[16] = "ColorOut2"; logicPortType[17] = 0; logicPortPos[17] = "9 3 0"; logicPortDir[17] = 1; logicPortUIName[17] = "ColorOut3"; logicPortType[18] = 0; logicPortPos[18] = "7 3 0"; logicPortDir[18] = 1; logicPortUIName[18] = "ColorOut4"; logicPortType[19] = 0; logicPortPos[19] = "5 3 0"; logicPortDir[19] = 1; logicPortUIName[19] = "ColorOut5"; logicPortType[20] = 0; logicPortPos[20] = "1 3 0"; logicPortDir[20] = 1; logicPortUIName[20] = "Brick Detected"; logicPortType[21] = 1; logicPortPos[21] = "-1 3 0"; logicPortDir[21] = 1; logicPortUIName[21] = "Detect Brick"; logicPortCauseUpdate[21] = true; }; function LogicGate_RobotController_Data::LuaLogic_Callback(%this, %brick, %data) { %robot = %brick.luaLogicRobot; if(!isObject(%robot)) { talk("brick " @ %brick @ " has no robot!"); return; } %pos = %robot.getPosition(); initContainerBoxSearch(%pos, "0.49 0.49 0.19", $TypeMasks::FxBrickAlwaysObjectType); %tbrick = containerSearchNext(); %output = ""; for(%i=0; %i<getFieldCount(%data); %i++) { %field = getField(%data, %i); %first = getWord(%field, 0); if(%first $= "D") { // remove / detect brick if(isObject(%tbrick)) { %field = "B" @ 1 SPC %tbrick.getColorId() SPC %tbrick.getColorFxID() SPC %tbrick.getShapeFxId() SPC %tbrick.isRaycasting() SPC %tbrick.isColliding() SPC %tbrick.isRendering(); %output = %output @ %field @ "\t"; } else { %output = %output @ "B 0 0 0 0 0 0 0\t"; } } else if(%first $= "R") { if(isObject(%tbrick)) { %tbrick.schedule(0, delete); } } else if(%first $= "P") { // plant brick LogicRobot_CreateBrickGroup(); if(!isObject(%tbrick)) { %nbrick = new fxDTSBrick() { datablock = brick1x1fData; position = %pos; colorId = getWord(%field, 1); colorFxId = getWord(%field, 2); shapeFxId = getWord(%field, 3); isPlanted = 1; }; %nbrick.setTransform(%pos SPC "0 0 1 0"); %err = %nbrick.plant(); if(%err != 0 && %err != 2 && %err != 3) { %nbrick.delete(); } else { %nbrick.setRaycasting(getWord(%field, 4)); %nbrick.setColliding (getWord(%field, 5)); %nbrick.setRendering (getWord(%field, 6)); BrickGroup_12345678.add(%nbrick); %nbrick.setTrusted(1); } } } else if(%first $= "M") { // move %pos = getWords(%field, 1, 3); %rot = getWord(%field, 4); %robot.setTransform(%pos SPC "0 0 1" SPC (%rot*$pi/2)); } else { talk("invalid robot callback " @ %field); } } lualogic_sendinput(%brick, 1, trim(%output)); } function LogicGate_RobotController_Data::getRelativeVector(%this, %obj, %vec) { %rot = %obj.angleID; %x = getWord(%vec, 0); %y = getWord(%vec, 1); %z = getWord(%vec, 2); %ax = %x; switch(%rot) { case 1: %x = %y; %y = -%ax; case 2: %x = -%x; %y = -%y ; case 3: %x = -%y; %y = %ax; } return %x SPC %y SPC %z; } function LogicRobot_CreateBrickGroup() { if(!isObject(BrickGroup_12345678)) { new SimGroup(BrickGroup_12345678) { bl_id = 12345678; name = "\c1Robot"; QuotaObject = GlobalQuota; }; mainBrickGroup.add(BrickGroup_12345678); } } function LogicGate_RobotController_Data::createRobot(%this, %obj) { if(isObject(%obj.luaLogicRobot)) return; %pos = %obj.getPosition(); %rpos = vectorAdd(%pos, %this.getRelativeVector(%obj, "0.25 7.75 0")); %robot = new StaticShape() { datablock = LuaLogic_RobotShapeData; position = %rpos; }; %robot.setScale("1 1 1"); %robot.setNodeColor("ALL", "1 1 1 1"); missionCleanup.add(%robot); %obj.luaLogicRobot = %robot; } function LogicGate_RobotController_Data::Logic_onRemove(%this, %obj) { if(isObject(%obj.luaLogicRobot)) %obj.luaLogicRobot.delete(); } function LogicGate_RobotController_Data::Logic_onPlant(%this, %obj) { if(!isObject(%obj.luaLogicRobot)) %this.createRobot(%obj); } function LogicGate_RobotController_Data::Logic_onAdd(%this, %obj) { if(!isObject(%obj.luaLogicRobot)) %this.createRobot(%obj); lualogic_sendinput(%obj, 1, "P" @ %obj.luaLogicRobot.getPosition() SPC %obj.getAngleId()); }