private bool FnGetTo(uint targetPlaceId, uint mode, uint c) { _compact.Core.upFlag = (ushort)mode; // save mode for action script _compact.Core.mode += 4; // next level up Compact cpt = _skyCompact.FetchCpt(_compact.Core.place); if (cpt == null) { // TODO: warning("can't find _compact's getToTable. Place compact is NULL"); return(false); } var raw = _skyCompact.FetchCptRaw(cpt.Core.getToTableId); if (raw == null) { //TODO: warning("Place compact's getToTable is NULL"); return(false); } var getToTable = new UShortAccess(raw, 0); while (getToTable.Value != targetPlaceId) { getToTable.Offset += 4; } // get new script SkyCompact.GetSub(_compact, _compact.Core.mode).Field = getToTable[1]; SkyCompact.GetSub(_compact, (ushort)(_compact.Core.mode + 2)).Field = 0; return(false); // drop out of script }
private bool FnStartSub(uint scr, uint b, uint c) { _compact.Core.mode += 4; SkyCompact.GetSub(_compact, _compact.Core.mode).Field = (ushort)(scr & 0xffff); SkyCompact.GetSub(_compact, (ushort)(_compact.Core.mode + 2)).Field = (ushort)(scr >> 16); return(false); }
private void Stopped() { // waiting for another mega to move or give-up trying // // this mode will always be set up from a special script // that will be one level higher than the script we // would wish to restart from Compact cpt = _skyCompact.FetchCpt(_compact.Core.waitingFor); if (cpt != null) { if (cpt.Core.mood == 0 && Collide(cpt)) { return; } } // we are free, continue processing the script // restart script one level below SkyCompact.GetSub(_compact, _compact.Core.mode - 2).Field = 0; _compact.Core.waitingFor = 0xffff; _compact.Core.logic = L_SCRIPT; LogicScript(); }
private void Alt() { // change the current script _compact.Core.logic = L_SCRIPT; SkyCompact.GetSub(_compact, _compact.Core.mode).Field = _compact.Core.alt; SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0; LogicScript(); }
private bool FnTheyStartSub(uint mega, uint scr, uint c) { Compact cpt = _skyCompact.FetchCpt((ushort)mega); cpt.Core.mode += 4; SkyCompact.GetSub(cpt, cpt.Core.mode).Field = (ushort)(scr & 0xffff); SkyCompact.GetSub(cpt, (ushort)(cpt.Core.mode + 2)).Field = (ushort)(scr >> 16); return(true); }
private bool FnInteract(uint targetId, uint b, uint c) { _compact.Core.mode += 4; // next level up _compact.Core.logic = L_SCRIPT; var cpt = _skyCompact.FetchCpt((ushort)targetId); SkyCompact.GetSub(_compact, _compact.Core.mode).Field = cpt.Core.actionScript; SkyCompact.GetSub(_compact, (ushort)(_compact.Core.mode + 2)).Field = 0; return(false); }
private void StopAndWait() { _compact.Core.mode += 4; var scriptNo = SkyCompact.GetSub(_compact, _compact.Core.mode); var offset = SkyCompact.GetSub(_compact, _compact.Core.mode + 2); scriptNo.Field = _compact.Core.stopScript; offset.Field = 0; _compact.Core.logic = L_SCRIPT; LogicScript(); }
/// <summary> /// This function is basicly a wrapper around the real script engine. It runs /// the script engine until a script has finished. /// </summary> private void LogicScript() { // Process the current mega's script // If the script finishes then drop back a level for (;;) { ushort mode = _compact.Core.mode; // get pointer to current script var scriptNo = SkyCompact.GetSub(_compact, mode); var offset = SkyCompact.GetSub(_compact, (ushort)(mode + 2)); offset.Field = Script(scriptNo.Field, offset.Field); if (offset.Field == 0) // script finished { _compact.Core.mode -= 4; } else if (_compact.Core.mode == mode) { return; } } }
private void ArAnim() { // Follow a route // Mega should be in getToMode // only check collisions on character boundaries if (((_compact.Core.xcood & 7) != 0) || ((_compact.Core.ycood & 7) != 0)) { MainAnim(); return; } // On character boundary. Have we been told to wait? // if not - are WE colliding? if (_compact.Core.waitingFor == 0xffff) { // 1st cycle of re-route does not require collision checks MainAnim(); return; } if (_compact.Core.waitingFor != 0) { // ok, we've been told we've hit someone // we will wait until we are no longer colliding // with them. here we check to see if we are (still) colliding. // if we are then run the stop script. if not clear the flag // and continue. // remember - this could be the first ar cycle for some time, // we might have been told to wait months ago. if we are // waiting for one person then another hits us then // c_waiting_for will be replaced by the new mega - this is // fine because the later collision will almost certainly // take longer to clear than the earlier one. if (Collide(_skyCompact.FetchCpt(_compact.Core.waitingFor))) { StopAndWait(); return; } // we are not in fact hitting this person so clr & continue // it must have registered some time ago _compact.Core.waitingFor = 0; // clear id flag } // ok, our turn to check for collisions var logicList = new UShortAccess(_skyCompact.FetchCptRaw((ushort)_scriptVariables[LOGIC_LIST_NO]), 0); ushort id; while ((id = logicList[0]) != 0) { // get an id logicList.Offset += 2; if (id == 0xffff) { // address change? logicList = new UShortAccess(_skyCompact.FetchCptRaw(logicList[0]), 0); // get new logic list continue; } if (id == (ushort)(_scriptVariables[CUR_ID] & 0xffff)) // is it us? { continue; } _scriptVariables[HIT_ID] = id; // save target id for any possible c_mini_bump var cpt = _skyCompact.FetchCpt(id); if ((cpt.Core.status & (1 << ST_COLLISION_BIT)) == 0) // can it collide? { continue; } if (cpt.Core.screen != _compact.Core.screen) // is it on our screen? { continue; } if (Collide(cpt)) { // check for a hit // ok, we've hit a mega // is it moving... or something else? if (cpt.Core.logic != L_AR_ANIM) { // check for following route // it is doing something else // we restart our get-to script // first tell it to wait for us - in case it starts moving // ( *it may have already hit us and stopped to wait ) _compact.Core.waitingFor = 0xffff; // effect 1 cycle collision skip // tell it it is waiting for us cpt.Core.waitingFor = (ushort)(_scriptVariables[CUR_ID] & 0xffff); // restart current script SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0; _compact.Core.logic = L_SCRIPT; LogicScript(); return; } Script(_compact.Core.miniBump, 0); return; } } // ok, there was no collisions // now check for interaction request // *note: the interaction is always set up as an action script if (_compact.Core.request != 0) { _compact.Core.mode = C_ACTION_MODE; // put into action mode _compact.Core.actionSub = _compact.Core.request; _compact.Core.actionSub_off = 0; _compact.Core.request = 0; // trash request _compact.Core.logic = L_SCRIPT; LogicScript(); return; } // any flag? - or any change? // if change then re-run the current script, which must be // a position independent get-to ---- if (_compact.Core.atWatch == 0) { // any flag set? MainAnim(); return; } // ok, there is an at watch - see if it's changed if (_compact.Core.atWas == _scriptVariables[_compact.Core.atWatch / 4]) { // still the same? MainAnim(); return; } // changed so restart the current script // *not suitable for base initiated ARing SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0; _compact.Core.logic = L_SCRIPT; LogicScript(); }