private void HandleStrafing(Quaternion rotation, SuperObject *rayman, float strafeX, float strafeY)
        {
            float strafeSpeed = (float)Math.Sqrt(strafeX * strafeX + strafeY * strafeY);

            float *padAnalogForce = ((float *)0x4B9B78);

            *padAnalogForce = strafeSpeed;

            float *padTrueAnalogForce = ((float *)0x4B9B7C);

            *padTrueAnalogForce = strafeSpeed;

            float *padGlobalX = ((float *)0x4B9B68);
            float *padGlobalY = ((float *)0x4B9B6C);

            Vector3 rotationEuler = rotation.ToEuler();

            double strafeAngle = Math.Atan2(strafeY, strafeX);

            if (double.IsNaN(strafeAngle) || double.IsInfinity(strafeAngle))
            {
                strafeAngle = 0;
            }

            *padGlobalX = strafeSpeed * (float)Math.Sin(rotationEuler.Z - strafeAngle + quarterTau);
            *padGlobalY = strafeSpeed * -(float)Math.Cos(rotationEuler.Z - strafeAngle + quarterTau);

            float *padRotationAngle = ((float *)0x4B9B80);

            *padRotationAngle = (float)(strafeAngle * 180 / Math.PI);

            int *padSector = ((int *)0x4B9B84);

            *padSector = GetPadSector(strafeX, strafeY);
        }
        public int MarioFunction(SuperObject *spo, int *nodeInterp)
        {
            RaymanState state          = RaymanState.Inactive;
            byte        dsgVar16_value = 0;
            int *       idleTimer      = null;

            if (spo->PersoData->GetModelName(w) == "YLT_RaymanModel")
            {
                var dsgVars = spo->PersoData->GetDsgVarList();
                dsgVar16_value = *(byte *)dsgVars[16].valuePtrCurrent.ToPointer();
                byte dsgVar9_value = *(byte *)dsgVars[9].valuePtrCurrent.ToPointer();
                state     = (RaymanState)dsgVar9_value;
                idleTimer = (int *)dsgVars[24].valuePtrCurrent;
            }

            bool strafing = InputStructure.GetInputStructure()->GetEntryAction(EntryActionNames.Action_Strafe)->IsValidated();

            if (spo->PersoData->GetInstanceName(w) != "Rayman" || dsgVar16_value != 1 || !AllowTankControlState(state))
            {
                currentSpeed = 0;

                return(EngineFunctions.fn_p_stReadAnalogJoystickMario.Call(spo, nodeInterp));
            }

            int result = OriginalScript(spo, nodeInterp);

            DoTankControls(spo, state, strafing, idleTimer);

            return(result);
        }
示例#3
0
        private void RandomizeAllObjects(World world)
        {
            world.ReadObjectNames();
            Dictionary <string, Pointer <SuperObject> > superObjects = world.GetActiveSuperObjects();

            foreach (SuperObject *superObject in superObjects.Values)
            {
                Perso *perso       = (Perso *)superObject->engineObjectPtr;
                int    aiModelID   = perso->stdGamePtr->modelID;
                string aiModelName = world.ObjectNames[ObjectSet.Model][aiModelID];

                if (aiModelName == "DS1_GEN_PTC_GenCKS" || aiModelName == "DS1_GEN_PTC_GenBigFile")
                {
                    perso->brain = null;
                    continue;
                }

                RandomizeObject(superObject);
            }

            SuperObject *global  = superObjects["global"];
            DsgMem *     dsgMem  = ((Perso *)global->engineObjectPtr)->brain->mind->dsgMem;
            DsgVar *     dsgVars = *dsgMem->dsgVar;
            DsgVarInfo   info    = dsgVars->dsgVarInfos[63];

            bool *bool63 = (bool *)((int)dsgMem->memoryBufferCurrent + info.offsetInBuffer);

            *bool63 = false;
        }
