private void Move(ref MonsterCharacter.InputFrame frame) { if (target == null) { return; } character.TurnSpeed = MoveTurnSpeedOverride; frame.up = MovementDecision.y; frame.right = MovementDecision.x; if (LookAtTargetOverride) { frame.WantDirection = TowardsTarget; } else { frame.WantDirection = DirectionDecision; } decisionTimer -= Time.deltaTime; if (decisionTimer <= 0f) { character.OnInputRequest = Hesitate; } }
private void BlipMove(ref MonsterCharacter.InputFrame frame) { frame.up = dir.y; frame.right = dir.x; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg); if (blipTimer > 0) { blipTimer -= Time.deltaTime; return; } blipTimer = BlipTime; dir = Vec2I.zero; if (Random.value < BlipWaitChance) { return; } if (Leashed) { if ((homePosition - transform.position).sqrMagnitude >= LeashRange * LeashRange) { Vector2 distance = transform.position - Camera.main.transform.position; if (Mathf.Max(distance.x) > Options.AlertDistance.x || Mathf.Max(distance.y) > Options.AlertDistance.y) { Destroy(gameObject); } } } if (Random.value < BlipRandomChance) { dir = Vec2I.directions[Random.Range(1, Vec2I.directions.Length)]; return; } if (HuntPlayer) { if (LastKnownPlayerRoom != -1) { targetRoom = LastKnownPlayerRoom; } } if (targetRoom >= 0 && targetRoom < Room.Rooms.Length) { //simplistic behavior //dir = Room.Rooms[targetRoom].parent[thing.gridPos.x, thing.gridPos.y] - thing.gridPos; //return; //to avoid monsters piling up on single point if (Vec2I.Manhattan(Room.Rooms[targetRoom].gridPos, thing.gridPos) < NearSteps) { return; } if (!AI.RoomPath(thing.gridPos, Room.Rooms[targetRoom], MaxSteps, out Vec2I[] path))
private void FillInputFrame(ref MonsterCharacter.InputFrame frame) { if (Input.GetKeyDown(KeyCode.R)) { destinationRoom = Random.Range(0, Room.Rooms.Length); Debug.Log("Moving towards room \"" + Room.Rooms[destinationRoom].gameObject.name + "\""); } /*int currentRoom = Room.GetRoomIndex(character.thingController.gridPos); * * if (currentRoom == destinationRoom) * return;*/ frame.up = dir.y; frame.right = dir.x; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg); if (timer > 0f) { return; } timer = DecisionTime; dir = Vec2I.zero; /*if (currentRoom == -1 || destinationRoom == -1) * return; * int nextRoom = Room.Rooms[currentRoom].ClosestNeighborTowards[destinationRoom]; * if (nextRoom == -1) * return; * * Vec2I p = Vec2I.illegalMin; * * Vec2I p = Room.Parents[nextRoom][thing.gridPos.x, thing.gridPos.y]; * * HeatmapNode h = Heatmap.GetNode(p); * if (h != null) * { * int closest = Room.Distance[nextRoom][thing.gridPos.x, thing.gridPos.y]; * * foreach (HeatmapNode n in h.neighbors) * { * int distance = Room.Distance[nextRoom][n.gridPos.x, n.gridPos.y]; * if (distance < closest) * { * p = n.gridPos; * closest = distance; * } * } * } * * if (p != Vec2I.illegalMin) * dir = p - thing.gridPos;*/ }
private void OnInputRequest(ref MonsterCharacter.InputFrame frame) { if (target == null) return; if (dualSwingTimer > 0f) dualSwingTimer -= Time.deltaTime; frame.LocalTransform = true; int steps = Vec2I.Max(thing.gridPos, target.thingController.gridPos); if (steps <= MaxAttackConsiderationStepCount) { frame.WantDirection = TowardsTarget; if (character.CurrentWeapon.IsReady && character.CurrentOffhand.IsReady) { if (Random.value > .5f) frame.PrimaryAttackContinuous = true; else frame.SecondaryAttackContinuous = true; dualSwingTimer = DualSwingDelay; } else if (dualSwingTimer <= 0f) { frame.PrimaryAttackContinuous = true; frame.SecondaryAttackContinuous = true; } frame.up = 1f; return; } if (CanSeeTargetGrid) { frame.WantDirection = TowardsTarget; if (steps > StopMovingStepCount) frame.up = 1f; return; } Vec2I smart = SmartMove; if (SmartMove != Vec2I.zero) { frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(smart.y, smart.x) * Mathf.Rad2Deg); if (steps > StopMovingStepCount) frame.up = 1; } }
private void OnInputRequest(ref MonsterCharacter.InputFrame frame) { if (target == null) { return; } Vec2I smart = SmartMove; frame.up = smart.y; frame.right = smart.x; //frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(smart.y, smart.x) * Mathf.Rad2Deg); frame.WantDirection = TowardsTarget; }
private void StandAround(ref MonsterCharacter.InputFrame frame) { if (lookatTarget != null) { Vector2 dif = lookatTarget.transform.position - transform.position; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dif.y, dif.x) * Mathf.Rad2Deg); } if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); lookatTarget = null; //look at player Vector2 distance = transform.position - Camera.main.transform.position; if (Mathf.Max(distance.x) > Options.AlertDistance.x || Mathf.Max(distance.y) > Options.AlertDistance.y) { return; } Collider2D[] hits = Physics2D.OverlapAreaAll( (Vector2)transform.position + Options.AlertDistance, (Vector2)transform.position - Options.AlertDistance, LayerMask.Walkers); foreach (Collider2D hit in hits) { MonsterCharacter monster = hit.GetComponent <MonsterCharacter>(); if (monster == null) { continue; } if (monster.GetComponent <PlayerControls>() != null) { lookatTarget = monster; } } }
private void StandAround(ref MonsterCharacter.InputFrame frame) { if (target != null) { character.OnInputRequest = Hesitate; return; } Vec2I dif = playerGridPos - thing.gridPos; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dif.y, dif.x) * Mathf.Rad2Deg); if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); if (activated) { if (Vec2I.Manhattan(playerGridPos, thing.gridPos) <= PlayerDistance.x) { character.OnInputRequest = MoveOut; return; } if (targetRoom >= 0 || targetRoom < Room.Rooms.Length) { Room room = Room.Rooms[targetRoom]; if (TheGrid.Valid(playerGridPos) && TheGrid.Valid(thing.gridPos)) { if (room.steps[playerGridPos.x, playerGridPos.y] < room.steps[thing.gridPos.x, thing.gridPos.y]) { character.OnInputRequest = MoveOut; return; } } } } }
private void MoveOut(ref MonsterCharacter.InputFrame frame) { Vector2 dif = TheGrid.WorldPosition(moveTarget) - (Vector2)transform.position; if (dif != Vector2.zero) { dir = dif.normalized; } frame.up = dir.y; frame.right = dir.x; if (LookAtMoveDir) { lookDir = dir; } frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg); if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); LookAtMoveDir = Random.value < LookAtMoveDirChance; if (targetRoom < 0 || targetRoom >= Room.Rooms.Length) { return; } Room room = Room.Rooms[targetRoom]; if (!AI.RoomPath(thing.gridPos, room, MaxSteps, out Vec2I[] path))
private void FillInputFrame(ref MonsterCharacter.InputFrame frame) { frame.up = dir.y; frame.right = dir.x; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg); if (timer > 0f) { return; } timer = DecisionTime; dir = Vector2.zero; Mouse.UpdateWorldPosition(); if (Mouse.InWorld) { if (Mouse.GridPosition != lastMouseGrid) { Vec2I a = thing.gridPos; Vec2I b = Mouse.GridPosition; if (AI.GetPath(a, b, Vec2I.Max(a, b), out Vec2I[] path))
private void Hesitate(ref MonsterCharacter.InputFrame frame) { if (target == null) { return; } if (character.CurrentWeapon != null && character.CurrentWeapon.IsReady && Random.value < AggroChance && OnScreen && RayToTarget(character.transform.position)) //RayToTarget(character.CurrentWeapon.AttackRayStartPosition)) //fails on boss and other multi weapon monsters, also the weapon barrel might be inside wall { character.OnInputRequest = Attack; attackTimer = AttackTime; attacked = false; secondaryAttacked = false; return; } if (decisionTimer > 0f) { if (LookAtTargetOverride) { frame.WantDirection = TowardsTarget; } decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); LookAtTargetOverride = Random.value < LookAtPlayerChance; if (Random.value < IdleChance) { MovementDecision = Vector2.zero; DirectionDecision = character.LookDirection; character.OnInputRequest = Move; return; } if (Random.value < RandomMoveChance) { float a = Random.value * Mathf.PI * 2f; MovementDecision.x = Mathf.Cos(a); MovementDecision.y = Mathf.Sin(a); DirectionDecision = character.LookDirection; character.OnInputRequest = Move; return; } if ((MovementDecision = (Vector2)SmartMove) != Vector2.zero) { MovementDecision.Normalize(); DirectionDecision = Quaternion.Euler(0, 0, AxMath.SafeAtan2(MovementDecision.y, MovementDecision.x) * Mathf.Rad2Deg); character.OnInputRequest = Move; } }
private void Attack(ref MonsterCharacter.InputFrame frame) { if (target == null) { return; } Vector3 predictedPosition = TargetPredictedPosition(EstimatedBulletSpeed, PredictionMultiplier); character.TurnSpeed = AttackTurnSpeedOverride; frame.WantDirection = TowardsPosition(predictedPosition); attackTimer -= Time.deltaTime; if (!attacked && attackTimer < AttackHappenTime && OnScreen && AngleToTarget(predictedPosition) < AttackMaxAngle) { attacked = true; character.CurrentWeapon.PointTowards(predictedPosition); frame.PrimaryAttackTrigger = true; } if (UseOffhand && !secondaryAttacked && attackTimer < SecondaryAttackHappenTime && OnScreen && AngleToTarget(predictedPosition) < AttackMaxAngle) { secondaryAttacked = true; character.CurrentOffhand.PointTowards(predictedPosition); frame.SecondaryAttackTrigger = true; } if (MoveWhileShooting) { if ((MovementDecision = (Vector2)SmartMove) != Vector2.zero) { MovementDecision.Normalize(); frame.up = MovementDecision.y; frame.right = MovementDecision.x; } } if (attackTimer <= 0f) { if (Random.value < BurstChance) { if (OnScreen && RayToTarget(character.CurrentWeapon.AttackRayStartPosition)) { character.OnInputRequest = Attack; attackTimer = AttackTime; attacked = false; secondaryAttacked = false; return; } } else { character.OnInputRequest = Hesitate; } } }
void FillInputFrame(ref MonsterCharacter.InputFrame frame) { if (HotkeyAssigment.Assigments[(int)Hotkey.Attack1].Pressed) { frame.PrimaryAttackTrigger = true; } if (HotkeyAssigment.Assigments[(int)Hotkey.Attack2].Pressed) { frame.SecondaryAttackTrigger = true; } if (HotkeyAssigment.Assigments[(int)Hotkey.Attack1].Continuous) { frame.PrimaryAttackContinuous = true; } if (HotkeyAssigment.Assigments[(int)Hotkey.Attack2].Continuous) { frame.SecondaryAttackContinuous = true; } if (HotkeyAssigment.Assigments[(int)Hotkey.Up].Continuous) { frame.up += 1f; } if (HotkeyAssigment.Assigments[(int)Hotkey.Down].Continuous) { frame.up -= 1f; } if (HotkeyAssigment.Assigments[(int)Hotkey.Right].Continuous) { frame.right += 1f; } if (HotkeyAssigment.Assigments[(int)Hotkey.Left].Continuous) { frame.right -= 1f; } if (HotkeyAssigment.Assigments[(int)Hotkey.Use].Pressed) { frame.UseObject = true; } if (HotkeyAssigment.Assigments[(int)Hotkey.Map].Pressed) { Messaging.GUI.PauseCurtain.Invoke(); Messaging.GUI.OpenWindow.Invoke("UIMap"); Messaging.System.SetTimeScale.Invoke(TimeScale.Paused); Messaging.GUI.ChangeCursor.Invoke(0); } //pretty hacky, should have proper cascading capture :'( if (Input.GetKeyDown(KeyCode.Escape) && !TimeScaler.Paused) { Messaging.GUI.PauseCurtain.Invoke(); Messaging.GUI.OpenWindow.Invoke("Ingame Menu"); Messaging.System.SetTimeScale.Invoke(TimeScale.Paused); Messaging.GUI.ChangeCursor.Invoke(0); } if (HotkeyAssigment.Assigments[(int)Hotkey.Weapon1].Pressed) { frame.SwapWeapon = 0; } if (HotkeyAssigment.Assigments[(int)Hotkey.Weapon2].Pressed) { frame.SwapWeapon = 1; } if (HotkeyAssigment.Assigments[(int)Hotkey.Weapon3].Pressed) { frame.SwapWeapon = 2; } if (HotkeyAssigment.Assigments[(int)Hotkey.Weapon4].Pressed) { frame.SwapWeapon = 3; } if (HotkeyAssigment.Assigments[(int)Hotkey.Weapon5].Pressed) { frame.SwapWeapon = 4; } if (HotkeyAssigment.Assigments[(int)Hotkey.Skill1].Pressed) { if (character.Skills.Length > 0 && character.Skills[0] != null) { character.Skills[0].Activate(character, 0); } } if (HotkeyAssigment.Assigments[(int)Hotkey.Skill2].Pressed) { if (character.Skills.Length > 1 && character.Skills[1] != null) { character.Skills[1].Activate(character, 1); } } if (HotkeyAssigment.Assigments[(int)Hotkey.Skill3].Pressed) { if (character.Skills.Length > 2 && character.Skills[2] != null) { character.Skills[2].Activate(character, 2); } } if (HotkeyAssigment.Assigments[(int)Hotkey.Skill4].Pressed) { if (character.Skills.Length > 3 && character.Skills[3] != null) { character.Skills[3].Activate(character, 3); } } if (HotkeyAssigment.Assigments[(int)Hotkey.Skill5].Pressed) { if (character.Skills.Length > 4 && character.Skills[4] != null) { character.Skills[4].Activate(character, 4); } } frame.WantDirection = TowardsMouse; }
private void MoveOut(ref MonsterCharacter.InputFrame frame) { if (target != null) { character.OnInputRequest = Hesitate; return; } if (PlayerTooFar) { character.OnInputRequest = StandAround; } if (moveTarget != Vec2I.illegalMin) { Vector2 dif = TheGrid.WorldPosition(moveTarget) - (Vector2)transform.position; if (dif != Vector2.zero) { dir = dif.normalized; } frame.up = dir.y; frame.right = dir.x; if (LookAtMoveDir) { lookDir = dir; } frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg); } if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); LookAtMoveDir = Random.value < LookAtMoveDirChance; if (targetRoom < 0 || targetRoom >= Room.Rooms.Length) { return; } Room room = Room.Rooms[targetRoom]; if (Vec2I.Max(room.gridPos, thing.gridPos) < 3) { if (MissionObjective == 0) { Messaging.GUI.CommsMessage.Invoke(0, OnExitMessagePortrait, OnExitMessage); MissionObjective++; Messaging.Mission.MissionStatus.Invoke(true); } Instantiate(TeleportEffect, transform.position, Quaternion.identity, LevelLoader.TemporaryObjects); Destroy(gameObject); } if (!AI.RoomPath(thing.gridPos, room, MaxSteps, out Vec2I[] path))
private void OnInputRequest(ref MonsterCharacter.InputFrame frame) { if (target == null) { return; } frame.WantDirection = TowardsTarget; if (character.ChargePoints >= MinChargePointsForSkill) { if (character.Skills.Length > 0) { if (character.Skills[0] != null) { if (character.SkillCooldowns[0] <= 0f) { if (CanSeeTargetGrid) { character.Skills[0].Activate(character, 0); } } } } } if (dualSwingTimer > 0f) { dualSwingTimer -= Time.deltaTime; } int steps = Vec2I.Max(thing.gridPos, target.thingController.gridPos); if (steps <= MaxAttackConsiderationStepCount) { if (character.CurrentWeapon.IsReady && character.CurrentOffhand.IsReady) { if (Random.value > .5f) { frame.PrimaryAttackContinuous = true; } else { frame.SecondaryAttackContinuous = true; } dualSwingTimer = DualSwingDelay; } else if (dualSwingTimer <= 0f) { frame.PrimaryAttackContinuous = true; frame.SecondaryAttackContinuous = true; } } frame.LocalTransform = false; if (chargeTimer > 0f) { if (AngleToTarget(target.transform.position) > MaxChargeAngle) { chargeTimer = 0f; } frame.LocalTransform = true; chargeTimer -= Time.deltaTime; frame.up = 1f; character.walkSpeed = RunSpeed; character.TurnSpeed = RunTurnSpeed; return; } if (chargeCooldownTimer > 0f) { chargeCooldownTimer -= Time.deltaTime; } character.walkSpeed = walkSpeed; character.TurnSpeed = walkTurnSpeed; float distanceSqr = (target.transform.position - transform.position).sqrMagnitude; if (steps > StopMovingStepCount) { if (chargeCooldownTimer <= 0f) { if (distanceSqr >= StopRange * StopRange && distanceSqr <= RunRange * RunRange) { if (AngleToTarget(target.transform.position) <= MaxChargeAngle) { if (CanSeeTargetGrid) { chargeTimer = ChargeTime; chargeCooldownTimer = ChargeCooldown; return; } } } } } if (hesitateTimer > 0f) { hesitateTimer -= Time.deltaTime; return; } if (Random.value < IdleChance) { frame.up = 0; frame.right = 0; hesitateTimer = Random.Range(IdleTime.x, IdleTime.y); return; } if (Random.value < RandomMoveChance) { float a = Random.value * Mathf.PI * 2f; frame.right = Mathf.Cos(a); frame.up = Mathf.Sin(a); return; } //path find to target { Vec2I smart = SmartMove; frame.up = smart.y; frame.right = smart.x; } }