public static void DispatchDestructionDomainSignal(this GameObject critter, D20DispatcherKey dispKey)
    {
        var dispatcher = critter.GetDispatcher();
        var dispIo     = new DispIoD20Signal();

        dispatcher?.Process(DispatcherType.DestructionDomain, dispKey, dispIo);
    }
예제 #2
0
    public static ConditionSpec.Builder AddQueryHandler <T>(this ConditionSpec.Builder builder,
                                                            D20DispatcherKey query, SubDispatcherCallback <T> handler, T data)
    {
        void HandlerWithArgs(in DispatcherCallbackArgs args) => handler(in args, data);

        return(AddQueryHandler(builder, query, HandlerWithArgs));
    }
예제 #3
0
    public static ConditionSpec.Builder AddHandler <T, U>(this ConditionSpec.Builder builder, DispatcherType type,
                                                          D20DispatcherKey key, SubDispatcherCallback <T, U> handler, T data1, U data2)
    {
        void HandlerWithArgs(in DispatcherCallbackArgs args) => handler(in args, data1, data2);

        return(builder.AddHandler(type, key, HandlerWithArgs));
    }
예제 #4
0
    public static ConditionSpec.Builder AddSignalHandler <T, U>(this ConditionSpec.Builder builder,
                                                                D20DispatcherKey signal, SubDispatcherCallback <T, U> handler, T data1, U data2)
    {
        void HandlerWithArgs(in DispatcherCallbackArgs args) => handler(in args, data1, data2);

        return(AddSignalHandler(builder, signal, HandlerWithArgs));
    }
예제 #5
0
    private void DispatchForItem(GameObject item, DispatcherType dispType, D20DispatcherKey dispKey,
                                 object dispIo)
    {
        var condArray     = item.GetInt32Array(obj_f.item_pad_wielder_condition_array);
        var argArrayCount = 0; // there's only one argument list for all attached conditions

        for (var i = 0; i < condArray.Count; i++)
        {
            var condNameHash = condArray[i];

            var condition = Conditions.GetByHash(condNameHash);
            if (condition != null)
            {
                using var condArgsInMem = MemoryPool <int> .Shared.Rent(condition.numArgs);

                var condArgsIn = condArgsInMem.Memory.Slice(0, condition.numArgs).Span;
                foreach (ref var arg in condArgsIn)
                {
                    arg = item.GetInt32(obj_f.item_pad_wielder_argument_array, argArrayCount++);
                }

                condArgsIn[2] = -1; // ... why?
                ItemDispatcher.DispatcherProcessorForItems(condition, condArgsIn, dispType, dispKey, dispIo);
            }
        }
    }
예제 #6
0
    public int D20QueryItem(GameObject item, D20DispatcherKey queryKey)
    {
        var dispIo = new DispIoD20Query();

        dispIo.obj = item;
        DispatchForItem(item, DispatcherType.D20Query, queryKey, dispIo);
        return(dispIo.return_val);
    }
예제 #7
0
    public static void D20SendSignalEx(this GameObject obj, D20DispatcherKey signal, GameObject target)
    {
        D20Action d20a = new D20Action(D20ActionType.CAST_SPELL, obj);

        d20a.d20ATarget = target;
        d20a.d20Caf     = D20CAF.HIT;

        if (signal == D20DispatcherKey.SIG_TouchAttack)
        {
            d20a.d20Caf = obj.PerformTouchAttack(target);
        }

        GameSystems.D20.D20SendSignal(obj, signal, d20a);
    }
    public static DamageType GetDamageTypeFromEnum(D20DispatcherKey key)
    {
        // Determine the intended damage type
        if (key == VersatileUnarmedStrikePiercingEnum)
        {
            return(DamageType.Piercing);
        }
        else if (key == VersatileUnarmedStrikeSlashingEnum)
        {
            return(DamageType.Slashing);
        }

        return(DamageType.Bludgeoning);
    }
예제 #9
0
    public int D20QueryWithObject(GameObject obj, D20DispatcherKey queryKey, object arg, int defaultResult = 0)
    {
        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            return(defaultResult);
        }

        var dispIO = DispIoD20Query.Default;

        dispIO.obj        = arg;
        dispIO.return_val = defaultResult;
        dispatcher.Process(DispatcherType.D20Query, queryKey, dispIO);
        return(dispIO.return_val);
    }
예제 #10
0
    public int D20QueryInt(GameObject obj, D20DispatcherKey queryKey, int data1 = 0, int data2 = 0)
    {
        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            return(0);
        }

        var dispIO = DispIoD20Query.Default;

        dispIO.data1 = data1;
        dispIO.data2 = data2;
        dispatcher.Process(DispatcherType.D20Query, queryKey, dispIO);
        return(dispIO.return_val);
    }