示例#4
0
        public Dictionary <string, Pointer <SuperObject> > GetActiveSuperObjects()
        {
            const int offDynamWorld = 0x0500FD0;
            Dictionary <string, Pointer <SuperObject> > result = new Dictionary <string, Pointer <SuperObject> >();

            SuperObject *superObject = (SuperObject *)Memory.GetPointerAtOffset(offDynamWorld, 0x8, 0x0);

            while (superObject != null)
            {
                Perso *perso = (Perso *)superObject->engineObjectPtr;
                if (perso != null)
                {
                    StandardGame *offStdGame = perso->stdGamePtr;
                    int           nameIndex  = offStdGame->instanceID;
                    string        name       = $"unknown_{(int)superObject:X}";

                    if (nameIndex >= 0 && nameIndex < ObjectNames[ObjectSet.Instance].Length)
                    {
                        name = ObjectNames[ObjectSet.Instance][nameIndex];
                    }

                    if (!result.ContainsKey(name))
                    {
                        result.Add(name, superObject);
                    }
                }

                superObject = superObject->nextBrother;
            }

            return(result);
        }
示例#5
0
        public TreeNode NewTreeNode(string text, IconId iconId, SuperObject *tag = null)
        {
            TreeNode node = new TreeNode(text, (int)iconId, (int)iconId);

            node.Name = text;
            node.Tag  = tag == null ? null : (Pointer <SuperObject>)tag;

            return(node);
        }
        private char PLA_fn_bSetNewState(SuperObject *persoSpo, LinkedList.ListElement_HHP <State> *state, char force, char withEvents, char setAnim)
        {
            if (persoSpo == rayman && playTurnAnimation)
            {
                int stateIndex = persoSpo->PersoData->GetStateIndex(state);
                if (stateIndex == 0)
                {
                    return((char)0);
                }
            }

            return(EngineFunctions.PLA_fn_bSetNewState.Call(persoSpo, state, force, withEvents, setAnim));
        }
        private static int OriginalScript(SuperObject *spo, int *nodeInterp)
        {
            // This is necessary because the script calls this function as "StdCamer.PAD_ReadAnalogJoystickMarioMode",
            // and the scripting engine keeps track of which object is executing a function (two ultra operator functions)
            *(int *)(Offsets.Globals.g_hCurrentSuperObjPerso) = 0;

            int *param = (int *)Marshal.AllocHGlobal(512);
            int *v4    = (int *)EngineFunctions.fn_p_stEvalTree.Call(spo, nodeInterp, param);
            int *v5    = (int *)EngineFunctions.fn_p_stEvalTree.Call(spo, v4, param);
            int *v7    = (int *)EngineFunctions.fn_p_stEvalTree.Call(spo, v5, param);
            int *v8    = (int *)EngineFunctions.fn_p_stEvalTree.Call(spo, v7, param);
            int *v9    = (int *)EngineFunctions.fn_p_stEvalTree.Call(spo, v8, param); // dsgVar_16 ? 1f : 0f

            int *v10 = (int *)EngineFunctions.fn_p_stEvalTree.Call(spo, v9, param);

            return(EngineFunctions.fn_p_stEvalTree.Call(spo, v10, param));
        }
示例#8
0
        public int GenerateAlwaysObject(SuperObject *spawnedBy, Perso *alwaysPerso, Vector3 position)
        {
            if (spawnedBy == null)
            {
                throw new NullReferenceException("GenerateAlwaysObject: spawnedBy is not allowed to be null!");
            }

            int[] interp =
            {
                0x00000042,       // Func_GenerateObj
                0x03020000,
                (int)alwaysPerso, // arg0, Perso to generate
                0x17030000,       // arg1, Vector3
                0x00000000,
                0x10030000,
                BitConverter.ToInt32(BitConverter.GetBytes(position.X), 0), // x
                0x0D040000,
                BitConverter.ToInt32(BitConverter.GetBytes(position.Y), 0), // y
                0x0D040000,
                BitConverter.ToInt32(BitConverter.GetBytes(position.Z), 0), // z
                0x0D040000,
            };

            // TODO: use ArrayPtr()

            IntPtr interpArray = Marshal.AllocHGlobal(interp.Length * 4);

            for (int i = 0; i < interp.Length; i++)
            {
                Marshal.WriteInt32(interpArray, i * 4, interp[i]);
            }

            IntPtr paramArray = Marshal.AllocHGlobal(0x20 * 4);

            IntPtr interpPtrStart = interpArray + 0x8; // we start at the second node of the interpreter tree

            EngineFunctions.MiscFunction.Call((int)spawnedBy, (int)interpPtrStart, (int)paramArray);

            return(*(int *)paramArray.ToPointer());
        }
