public static bool func_do(Character ch, AOFunctions func, bool dolocalstats, bool tosocialtab, int placement, bool doreqs)
            {
                int c;
                int r;
                Character chartarget = (Character)Misc.FindDynel.FindDynelByID(ch.Target.Type, ch.Target.Instance);
                Boolean reqs_met;
                Character ftarget = null;
                int statval;
                Boolean reqresult;
                if (ch != null)
                {
                    for (c = 0; c < func.TickCount; c++)
                    {
                        reqs_met = true;
                        int childop = -1;
                        if (!doreqs)
                        {
                            for (r = 0; r < func.Requirements.Count; r++)
                            {
                                switch (func.Requirements[r].Target)
                                {
                                    case itemtarget_user:
                                        ftarget = ch;
                                        break;
                                    case itemtarget_wearer:
                                        ftarget = ch;
                                        break;
                                    case itemtarget_target:
                                        ftarget = chartarget;
                                        break;
                                    case itemtarget_fightingtarget:
                                        // Fighting target
                                        break;
                                    case itemtarget_self:
                                        ftarget = ch;
                                        break;
                                    case itemtarget_selectedtarget:
                                        ftarget = chartarget;
                                        break;
                                }
                                if (ftarget == null)
                                {
                                    reqs_met = false;
                                    return false;
                                }
                                statval = ftarget.Stats.Get(func.Requirements[r].Statnumber);
                                switch (func.Requirements[r].Operator)
                                {
                                    case operator_and:
                                        reqresult = ((statval & func.Requirements[r].Value) != 0);
                                        break;
                                    case operator_or:
                                        reqresult = ((statval | func.Requirements[r].Value) != 0);
                                        break;
                                    case operator_equalto:
                                        reqresult = (statval == func.Requirements[r].Value);
                                        break;
                                    case operator_lessthan:
                                        reqresult = (statval < func.Requirements[r].Value);
                                        break;
                                    case operator_greaterthan:
                                        reqresult = (statval > func.Requirements[r].Value);
                                        break;
                                    case operator_unequal:
                                        reqresult = (statval != func.Requirements[r].Value);
                                        break;
                                    case operator_true:
                                        reqresult = (statval != 0);
                                        break;
                                    case operator_false:
                                        reqresult = (statval == 0);
                                        break;
                                    case operator_bitand:
                                        reqresult = ((statval & func.Requirements[r].Value) != 0);
                                        break;
                                    case operator_bitor:
                                        reqresult = ((statval | func.Requirements[r].Value) != 0);
                                        break;
                                    default:
                                        reqresult = true;
                                        break;
                                }

                                switch (childop)
                                {
                                    case operator_and:
                                        reqs_met &= reqresult;
                                        break;
                                    case operator_or:
                                        reqs_met |= reqresult;
                                        break;
                                    case -1:
                                        reqs_met = reqresult;
                                        break;
                                    default:
                                        break;
                                }
                                childop = func.Requirements[r].ChildOperator;
                            }
                        }

                        if (!reqs_met)
                        {
                            return reqs_met;
                        }

                        switch (func.FunctionType)
                        {
                            // Set new Texture
                            case ItemHandler.functiontype_texture:
                                SqlWrapper ms = new SqlWrapper();
                                if (!tosocialtab)
                                {
                                    ms.SqlUpdate("Update " + ch.getSQLTablefromDynelType() + " set Textures" + func.Arguments[1].ToString() + "=" + func.Arguments[0].ToString() + " WHERE ID=" + ch.ID.ToString());
                                    AOTextures ao = new AOTextures((int)func.Arguments[1], (int)func.Arguments[0]);
                                    ch.Textures.Add(ao);
                                }
                                else
                                {
                                    int texnum = Int32.Parse(func.Arguments[1].ToString());
                                    int texval = Int32.Parse(func.Arguments[0].ToString());
                                    if (ch.SocialTab.ContainsKey(texnum))
                                    {
                                        ch.SocialTab[texnum] = texval;
                                    }
                                    else
                                    {
                                        ch.SocialTab.Add(texnum, texval);
                                    }
                                    ch.SaveSocialTab();
                                }

                                break;
                            // Set Headmesh
                            case ItemHandler.functiontype_headmesh:
                                if (!tosocialtab)
                                {
                                    ch.Stats.HeadMesh.StatModifier = (Int32)((Int32)func.Arguments[1] - ch.Stats.HeadMesh.StatBaseValue); // Headmesh
                                    ch.MeshLayer.AddMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], 0);
                                }
                                else
                                {
                                    if (ch.SocialTab.ContainsKey(ch.Stats.HeadMesh.StatNumber))
                                    {
                                        ch.SocialTab[ch.Stats.HeadMesh.StatNumber] = (Int32)func.Arguments[0];
                                        ch.SocialMeshLayer.AddMesh(0, (Int32)func.Arguments[0], (Int32)func.Arguments[1], 0);
                                    }
                                    else
                                    {
                                        ch.SocialTab.Add(ch.Stats.HeadMesh.StatNumber, (Int32)func.Arguments[0]);
                                        ch.SocialMeshLayer.AddMesh(0, (Int32)func.Arguments[0], (Int32)func.Arguments[1], 0);
                                    }
                                    ch.SaveSocialTab();
                                }
                                break;
                            // Set Shouldermesh
                            case ItemHandler.functiontype_shouldermesh:
                                if ((placement == 19) || (placement == 51))
                                {
                                    if (!tosocialtab)
                                    {
                                        ch.Stats.ShoulderMeshRight.Set((Int32)func.Arguments[1]);
                                        ch.Stats.ShoulderMeshLeft.Set((Int32)func.Arguments[1]);
                                        ch.MeshLayer.AddMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        ch.MeshLayer.AddMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                    else
                                    {
                                        ch.SocialMeshLayer.AddMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        ch.SocialMeshLayer.AddMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                }
                                else
                                {
                                    if (!tosocialtab)
                                    {
                                        if (placement == 20)
                                        {
                                            ch.Stats.ShoulderMeshLeft.Set((Int32)func.Arguments[1]);
                                            ch.MeshLayer.AddMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        }
                                        if (placement == 22)
                                        {
                                            ch.Stats.ShoulderMeshLeft.Set((Int32)func.Arguments[1]);
                                            ch.MeshLayer.AddMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        }
                                    }
                                    else
                                    {
                                        if (placement == 52)
                                        {
                                            ch.Stats.ShoulderMeshRight.Set((Int32)func.Arguments[1]);
                                            ch.SocialMeshLayer.AddMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        }
                                        if (placement == 54)
                                        {
                                            ch.Stats.ShoulderMeshLeft.Set((Int32)func.Arguments[1]);
                                            ch.SocialMeshLayer.AddMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        }
                                    }


                                }
                                break;
                            // Set Backmesh
                            case ItemHandler.functiontype_backmesh:
                                if (!tosocialtab)
                                {
                                    ch.Stats.BackMesh.Set((Int32)func.Arguments[0]); // Shouldermesh
                                    ch.MeshLayer.AddMesh(5, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                else
                                {
                                    ch.SocialMeshLayer.AddMesh(5, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                break;
                            // Set Hairmesh
                            case ItemHandler.functiontype_hairmesh:
                                if (!tosocialtab)
                                {
                                    ch.Stats.HairMesh.Set((Int32)func.Arguments[0]); // HairMesh
                                    ch.MeshLayer.AddMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                else
                                {
                                    ch.SocialMeshLayer.AddMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                break;
                            case ItemHandler.functiontype_attractormesh:
                                if (!tosocialtab)
                                {
                                    ch.Stats.HairMesh.Set((Int32)func.Arguments[0]); // HairMesh
                                    ch.MeshLayer.AddMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                else
                                {
                                    ch.SocialMeshLayer.AddMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                break;
                            case ItemHandler.functiontype_modify:
                                // TODO: req check for OE
                                if (dolocalstats)
                                {
                                    if (!tosocialtab)
                                    {
                                        ch.Stats.SetModifier((Int32)func.Arguments[0], ch.Stats.GetModifier((Int32)func.Arguments[0]) + (Int32)func.Arguments[1]);
                                    }
                                }
                                break;
                            case ItemHandler.functiontype_modifypercentage:
                                // TODO: req check for OE
                                if (dolocalstats)
                                {
                                    if (!tosocialtab)
                                    {
                                        ch.Stats.SetPercentageModifier((Int32)func.Arguments[0], ch.Stats.GetPercentageModifier((Int32)func.Arguments[0]) + (Int32)func.Arguments[1]);
                                    }
                                }
                                break;
                            case ItemHandler.functiontype_uploadnano:
                                ch.UploadNano((Int32)func.Arguments[0]);
                                Packets.UploadNanoupdate.Send(ch, 53019, (Int32)func.Arguments[0]);
                                break;
                            case ItemHandler.functiontype_shophash:
                                // Do nothing, it's covered in 
                                break;
                            default:
                                break;
                        }
                    }
                }
                return false;
            }
            public static bool func_revert(Character ch, AOFunctions func, bool fromsocialtab, int placement)
            {
                int c;

                if (ch != null)
                {
                    for (c = 0; c < func.TickCount; c++)
                    {
                        switch (func.FunctionType)
                        {
                            case ItemHandler.functiontype_texture:
                                // Todo: check for second Arm item
                                SqlWrapper ms = new SqlWrapper();
                                if (!fromsocialtab)
                                {
                                    ms.SqlUpdate("Update " + ch.getSQLTablefromDynelType() + " set Textures" + func.Arguments[1].ToString() + "=0 WHERE ID=" + ch.ID.ToString() + " AND Textures" + func.Arguments[1].ToString() + "=" + func.Arguments[0].ToString());
                                    int ct = ch.Textures.Count - 1;
                                    while (ct >= 0)
                                    {
                                        if (ch.Textures[ct].place == (int)func.Arguments[1])
                                        {
                                            ch.Textures.RemoveAt(ct);
                                            break;
                                        }
                                        ct--;
                                    }
                                }
                                else
                                {
                                    if (ch.SocialTab.ContainsKey((Int32)func.Arguments[1]))
                                    {
                                        ch.SocialTab[(Int32)func.Arguments[1]] = 0;
                                    }
                                    else
                                    {
                                        ch.SocialTab.Add((Int32)func.Arguments[1], 0);
                                    }
                                }
                                break;
                            case ItemHandler.functiontype_headmesh:
                                if (!fromsocialtab)
                                {
                                    ch.Stats.HeadMesh.StatModifier = 0;
                                    ch.MeshLayer.RemoveMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                else
                                {
                                    ch.SocialMeshLayer.RemoveMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                // Reverting the Head modification
                                break;
                            case ItemHandler.functiontype_shouldermesh:
                                // TODO: check for second shoulder item
                                if (!fromsocialtab)
                                {
                                    if (placement == 19)
                                    {
                                        ch.MeshLayer.RemoveMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                        ch.MeshLayer.RemoveMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                    if (placement == 20) // Right
                                    {
                                        ch.Stats.ShoulderMeshRight.Set(0); // Shouldermesh Right
                                        ch.MeshLayer.RemoveMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                    if (placement == 22) // Left
                                    {
                                        ch.Stats.ShoulderMeshLeft.Set(0); // Shouldermesh Left
                                        ch.MeshLayer.RemoveMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                }
                                else
                                {
                                    if (placement == 52) // Right
                                    {
                                        ch.SocialMeshLayer.RemoveMesh(3, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                    if (placement == 54) // Left
                                    {
                                        ch.SocialMeshLayer.RemoveMesh(4, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                    }
                                }
                                break;
                            case ItemHandler.functiontype_backmesh:
                                if (!fromsocialtab)
                                {
                                    ch.Stats.BackMesh.Set(0); // Backmesh
                                    ch.MeshLayer.RemoveMesh(5, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                else
                                {
                                    ch.SocialMeshLayer.RemoveMesh(5, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                break;
                            case ItemHandler.functiontype_attractormesh:
                                if (!fromsocialtab)
                                {
                                    ch.Stats.HairMesh.Set(0); // Attractormesh
                                    ch.MeshLayer.RemoveMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                else
                                {
                                    if (ch.SocialTab.ContainsKey(32))
                                    {
                                        ch.SocialTab[32] = 0;
                                    }
                                    else
                                    {
                                        ch.SocialTab.Add(32, 0);
                                    }
                                    ch.SocialMeshLayer.RemoveMesh(0, (Int32)func.Arguments[1], (Int32)func.Arguments[0], Misc.MeshLayers.GetLayer(placement));
                                }
                                break;
                            default:
                                break;
                        }
                    }
                }
                return false;
            }