private void ExecuteInteraction(ActorInteractionType type, string target, ActionSpecial special, ActionInvokerData data) { switch (type) { case ActorInteractionType.None: break; //do nothing case ActorInteractionType.Special: special.Execute(data); break; case ActorInteractionType.AmbientMonologue: string msg = DialogueModule.GetMonologue(target).GetLineRandom(); //VERY inefficient, will fix later //QdmsMessageBus.Instance.PushBroadcast(new HUDPushMessage(msg));//also a very temporary display QdmsMessageBus.Instance.PushBroadcast(new SubtitleMessage(msg, 5.0f, true, -1)); //and we need to rework Monologue and implement an audio manager before we can do speech break; case ActorInteractionType.Dialogue: DialogueInitiator.InitiateDialogue(target, true, null); break; case ActorInteractionType.Script: ScriptingModule.Call(target, new ScriptExecutionContext() { Caller = this, Activator = data.Activator.gameObject }, new object[] { }); break; default: throw new NotImplementedException(); } }
public void EnterState(ActorAiState newState) { if (LockAiState) { return; } LastAiState = CurrentAiState; ExitState(CurrentAiState); //good place or no? TimeInState = 0; switch (newState) { case ActorAiState.Idle: Target = null; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Idle); MovementComponent.AbortMove(); break; case ActorAiState.Dead: if (CurrentAiState == ActorAiState.Dead) //fix for glitchy looking behaviour { break; } MovementComponent.AbortMove(); MovementComponent.HandleDeath(); if (DieImmediately) { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Dead); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Dying); } if (InteractionComponent != null) { InteractionComponent.InteractionDisabledByHit = false; } if (DestroyOnDeath) { this.gameObject.SetActive(false); //actually destroying the object breaks saving } if (OnDeathSpecial != null) { OnDeathSpecial.Execute(new ActionInvokerData { Activator = this }); } if (Target != null && Target.GetComponent <PlayerController>() && GrantXpOnDeath > 0) { GameState.Instance.PlayerRpgState.GrantXPScaled(GrantXpOnDeath); } break; case ActorAiState.Wandering: Target = null; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); //set initial destination Vector2 newpos = VectorUtils.GetRandomVector2(InitialPosition.GetFlatVector(), WanderRadius); MovementComponent.SetDestination(newpos.GetSpaceVector()); break; case ActorAiState.Chasing: if (RunOnChase) { MovementComponent.IsRunning = true; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Running); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); } { //set target if (Target == null) { GetSwizzledTarget(); //fix for loading saves } var d = Target.position; //FIXME what if Target is null? MovementComponent.SetDestination(d); } break; case ActorAiState.ScriptedMoveTo: if (RunOnChase) { MovementComponent.IsRunning = true; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Running); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); } MovementComponent.SetDestination(MovementComponent.MovementTarget); break; case ActorAiState.Attacking: if (AttackComponent == null) { Debug.LogError($"{name} tried to attack, but has no attack component!"); EnterState(ActorAiState.Idle); return; } if (Target == null) { GetSwizzledTarget(); //fix for loading saves } //set animation, fire projectile, set timer AttackComponent.BeginAttack(); break; case ActorAiState.Covering: break; case ActorAiState.Hurting: AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Hurting); break; case ActorAiState.Fleeing: if (RunOnFlee) { MovementComponent.IsRunning = true; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Running); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); } { //set target var d = transform.position + ((Target.position - transform.position).normalized * -1); MovementComponent.SetDestination(d); } break; default: break; } CurrentAiState = newState; }
public void EnterState(ActorAiState newState) { if (LockAiState) { return; } if (newState != CurrentAiState) { LastAiState = CurrentAiState; } ExitState(CurrentAiState); //good place or no? TimeInState = 0; switch (newState) { case ActorAiState.Idle: Target = null; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Idle); MovementComponent.AbortMove(); break; case ActorAiState.Dead: { if (CurrentAiState == ActorAiState.Dead) //fix for glitchy looking behaviour { break; } MovementComponent.AbortMove(); MovementComponent.HandleDeath(); var deathStateArgs = new DeathStateActorAnimationArgs() { DamageEffector = LastHit?.DamageEffector ?? 0, DamageType = LastHit?.DamageType ?? 0, ExtremeDeath = WasExtremeDeath, HitLocation = LastHit?.HitLocation ?? 0, HitMaterial = LastHit?.HitMaterial ?? 0 }; if (DieImmediately) { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Dead, deathStateArgs); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Dying, deathStateArgs); } AudioComponent.Ref()?.StopLivingSounds(); if (WasExtremeDeath) { AudioComponent.Ref()?.PlayExtremeDeathSound(); } else { AudioComponent.Ref()?.PlayDeathSound(); } if (InteractionComponent != null) { InteractionComponent.InteractionDisabledByHit = false; } if (DestroyOnDeath) { this.gameObject.SetActive(false); //actually destroying the object breaks saving } if (OnDeathSpecial != null) { OnDeathSpecial.Execute(new ActionInvokerData { Activator = this }); } if (DisableHitboxesOnDeath) { var hitboxComponents = GetComponentsInChildren <IHitboxComponent>(true); foreach (var hitboxComponent in hitboxComponents) { if (hitboxComponent is MonoBehaviour mb) //IHitboxComponent does not actually imply MonoBehaviour { mb.gameObject.SetActive(false); } } } if (DisableCollidersOnDeath) { var colliders = GetComponentsInChildren <Collider>(true); foreach (var collider in colliders) { collider.enabled = false; } } if ( ((LastHit != null && LastHit.Value.Originator != null && LastHit.Value.Originator is PlayerController) || (Target != null && Target.GetComponent <PlayerController>()) ) && GrantXpOnDeath > 0 ) { GameState.Instance.PlayerRpgState.GrantXPScaled(GrantXpOnDeath); } } break; case ActorAiState.Wandering: Target = null; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); //set initial destination Vector2 newpos = VectorUtils.GetRandomVector2(InitialPosition.GetFlatVector(), WanderRadius); MovementComponent.SetDestination(newpos.GetSpaceVector()); AudioComponent.Ref()?.StartWalkSound(); break; case ActorAiState.Chasing: if (RunOnChase) { MovementComponent.IsRunning = true; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Running); AudioComponent.Ref()?.StartRunSound(); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); AudioComponent.Ref()?.StartWalkSound(); } { //set target if (Target == null) { GetSwizzledTarget(); //fix for loading saves } SetChaseDestination(); } break; case ActorAiState.ScriptedMoveTo: if (RunOnChase) { MovementComponent.IsRunning = true; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Running); AudioComponent.Ref()?.StartRunSound(); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); AudioComponent.Ref()?.StartWalkSound(); } MovementComponent.SetDestination(MovementComponent.MovementTarget); break; case ActorAiState.Attacking: if (AttackComponent == null) { Debug.LogError($"{name} tried to attack, but has no attack component!"); EnterState(ActorAiState.Idle); return; } if (Target == null) { GetSwizzledTarget(); //fix for loading saves } //set animation, fire projectile, set timer AttackComponent.BeginAttack(); break; case ActorAiState.Covering: break; case ActorAiState.Hurting: AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Hurting); AudioComponent.Ref()?.PlayPainSound(); break; case ActorAiState.Fleeing: if (RunOnFlee) { MovementComponent.IsRunning = true; AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Running); AudioComponent.Ref()?.StartRunSound(); } else { AnimationComponent.Ref()?.SetAnimation(ActorAnimState.Walking); AudioComponent.Ref()?.StartWalkSound(); } { //set target var d = transform.position + ((Target.position - transform.position).normalized * -(1 + Mathf.Abs(MovementComponent.TargetThreshold))); MovementComponent.SetDestination(d); } break; case ActorAiState.ScriptedAction: //nop break; default: break; } CurrentAiState = newState; }