示例#9
0
文件: Acp.cs 项目: raytools/R2ObjView
 public static extern int XAI_fn_lEnumSpoDsgVars(SuperObject *p_stSpo, XAI_tdfnEnumDsgVarCallback p_fnCallback);
示例#10
0
文件: Acp.cs 项目: raytools/R2ObjView
 public static extern int XHIE_fn_lEnumSpoChildren(SuperObject *p_stSpo, XHIE_tdfnEnumSpoCallback p_fnCallback);
示例#11
0
文件: Acp.cs 项目: raytools/R2ObjView
 public static extern string XHIE_fn_szGetObjectName(SuperObject *p_stSpo, XHIE_OI_TYPE ulInfoType);
        private void DoTankControls(SuperObject *spo, RaymanState state, bool strafing, int *idleTimer)
        {
            EntryAction *leftAction    = *(EntryAction **)0x4B9B90;
            EntryAction *rightAction   = *(EntryAction **)0x4B9B94;
            EntryAction *forwardAction = *(EntryAction **)0x4B9B88;
            EntryAction *backAction    = *(EntryAction **)0x4B9B8C;
            EntryAction *shiftAction   = *(EntryAction **)0x4B9B98;

            rayman = spo;
            var transformationMatrix = rayman->PersoData->dynam->DynamicsAsBigDynamics->matrixA.TransformationMatrix;
            var rotation             = Quaternion.CreateFromRotationMatrix(transformationMatrix);

            float rotationSpeedTarget = ((leftAction->IsValidated() ? 1f : 0) + (rightAction->IsValidated() ? -1f : 0)) * maxRotationSpeed * (shiftAction->IsValidated()?0.75f:1f);

            if (state == RaymanState.Swimming || state == RaymanState.Sliding)
            {
                rotationSpeedTarget *= 8.0f;
            }

            // Interpolate to target speed
            rotationSpeed += (rotationSpeedTarget - rotationSpeed) * rotationSpeedLerp;

            if (state == RaymanState.LedgeGrab)
            {
                if (forwardAction->IsValidated())
                {
                    currentSpeed = 10;
                }
                else if (backAction->IsValidated())
                {
                    currentSpeed = -10;
                }
                else
                {
                    currentSpeed = 0;
                }
            }
            else if (strafing && state != RaymanState.Swimming && state != RaymanState.Sliding)
            {
                float strafeX = ((leftAction->IsValidated() ? 1f : 0) + (rightAction->IsValidated() ? -1f : 0));
                float strafeY = ((forwardAction->IsValidated() ? 1f : 0) + (backAction->IsValidated() ? -1f : 0));

                float strafeMagnitude = (float)Math.Sqrt(strafeX * strafeX + strafeY * strafeY);

                if (strafeMagnitude == 0 || float.IsNaN(strafeMagnitude) || float.IsInfinity(strafeMagnitude))
                {
                    strafeMagnitude = 1.0f;
                }

                // Normalize and set length to 100
                strafeX *= 100.0f / strafeMagnitude;
                strafeY *= 100.0f / strafeMagnitude;

                HandleStrafing(rotation, rayman, strafeX, strafeY);

                return;
            }
            else
            {
                // Can be turning?
                if (state == RaymanState.Idle)
                {
                    var entryActions = InputStructure.GetInputStructure()->EntryActions;

                    int[] bannedActions = new int[] { (int)EntryActionNames.Action_Tirer, (int)EntryActionNames.Action_Sauter };

                    bool usingBannedAction = bannedActions.Where(a => entryActions[a]->IsValidated()).Count() > 0;

                    if (!usingBannedAction)
                    {
                        if (rightAction->IsValidated() && !leftAction->IsValidated())
                        {
                            if (rayman->PersoData->GetStateIndex() != 70)
                            {
                                rayman->PersoData->SetState(70);
                            }
                            playTurnAnimation = true;
                        }
                        else if (leftAction->IsValidated() && !rightAction->IsValidated())
                        {
                            if (rayman->PersoData->GetStateIndex() != 71)
                            {
                                rayman->PersoData->SetState(71);
                            }
                            playTurnAnimation = true;
                        }
                        else
                        {
                            playTurnAnimation = false;
                        }
                    }
                }

                rotation *= Quaternion.CreateFromYawPitchRoll(0, 0, rotationSpeed); // Add rotation

                float targetSpeed = (forwardAction->IsValidated() ? 100f : 0f) * (shiftAction->IsValidated() ? 0.5f : 1f);
                currentSpeed += (targetSpeed - currentSpeed) * 0.1f;
            }

            if (currentSpeed > 0 && currentSpeed < 0.5f)
            {
                currentSpeed = 0;
            }

            if (currentSpeed < 70 && Math.Abs(rotationSpeed) > 0.01f && state == RaymanState.Sliding)
            {
                currentSpeed = 70;
            }

            WriteVariables(rotation, rotationSpeed, transformationMatrix, rayman);
        }
        private void WriteVariables(Quaternion rotation, float rotationDelta, Matrix4x4 transformationMatrix, SuperObject *rayman)
        {
            float *padAnalogForce = ((float *)0x4B9B78);

            *padAnalogForce = currentSpeed;

            float *padTrueAnalogForce = ((float *)0x4B9B7C);

            *      padTrueAnalogForce = currentSpeed;
            float *padGlobalX         = ((float *)0x4B9B68);
            float *padGlobalY         = ((float *)0x4B9B6C);

            Vector3 rotationEuler = rotation.ToEuler();

            *padGlobalX = currentSpeed * (float)Math.Sin(rotationEuler.Z);
            *padGlobalY = currentSpeed * -(float)Math.Cos(rotationEuler.Z);

            float *padRotationAngle = ((float *)0x4B9B80);

            *padRotationAngle = rotationDelta * 100.0f;

            var newMatrix = Matrix4x4.CreateFromQuaternion(rotation);

            newMatrix.Translation = transformationMatrix.Translation;

            rayman->PersoData->dynam->DynamicsAsBigDynamics->matrixA.TransformationMatrix = newMatrix;
            rayman->PersoData->dynam->DynamicsAsBigDynamics->matrixB.TransformationMatrix = newMatrix;
        }
