Пример #1
0
        public void ChangePosition(short x, short y, sbyte level, Direction direction, VMContext context)
        {
            int Dir = 0;
            switch (direction)
            {
                case Direction.NORTH:
                    Dir = 0; break;
                case Direction.EAST:
                    Dir = 2; break;
                case Direction.SOUTH:
                    Dir = 4; break;
                case Direction.WEST:
                    Dir = 6; break;
            }

            for (int i = 0; i < Objects.Count(); i++)
            {
                var sub = Objects[i];
                var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8), (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF), 0);
                off = Vector3.Transform(off, Matrix.CreateRotationZ((float)(Dir * Math.PI / 4.0)));

                sub.Direction = direction;
                context.Blueprint.ChangeObjectLocation((ObjectComponent)sub.WorldUI, (short)Math.Round(x + off.X), (short)Math.Round(y + off.Y), (sbyte)level);
            }
            for (int i = 0; i < Objects.Count(); i++) Objects[i].PositionChange(context);
        }
Пример #2
0
        public VMThread(VMContext context, VMEntity entity, int stackSize)
        {
            this.Context = context;
            this.Entity = entity;

            this.Stack = new List<VMStackFrame>(stackSize);
            this.Queue = new List<VMQueuedAction>();
        }
Пример #3
0
 public void Load(VMFindLocationResultMarshal input, VMContext context)
 {
     RadianDirection = input.RadianDirection;
     Position = input.Position;
     Score = input.Score;
     FaceAnywhere = input.FaceAnywhere;
     Chair = context.VM.GetObjectById(input.Chair);
     RouteEntryFlags = input.RouteEntryFlags;
 }
Пример #4
0
 public void Load(VMActionCallbackMarshal input, VMContext context)
 {
     type = input.Type;
     Target = context.VM.GetObjectById(input.Target);
     Interaction = input.Interaction;
     SetParam = input.SetParam;
     StackObject = context.VM.GetObjectById(input.StackObject);
     Caller = context.VM.GetObjectById(input.Caller);
 }
Пример #5
0
 public VMRuntimeHeadline(VMRuntimeHeadlineMarshal input, VMContext context)
 {
     Operand = input.Operand;
     Target = context.VM.GetObjectById(input.Target);
     IconTarget = context.VM.GetObjectById(input.IconTarget);
     Index = input.Index;
     Duration = input.Duration;
     Anim = input.Anim;
 }
Пример #6
0
        private short StackPointer; /** -1 means idle **/

        #endregion Fields

        #region Constructors

        public VMThread(VMContext context, VMEntity entity, int stackSize)
        {
            this.Context = context;
            this.Entity = entity;

            this.Stack = new VMStackFrame[stackSize];
            this.StackPointer = -1;
            this.Queue = new List<VMQueuedAction>();

            Context.ThreadIdle(this);
        }
Пример #7
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMQueuedAction action)
 {
     var temp = new VMThread(context, entity, 5);
     temp.IsCheck = true;
     temp.EnqueueAction(action);
     while (temp.Queue.Count > 0 && temp.DialogCooldown == 0) //keep going till we're done! idling is for losers!
     {
         temp.Tick();
     }
     return (temp.DialogCooldown > 0) ? VMPrimitiveExitCode.ERROR:temp.LastStackExitCode;
 }
Пример #8
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMQueuedAction action)
 {
     var temp = new VMThread(context, entity, 5);
     temp.EnqueueAction(action);
     while (temp.Queue.Count > 0) //keep going till we're done! idling is for losers!
     {
         temp.Tick();
     }
     context.ThreadRemove(temp); //hopefully this thread should be completely dereferenced...
     return temp.LastStackExitCode;
 }
Пример #9
0
        public void Tick(VMAvatar avatar, VMContext context)
        {
            if (context.Clock.Minutes == LastMinute) return;
            LastMinute = context.Clock.Minutes;

            string category = "Skills";
            string sleepState = (avatar.GetMotiveData(VMMotive.SleepState) == 0)?"Awake":"Asleep";

            int moodSum = 0;

            for (int i = 0; i < 7; i++) {
                if (avatar.IsPet && i == 5) return;
                float lotMul = LotMotives.GetNum(category + "_" + LotMotiveNames[i] + "Weight");
                float frac = 0;
                var motive = avatar.GetMotiveData(DecrementMotives[i]);
                var r_Hunger = (SimMotives.GetNum("HungerDecrementRatio") * (100+avatar.GetMotiveData(VMMotive.Hunger))) * LotMotives.GetNum(category+"_HungerWeight");
                switch (i)
                {
                    case 0:
                        frac = r_Hunger; break;
                    case 1:
                        frac = (SimMotives.GetNum("ComfortDecrementActive") * lotMul); break;
                    case 2:
                        frac = (SimMotives.GetNum("HygieneDecrement" + sleepState) * lotMul); break;
                    case 3:
                        frac = (SimMotives.GetNum("BladderDecrement" + sleepState) * lotMul) + (SimMotives.GetNum("HungerToBladderMultiplier") * r_Hunger); break;
                    case 4:
                        frac = (SimMotives.GetNum("EnergySpan") / (60 * SimMotives.GetNum("WakeHours")));
                        // TODO: wrong but appears to be close? need one which uses energy weight, which is about 2.4 on skills
                        break;
                    case 5:
                        frac = (sleepState == "Asleep") ? 0 : (SimMotives.GetNum("EntDecrementAwake") * lotMul);
                        break;
                    case 6:
                        frac = (SimMotives.GetNum("SocialDecrementBase") + (SimMotives.GetNum("SocialDecrementMultiplier") * (100+motive))) * lotMul;
                        frac /= 2; //make this less harsh right now, til I can work out how multiplayer bonus is meant to work
                        break;
                }

                MotiveFractions[i] += (short)(frac * 1000);
                if (MotiveFractions[i] >= 1000)
                {
                    motive -= (short)(MotiveFractions[i] / 1000);
                    MotiveFractions[i] %= 1000;
                    if (motive < -100) motive = -100;
                    avatar.SetMotiveData(DecrementMotives[i], motive);
                }
                moodSum += motive;
            }
            avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 7));
        }
Пример #10
0
 public static bool FindLocationVector(VMEntity obj, VMEntity refObj, VMContext context, int dir)
 {
     LotTilePos step = DirectionVectors[dir];
     for (int i = 0; i < 32; i++)
     {
         if (obj.SetPosition(new LotTilePos(refObj.Position) + step * i,
             (Direction)(1 << (dir)), context).Status == VMPlacementError.Success)
             return true;
         if (i != 0)
         {
             if (obj.SetPosition(new LotTilePos(refObj.Position) - step * i,
                 (Direction)(1 << (dir)), context).Status == VMPlacementError.Success)
                 return true;
         }
     }
     return false;
 }
Пример #11
0
		/// <summary>
		/// Renders the macro using the context
		/// </summary>
		public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node)
		{
			try
			{
				// it's possible the tree hasn't been parsed yet, so get 
				// the VMManager to parse and init it
				if (nodeTree != null)
				{
					if (!init)
					{
						nodeTree.Init(context, rsvc);
						init = true;
					}

					// wrap the current context and add the VMProxyArg objects
					VMContext vmc = new VMContext(context, rsvc);

					for(int i = 1; i < argArray.Length; i++)
					{
						// we can do this as VMProxyArgs don't change state. They change
						// the context.
						VMProxyArg arg = (VMProxyArg) proxyArgHash[argArray[i]];
						vmc.AddVMProxyArg(arg);
					}

					// now render the VM
					nodeTree.Render(vmc, writer);
				}
				else
				{
					rsvc.Error("VM error : " + macroName + ". Null AST");
				}
			}
			catch(Exception e)
			{
				// if it's a MIE, it came from the render.... throw it...
				if (e is MethodInvocationException)
					throw;

				rsvc.Error("VelocimacroProxy.render() : exception VM = #" + macroName + "() : " + e);
			}

			return true;
		}
Пример #12
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action, List<VMPieMenuInteraction> actionStrings)
 {
     var temp = new VMThread(context, entity, 5);
     if (entity.Thread != null)
     {
         temp.TempRegisters = entity.Thread.TempRegisters;
         temp.TempXL = entity.Thread.TempXL;
     }
     temp.IsCheck = true;
     temp.ActionStrings = actionStrings; //generate and place action strings in here
     temp.Push(initFrame);
     if (action != null) temp.Queue.Add(action); //this check runs an action. We may need its interaction number, etc.
     while (temp.Stack.Count > 0 && temp.DialogCooldown == 0) //keep going till we're done! idling is for losers!
     {
         temp.Tick();
         temp.ThreadBreak = VMThreadBreakMode.Active; //cannot breakpoint in check trees
     }
     return (temp.DialogCooldown > 0) ? VMPrimitiveExitCode.ERROR:temp.LastStackExitCode;
 }
Пример #13
0
        public static bool FindLocationFor(VMEntity obj, VMEntity refObj, VMContext context)
        {
            for (int i = 0; i < 10; i++)
            {
                if (i == 0)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        if (obj.SetPosition(new LotTilePos(refObj.Position), (Direction)(1 << (j * 2)), context).Status == VMPlacementError.Success)
                            return true;
                    }
                }
                else
                {
                    LotTilePos bPos = refObj.Position;
                    for (int x = -i; x <= i; x++)
                    {
                        for (int j = 0; j < 8; j++)
                        {
                            if (obj.SetPosition(LotTilePos.FromBigTile((short)(bPos.TileX + x), (short)(bPos.TileY + ((j % 2) * 2 - 1) * i), bPos.Level),
                                (Direction)(1 << ((j / 2) * 2)), context).Status == VMPlacementError.Success)
                                return true;
                        }
                    }

                    for (int y = 1 - i; y < i; y++)
                    {
                        for (int j = 0; j < 8; j++)
                        {
                            if (obj.SetPosition(LotTilePos.FromBigTile((short)(bPos.TileX + ((j % 2) * 2 - 1) * i), (short)(bPos.TileY + y), bPos.Level),
                                (Direction)(1 << ((j / 2) * 2)), context).Status == VMPlacementError.Success)
                                return true;
                        }
                    }
                }
            }
            return false;
        }
