public void Engine() { do { var raw = _skyCompact.FetchCptRaw((ushort)_scriptVariables[LOGIC_LIST_NO]); var logicList = new UShortAccess(raw, 0); ushort id; while ((id = logicList[0]) != 0) { logicList.Offset += 2; // 0 means end of list if (id == 0xffff) { // Change logic data address raw = _skyCompact.FetchCptRaw(logicList[0]); logicList = new UShortAccess(raw, 0); continue; } _scriptVariables[CUR_ID] = id; _compact = _skyCompact.FetchCpt(id); // check the id actually wishes to be processed if ((_compact.Core.status & (1 << 6)) == 0) { continue; } // ok, here we process the logic bit system if ((_compact.Core.status & (1 << 7)) != 0) { _skyGrid.RemoveObjectFromWalk(_compact); } Debug.Instance.Logic(_compact.Core.logic); _logicTable[_compact.Core.logic](); if ((_compact.Core.status & (1 << 7)) != 0) { _skyGrid.ObjectToWalk(_compact); } // a sync sent to the compact is available for one cycle // only. that cycle has just ended so remove the sync. // presumably the mega has just reacted to it. _compact.Core.sync = 0; } // usually this loop is run only once, it'll only be run a second time if the game // script just asked the user to enter a copy protection code. // this is done to prevent the copy protection screen from flashing up. // (otherwise it would be visible for 1/50 second) } while (CheckProtection()); }
public ushort DoAutoRoute(Compact cpt) { var cptScreen = (byte)cpt.Core.screen; var cptWidth = (byte)SkyCompact.GetMegaSet(cpt).gridWidth; InitWalkGrid(cptScreen, cptWidth); byte startX, startY, destX, destY; short initStaX, initStaY, initDestX, initDestY; ClipCoordX(cpt.Core.xcood, out startX, out initStaX); ClipCoordY(cpt.Core.ycood, out startY, out initStaY); ClipCoordX(cpt.Core.arTargetX, out destX, out initDestX); ClipCoordY(cpt.Core.arTargetY, out destY, out initDestY); var raw = _skyCompact.FetchCptRaw(cpt.Core.animScratchId); Array.Clear(raw, 0, 64); var routeDest = new UShortAccess(raw, 0); if ((startX == destX) && (startY == destY)) { return(2); } var routeGrid = new UShortAccess(_routeGrid, 0); if (routeGrid[(destY + 1) * RouteGridWidth + destX + 1] != 0) { //if ((cpt == &Sky::SkyCompact::foster) && (cptScreen == 12) && (destX == 2) && (destY == 14)) { if (_skyCompact.CptIsId(cpt, (ushort)CptIds.Foster) && (cptScreen == 12) && (destX == 2) && (destY == 14)) { /* workaround for Scriptbug #1043047 * In screen 12 (the pipe factory) Joey can block Foster's target * coordinates (2/14). This is normally not too tragic, but in the * scene when foster gets thrown out by Lamb (first time you enter * the pipe factory), the game would enter an infinite loop. */ routeGrid[(destY + 1) * RouteGridWidth + destX + 1] = 0; // hide this part joey from the grid } else { return(1); // AR destination is an unaccessible block } } if (!CalcWalkGrid(startX, startY, destX, destY)) { return(1); // can't find route to block } var routeData = MakeRouteData(destX, destY); // the route is done. // if there was an initial x movement (due to clipping) tag it onto the start routeData = CheckInitMove(routeData, initStaX); byte cnt = 0; do { routeDest[cnt] = routeData[cnt]; routeDest[cnt + 1] = routeData[cnt + 1]; cnt += 2; } while (routeData[cnt - 2] != 0); return(0); }
private void PointerEngine(ushort xPos, ushort yPos) { UShortAccess currentList; var currentListNum = Logic.ScriptVariables[Logic.MOUSE_LIST_NO]; do { currentList = new UShortAccess(_skyCompact.FetchCptRaw((ushort)currentListNum), 0); while ((currentList[0] != 0) && (currentList[0] != 0xFFFF)) { var itemNum = currentList[0]; var itemData = _skyCompact.FetchCpt(itemNum); currentList.Offset += 2; if ((itemData.Core.screen == Logic.ScriptVariables[Logic.SCREEN]) && ((itemData.Core.status & 16) != 0)) { if (itemData.Core.xcood + itemData.Core.mouseRelX > xPos) { continue; } if (itemData.Core.xcood + itemData.Core.mouseRelX + itemData.Core.mouseSizeX < xPos) { continue; } if (itemData.Core.ycood + itemData.Core.mouseRelY > yPos) { continue; } if (itemData.Core.ycood + itemData.Core.mouseRelY + itemData.Core.mouseSizeY < yPos) { continue; } // we've hit the item if (Logic.ScriptVariables[Logic.SPECIAL_ITEM] == itemNum) { return; } Logic.ScriptVariables[Logic.SPECIAL_ITEM] = itemNum; if (Logic.ScriptVariables[Logic.GET_OFF] != 0) { Logic.MouseScript(Logic.ScriptVariables[Logic.GET_OFF], itemData); } Logic.ScriptVariables[Logic.GET_OFF] = itemData.Core.mouseOff; if (itemData.Core.mouseOn != 0) { Logic.MouseScript(itemData.Core.mouseOn, itemData); } return; } } if (currentList[0] == 0xFFFF) { currentListNum = currentList[1]; } } while (currentList[0] != 0); if (Logic.ScriptVariables[Logic.SPECIAL_ITEM] != 0) { Logic.ScriptVariables[Logic.SPECIAL_ITEM] = 0; if (Logic.ScriptVariables[Logic.GET_OFF] != 0) { Logic.Script((ushort)Logic.ScriptVariables[Logic.GET_OFF], (ushort)(Logic.ScriptVariables[Logic.GET_OFF] >> 16)); } Logic.ScriptVariables[Logic.GET_OFF] = 0; } }