예제 #1
0
        private void HandleAttack(GameEvent_PrepareAttack ev)
        {
            if (ev.ExecutorEntity == this.Parent)
            {
                // If it's out of range, then the attack misses
                int weaponRange = ev.ExecutorEntity.TryGetAttribute(EntityAttributeType.MAX_RANGE, ev.ExecutorEntity)
                                  .Value;
                int distance = FloorState.DistanceBetweenEntities(ev.Target, ev.CommandEntity);
                if (distance > weaponRange)
                {
                    ev.RegisterResult("MISS (out of range)");
                    return;
                }

                // TODO: This sequence of early exists is crufty because there's a lot of "before-exit-do" stuff here!
                // If any of the cells isn't walkable, then your shot is blocked and the attack stops
                var targetPos   = ev.Target.TryGetPosition();
                var attackerPos = ev.CommandEntity.TryGetPosition();
                var lineCells   = ev.GameMap.GetCellsAlongLine(attackerPos.X, attackerPos.Y, targetPos.X, targetPos.Y);

                if (lineCells.Any(c => !c.IsWalkable))
                {
                    ev.RegisterResult("MISS (no straight shot)");
                    return;
                }

                // Forward the attack to the target
                var receiveAttack = new GameEvent_ReceiveAttack(ev);
                ev.Target.HandleEvent(receiveAttack);
                if (!receiveAttack.Completed)
                {
                    Log.DebugLine("Could not resolve attack against " + ev.Target.ToString());
                }
            }
        }
예제 #2
0
        private void HandleQueryCommand(GameQuery_Command q)
        {
            if (this.Alerted)
            {
                this.activeBook.TryRegisterCommand(q);
            }
            else if (q.FloorState.Player != null &&
                     FloorState.DistanceBetweenEntities(this.Parent, q.FloorState.Player) <=
                     this.Parent.TryGetAttribute(EntityAttributeType.DETECTION_RADIUS).Value)
            {
                q.FloorState.AlertAllAIs();
            }
            else
            {
                var myPos = this.Parent.TryGetPosition();
                if (myPos.X == this.PatrolStart.X && myPos.Y == this.PatrolStart.Y)
                {
                    this.OnReturnLeg = false;
                }
                else if (myPos.X == this.PatrolEnd.X && myPos.Y == this.PatrolEnd.Y)
                {
                    this.OnReturnLeg = true;
                }

                Cell myCell = q.FloorState.FloorMap.GetCell(myPos.X, myPos.Y);
                Path patrolPath;
                if (!this.OnReturnLeg)
                {
                    patrolPath = q.FloorState.ShortestPath(myCell, this.PositionToCell(this.PatrolEnd, q.FloorState));
                }
                else
                {
                    patrolPath = q.FloorState.ShortestPath(myCell,
                                                           this.PositionToCell(this.PatrolStart, q.FloorState));
                }
                if (patrolPath != null)
                {
                    q.RegisterCommand(this.MoveEventForPath(q, patrolPath));
                }
                else
                {
                    q.RegisterCommand(new CommandStub_Delay(this.Parent.EntityID, Config.ONE));
                }
            }
        }
예제 #3
0
        public override bool IsMet(GameQuery_Command commandQuery)
        {
            // TODO: This is gonna show up in a lot of conditions, and looks pretty janky.
            Entity target = commandQuery.FloorState.Player;

            // TODO: Smooth out this int? business!
            // It's an int? because some conditions (asking for WEAPON_RANGE on something which has no range, like a
            // MechSkeleton, but which does get turns) are nonsensical.
            int?optionDistance = this.ResolveOptionDistance(commandQuery, target);

            if (optionDistance == null)
            {
                return(true);
            }

            int currDist = FloorState.DistanceBetweenEntities(target, commandQuery.CommandEntity);

            switch (this.Operator)
            {
            case ComparisonOperator.EQUAL:
                return(currDist == optionDistance);

            case ComparisonOperator.LESS_THAN:
                return(currDist < optionDistance);

            case ComparisonOperator.LESS_THAN_EQUAL:
                return(currDist <= optionDistance);

            case ComparisonOperator.GREATER_THAN:
                return(currDist > optionDistance);

            case ComparisonOperator.GREATER_THAN_EQUAL:
                return(currDist >= optionDistance);

            default:
                throw new InvalidOperationException("Condition_Distance can't handle " + this.Operator);
            }
        }