Пример #14
0
 public virtual void Load(VMMultitileGroupMarshal input, VMContext context)
 {
     MultiTile = input.MultiTile;
     Objects = new List<VMEntity>();
     foreach (var id in input.Objects)
     {
         var obj = context.VM.GetObjectById(id);
         Objects.Add(obj);
         obj.MultitileGroup = this;
     }
 }
 public void Delete(VMContext context)
 {
     for (int i = 0; i < Objects.Count(); i++)
     {
         var obj = Objects[i];
         obj.PrePositionChange(context);
         context.RemoveObjectInstance(obj);
     }
 }
Пример #16
0
 public void ExecuteEntryPoint(int num, VMContext context)
 {
     for (int i = 0; i < Objects.Count; i++) Objects[i].ExecuteEntryPoint(num, context, true);
 }
Пример #17
0
        public virtual void Load(VMThreadMarshal input, VMContext context)
        {
            Stack = new List<VMStackFrame>();
            foreach (var item in input.Stack)
            {
                Stack.Add((item is VMRoutingFrameMarshal)? new VMRoutingFrame(item, context, this) : new VMStackFrame(item, context, this));
            }
            Queue = new List<VMQueuedAction>();
            foreach (var item in input.Queue) Queue.Add(new VMQueuedAction(item, context));
            TempRegisters = input.TempRegisters;
            TempXL = input.TempXL;
            LastStackExitCode = input.LastStackExitCode;

            BlockingDialog = input.BlockingDialog;
            Interrupt = input.Interrupt;
            ActionUID = input.ActionUID;
            DialogCooldown = input.DialogCooldown;
        }
Пример #18
0
 public VMThread(VMThreadMarshal input, VMContext context, VMEntity entity)
 {
     Context = context;
     Entity = entity;
     Load(input, context);
 }
Пример #19
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action)
 {
     return(EvaluateCheck(context, entity, initFrame, action, null));
 }
Пример #20
0
 public VMActionCallback(VMActionCallbackMarshal input, VMContext context)
 {
     Load(input, context);
 }
Пример #21
0
        // TODO: float values may desync if devices are not both x86 or using a different C# library.
        // Might need to replace with fixed point library for position and rotation

        /// <summary>
        /// This method will find all the avaliable locations within the criteria ordered by proximity to the optimal proximity
        /// External functions can then decide which is most desirable. E.g. the nearest slot to the object may be the longest route if
        /// its in another room.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="slot"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public List <VMFindLocationResult> FindAvaliableLocations(VMEntity obj, VMContext context, VMEntity caller)
        {
            /**
             * Start at min proximity and circle around the object to find the avaliable locations.
             * Then pick the one nearest to the optimal value
             */

            /**
             * ------ MAJOR TODO: ------
             * Avoid vector math at all costs! Small differences in hardware could cause desyncs.
             * This really goes for all areas of the SimAntics engine, but here it's particularly bad.
             */
            Vector2 center;

            if (OnlySit)
            {
                FailCode = VMRouteFailCode.NoChair;
            }

            // if we need to use the average location of an object group, it needs to be calculated.
            if (((Flags & SLOTFlags.UseAverageObjectLocation) > 0) && (obj.MultitileGroup.MultiTile))
            {
                center = new Vector2(0, 0);
                var objs = obj.MultitileGroup.Objects;
                for (int i = 0; i < objs.Count; i++)
                {
                    center += new Vector2(objs[i].Position.x / 16f, objs[i].Position.y / 16f);
                }
                center /= objs.Count;
            }
            else
            {
                center = new Vector2(obj.Position.x / 16f, obj.Position.y / 16f);
            }

            //add offset of slot if it exists. must be rotated to be relative to object
            var rotOff    = Vector3.Transform(Slot.Offset, Matrix.CreateRotationZ(obj.RadianDirection));
            var circleCtr = new Vector2(center.X + rotOff.X / 16, center.Y + rotOff.Y / 16);

            ushort room = context.VM.Context.GetRoomAt(obj.Position);

            Results = new List <VMFindLocationResult>();

            if ((Flags & SLOTFlags.SnapToDirection) > 0)
            { //snap to the specified direction, on the specified point.
                double baseRot;
                if (Slot.Facing > SLOTFacing.FaceAwayFromObject)
                {
                    // bit of a legacy thing here. Facing field did not use to exist,
                    // which is why SnapToDirection was hacked to use the directional flags.
                    // now that it exists, it is used instead, to encode the same information...
                    // just transform back into old format.
                    Flags |= (SLOTFlags)(1 << (int)Slot.Facing);
                }
                else
                {
                    if (((int)Flags & 255) == 0)
                    {
                        Flags |= SLOTFlags.NORTH;
                    }
                }

                var flagRot = DirectionUtils.PosMod(obj.RadianDirection + FlagsAsRad(Flags), Math.PI * 2);
                if (flagRot > Math.PI)
                {
                    flagRot -= Math.PI * 2;
                }

                VerifyAndAddLocation(obj, circleCtr, center, Flags, Double.MaxValue, context, caller, (float)flagRot);
                return(Results);
            }
            else
            {
                if (((int)Flags & 255) == 0 || Slot.Offset != new Vector3())
                {
                    //exact position
                    //Flags |= (SLOTFlags)255;

                    // special case, walk directly to point.
                    VerifyAndAddLocation(obj, circleCtr, center, Flags, Double.MaxValue, context, caller, float.NaN);
                    return(Results);
                }
                var maxScore    = Math.Max(DesiredProximity - MinProximity, MaxProximity - DesiredProximity) + (LotTilePos.Distance(obj.Position, caller.Position) + MaxProximity) / 3 + 2;
                var ignoreRooms = (Flags & SLOTFlags.IgnoreRooms) > 0;

                SLOTEnumerationFunction((x, y, distance) =>
                {
                    var pos = new Vector2(circleCtr.X + x / 16.0f, circleCtr.Y + y / 16.0f);
                    if (distance >= MinProximity - 0.5 && distance <= MaxProximity + 0.5 && (ignoreRooms || context.VM.Context.GetRoomAt(new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level)) == room)) //slot is within proximity
                    {
                        var routeEntryFlags = (GetSearchDirection(circleCtr, pos, obj.RadianDirection) & Flags);                                                                                                                                     //the route needs to know what conditions it fulfilled
                        if (routeEntryFlags > 0)                                                                                                                                                                                                     //within search location
                        {
                            double baseScore = ((maxScore - Math.Abs(DesiredProximity - distance)) + context.VM.Context.NextRandom(1024) / 1024.0f);
                            VerifyAndAddLocation(obj, pos, center, routeEntryFlags, baseScore, context, caller, float.NaN);
                        }
                    }
                });
            }
            /** Sort by how close they are to desired proximity **/

            if (Results.Count > 1)
            {
                Results = Results.OrderBy(x => - x.Score).ToList();                   //avoid sort because it acts incredibly unusually
            }
            if (Results.Count > 0)
            {
                FailCode = VMRouteFailCode.Success;
            }
            return(Results);
        }
Пример #22
0
        private void VerifyAndAddLocation(VMEntity obj, Vector2 pos, Vector2 center, SLOTFlags entryFlags, double score, VMContext context, VMEntity caller, float facingDir)
        {
            //note: verification is not performed if snap target slot is enabled.
            var tpos = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level);

            if (context.IsOutOfBounds(tpos))
            {
                return;
            }

            score -= LotTilePos.Distance(tpos, caller.Position) / 3.0;

            if (Slot.SnapTargetSlot < 0 && context.Architecture.RaycastWall(new Point((int)pos.X, (int)pos.Y), new Point(obj.Position.TileX, obj.Position.TileY), obj.Position.Level))
            {
                SetFail(VMRouteFailCode.WallInWay, null);
                return;
            }

            bool faceAnywhere = false;

            if (float.IsNaN(facingDir))
            {
                var obj3P = obj.Position.ToVector3();
                var objP  = new Vector2(obj3P.X, obj3P.Y);
                switch (Slot.Facing)
                {
                case SLOTFacing.FaceTowardsObject:
                    facingDir = (float)GetDirectionTo(pos, objP); break;

                case SLOTFacing.FaceAwayFromObject:
                    facingDir = (float)GetDirectionTo(objP, pos); break;

                case SLOTFacing.FaceAnywhere:
                    faceAnywhere = true;
                    facingDir    = 0.0f; break;

                default:
                    int intDir   = (int)Math.Round(Math.Log((double)obj.Direction, 2));
                    var rotatedF = ((int)Slot.Facing + intDir) % 8;
                    facingDir = (float)(((int)rotatedF > 4) ? ((double)rotatedF * Math.PI / 4.0) : (((double)rotatedF - 8.0) * Math.PI / 4.0)); break;
                }
            }

            VMEntity chair = null;

            if (Slot.SnapTargetSlot < 0)
            {
                var solid = caller.PositionValid(tpos, Direction.NORTH, context);
                if (solid.Status != Model.VMPlacementError.Success)
                {
                    if (solid.Object != null && solid.Object is VMGameObject)
                    {
                        if (Slot.Sitting > 0 && solid.Object.EntryPoints[26].ActionFunction != 0)
                        {
                            chair = solid.Object;
                        }
                        else
                        {
                            SetFail(VMRouteFailCode.DestTileOccupied, solid.Object);
                            return;
                        }
                    }
                }

                if (chair != null && (Math.Abs(DirectionUtils.Difference(chair.RadianDirection, facingDir)) > Math.PI / 4))
                {
                    return; //not a valid goal.
                }
                if (chair == null && OnlySit)
                {
                    return;
                }
            }

            Results.Add(new VMFindLocationResult
            {
                Position        = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level),
                Score           = score * ((chair != null) ? Slot.Sitting : Slot.Standing), //todo: prefer closer?
                RadianDirection = facingDir,
                Chair           = chair,
                FaceAnywhere    = faceAnywhere,
                RouteEntryFlags = entryFlags
            });
        }