示例#14
0
        public void Run(RemoteInterface remoteInterface)
        {
            Interface             = remoteInterface;
            GlobalActions.Engine += CountFrames;
            random = new Random();

            World world             = new World(remoteInterface);
            List <TextOverlay> vars = new List <TextOverlay>();

            GlobalInput.Actions['g'] = () =>
            {
                foreach (TextOverlay overlay in vars)
                {
                    overlay.Hide();
                }
                vars = new List <TextOverlay>();

                vars.Add(new TextOverlay("Rayman Dsgvars=".Red(), 6, 5, 0).Show());

                world.ReadObjectNames();
                Dictionary <string, Pointer <SuperObject> > superObjects = world.GetActiveSuperObjects();

                Interface.Log("SUPEROBJECT NAMES:", LogType.Debug);
                foreach (KeyValuePair <string, Pointer <SuperObject> > o in superObjects)
                {
                    Interface.Log($"{o.Key} {o.Value}", LogType.Debug);
                }

                SuperObject *rayman = superObjects["Rayman"];
                Perso *      perso  = (Perso *)rayman->engineObjectPtr;

                DsgVar *dsgVars = *perso->brain->mind->dsgMem->dsgVar;

                Interface.Log("DSGVARS:", LogType.Debug);
                for (int i = 0; i < dsgVars->dsgVarInfosLength; i++)
                {
                    DsgVarInfo info = dsgVars->dsgVarInfos[i];
                    DsgVarType type = info.type;

                    Pointer <byte> buffer = perso->brain->mind->dsgMem->memoryBufferCurrent;
                    int            offset = info.offsetInBuffer;

                    string        name  = $"{Enum.GetName(typeof(DsgVarType), type)}!{i}";
                    Func <object> value = buffer.GetDisplayReference(type, offset);

                    if (value != null)
                    {
                        vars.Add(new TextOverlay(_ => $"{name.Yellow()}\\{value()}", 5, ((vars.Count + 1) * 5 * 2.6f + 5) < 1000 ? 5 : 505, (vars.Count * 5 * 2.6f + 5) % 980).Show());
                    }
                }
            };

            GlobalInput.Actions['r'] = () =>
            {
                RandomizeAllObjects(world);
            };

            RandomizeMode mode = new RandomizeModeInterval(randomizeInterval);

            GlobalActions.Engine += () =>
            {
                if (mode.ShouldRandomize())
                {
                    RandomizeAllObjects(world);
                }
            };
        }