예제 #11
0
    public void D20SendSignal(GameObject obj, D20DispatcherKey key, int arg1 = 0, int arg2 = 0)
    {
        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            Logger.Info("d20SendSignal(): Object {0} lacks a Dispatcher", obj);
            return;
        }

        var dispIO = DispIoD20Signal.Default;

        dispIO.data1 = arg1;
        dispIO.data2 = arg2;
        dispatcher.Process(DispatcherType.D20Signal, key, dispIO);
    }
예제 #12
0
    public void Process(DispatcherType type, D20DispatcherKey key, object dispIo)
    {
        if (_dispCounter > DISPATCHER_MAX)
        {
            Logger.Error("Dispatcher maximum recursion reached!");
            return;
        }

        _dispCounter++;

        foreach (var subDispNode in GetSubDispatcher(type))
        {
            if ((subDispNode.subDispDef.dispKey == key ||
                 subDispNode.subDispDef.dispKey == D20DispatcherKey.NONE) && !subDispNode.condNode.IsExpired)
            {
                DispIoTypeImmunityTrigger dispIoImmunity = DispIoTypeImmunityTrigger.Default;
                dispIoImmunity.condNode = subDispNode.condNode;

                if (type != DispatcherType.ImmunityTrigger || key != D20DispatcherKey.IMMUNITY_SPELL)
                {
                    Process(DispatcherType.ImmunityTrigger, D20DispatcherKey.IMMUNITY_SPELL, dispIoImmunity);
                }

                if (dispIoImmunity.interrupt == 1 && type != DispatcherType.Unused63)
                {
                    // dispType63 is essentially <. Minor globe of invulnerability
                    dispIoImmunity.interrupt = 0;
                    dispIoImmunity.val2      = 10;
                    Process(DispatcherType.Unused63, D20DispatcherKey.NONE, dispIo);
                    if (dispIoImmunity.interrupt == 0)
                    {
                        var args = new DispatcherCallbackArgs(subDispNode, _owner, type, key, dispIo);
                        subDispNode.subDispDef.callback(in args);
                    }
                }
                else
                {
                    var args = new DispatcherCallbackArgs(subDispNode, _owner, type, key, dispIo);

                    subDispNode.subDispDef.callback(in args);
                }
            }
        }

        _dispCounter--;
    }
예제 #13
0
    public void D20SendSignal(GameObject obj, D20DispatcherKey key, object arg)
    {
        if (obj == null)
        {
            Logger.Warn("D20SendSignal called with null handle! Key was {0}", key);
            return;
        }

        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            Logger.Info("d20SendSignal(): Object {0} lacks a Dispatcher", obj);
            return;
        }

        DispIoD20Signal dispIO = DispIoD20Signal.Default;

        dispIO.obj = arg;
        dispatcher.Process(DispatcherType.D20Signal, key, dispIO);
    }
예제 #14
0
    public ulong D20QueryReturnData(GameObject obj, D20DispatcherKey queryKey, int arg1 = 0, int arg2 = 0)
    {
        Trace.Assert(queryKey != D20DispatcherKey.QUE_Critter_Is_Charmed &&
                     queryKey != D20DispatcherKey.QUE_Critter_Is_Afraid &&
                     queryKey != D20DispatcherKey.QUE_Critter_Is_Held);

        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            return(0);
        }

        var dispIO = new DispIoD20Query();

        dispIO.return_val = 0;
        dispIO.data1      = arg1;
        dispIO.data2      = arg2;
        dispatcher.Process(DispatcherType.D20Query, queryKey, dispIO);

        return(dispIO.resultData);
    }
예제 #15
0
    public static void DispatcherProcessorForItems(ConditionSpec condStruct, Span <int> condArgs,
                                                   DispatcherType dispType, D20DispatcherKey key, object dispIo)
    {
        var condAttachment = new ConditionAttachment(condStruct);

        for (int i = 0; i < condStruct.numArgs; i++)
        {
            condAttachment.args[i] = condArgs[i];
        }

        for (int i = 0; i < condStruct.subDispDefs.Length; i++)
        {
            var sdd = condStruct.subDispDefs[i];
            if (sdd.dispType == dispType && (sdd.dispKey == key || sdd.dispKey == D20DispatcherKey.NONE))
            {
                var attachment = new SubDispatcherAttachment();
                attachment.subDispDef = sdd;
                attachment.condNode   = condAttachment;
                var callbackArgs = new DispatcherCallbackArgs(attachment, null, dispType, key, dispIo);
                sdd.callback(in callbackArgs);
            }
        }
    }