Пример #23
0
        void VerifyAndAddLocation(VMEntity obj, Vector2 pos, Vector2 center, SLOTFlags entryFlags, double score, VMContext context, VMEntity caller, float facingDir)
        {
            //note: verification is not performed if snap target slot is enabled.
            var tpos = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level);

            if (context.IsOutOfBounds(tpos))
            {
                return;
            }

            score -= LotTilePos.Distance(tpos, caller.Position) / 3.0;

            if (Slot.SnapTargetSlot < 0 && context.Architecture.RaycastWall(new Point((int)pos.X, (int)pos.Y), new Point(obj.Position.TileX, obj.Position.TileY), obj.Position.Level))
            {
                SetFail(VMRouteFailCode.WallInWay, null);
                return;
            }

            bool faceAnywhere = false;

            if (float.IsNaN(facingDir))
            {
                var obj3P = obj.Position.ToVector3();
                var objP  = new Vector2(obj3P.X, obj3P.Y);
                switch (Slot.Facing)
                {
                case SLOTFacing.FaceTowardsObject:
                    facingDir = (float)GetDirectionTo(pos, objP); break;

                case SLOTFacing.FaceAwayFromObject:
                    facingDir = (float)GetDirectionTo(objP, pos); break;

                case SLOTFacing.FaceAnywhere:
                    faceAnywhere = true;
                    facingDir    = 0.0f; break;

                default:
                    int intDir   = (int)Math.Round(Math.Log((double)obj.Direction, 2));
                    var rotatedF = ((int)Slot.Facing + intDir) % 8;
                    facingDir = (float)((rotatedF > 4) ? (rotatedF * Math.PI / 4.0) : ((rotatedF - 8.0) * Math.PI / 4.0)); break;
                }
            }

            VMFindLocationResult result = new VMFindLocationResult
            {
                Position        = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level),
                RadianDirection = facingDir,
                FaceAnywhere    = faceAnywhere,
                RouteEntryFlags = entryFlags
            };
            var avatarInWay = false;

            if (Slot.SnapTargetSlot < 0)
            {
                var solid = caller.PositionValid(tpos, Direction.NORTH, context, VMPlaceRequestFlags.AcceptSlots | VMPlaceRequestFlags.AllAvatarsSolid);
                if (solid.Status != VMPlacementError.Success)
                {
                    if (solid.Object != null)
                    {
                        if (solid.Object is VMGameObject)
                        {
                            if (Slot.Sitting > 0 && solid.Object.EntryPoints[26].ActionFunction != 0)
                            {
                                result.Chair = solid.Object;
                            }
                            else
                            {
                                SetFail(VMRouteFailCode.DestTileOccupied, solid.Object);
                                return;
                            }
                        }
                        else
                        {
                            avatarInWay = true;
                        }
                    }
                }

                if (context.ObjectQueries.GetObjectsAt(tpos)?.Any(
                        x => ((VMEntityFlags2)x.GetValue(VMStackObjectVariable.FlagField2) & VMEntityFlags2.ArchitectualDoor) > 0) ?? false)
                {
                    avatarInWay = true; //prefer not standing in front of a door. (todo: merge with above check?)
                }
                if (result.Chair != null && (Math.Abs(DirectionUtils.Difference(result.Chair.RadianDirection, facingDir)) > Math.PI / 4))
                {
                    return; //not a valid goal.
                }
                if (result.Chair == null && OnlySit)
                {
                    return;
                }

                score = score * ((result.Chair != null) ? Slot.Sitting : Slot.Standing);
                //if an avatar is in or going to our destination positon, we this spot becomes low priority as getting into it will require a shoo.
                if (!avatarInWay)
                {
                    foreach (var avatar in context.ObjectQueries.Avatars)
                    {
                        if (avatar == caller)
                        {
                            continue;
                        }
                        //search for routing frame. is its destination the same as ours?
                        if (avatar.Thread != null)
                        {
                            var intersects = avatar.Thread.Stack.Any(x => x is VMRoutingFrame && ((VMRoutingFrame)x).IntersectsOurDestination(result));
                            if (intersects)
                            {
                                score = score / 100000;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    score = score / 100000;
                }
            }
            result.Score = score;

            Results.Add(result);
        }
Пример #24
0
 public VMFindLocationResult(VMFindLocationResultMarshal input, VMContext context)
 {
     Load(input, context);
 }
Пример #25
0
        public void Tick(VMAvatar avatar, VMContext context)
        {
            if (context.Clock.Minutes == LastMinute)
            {
                return;
            }
            LastMinute = context.Clock.Minutes;

            string category   = "Skills";
            string sleepState = (avatar.GetMotiveData(VMMotive.SleepState) == 0)?"Awake":"Asleep";

            int moodSum = 0;

            for (int i = 0; i < 7; i++)
            {
                float lotMul   = LotMotives.GetNum(category + "_" + LotMotiveNames[i] + "Weight");
                float frac     = 0;
                var   motive   = avatar.GetMotiveData(DecrementMotives[i]);
                var   r_Hunger = (SimMotives.GetNum("HungerDecrementRatio") * (100 + avatar.GetMotiveData(VMMotive.Hunger))) * LotMotives.GetNum(category + "_HungerWeight");
                switch (i)
                {
                case 0:
                    frac = r_Hunger; break;

                case 1:
                    frac = (SimMotives.GetNum("ComfortDecrementActive") * lotMul); break;

                case 2:
                    frac = (SimMotives.GetNum("HygieneDecrement" + sleepState) * lotMul); break;

                case 3:
                    frac = (SimMotives.GetNum("BladderDecrement" + sleepState) * lotMul) + (SimMotives.GetNum("HungerToBladderMultiplier") * r_Hunger); break;

                case 4:
                    frac = (SimMotives.GetNum("EnergySpan") / (60 * SimMotives.GetNum("WakeHours")));
                    // TODO: wrong but appears to be close? need one which uses energy weight, which is about 2.4 on skills
                    break;

                case 5:
                    frac = (sleepState == "Asleep") ? 0 : (SimMotives.GetNum("EntDecrementAwake") * lotMul);
                    break;

                case 6:
                    frac  = (SimMotives.GetNum("SocialDecrementBase") + (SimMotives.GetNum("SocialDecrementMultiplier") * (100 + motive))) * lotMul;
                    frac /= 2;     //make this less harsh right now, til I can work out how multiplayer bonus is meant to work
                    break;
                }

                MotiveFractions[i] += (short)(frac * 1000);
                if (MotiveFractions[i] >= 1000)
                {
                    motive             -= (short)(MotiveFractions[i] / 1000);
                    MotiveFractions[i] %= 1000;
                    if (motive < -100)
                    {
                        motive = -100;
                    }
                    avatar.SetMotiveData(DecrementMotives[i], motive);
                }
                moodSum += motive;
            }
            avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 7));
        }
Пример #26
0
 public VMQueuedAction(VMQueuedActionMarshal input, VMContext context)
 {
     Load(input, context);
 }
Пример #27
0
 public VMThread(VMThreadMarshal input, VMContext context, VMEntity entity)
 {
     Context = context;
     Entity  = entity;
     Load(input, context);
 }
Пример #28
0
 public VMMultitileGroup(VMMultitileGroupMarshal input, VMContext context)
 {
     Load(input, context);
 }
Пример #29
0
 public VMFindLocationResult(VMFindLocationResultMarshal input, VMContext context)
 {
     Load(input, context);
 }
Пример #30
0
        public override void Update(UpdateState state)
        {
            base.Update(state);
            if (TempVM == null && GUID != 0)
            {
                var world = new ExternalWorld(GameFacade.GraphicsDevice);
                world.Initialize(GameFacade.Scenes);
                var context = new VMContext(world);

                TempVM = new VM(context, new VMServerDriver(new VMTSOGlobalLinkStub()), new VMNullHeadlineProvider());
                TempVM.Init();

                var blueprint = new Blueprint(32, 32);
                blueprint.Light = new RoomLighting[]
                {
                    new RoomLighting()
                    {
                        OutsideLight = 100
                    },
                    new RoomLighting()
                    {
                        OutsideLight = 100
                    },
                    new RoomLighting()
                    {
                        OutsideLight = 100
                    },
                };
                blueprint.OutsideColor = Color.White;
                blueprint.GenerateRoomLights();
                blueprint.RoomColors[2].A /= 2;
                world.State.AmbientLight.SetData(blueprint.RoomColors);
                world.State.OutsidePx.SetData(new Color[] { Color.White });

                world.InitBlueprint(blueprint);
                context.Blueprint    = blueprint;
                context.Architecture = new VMArchitecture(1, 1, blueprint, TempVM.Context);
            }

            if (GUID != oldGUID)
            {
                SetGUIDLocal(GUID, TempVM);
                state.SharedData["ExternalDraw"] = true;
            }

            if (ForceRedraw)
            {
                state.SharedData["ExternalDraw"] = true;
                ForceRedraw = false;
            }

            if (TempVM != null)
            {
                var lcount = TempVM.Scheduler.CurrentTickID;
                TempVM.Update();
                var count = TempVM.Scheduler.CurrentTickID;
                foreach (var ent in TempVM.Entities)
                {
                    if (ent is VMAvatar)
                    {
                        for (uint i = lcount; i < count; i++)
                        {
                            ent.Tick();
                        }
                    }
                }
                TempVM.PreDraw();
            }
        }