示例#15
0
        private void RandomizeObject(SuperObject *superObject)
        {
            Perso *perso = (Perso *)superObject->engineObjectPtr;

            Brain *brain = perso->brain;

            if (brain == null)
            {
                return;
            }

            DsgMem *dsgMem = brain->mind->dsgMem;

            if (dsgMem == null)
            {
                return;
            }

            DsgVar *dsgVars = *dsgMem->dsgVar;

            for (int i = 0; i < dsgVars->dsgVarInfosLength; i++)
            {
                if (random.NextDouble() > randomizeChance)
                {
                    continue;
                }

                DsgVarInfo info = dsgVars->dsgVarInfos[i];
                DsgVarType type = info.type;

                byte *buffer = dsgMem->memoryBufferCurrent;
                int   ptr    = (int)buffer + info.offsetInBuffer;

                switch (type)
                {
                case DsgVarType.Boolean:
                    *(bool *)ptr = random.Next(0, 2) == 0;
                    break;

                case DsgVarType.Byte:
                    *(sbyte *)ptr = (sbyte)random.Next(-127, 128);
                    break;

                case DsgVarType.UByte:
                    *(byte *)ptr = (byte)random.Next(0, 256);
                    break;

                case DsgVarType.Short:
                    *(short *)ptr = (short)random.Next();
                    break;

                case DsgVarType.UShort:
                    *(ushort *)ptr = (ushort)random.Next();
                    break;

                case DsgVarType.Int:
                    *(int *)ptr = random.Next();
                    break;

                case DsgVarType.UInt:
                    *(uint *)ptr = (uint)random.Next();
                    break;

                case DsgVarType.Float:
                    *(float *)ptr += random.RandomFloat(-10f, 10f);
                    break;

                case DsgVarType.Vector:
                    Vector3 *vector = (Vector3 *)ptr;
                    vector->X += random.RandomFloat(-10f, 10f);
                    vector->Y += random.RandomFloat(-10f, 10f);
                    vector->Z += random.RandomFloat(-10f, 10f);
                    break;

                case DsgVarType.IntegerArray:
                    int *array = brain->mind->GetDsgVar <int>(i, buffer, out byte size);
                    for (int j = 0; j < size; j++)
                    {
                        array[j] = random.Next();
                    }
                    break;
                }
            }
        }