예제 #16
0
    public void D20SignalPython(GameObject handle, D20DispatcherKey queryKey, int arg1, int arg2)
    {
        if (handle == null)
        {
            Logger.Warn("D20SignalPython called with null handle! Key was {0}, arg1 {1}, arg2 {2}", queryKey, arg1,
                        arg2);
            return;
        }

        var dispatcher = handle.GetDispatcher();

        if (dispatcher == null)
        {
            return;
        }

        var dispIo = DispIoD20Signal.Default;

        dispIo.return_val = 0;
        dispIo.data1      = arg1;
        dispIo.data2      = arg2;
        dispatcher.Process(DispatcherType.PythonSignal, queryKey, dispIo);
    }
예제 #17
0
    public GameObject D20QueryReturnObject(GameObject obj, D20DispatcherKey queryKey,
                                           int arg1 = 0, int arg2 = 0)
    {
        Trace.Assert(queryKey == D20DispatcherKey.QUE_Critter_Is_Charmed ||
                     queryKey == D20DispatcherKey.QUE_Critter_Is_Afraid ||
                     queryKey == D20DispatcherKey.QUE_Critter_Is_Held);

        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            return(null);
        }

        var dispIO = new DispIoD20Query();

        dispIO.return_val = 0;
        dispIO.data1      = arg1;
        dispIO.data2      = arg2;
        dispatcher.Process(DispatcherType.D20Query, queryKey, dispIO);

        return((GameObject)dispIO.obj);
    }
    public static int DispatchForCritter(this GameObject obj, DispIoBonusList eventObj, DispatcherType dispType,
                                         D20DispatcherKey dispKey)
    {
        if (obj == null || !obj.IsCritter())
        {
            return(0);
        }

        var dispatcher = obj.GetDispatcher();

        if (dispatcher == null)
        {
            return(0);
        }

        if (eventObj == null)
        {
            eventObj = DispIoBonusList.Default;
        }

        dispatcher.Process(dispType, dispKey, eventObj);

        return(eventObj.bonlist.OverallBonus);
    }
 public ActionErrorCode PyAddToSeq(D20DispatcherKey actionData1, D20Action action, ActionSequence actSeq, TurnBasedStatus tbStatus)
 {
     throw new System.NotImplementedException();
 }
예제 #20
0
 public static void D20SendSignal(this GameObject obj, D20DispatcherKey signal, int data)
 {
     GameSystems.D20.D20SendSignal(obj, signal, data);
 }
예제 #21
0
 // Removes the condition when the given signal is received
 public static ConditionSpec.Builder RemoveOnSignal(this ConditionSpec.Builder builder, D20DispatcherKey signal)
 {
     builder.AddSignalHandler(signal, (in DispatcherCallbackArgs evt) => evt.RemoveThisCondition());
     return(builder);
 }
예제 #22
0
 // Sets the result for the given query to the given constant boolean
 public static ConditionSpec.Builder SetQueryResult(this ConditionSpec.Builder builder, D20DispatcherKey query,
                                                    bool result)
 {
     if (result)
     {
         return(builder.AddHandler(
                    DispatcherType.D20Query,
                    query,
                    CommonConditionCallbacks.QuerySetReturnVal1
                    ));
     }
     else
     {
         return(builder.AddHandler(
                    DispatcherType.D20Query,
                    query,
                    CommonConditionCallbacks.QuerySetReturnVal0
                    ));
     }
 }
예제 #23
0
 public static bool D20Query(this GameObject obj, D20DispatcherKey key, int data1 = 0, int data2 = 0)
 {
     return(GameSystems.D20.D20Query(obj, key, data1, data2));
 }
예제 #24
0
 public static ConditionSpec.Builder AddSignalHandler(this ConditionSpec.Builder builder,
                                                      D20DispatcherKey signal, SubDispatcherCallback callback)
 {
     builder.AddHandler(DispatcherType.D20Signal, signal, callback);
     return(builder);
 }
예제 #25
0
 public static ConditionSpec.Builder AddQueryHandler(this ConditionSpec.Builder builder, D20DispatcherKey query,
                                                     SubDispatcherCallback callback)
 {
     builder.AddHandler(DispatcherType.D20Query, query, callback);
     return(builder);
 }
 public bool PyProjectileHit(D20DispatcherKey actionData1, D20Action action, GameObject projectile, GameObject obj2)
 {
     throw new System.NotImplementedException();
 }