Пример #31
0
        private bool SetPosition(VMEntity entity, LotTilePos pos, float radDir, bool shooAva, VMContext context)
        {
            var posChange = entity.SetPosition(pos, (Direction)(1 << (int)(Math.Round(DirectionUtils.PosMod(radDir, (float)Math.PI * 2) / (Math.PI / 4)) % 8)), context);

            if (posChange.Status != VMPlacementError.Success)
            {
                if (shooAva && posChange.Object != null && posChange.Object is VMAvatar)
                {
                    if (!posChange.Object.Thread.Queue.Any(x => x.Callee != null && x.Callee.Object.GUID == GOTO_GUID && x.InteractionNumber == SHOO_INTERACTION))
                    {
                        //push shoo if not already being shooed
                        VMEntity callee = context.VM.Context.CreateObjectInstance(GOTO_GUID, new LotTilePos(posChange.Object.Position), Direction.NORTH).Objects[0];
                        callee.PushUserInteraction(SHOO_INTERACTION, posChange.Object, context.VM.Context, false);
                    }
                }
                if (posChange.Status == VMPlacementError.LocationOutOfBounds)
                {
                    entity.SetValue(VMStackObjectVariable.PrimitiveResult, 2);
                }
                entity.SetValue(VMStackObjectVariable.PrimitiveResultID, (posChange.Object == null) ? (short)0 : posChange.Object.ObjectID);
                return(false);
            }
            if (entity is VMAvatar)
            {
                entity.RadianDirection = radDir;
            }
            return(true);
        }
Пример #32
0
 private bool SetPosition(VMEntity entity, LotTilePos pos, Direction dir, bool shooAva, VMContext context)
 {
     return(SetPosition(entity, pos, (float)(Math.Round(Math.Log((double)dir, 2)) * (Math.PI / 4)), shooAva, context));
 }
Пример #33
0
 public VMStackFrame(VMStackFrameMarshal input, VMContext context, VMThread thread)
 {
     Thread = thread;
     Load(input, context);
 }
Пример #34
0
        public List <VMObstacle> GenerateRoomObs(ushort room, sbyte level, Rectangle bounds, VMContext context)
        {
            var result = new List <VMObstacle>();

            if (room == 0)
            {
                bounds = new Rectangle(1, 1, Width - 2, Height - 2);
            }
            var x1 = Math.Max(0, bounds.X - 1);
            var x2 = Math.Min(Width, bounds.Right + 1);
            var y1 = Math.Max(0, bounds.Y - 1);
            var y2 = Math.Min(Height, bounds.Bottom + 1);

            for (int y = y1; y < y2; y++)
            {
                VMObstacle next = null;
                for (int x = x1; x < x2; x++)
                {
                    uint tRoom = Map[x + y * Width];
                    if ((ushort)tRoom != room && ((tRoom >> 16) & 0x7FFF) != room)
                    {
                        //is there a door on this tile?
                        var door = (context.ObjectQueries.GetObjectsAt(LotTilePos.FromBigTile((short)x, (short)y, level))?.FirstOrDefault(
                                        o => ((VMEntityFlags2)(o.GetValue(VMStackObjectVariable.FlagField2)) & VMEntityFlags2.ArchitectualDoor) > 0)
                                    );
                        if (door != null)
                        {
                            //ok... is is a portal to this room? block all sides that are not a portal to this room
                            var otherSide = door.MultitileGroup.Objects.FirstOrDefault(o => context.GetObjectRoom(o) == room && o.EntryPoints[15].ActionFunction != 0);
                            if (otherSide != null)
                            {
                                //make a hole for this door
                                if (next != null)
                                {
                                    next = null;
                                }
                                // note: the sims 1 stops here. this creates issues where sims can walk through doors in some circumstance
                                // eg. two doors back to back into the same room. The sim will not perform a room route to the middle room, they will just walk through the door.
                                // like, through it. This also works for pools but some additional rules prevent you from doing anything too silly.
                                // we want to create 1 unit thick walls blocking each non-portal side.

                                // todo: fix for this
                                continue;
                            }
                        }

                        if (next != null)
                        {
                            next.x2 += 16;
                        }
                        else
                        {
                            next = new VMObstacle((x << 4) - 3, (y << 4) - 3, (x << 4) + 19, (y << 4) + 19);
                            result.Add(next);
                        }
                    }
                    else
                    {
                        if (next != null)
                        {
                            next = null;
                        }
                    }
                }
            }
            OptimizeObstacles(result);
            return(result);
        }
Пример #35
0
 public void Run(VMContext ctx, out ExecutionState state)
 {
     state = ExecutionState.Exit;
 }
Пример #36
0
        /// <summary>
        /// Generates the room map for the specified walls array.
        /// </summary>
        public void GenerateMap(WallTile[] Walls, FloorTile[] Floors, int width, int height, List <VMRoom> rooms, sbyte floor, VMContext context) //for first floor gen, curRoom should be 1. For floors above, it should be the last genmap result
        {
            Map = new uint[width * height];                                                                                                       //although 0 is the base of the array, room 1 is known to simantics as room 0.
            //values of 0 indicate the room has not been chosen in that location yet.

            bool noFloorBad = (rooms.Count > 1);

            this.Width  = width;
            this.Height = height;

            //flood fill recursively. Each time choose find and choose the first "0" as the base.
            //The first recursion (outside) cannot fill into diagonals.
            bool remaining = true;
            bool outside   = true;
            int  i         = 0;

            while (remaining)
            {
                var spread = new Stack <SpreadItem>();
                remaining = false;
                while (i < Map.Length)
                {
                    remaining = true;

                    //get the wall on this tile.
                    var wall = Walls[i];
                    var segs = wall.Segments;
                    var room = (uint)rooms.Count;
                    if (Map[i] == 0 && (segs & (WallSegments.AnyDiag)) == 0)
                    {
                        //normal tile - no diagonal
                        ExpectedTile = Floors[i].Pattern;
                        Map[i]       = room | (room << 16);
                        spread.Push(new SpreadItem(new Point(i % width, i / width), WallSegments.AnyAdj));
                        break;
                    }
                    else if ((Map[i] & 0xFFFF) == 0)
                    {
                        //start spreading from this side of the diagonal
                        WallSegments validSpread;
                        if ((segs & WallSegments.HorizontalDiag) > 0)
                        {
                            validSpread  = WallSegments.TopLeft | WallSegments.TopRight;
                            ExpectedTile = wall.TopLeftStyle;
                            Map[i]      |= 0x80000000;
                        }
                        else
                        {
                            validSpread  = WallSegments.TopRight | WallSegments.BottomRight;
                            ExpectedTile = wall.TopLeftPattern;
                        }

                        Map[i] |= room;
                        spread.Push(new SpreadItem(new Point(i % width, i / width), validSpread));
                        break;
                    }
                    else if ((Map[i] & 0x7FFF0000) == 0)
                    {
                        //start spreading the other side
                        WallSegments validSpread;
                        if ((segs & WallSegments.HorizontalDiag) > 0)
                        {
                            validSpread  = WallSegments.BottomLeft | WallSegments.BottomRight;
                            ExpectedTile = wall.TopLeftPattern;
                            Map[i]      |= 0x80000000;
                        }
                        else
                        {
                            validSpread  = WallSegments.TopLeft | WallSegments.BottomLeft;
                            ExpectedTile = wall.TopLeftStyle;
                        }
                        Map[i] |= (room << 16);
                        spread.Push(new SpreadItem(new Point(i % width, i / width), validSpread));
                        i++;
                        break;
                    }
                    else
                    {
                        remaining = false;
                    }
                    i++;
                }

                if (remaining)
                {
                    int    rminX      = spread.Peek().Pt.X;
                    int    rmaxX      = rminX;
                    int    rminY      = spread.Peek().Pt.Y;
                    int    rmaxY      = rminY;
                    var    wallObs    = new List <VMObstacle>();
                    var    wallLines  = (VM.UseWorld)?new VMWallLineBuilder():null;
                    var    fenceLines = (VM.UseWorld) ? new VMWallLineBuilder() : null;
                    var    wallDict   = new Dictionary <uint, Vector2[]>();
                    var    adjRooms   = new HashSet <ushort>();
                    ushort area       = 0;
                    while (spread.Count > 0)
                    {
                        area++;
                        var itemT = spread.Pop();
                        var item  = itemT.Pt;

                        if (item.X > rmaxX)
                        {
                            rmaxX = item.X;
                        }
                        if (item.X < rminX)
                        {
                            rminX = item.X;
                        }
                        if (item.Y > rmaxY)
                        {
                            rmaxY = item.Y;
                        }
                        if (item.Y < rminY)
                        {
                            rminY = item.Y;
                        }

                        var plusX = (item.X + 1) % width;
                        var minX  = (item.X + width - 1) % width;
                        var plusY = (item.Y + 1) % height;
                        var minY  = (item.Y + height - 1) % height;

                        var mainWalls = Walls[item.X + item.Y * width];

                        int obsX = item.X << 4;
                        int obsY = item.Y << 4;

                        if ((mainWalls.Segments & WallSegments.HorizontalDiag) > 0)
                        {
                            wallObs.Add(new VMObstacle(obsX + 11, obsY - 1, obsX + 17, obsY + 5));
                            wallObs.Add(new VMObstacle(obsX + 7, obsY + 3, obsX + 13, obsY + 9));
                            wallObs.Add(new VMObstacle(obsX + 3, obsY + 7, obsX + 9, obsY + 13));
                            wallObs.Add(new VMObstacle(obsX - 1, obsY + 11, obsX + 5, obsY + 17));
                            if (mainWalls.TopRightStyle == 1)
                            {
                                wallLines?.AddLine(obsX, obsY, 2);
                            }
                            else
                            {
                                fenceLines?.AddLine(obsX, obsY, 2);
                            }
                        }

                        if ((mainWalls.Segments & WallSegments.VerticalDiag) > 0)
                        {
                            wallObs.Add(new VMObstacle(obsX - 1, obsY - 1, obsX + 5, obsY + 5));
                            wallObs.Add(new VMObstacle(obsX + 3, obsY + 3, obsX + 9, obsY + 9));
                            wallObs.Add(new VMObstacle(obsX + 7, obsY + 7, obsX + 13, obsY + 13));
                            wallObs.Add(new VMObstacle(obsX + 11, obsY + 11, obsX + 17, obsY + 17));
                            if (mainWalls.TopRightStyle == 1)
                            {
                                wallLines?.AddLine(obsX, obsY, 3);
                            }
                            else
                            {
                                fenceLines?.AddLine(obsX, obsY, 3);
                            }
                        }

                        var PXWalls = Walls[plusX + item.Y * width];
                        var PYWalls = Walls[item.X + plusY * width];

                        if ((mainWalls.Segments & WallSegments.TopLeft) > 0)
                        {
                            if (!mainWalls.TopLeftDoor)
                            {
                                wallObs.Add(new VMObstacle(obsX - 3, obsY - 3, obsX + 6, obsY + 19));
                            }
                            if (mainWalls.TopLeftThick)
                            {
                                wallLines?.AddLine(obsX, obsY, 0);
                            }
                            else
                            {
                                fenceLines?.AddLine(obsX, obsY, 0);
                            }
                        }
                        if ((mainWalls.Segments & WallSegments.TopRight) > 0)
                        {
                            if (!mainWalls.TopRightDoor)
                            {
                                wallObs.Add(new VMObstacle(obsX - 3, obsY - 3, obsX + 19, obsY + 6));
                            }
                            if (mainWalls.TopRightThick)
                            {
                                wallLines?.AddLine(obsX, obsY, 1);
                            }
                            else
                            {
                                fenceLines?.AddLine(obsX, obsY, 1);
                            }
                        }
                        if ((mainWalls.Segments & WallSegments.BottomLeft) > 0)
                        {
                            if (!PYWalls.TopRightDoor)
                            {
                                wallObs.Add(new VMObstacle(obsX - 3, obsY + 13, obsX + 19, obsY + 19));
                            }
                            if (PYWalls.TopRightThick)
                            {
                                wallLines?.AddLine(obsX, obsY + 16, 1);
                            }
                            else
                            {
                                fenceLines?.AddLine(obsX, obsY + 16, 1);
                            }
                        }
                        if ((mainWalls.Segments & WallSegments.BottomRight) > 0)
                        {
                            if (!PXWalls.TopLeftDoor)
                            {
                                wallObs.Add(new VMObstacle(obsX + 13, obsY - 3, obsX + 19, obsY + 19));
                            }
                            if (PXWalls.TopLeftThick)
                            {
                                wallLines?.AddLine(obsX + 16, obsY, 0);
                            }
                            else
                            {
                                fenceLines?.AddLine(obsX + 16, obsY, 0);
                            }
                        }

                        bool segAllow = ((PXWalls.Segments & WallSegments.TopLeft) == 0);
                        if ((segAllow || PXWalls.TopLeftStyle != 1) && ((itemT.Dir & WallSegments.BottomRight) > 0))
                        {
                            SpreadOnto(Walls, Floors, plusX, item.Y, 0, Map, width, height, spread, (ushort)rooms.Count, ExpectedTile, noFloorBad, adjRooms, !segAllow);
                        }

                        segAllow = ((mainWalls.Segments & WallSegments.TopLeft) == 0);
                        if ((segAllow || mainWalls.TopLeftStyle != 1) && ((itemT.Dir & WallSegments.TopLeft) > 0))
                        {
                            SpreadOnto(Walls, Floors, minX, item.Y, 2, Map, width, height, spread, (ushort)rooms.Count, ExpectedTile, noFloorBad, adjRooms, !segAllow);
                        }

                        segAllow = ((PYWalls.Segments & WallSegments.TopRight) == 0);
                        if ((segAllow || PYWalls.TopRightStyle != 1) && ((itemT.Dir & WallSegments.BottomLeft) > 0))
                        {
                            SpreadOnto(Walls, Floors, item.X, plusY, 1, Map, width, height, spread, (ushort)rooms.Count, ExpectedTile, noFloorBad, adjRooms, !segAllow);
                        }

                        segAllow = ((mainWalls.Segments & WallSegments.TopRight) == 0);
                        if ((segAllow || mainWalls.TopRightStyle != 1) && ((itemT.Dir & WallSegments.TopRight) > 0))
                        {
                            SpreadOnto(Walls, Floors, item.X, minY, 3, Map, width, height, spread, (ushort)rooms.Count, ExpectedTile, noFloorBad, adjRooms, !segAllow);
                        }
                    }

                    var bounds  = new Rectangle(rminX, rminY, (rmaxX - rminX) + 1, (rmaxY - rminY) + 1);
                    var roomObs = GenerateRoomObs((ushort)rooms.Count, (sbyte)(floor + 1), bounds, context);
                    OptimizeObstacles(wallObs);
                    OptimizeObstacles(roomObs);
                    var supportRooms = new List <ushort>();

                    ushort myRoom      = (ushort)rooms.Count;
                    ushort minRoom     = myRoom;
                    bool   deferredLit = false;
                    foreach (var roomN in adjRooms)
                    {
                        var room = rooms[roomN];
                        if (minRoom > room.LightBaseRoom)
                        {
                            deferredLit = true;
                            minRoom     = room.LightBaseRoom;
                        }
                        room.AdjRooms.Add(myRoom);
                        if (outside)
                        {
                            MakeOutside(rooms, room);
                        }
                        else if (room.IsOutside)
                        {
                            outside = true;
                        }
                    }

                    if (deferredLit)
                    {
                        rooms[minRoom].SupportRooms.Add(myRoom);
                    }
                    else
                    {
                        supportRooms.Add(myRoom);
                    }

                    if (VM.UseWorld && minRoom != rooms.Count)
                    {
                        rooms[minRoom].WallLines.AddRange(wallLines.Lines);
                        rooms[minRoom].FenceLines.AddRange(fenceLines.Lines);
                    }

                    rooms.Add(new VMRoom
                    {
                        IsOutside     = outside,
                        IsPool        = ExpectedTile > 65533,
                        Bounds        = bounds,
                        WallObs       = wallObs,
                        RoomObs       = roomObs,
                        WallLines     = (deferredLit) ? null : wallLines?.Lines,
                        FenceLines    = (deferredLit) ? null : fenceLines?.Lines,
                        AdjRooms      = adjRooms,
                        RoomID        = myRoom,
                        LightBaseRoom = minRoom,
                        Area          = area,
                        Floor         = floor,
                        SupportRooms  = supportRooms
                    });

                    foreach (var roomN in adjRooms)
                    {
                        var room = rooms[roomN];
                        TrySwitchBaseRoom(rooms, room, minRoom);
                    }

                    outside = false;
                }
            }
        }
