Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Mixin class SmoothMoveTurnMixin
- {
- //ChaseSmooth works by storing the state ChaseSmooth was called from, and using that information along with
- //the actor's tics value to determine if the ChaseSmoth call each tic should have the chance to result in an attack, or just moving & turning.
- //The smooth turning functions work in a similar way.
- Actor smtActor;//the actor instance this mixin belongs to
- State smtChaseState;
- bool smtChasing;//controls wether to call A_Chase or A_Wander in ChaseSmooth
- int smtChaseFlags;//stores any A_Chase flags for use during Tick()
- State smtTurnState;
- double smtAngleTarget;
- double smtAngleTurnSpeed;//the difference between starting angle and smtAngleTarget divided by smtTurnState.tics
- double smtAngleTurnSpeedMax;//if > 0, if smtLimitAngleTurnSpeed is true and when chasing or wandering, limit smtAngleTurnSpeed to to this
- bool smtLimitAngleTurnSpeed;//set to true when chasing or wandering
- bool affectPitch;
- double smtPitchTarget;
- double smtPitchTurnSpeed;//the difference between starting Pitch and smtPitchTarget divided by smtTurnState.tics
- double smtPitchTurnSpeedMax;//if > 0, if smtLimitPitchTurnSpeed is true and when chasing or wandering, limit smtPitchTurnSpeed to to this
- bool smtLimitPitchTurnSpeed;//set to true when chasing or wandering
- property ChaseAffectsPitch : affectPitch;
- void InitSmoothMoveTurnMixin(Actor other, double AngleTurnSpeedMax = 0, double PitchTurnSpeedMax = 0)
- {
- smtActor = other;
- smtAngleTurnSpeedMax = AngleTurnSpeedMax;
- smtPitchTurnSpeedMax = PitchTurnSpeedMax;
- }
- //To be called from the smtActor's Tick()
- void UpdateSmoothMoveTurn()
- {
- if(smtActor == null)
- {
- return;
- }
- //this chase behavior is called when the monster is in a state that called A_ChaseSmooth,
- //but is not the first tic in that state
- if(smtChaseState && smtActor.curState && smtActor.tics != smtActor.curState.tics)
- {
- if (smtActor.curState == smtChaseState)
- {
- ChaseSmooth(melee : null, missile : null, chaseFlags : smtChaseFlags, chase : smtChasing);
- }
- else
- {
- smtChaseState = null;
- smtChasing = false;
- smtChaseFlags = 0;
- }
- }
- //this is used for turning smoothly.
- if (smtTurnState && smtActor.curState && smtActor.tics != smtActor.curState.tics)
- {
- if(smtActor.curState == smtTurnState)
- {
- TurnTowards();
- }
- else
- {
- smtTurnState = null;
- smtLimitAngleTurnSpeed = false;
- smtLimitPitchTurnSpeed = false;
- }
- }
- }
- //Smooth chasing code by Boondorl
- //Smooth turning code by phantombeta
- void ChaseSmooth(StateLabel melee = '_a_chase_default', StateLabel missile = '_a_chase_default', int chaseFlags = 0, bool chase = true)
- {
- smtChasing = chase;
- smtChaseState = smtActor.curState;
- smtChaseFlags = chaseFlags;
- Vector3 tempPos = smtActor.pos;
- double angleTemp = smtActor.angle;
- smtLimitAngleTurnSpeed = true;
- double pitchTemp = smtActor.pitch;
- if (affectPitch)
- smtLimitpitchTurnSpeed = true;
- if(chase)
- {
- if(smtActor.target == null)
- {
- return;
- }
- A_Chase(melee,missile,chaseFlags);
- }
- else
- {
- A_Wander(chaseFlags);
- }
- Vector3 diff = (smtActor.pos - tempPos);
- Vector3 dir = !(diff ~== (0, 0, 0)) ? diff.Unit() : (0, 0, 0);
- smtActor.SetOrigin(tempPos + dir * smtActor.speed,true);
- smtActor.A_SetAngle(angleTemp);
- if (affectPitch)
- {
- smtActor.A_SetPitch(pitchTemp);
- }
- //only rotate for the initial ChaseSmooth call, and not the automatic ones from Tick()
- if(smtActor.tics == smtActor.curState.tics)
- {
- FaceAngleSmooth(smtActor.moveDir * 45, smtActor.moveDir * 45);
- }
- }
- //Shortcut for smooth wandering.
- void WanderSmooth(int flags = 0)
- {
- ChaseSmooth(null, null, flags, false);
- }
- //Smooth variant of A_Face(). Pass target as a parameter to replicate A_FaceTarget.
- void FaceSmooth(Actor other = null,int flags = 0)
- {
- if(other == null)
- {
- return;
- }
- double angleTemp = smtActor.angle;
- smtActor.A_Face(other,0,0,0,0,flags);//for pitch setting
- smtActor.A_SetAngle(angleTemp);
- FacePosSmooth(other.pos + (0,0,flags == FAF_MIDDLE ? double(other.height) / 2 : 0));
- }
- //for facing a position
- void FacePosSmooth(Vector3 targetPos)
- {
- Vector3 sCoords = LevelLocals.SphericalCoords(smtActor.pos,targetPos,(smtActor.angle,smtActor.pitch));
- FaceAngleSmooth(smtActor.angle - sCoords.x, smtActor.pitch - sCoords.y);
- }
- void FaceAngleSmooth(double a, double p = 0)
- {
- smtTurnState = smtActor.curState;
- smtAngleTarget = a;
- double angDiff = DeltaAngle(smtActor.angle,smtAngleTarget);
- smtAngleTurnSpeed = abs(angDiff / (smtTurnState.tics > 0 ? smtTurnState.tics : 1));
- smtPitchTarget = p;
- double pitchDiff = DeltaAngle(smtActor.Pitch,smtPitchTarget);
- smtPitchTurnSpeed = abs(pitchDiff / (smtTurnState.tics > 0 ? smtTurnState.tics : 1));
- if(smtLimitAngleTurnSpeed && smtAngleTurnSpeedMax > 0)
- {
- smtAngleTurnSpeed = Clamp(smtAngleTurnSpeed,0,smtAngleTurnSpeedMax);
- smtPitchTurnSpeed = Clamp(smtPitchTurnSpeed,0,smtPitchTurnSpeedMax);
- }
- TurnTowards();
- }
- //the base smooth turning function, turns smoothly towards any angle.
- //This is only to be called from Tick(), ChaseSmooth, or the other smooth rotating functions.
- protected void TurnTowards()
- {
- double angDiff = DeltaAngle(smtActor.angle,smtAngleTarget);
- double angleChange = angDiff < 0 ? max(-smtAngleTurnSpeed, angDiff) : min(smtAngleTurnSpeed, angDiff);
- smtActor.A_SetAngle(smtActor.angle + angleChange);
- if (affectPitch)
- {
- double pitDiff = DeltaAngle(smtActor.pitch,smtpitchTarget);
- double pitchChange = pitDiff < 0 ? max(-smtpitchTurnSpeed, pitDiff) : min(smtpitchTurnSpeed, pitDiff);
- smtActor.A_Setpitch(smtActor.pitch + pitchChange);
- }
- //console.printf("[SmoothMoveTurnMixin/TurnTowards] smtAngleTarget = %f, angDiff = %f, smtAngleTurnSpeed = %f, angleChange = %f, angle = %f",smtAngleTarget,angDiff,smtAngleTurnSpeed,angleChange,smtActor.angle);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement