Function RefreshKeepOffsetForFollow() Float fAngle = PlayerRef.GetHeadingAngle(FollowerRef) Float fDistance = FollowerRef.GetDistance(PlayerRef) Bool bIsInPosition = fDistance < 200.0 Bool bKeepOffset = false ;Log("distance=" + fDistance + " angle=" + fAngle + " IsInPosition=" + bIsInPosition) if IsMoving ; 隊形発動中 if fDistance > 500.0 ; 遠すぎるなら隊形解除(follow packageで走って追い付く) IsMoving = false FollowerRef.ClearKeepOffsetFromActor() ;Log("ClearKeepOffsetFromActor, reason=too far, distance=" + fDistance) else Float fSpeed = PlayerRef.GetAnimationVariableFloat("Speed") ;Log( "speed=" + fSpeed + " distance=" + FollowerRef.GetDistance(PlayerRef) ) if bIsInPosition ; 正しい位置についている ; 向きがおかしいなら補正 if Math.abs( FollowerRef.GetAngleZ() - PlayerRef.GetAngleZ() ) > 45.0 FollowerRef.SetAngle( 0.0, 0.0, PlayerRef.GetAngleZ() ) endif if fSpeed < 5.0 ; プレイヤーが立ち止まったらフォロワーも止まる(隊形解除) IsMoving = false FollowerRef.ClearKeepOffsetFromActor() ;Log("ClearKeepOffsetFromActor, reason=player is too slow, speed=" + fSpeed) elseif fSpeed < 190.0 ; プレイヤーが歩いているならフォロワーも歩く if IsKeepOffsetRun IsKeepOffsetRun = false bKeepOffset = true ;Log("stop running, reason=player is slow, speed=" + fSpeed) endif else ; プレイヤーが走っているならフォロワーも走る if IsKeepOffsetRun Float fSpeedP = PlayerRef.GetActorValue("SpeedMult") Float fSpeedF = FollowerRef.GetActorValue("SpeedMult") if fSpeedP > 100.0 && fSpeedP <= 150.0 && fSpeedF - fSpeedP > 0.0 && !PlayerRef.IsOnMount() bKeepOffset = true DamageSpeedMult = fSpeedF - fSpeedP + 15.0 ;Log("slow down, reason=player is fast, speed mult=" + fSpeedP + "/" + fSpeedF) endif else IsKeepOffsetRun = true bKeepOffset = true ;Log("start to run, reason=player is fast, speed=" + fSpeed) endif endif else ; 正しい位置にまだつけていない fAngle = FollowerRef.GetHeadingAngle(PlayerRef) ; 向きがおかしいなら補正 if Math.abs(fAngle) > 30.0 FollowerRef.SetAngle(0.0, 0.0, FollowerRef.GetAngleZ() + fAngle) endif ; 走る if !IsKeepOffsetRun IsKeepOffsetRun = true bKeepOffset = true ;Log("run, reason=in not in position, distance=" + fDistance) endif endif endif else ; まだ隊形を発動していない ; 十分に近くて正しい位置についていないなら隊形を発動 if !bIsInPosition && fDistance < 500.0 IsMoving = true IsKeepOffsetRun = true bKeepOffset = true ;Log("move, reason=in not in position, distance=" + fDistance) endif endif ; 隊形発動処理 if bKeepOffset Float fOffsetX = 80.0 Float fOffsetY = 80.0 Bool bMount = PlayerRef.IsOnMount() if bMount fOffsetX += 20.0 fOffsetY += 50.0 endif if KeepOffsetPosition % 2 == 0 fOffsetX = -fOffsetX endif if KeepOffsetPosition >= 3 fOffsetY -= 100.0 endif if IsKeepOffsetRun if IsKeepOffsetForceWalk IsKeepOffsetForceWalk = false DamageSpeedMult = 0.0 FollowerRef.RestoreActorValue("SpeedMult", 999.0) ;Log("resume speed, reason=must run") else if DamageSpeedMult FollowerRef.RestoreActorValue("SpeedMult", 999.0) FollowerRef.DamageActorValue("SpeedMult", DamageSpeedMult) endif endif else Float fSpeed = FollowerRef.GetActorValue("SpeedMult") if bMount IsKeepOffsetForceWalk = true DamageSpeedMult = fSpeed - 35.0 FollowerRef.RestoreActorValue("SpeedMult", 999.0) if DamageSpeedMult > 0.0 FollowerRef.DamageActorValue("SpeedMult", DamageSpeedMult) endif ;Log("slow down, reason=player is mount, speed damage=" + DamageSpeedMult) else DamageSpeedMult = fSpeed - 100.0 if DamageSpeedMult > 0.0 IsKeepOffsetForceWalk = true FollowerRef.RestoreActorValue("SpeedMult", 999.0) FollowerRef.DamageActorValue("SpeedMult", DamageSpeedMult) ;Log("slow down, reason=follower is too fast, speed damage=" + DamageSpeedMult) else if IsKeepOffsetForceWalk IsKeepOffsetForceWalk = false DamageSpeedMult = 0.0 FollowerRef.RestoreActorValue("SpeedMult", 999.0) ;Log("resume speed, reason=do not need to walk anymore") endif endif endif endif FollowerRef.ModActorValue("CarryWeight", 1.0) FollowerRef.ModActorValue("CarryWeight", -1.0) Float fCatchUpRadius = 0.0 if !IsKeepOffsetRun fCatchUpRadius = 150.0 endif FollowerRef.KeepOffsetFromActor(PlayerRef, fOffsetX, fOffsetY, 0.0, afCatchUpRadius = fCatchUpRadius, afFollowRadius = 0.0) ;Log("KeepOffsetFromActor, run=" + IsKeepOffsetRun + " walk=" + IsKeepOffsetForceWalk + " mount=" + bMount) endif EndFunction