Пример #37
0
        public void Load(VMQueuedActionMarshal input, VMContext context)
        {
            CodeOwner = FSO.Content.Content.Get().WorldObjects.Get(input.CodeOwnerGUID);

            BHAV bhav = null;
            if (input.RoutineID >= 8192) bhav = CodeOwner.Resource.SemiGlobal.Get<BHAV>(input.RoutineID);
            else if (input.RoutineID >= 4096) bhav = CodeOwner.Resource.Get<BHAV>(input.RoutineID);
            else bhav = context.Globals.Resource.Get<BHAV>(input.RoutineID);
            ActionRoutine = context.VM.Assemble(bhav);

            if (input.CheckRoutineID != 0)
            {
                if (input.CheckRoutineID >= 8192) bhav = CodeOwner.Resource.SemiGlobal.Get<BHAV>(input.CheckRoutineID);
                else if (input.CheckRoutineID >= 4096) bhav = CodeOwner.Resource.Get<BHAV>(input.CheckRoutineID);
                else bhav = context.Globals.Resource.Get<BHAV>(input.CheckRoutineID);
                CheckRoutine = context.VM.Assemble(bhav);
            }

            Callee = context.VM.GetObjectById(input.Callee);
            StackObject = context.VM.GetObjectById(input.StackObject);
            IconOwner = context.VM.GetObjectById(input.IconOwner);
            Name = input.Name;
            Args = input.Args;
            InteractionNumber = input.InteractionNumber;
            Cancelled = input.Cancelled;
            Priority = input.Priority;
            Mode = input.Mode;
            Flags = input.Flags;
            Flags2 = input.Flags2;
            UID = input.UID;
            Callback = (input.Callback == null)?null:new VMActionCallback(input.Callback, context);
        }
Пример #38
0
 public VMObjectQueries(VMContext context)
 {
     Context = context;
 }
Пример #39
0
 public VMActionCallback(VMActionCallbackMarshal input, VMContext context)
 {
     Load(input, context);
 }
Пример #40
0
        static void Main(string[] args)
        {
            FSO.Windows.Program.InitWindows();
            TimedReferenceController.SetMode(CacheType.PERMANENT);

            Console.WriteLine("Loading Config...");
            try
            {
                var configString = File.ReadAllText("facadeconfig.json");
                Config = Newtonsoft.Json.JsonConvert.DeserializeObject <FacadeConfig>(configString);
            }
            catch (Exception e)
            {
                Console.WriteLine("Could not find configuration file 'facadeconfig.json'. Please ensure it is valid and present in the same folder as this executable.");
                return;
            }

            Console.WriteLine("Locating The Sims Online...");
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;

            Directory.SetCurrentDirectory(baseDir);
            //Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            OperatingSystem os  = Environment.OSVersion;
            PlatformID      pid = os.Platform;

            ILocator gameLocator;
            bool     linux = pid == PlatformID.MacOSX || pid == PlatformID.Unix;

            if (linux && Directory.Exists("/Users"))
            {
                gameLocator = new MacOSLocator();
            }
            else if (linux)
            {
                gameLocator = new LinuxLocator();
            }
            else
            {
                gameLocator = new WindowsLocator();
            }

            bool useDX = true;

            FSOEnvironment.Enable3D = true;
            GraphicsModeControl.ChangeMode(FSO.LotView.Model.GlobalGraphicsMode.Full3D);
            GameThread.NoGame          = true;
            GameThread.UpdateExecuting = true;

            var path = gameLocator.FindTheSimsOnline();

            if (path != null)
            {
                FSOEnvironment.ContentDir    = "Content/";
                FSOEnvironment.GFXContentDir = "Content/" + (useDX ? "DX/" : "OGL/");
                FSOEnvironment.Linux         = linux;
                FSOEnvironment.DirectX       = useDX;
                FSOEnvironment.TexCompress   = FSOEnvironment.TexCompressSupport;
                FSOEnvironment.GameThread    = Thread.CurrentThread;

                FSO.HIT.HITVM.Init();
                FSO.HIT.HITVM.Get().SetMasterVolume(FSO.HIT.Model.HITVolumeGroup.AMBIENCE, 0);
                FSO.HIT.HITVM.Get().SetMasterVolume(FSO.HIT.Model.HITVolumeGroup.FX, 0);
                FSO.HIT.HITVM.Get().SetMasterVolume(FSO.HIT.Model.HITVolumeGroup.MUSIC, 0);
                FSO.HIT.HITVM.Get().SetMasterVolume(FSO.HIT.Model.HITVolumeGroup.VOX, 0);
                FSO.Files.Formats.IFF.Chunks.STR.DefaultLangCode = FSO.Files.Formats.IFF.Chunks.STRLangCode.EnglishUS;
            }

            Console.WriteLine("Creating Graphics Device...");
            var gds = new GraphicsDeviceServiceMock();
            var gd  = gds.GraphicsDevice;

            //set up some extra stuff like the content manager
            var services = new GameServiceContainer();
            var content  = new ContentManager(services);

            content.RootDirectory = FSOEnvironment.GFXContentDir;
            services.AddService <IGraphicsDeviceService>(gds);

            var vitaboyEffect = content.Load <Effect>("Effects/Vitaboy");

            FSO.Vitaboy.Avatar.setVitaboyEffect(vitaboyEffect);

            WorldConfig.Current = new WorldConfig()
            {
                LightingMode    = 3,
                SmoothZoom      = true,
                SurroundingLots = 0
            };
            DGRP3DMesh.Sync = true;

            Console.WriteLine("Looks like that worked. Loading FSO Content!");
            VMContext.InitVMConfig(false);
            Content.Init(path, gd);
            WorldContent.Init(services, content.RootDirectory);
            VMAmbientSound.ForceDisable = true;
            Layer = new _3DLayer();
            Layer.Initialize(gd);
            GD = gd;

            if (args.FirstOrDefault() == "debug")
            {
                DebugLot = uint.Parse(args[1]);
            }
            Console.WriteLine("Starting Worker Loop!");
            WorkerLoop();

            Console.WriteLine("Exiting.");
            GameThread.SetKilled();
            gds.Release();
        }
Пример #41
0
        public int Run()
        {
            LOG.Info("Starting server");
            TimedReferenceController.SetMode(CacheType.PERMANENT);

            if (Config.Services == null)
            {
                LOG.Warn("No services found in the configuration file, exiting");
                return(1);
            }

            if (!Directory.Exists(Config.GameLocation))
            {
                LOG.Fatal("The directory specified as gameLocation in config.json does not exist");
                return(1);
            }

            Directory.CreateDirectory(Config.SimNFS);
            Directory.CreateDirectory(Path.Combine(Config.SimNFS, "Lots/"));
            Directory.CreateDirectory(Path.Combine(Config.SimNFS, "Objects/"));

            Content.Model.AbstractTextureRef.ImageFetchFunction = Utils.SoftwareImageLoader.SoftImageFetch;

            //TODO: Some content preloading
            LOG.Info("Scanning content");
            Content.GameContent.Init(Config.GameLocation, Content.ContentMode.SERVER);
            Kernel.Bind <Content.GameContent>().ToConstant(Content.GameContent.Get);
            VMContext.InitVMConfig();
            Kernel.Bind <MemoryCache>().ToConstant(new MemoryCache("fso_server"));

            LOG.Info("Loading domain logic");
            Kernel.Load <ServerDomainModule>();

            Servers     = new List <AbstractServer>();
            CityServers = new List <CityServer>();
            Kernel.Bind <IServerNFSProvider>().ToConstant(new ServerNFSProvider(Config.SimNFS));

            if (Config.Services.UserApi != null &&
                Config.Services.UserApi.Enabled)
            {
                var childKernel = new ChildKernel(
                    Kernel
                    );
                var api = new UserApi(Config, childKernel);
                ActiveUApiServer = api;
                Servers.Add(api);
                api.OnRequestShutdown       += RequestedShutdown;
                api.OnBroadcastMessage      += BroadcastMessage;
                api.OnRequestUserDisconnect += RequestedUserDisconnect;
                api.OnRequestMailNotify     += RequestedMailNotify;
            }

            foreach (var cityServer in Config.Services.Cities)
            {
                /**
                 * Need to create a kernel for each city server as there is some data they do not share
                 */
                var childKernel = new ChildKernel(
                    Kernel,
                    new ShardDataServiceModule(Config.SimNFS),
                    new CityServerModule()
                    );

                var city = childKernel.Get <CityServer>(new ConstructorArgument("config", cityServer));
                CityServers.Add(city);
                Servers.Add(city);
            }

            foreach (var lotServer in Config.Services.Lots)
            {
                if (lotServer.SimNFS == null)
                {
                    lotServer.SimNFS = Config.SimNFS;
                }
                var childKernel = new ChildKernel(
                    Kernel,
                    new LotServerModule()
                    );

                Servers.Add(
                    childKernel.Get <LotServer>(new ConstructorArgument("config", lotServer))
                    );
            }

            if (Config.Services.Tasks != null &&
                Config.Services.Tasks.Enabled)
            {
                var childKernel = new ChildKernel(
                    Kernel,
                    new TaskEngineModule()
                    );

                childKernel.Bind <TaskServerConfiguration>().ToConstant(Config.Services.Tasks);
                childKernel.Bind <TaskTuning>().ToConstant(Config.Services.Tasks.Tuning);

                var tasks = childKernel.Get <TaskServer>(new ConstructorArgument("config", Config.Services.Tasks));
                Servers.Add(tasks);
                ActiveTaskServer = tasks;
                Server.Servers.Tasks.Domain.ShutdownTask.ShutdownHook = RequestedShutdown;
            }

            foreach (var server in Servers)
            {
                server.OnInternalShutdown += ServerInternalShutdown;
            }

            Running = true;

            AppDomain.CurrentDomain.DomainUnload += CurrentDomain_DomainUnload;
            AppDomain.CurrentDomain.ProcessExit  += CurrentDomain_ProcessExit;

            /*
             * NetworkDebugger debugInterface = null;
             *
             * if (Options.Debug)
             * {
             *  debugInterface = new NetworkDebugger(Kernel);
             *  foreach (AbstractServer server in Servers)
             *  {
             *      server.AttachDebugger(debugInterface);
             *  }
             * }
             */

            LOG.Info("Starting services");
            foreach (var server in Servers)
            {
                server.Start();
            }

            HostPool.Start();

            //Hacky reference to maek sure the assembly is included
            FSO.Common.DatabaseService.Model.LoadAvatarByIDRequest x;

            /*if (debugInterface != null)
             * {
             *  Application.EnableVisualStyles();
             *  Application.Run(debugInterface);
             * }
             * else*/
            {
                while (Running)
                {
                    Thread.Sleep(1000);
                    lock (Servers)
                    {
                        if (Servers.Count == 0)
                        {
                            LOG.Info("All servers shut down, shutting down program...");

                            Kernel.Get <IGluonHostPool>().Stop();

                            /*var domain = AppDomain.CreateDomain("RebootApp");
                             *
                             * var assembly = "FSO.Server.Updater, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
                             * var type = "FSO.Server.Updater.Program";
                             *
                             * var updater = typeof(FSO.Server.Updater.Program);
                             *
                             * domain.CreateInstance(assembly, type);
                             * AppDomain.Unload(AppDomain.CurrentDomain);*/
                            return(2 + (int)ShutdownMode);
                        }
                    }
                }
            }
            return(1);
        }
Пример #42
0
 public void Delete(VMContext context)
 {
     while (Objects.Count > 0)
     {
         var obj = Objects[0];
         obj.Delete(false, context);
     }
 }
Пример #43
0
        public void Tick(VMAvatar avatar, VMContext context)
        {
            var roomScore = context.GetRoomScore(context.GetRoomAt(avatar.Position));

            avatar.SetMotiveData(VMMotive.Room, roomScore);
            if (context.Clock.Minutes == LastMinute)
            {
                return;
            }
            if (avatar.GetPersonData(VMPersonDataVariable.Cheats) > 0)
            {
                return;
            }
            LastMinute = context.Clock.Minutes;

            UpdateCategory(context);
            int sleepState = (avatar.GetMotiveData(VMMotive.SleepState) == 0)?1:0;

            int moodSum = 0;

            for (int i = 0; i < 7; i++)
            {
                int lotMul   = LotMuls[i];
                int frac     = 0;
                var motive   = avatar.GetMotiveData(DecrementMotives[i]);
                var r_Hunger = FracMul(FlatSimMotives[0] * (100 + avatar.GetMotiveData(VMMotive.Hunger)), LotMuls[0]);
                switch (i)
                {
                case 0:
                    frac = r_Hunger; break;

                case 1:
                    frac = FracMul(FlatSimMotives[1], lotMul); break;

                case 2:
                    frac = FracMul(FlatSimMotives[2 + sleepState], lotMul); break;

                case 3:
                    frac = FracMul(FlatSimMotives[4 + sleepState], lotMul) + FracMul(r_Hunger, FlatSimMotives[6]); break;

                case 4:
                    frac = (FlatSimMotives[7] / (60 * FlatSimMotives[8]));
                    // TODO: wrong but appears to be close? need one which uses energy weight, which is about 2.4 on skills
                    break;

                case 5:
                    frac = (sleepState == 0) ? 0 : FracMul(FlatSimMotives[9], lotMul);
                    break;

                case 6:
                    frac = FlatSimMotives[10] +
                           FracMul((FlatSimMotives[11] * (100 + motive)), lotMul);
                    frac /= 2;     //make this less harsh right now, til I can work out how multiplayer bonus is meant to work
                    break;
                }

                MotiveFractions[i] += (short)frac;
                if (MotiveFractions[i] >= 1000)
                {
                    motive             -= (short)(MotiveFractions[i] / 1000);
                    MotiveFractions[i] %= 1000;
                    if (motive < -100)
                    {
                        motive = -100;
                    }
                    avatar.SetMotiveData(DecrementMotives[i], motive);
                }
                moodSum += motive;
            }
            moodSum += roomScore;

            avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 8));
        }
Пример #44
0
 public void Init(VMContext context)
 {
     for (int i = 0; i < Objects.Count(); i++)
     {
         Objects[i].Init(context);
     }
 }
Пример #45
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame)
 {
     return EvaluateCheck(context, entity, initFrame, null, null);
 }
Пример #46
0
        public void SetVisualPosition(Vector3 pos, Direction direction, VMContext context)
        {
            int Dir = 0;
            switch (direction)
            {
                case Direction.NORTH:
                    Dir = 0; break;
                case Direction.EAST:
                    Dir = 2; break;
                case Direction.SOUTH:
                    Dir = 4; break;
                case Direction.WEST:
                    Dir = 6; break;
            }

            Matrix rotMat = Matrix.CreateRotationZ((float)(Dir * Math.PI / 4.0));
            var bObj = BaseObject;
            var leadOff = new Vector3((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) >> 8), (sbyte)(((ushort)bObj.Object.OBJ.SubIndex) & 0xFF), 0);

            for (int i = 0; i < Objects.Count(); i++)
            {
                var sub = Objects[i];
                var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8), (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF), sub.Object.OBJ.LevelOffset*2.95f);
                off = Vector3.Transform(off-leadOff, rotMat);

                sub.Direction = direction;
                sub.VisualPosition = pos + off;
            }
        }
Пример #47
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action)
 {
     return EvaluateCheck(context, entity, initFrame, action, null);
 }
Пример #48
0
        public VMPlacementResult ChangePosition(LotTilePos pos, Direction direction, VMContext context)
        {
            if (pos.Level > context.Architecture.Stories) return new VMPlacementResult(VMPlacementError.NotAllowedOnFloor);

            VMEntity[] OldContainers = new VMEntity[Objects.Count];
            short[] OldSlotNum = new short[Objects.Count];
            for (int i = 0; i < Objects.Count(); i++)
            {
                OldContainers[i] = Objects[i].Container;
                OldSlotNum[i] = Objects[i].ContainerSlot;
                Objects[i].PrePositionChange(context);
            }

            int Dir = 0;
            switch (direction)
            {
                case Direction.NORTH:
                    Dir = 0; break;
                case Direction.EAST:
                    Dir = 2; break;
                case Direction.SOUTH:
                    Dir = 4; break;
                case Direction.WEST:
                    Dir = 6; break;
            }

            Matrix rotMat = Matrix.CreateRotationZ((float)(Dir * Math.PI / 4.0));
            VMPlacementResult[] places = new VMPlacementResult[Objects.Count];

            var bObj = BaseObject;
            var leadOff = new Vector3(((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) >> 8) * 16), ((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) & 0xFF) * 16), 0);

            //TODO: optimize so we don't have to recalculate all of this
            if (pos != LotTilePos.OUT_OF_WORLD)
            {
                for (int i = 0; i < Objects.Count(); i++)
                {
                    var sub = Objects[i];
                    var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8) * 16, (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF) * 16, 0);
                    off = Vector3.Transform(off-leadOff, rotMat);

                    var offPos = new LotTilePos((short)Math.Round(pos.x + off.X), (short)Math.Round(pos.y + off.Y), (sbyte)(pos.Level + sub.Object.OBJ.LevelOffset));
                    places[i] = sub.PositionValid(offPos, direction, context);
                    if (places[i].Status != VMPlacementError.Success)
                    {
                        //go back to where we started: we're no longer out of world.
                        for (int j = 0; j < Objects.Count(); j++)
                        {
                            //need to restore slot we were in
                            if (OldContainers[j] != null) {
                                OldContainers[j].PlaceInSlot(Objects[j], OldSlotNum[j], false, context);
                            }
                            Objects[j].PositionChange(context, false);
                        }
                        return places[i];
                    }
                }
            }

            //verification success

            for (int i = 0; i < Objects.Count(); i++)
            {
                var sub = Objects[i];
                var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8) * 16, (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF)*16, 0);
                off = Vector3.Transform(off-leadOff, rotMat);

                var offPos = (pos==LotTilePos.OUT_OF_WORLD)?
                    LotTilePos.OUT_OF_WORLD :
                    new LotTilePos((short)Math.Round(pos.x + off.X), (short)Math.Round(pos.y + off.Y), (sbyte)(pos.Level+sub.Object.OBJ.LevelOffset));

                sub.SetIndivPosition(offPos, direction, context, places[i]);
            }
            for (int i = 0; i < Objects.Count(); i++) Objects[i].PositionChange(context, false);
            return new VMPlacementResult(VMPlacementError.Success);
        }
Пример #49
0
        // TODO: float values may desync if devices are not both x86 or using a different C# library.
        // Might need to replace with fixed point library for position and rotation
        /// <summary>
        /// This method will find all the avaliable locations within the criteria ordered by proximity to the optimal proximity
        /// External functions can then decide which is most desirable. E.g. the nearest slot to the object may be the longest route if
        /// its in another room.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="slot"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public List<VMFindLocationResult> FindAvaliableLocations(VMEntity obj, VMContext context, VMEntity caller)
        {
            /**
             * Start at min proximity and circle around the object to find the avaliable locations.
             * Then pick the one nearest to the optimal value
             */

            /**
             * ------ MAJOR TODO: ------
             * Avoid vector math at all costs! Small differences in hardware could cause desyncs.
             * This really goes for all areas of the SimAntics engine, but here it's particularly bad.
             */
            Vector2 center;
            if (OnlySit) FailCode = VMRouteFailCode.NoChair;

            // if we need to use the average location of an object group, it needs to be calculated.
            if (((Flags & SLOTFlags.UseAverageObjectLocation) > 0) && (obj.MultitileGroup.MultiTile)) {
                center = new Vector2(0, 0);
                var objs = obj.MultitileGroup.Objects;
                for (int i = 0; i < objs.Count; i++)
                {
                    center += new Vector2(objs[i].Position.x/16f, objs[i].Position.y/16f);
                }
                center /= objs.Count;
            } else center = new Vector2(obj.Position.x/16f, obj.Position.y/16f);

            //add offset of slot if it exists. must be rotated to be relative to object
            var rotOff = Vector3.Transform(Slot.Offset, Matrix.CreateRotationZ(obj.RadianDirection));
            var circleCtr = new Vector2(center.X + rotOff.X / 16, center.Y + rotOff.Y / 16);

            ushort room = context.VM.Context.GetRoomAt(obj.Position);
            Results = new List<VMFindLocationResult>();

            if ((Flags & SLOTFlags.SnapToDirection) > 0)
            { //snap to the specified direction, on the specified point.
                double baseRot;
                if (Slot.Facing > SLOTFacing.FaceAwayFromObject)
                {
                    // bit of a legacy thing here. Facing field did not use to exist,
                    // which is why SnapToDirection was hacked to use the directional flags.
                    // now that it exists, it is used instead, to encode the same information...
                    // just transform back into old format.
                    Flags |= (SLOTFlags)(1 << (int)Slot.Facing);
                }
                else
                {
                    if (((int)Flags & 255) == 0) Flags |= SLOTFlags.NORTH;
                }

                var flagRot = DirectionUtils.PosMod(obj.RadianDirection+FlagsAsRad(Flags), Math.PI*2);
                if (flagRot > Math.PI) flagRot -= Math.PI * 2;

                VerifyAndAddLocation(obj, circleCtr, center, Flags, Double.MaxValue, context, caller, (float)flagRot);
                return Results;
            }
            else
            {
                if (((int)Flags & 255) == 0 || Slot.Offset != new Vector3())
                {
                    //exact position
                    //Flags |= (SLOTFlags)255;

                    // special case, walk directly to point.
                    VerifyAndAddLocation(obj, circleCtr, center, Flags, Double.MaxValue, context, caller, float.NaN);
                    return Results;
                }
                var maxScore = Math.Max(DesiredProximity - MinProximity, MaxProximity - DesiredProximity) + (LotTilePos.Distance(obj.Position, caller.Position)+MaxProximity)/3 + 2;
                var ignoreRooms = (Flags & SLOTFlags.IgnoreRooms) > 0;

                var resolutionBound = (MaxProximity / Slot.Resolution) * Slot.Resolution;

                for (int x = -resolutionBound; x <= resolutionBound; x += Slot.Resolution)
                {
                    for (int y = -resolutionBound; y <= resolutionBound; y += Slot.Resolution)
                    {
                        var pos = new Vector2(circleCtr.X + x / 16.0f, circleCtr.Y + y / 16.0f);
                        double distance = Math.Sqrt(x * x + y * y);
                        if (distance >= MinProximity - 0.01 && distance <= MaxProximity + 0.01 && (ignoreRooms || context.VM.Context.GetRoomAt(new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level)) == room)) //slot is within proximity
                        {
                            var routeEntryFlags = (GetSearchDirection(circleCtr, pos, obj.RadianDirection) & Flags); //the route needs to know what conditions it fulfilled
                            if (routeEntryFlags > 0) //within search location
                            {
                                double baseScore = ((maxScore - Math.Abs(DesiredProximity - distance)) + context.VM.Context.NextRandom(1024) / 1024.0f);
                                VerifyAndAddLocation(obj, pos, center, routeEntryFlags, baseScore, context, caller, float.NaN);
                            }
                        }
                    }
                }
            }
            /** Sort by how close they are to desired proximity **/

            if (Results.Count > 1) Results = Results.OrderBy(x => -x.Score).ToList(); //avoid sort because it acts incredibly unusually
            if (Results.Count > 0) FailCode = VMRouteFailCode.Success;
            return Results;
        }
Пример #50
0
        private void vTree_NodeMouseUp(object sender, vTreeViewMouseEventArgs e)
        {
            switch (e.Node.Depth)
            {
            case 0:
                ClearDateCallback();
                break;

            case 1:
                ClearDateCallback();
                if (e.Node.Nodes.Count != 0)
                {
                    break;
                }
                using (VMContext VMContext = new VMContext())
                {
                    IQueryable <DataFile> source = VMContext.DataFiles.Where(dataFile => dataFile.AccountId == AccountID);
                    Expression <Func <DataFile, int> > selector = dataFile => dataFile.FileAddedTimestamp.Value.Year;
                    using (List <int> .Enumerator enumerator = source.Select(selector).Distinct().ToList().GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            int current = enumerator.Current;
                            e.Node.Nodes.Add(new vTreeNode(string.Format("{0}", current))
                            {
                                ImageIndex = 2,
                                Tag        = current
                            });
                        }
                        break;
                    }
                }

            case 2:
                ClearDateCallback();
                if (e.Node.Nodes.Count != 0)
                {
                    break;
                }
                AccountID = (Guid)e.Node.Parent.Tag;
                YEAR      = (int)e.Node.Tag;
                using (VMContext VMContext = new VMContext())
                {
                    IQueryable <DataFile> source = VMContext.DataFiles.Where(dataFile => dataFile.AccountId == AccountID && dataFile.FileAddedTimestamp.Value.Year == YEAR && dataFile.IsPurged == false);
                    Expression <Func <DataFile, int> > selector = dataFile => dataFile.FileAddedTimestamp.Value.Month;
                    using (List <int> .Enumerator enumerator = source.Select(selector).Distinct().ToList().GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            int current = enumerator.Current;
                            e.Node.Nodes.Add(new vTreeNode(string.Format("{0}", Months[current - 1]))
                            {
                                ImageIndex = 3,
                                Tag        = current
                            });
                        }
                        break;
                    }
                }

            case 3:
                ClearDateCallback();
                if (e.Node.Nodes.Count != 0)
                {
                    break;
                }
                vTreeNode parent1 = e.Node.Parent;
                YEAR      = (int)parent1.Tag;
                AccountID = (Guid)parent1.Parent.Tag;
                MONTH     = (int)e.Node.Tag;
                using (VMContext VMContext = new VMContext())
                {
                    IQueryable <DataFile> source = VMContext.DataFiles.Where(dataFile => dataFile.AccountId == AccountID && dataFile.FileAddedTimestamp.Value.Year == YEAR && dataFile.FileAddedTimestamp.Value.Month == MONTH && dataFile.IsPurged == false);
                    Expression <Func <DataFile, int> > selector = dataFile => dataFile.FileAddedTimestamp.Value.Day;
                    using (List <int> .Enumerator enumerator = source.Select(selector).Distinct().ToList().GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            int       current   = enumerator.Current;
                            DayOfWeek dayOfWeek = new DateTime(YEAR, MONTH, current).DayOfWeek;
                            e.Node.Nodes.Add(new vTreeNode(string.Format("{0} • {1}", current, dayOfWeek))
                            {
                                ImageIndex = 4,
                                Tag        = current
                            });
                        }
                        break;
                    }
                }

            case 4:
                vTreeNode parent2 = e.Node.Parent;
                MONTH = (int)parent2.Tag;
                vTreeNode parent3 = parent2.Parent;
                YEAR      = (int)parent3.Tag;
                AccountID = (Guid)parent3.Parent.Tag;
                int tag = (int)e.Node.Tag;
                if (tag <= 0 || tag > 31)
                {
                    break;
                }
                Callback(new DateTime(YEAR, MONTH, tag, 0, 0, 0));
                break;
            }
        }
Пример #51
0
        private void VerifyAndAddLocation(VMEntity obj, Vector2 pos, Vector2 center, SLOTFlags entryFlags, double score, VMContext context, VMEntity caller, float facingDir)
        {
            //note: verification is not performed if snap target slot is enabled.
            var tpos = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level);

            if (context.IsOutOfBounds(tpos)) return;

            score -= LotTilePos.Distance(tpos, caller.Position)/3.0;

            if (Slot.SnapTargetSlot < 0 && context.Architecture.RaycastWall(new Point((int)pos.X, (int)pos.Y), new Point(obj.Position.TileX, obj.Position.TileY), obj.Position.Level))
            {
                SetFail(VMRouteFailCode.WallInWay, null);
                return;
            }

            bool faceAnywhere = false;
            if (float.IsNaN(facingDir))
            {
                var obj3P = obj.Position.ToVector3();
                var objP = new Vector2(obj3P.X, obj3P.Y);
                switch (Slot.Facing)
                {
                    case SLOTFacing.FaceTowardsObject:
                        facingDir = (float)GetDirectionTo(pos, objP); break;
                    case SLOTFacing.FaceAwayFromObject:
                        facingDir = (float)GetDirectionTo(objP, pos); break;
                    case SLOTFacing.FaceAnywhere:
                        faceAnywhere = true;
                        facingDir = 0.0f; break;
                    default:
                        int intDir = (int)Math.Round(Math.Log((double)obj.Direction, 2));
                        var rotatedF = ((int)Slot.Facing + intDir) % 8;
                        facingDir = (float)(((int)rotatedF > 4) ? ((double)rotatedF * Math.PI / 4.0) : (((double)rotatedF - 8.0) * Math.PI / 4.0)); break;
                }
            }

            VMEntity chair = null;
            if (Slot.SnapTargetSlot < 0)
            {
                var solid = caller.PositionValid(tpos, Direction.NORTH, context);
                if (solid.Status != Model.VMPlacementError.Success)
                {
                    if (solid.Object != null && solid.Object is VMGameObject)
                    {
                        if (Slot.Sitting > 0 && solid.Object.EntryPoints[26].ActionFunction != 0)
                        {
                            chair = solid.Object;
                        }
                        else
                        {
                            SetFail(VMRouteFailCode.DestTileOccupied, solid.Object);
                            return;
                        }
                    }
                }

                if (chair != null && (Math.Abs(DirectionUtils.Difference(chair.RadianDirection, facingDir)) > Math.PI / 4))
                    return; //not a valid goal.
                if (chair == null && OnlySit) return;
            }

            Results.Add(new VMFindLocationResult
            {
                Position = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level),
                Score = score * ((chair != null) ? Slot.Sitting : Slot.Standing), //todo: prefer closer?
                RadianDirection = facingDir,
                Chair = chair,
                FaceAnywhere = faceAnywhere,
                RouteEntryFlags = entryFlags
            });
        }
Пример #52
0
        public void ChangePosition(short x, short y, sbyte level, Direction direction, VMContext context)
        {
            int Dir = 0;

            switch (direction)
            {
            case Direction.NORTH:
                Dir = 0; break;

            case Direction.EAST:
                Dir = 2; break;

            case Direction.SOUTH:
                Dir = 4; break;

            case Direction.WEST:
                Dir = 6; break;
            }

            for (int i = 0; i < Objects.Count(); i++)
            {
                var sub = Objects[i];
                var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8), (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF), 0);
                off = Vector3.Transform(off, Matrix.CreateRotationZ((float)(Dir * Math.PI / 4.0)));

                sub.Direction = direction;
                context.Blueprint.ChangeObjectLocation((ObjectComponent)sub.WorldUI, (short)Math.Round(x + off.X), (short)Math.Round(y + off.Y), (sbyte)level);
            }
            for (int i = 0; i < Objects.Count(); i++)
            {
                Objects[i].PositionChange(context);
            }
        }
Пример #53
0
        public void Tick(VMAvatar avatar, VMContext context)
        {
            var roomScore = context.GetRoomScore(context.GetRoomAt(avatar.Position));

            avatar.SetMotiveData(VMMotive.Room, roomScore);
            if (context.Clock.Minutes / 2 == LastMinute || avatar.GetValue(VMStackObjectVariable.Hidden) > 0)
            {
                return;
            }
            LastMinute = context.Clock.Minutes / 2;
            var sleeping = (avatar.GetMotiveData(VMMotive.SleepState) != 0);

            int moodSum = 0;

            for (int i = 0; i < 7; i++)
            {
                int frac = 0;
                var dm   = DecrementMotives[i];
                if (avatar.HasMotiveChange(dm) && dm != VMMotive.Energy)
                {
                    continue;
                }
                var motive   = avatar.GetMotiveData(dm);
                var r_Hunger = ToFixed1000(Constants[5]) * (100 + avatar.GetMotiveData(VMMotive.Hunger));
                switch (i)
                {
                case 0:
                    frac = r_Hunger; break;

                case 1:
                    var active = avatar.GetPersonData(VMPersonDataVariable.ActivePersonality);
                    if (active > 666)
                    {
                        frac = ToFixed1000(Constants[14]);
                    }
                    else if (active < 666)
                    {
                        frac = ToFixed1000(Constants[15]);
                    }
                    else
                    {
                        frac = ToFixed1000(Constants[16]);
                    }
                    break;

                case 2:
                    frac = ToFixed1000(Constants[sleeping ? 11 : 10]); break;

                case 3:
                    frac = ToFixed1000(Constants[sleeping ? 13 : 12]) + FracMul(r_Hunger, ToFixed1000(Constants[4])); break;

                case 4:
                    if (sleeping)
                    {
                        frac = (context.Clock.Hours >= Constants[2]) ? ToFixed1000(Constants[3]) : 0;
                    }
                    else
                    {
                        frac = (ToFixed1000(Constants[0]) / (30 * (int)Constants[1]));
                    }
                    //energy span over wake hours. small energy drift applied if asleep during the day.
                    break;

                case 5:
                    frac = (sleeping)?0:ToFixed1000(Constants[8]);
                    break;

                case 6:
                    frac = ToFixed1000(Constants[6]) +
                           ToFixed1000(Constants[7]) * avatar.GetPersonData(VMPersonDataVariable.OutgoingPersonality);
                    break;
                }

                MotiveFractions[i] += (short)frac;
                if (MotiveFractions[i] >= 1000)
                {
                    motive             -= (short)(MotiveFractions[i] / 1000);
                    MotiveFractions[i] %= 1000;
                    if (motive < -100)
                    {
                        motive = -100;
                    }
                    avatar.SetMotiveData(DecrementMotives[i], motive);
                }
                moodSum += motive;
            }
            moodSum += roomScore;

            avatar.SetMotiveData(VMMotive.Mood, (short)(moodSum / 8));
        }