Character can now move interactively
This commit is contained in:
Binary file not shown.
@@ -279,6 +279,9 @@ FlxAnimTracker::FlxAnimTracker() {
|
|||||||
void FlxAnimTracker::Clear() {
|
void FlxAnimTracker::Clear() {
|
||||||
AQ.Empty();
|
AQ.Empty();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
AutoFinish = false;
|
||||||
|
AutoFinishAction.Empty();
|
||||||
|
AutoFinishXYZ.Set(0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlxAnimTracker::FinishedAnimation(uint64 hash) {
|
void FlxAnimTracker::FinishedAnimation(uint64 hash) {
|
||||||
@@ -358,7 +361,6 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
|
|||||||
while (!newsteps.IsEmpty()) {
|
while (!newsteps.IsEmpty()) {
|
||||||
FlxAnimationStepView step = newsteps.Pop();
|
FlxAnimationStepView step = newsteps.Pop();
|
||||||
AQ.EmplaceLast(step.Hash, step.Body);
|
AQ.EmplaceLast(step.Hash, step.Body);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are too many animations in AQ, discard
|
// If there are too many animations in AQ, discard
|
||||||
@@ -374,6 +376,36 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
|
|||||||
AQ.PopFirst();
|
AQ.PopFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Autofinish up to one animation.
|
||||||
|
//
|
||||||
|
if (AutoFinish) {
|
||||||
|
for (int i = 0; i < AQ.Num(); i++) {
|
||||||
|
if (!AQ[i].Finished) {
|
||||||
|
if (MatchesAutoFinish(AQ[i])) {
|
||||||
|
AQ[i].Finished = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AutoFinish = false;
|
||||||
|
AutoFinishAction.Empty();
|
||||||
|
AutoFinishXYZ.Set(0,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlxAnimTracker::SetAutoFinish(const FString &action, const FVector &xyz) {
|
||||||
|
AutoFinish = true;
|
||||||
|
AutoFinishAction = action;
|
||||||
|
AutoFinishXYZ = xyz;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FlxAnimTracker::MatchesAutoFinish(const FlxAnimationStep &step) {
|
||||||
|
FVector xyz = UlxAnimationStepLibrary::AnimationStepGetVector(step, TEXT("xyz"));
|
||||||
|
if (xyz != AutoFinishXYZ) return false;
|
||||||
|
FString action = UlxAnimationStepLibrary::AnimationStepGetString(step, TEXT("action"));
|
||||||
|
if (action != AutoFinishAction) return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FString FlxAnimTracker::GetCurrentBlueprintName() {
|
FString FlxAnimTracker::GetCurrentBlueprintName() {
|
||||||
@@ -393,6 +425,8 @@ FlxAnimationStep FlxAnimTracker::GetCurrentAnimation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = AQ.Last();
|
result = AQ.Last();
|
||||||
result.Hash = 0;
|
// This next line is a hack. We need the idle step to have a unique
|
||||||
|
// hash. This is a passable way to get a unique hash value.
|
||||||
|
result.Hash += 1;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,7 +259,15 @@ public:
|
|||||||
//
|
//
|
||||||
bool Changed;
|
bool Changed;
|
||||||
|
|
||||||
|
// Autofinish parameters.
|
||||||
|
//
|
||||||
|
bool AutoFinish;
|
||||||
|
FString AutoFinishAction;
|
||||||
|
FVector AutoFinishXYZ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool MatchesAutoFinish(const FlxAnimationStep &step);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Construct a tracker.
|
// Construct a tracker.
|
||||||
//
|
//
|
||||||
@@ -278,6 +286,14 @@ public:
|
|||||||
//
|
//
|
||||||
void Update(std::string_view encqueue);
|
void Update(std::string_view encqueue);
|
||||||
|
|
||||||
|
// Auto-finish animation.
|
||||||
|
//
|
||||||
|
// Next time 'update' is called, we will check for the presence
|
||||||
|
// of a new animation matching these parameters. If there is
|
||||||
|
// one, it is automatically marked 'finished'.
|
||||||
|
//
|
||||||
|
void SetAutoFinish(const FString &action, const FVector &xyz);
|
||||||
|
|
||||||
// Get the current blueprint name, as a string.
|
// Get the current blueprint name, as a string.
|
||||||
//
|
//
|
||||||
FString GetCurrentBlueprintName();
|
FString GetCurrentBlueprintName();
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ void AIntegrationGameModeBase::UpdateTangibles() {
|
|||||||
TangibleManager->DeleteFarawayTangibles();
|
TangibleManager->DeleteFarawayTangibles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIntegrationGameModeBase::InvokeEngioMove(const FString &action, const FVector &xyz) {
|
void AIntegrationGameModeBase::InvokeEngioMove(const FString &action, const FVector &xyz, double facing) {
|
||||||
FTCHARToUTF8 utf8action(action);
|
FTCHARToUTF8 utf8action(action);
|
||||||
std::string uaction(utf8action.Get(), utf8action.Length());
|
std::string uaction(utf8action.Get(), utf8action.Length());
|
||||||
FlxStreamBuffer sb;
|
FlxStreamBuffer sb;
|
||||||
@@ -141,6 +141,8 @@ void AIntegrationGameModeBase::InvokeEngioMove(const FString &action, const FVec
|
|||||||
sb.write_string(uaction);
|
sb.write_string(uaction);
|
||||||
sb.write_simple_dynamic_tag(SimpleDynamicTag::VECTOR);
|
sb.write_simple_dynamic_tag(SimpleDynamicTag::VECTOR);
|
||||||
sb.write_fvector(xyz);
|
sb.write_fvector(xyz);
|
||||||
|
sb.write_simple_dynamic_tag(SimpleDynamicTag::NUMBER);
|
||||||
|
sb.write_double(facing);
|
||||||
std::string_view datapk = sb.view();
|
std::string_view datapk = sb.view();
|
||||||
FlxLockedWrapper w(LockableWrapper);
|
FlxLockedWrapper w(LockableWrapper);
|
||||||
int64 player = w.GetActor();
|
int64 player = w.GetActor();
|
||||||
@@ -197,6 +199,8 @@ void AIntegrationGameModeBase::OnWorldPreActorTick(UWorld* InWorld, ELevelTick I
|
|||||||
{
|
{
|
||||||
LuprexUpdateTask.Wait();
|
LuprexUpdateTask.Wait();
|
||||||
EngineSeconds += deltaseconds;
|
EngineSeconds += deltaseconds;
|
||||||
|
UpdateConsoleOutput();
|
||||||
|
UpdateTangibles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
int64 GetPlayerId();
|
int64 GetPlayerId();
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Luprex")
|
UFUNCTION(BlueprintCallable, Category = "Luprex")
|
||||||
void InvokeEngioMove(const FString &action, const FVector &xyz);
|
void InvokeEngioMove(const FString &action, const FVector &xyz, double facing);
|
||||||
|
|
||||||
// Execute a debugging command, typed on the GUI.
|
// Execute a debugging command, typed on the GUI.
|
||||||
void ExecuteDebuggingCommand(FlxLockedWrapper &w, const FString &fs);
|
void ExecuteDebuggingCommand(FlxLockedWrapper &w, const FString &fs);
|
||||||
|
|||||||
@@ -163,3 +163,8 @@ bool UlxTangible::IsCurrentPlayer(AActor* target) {
|
|||||||
AIntegrationGameModeBase *gamemode = tan->Manager->GetGameMode();
|
AIntegrationGameModeBase *gamemode = tan->Manager->GetGameMode();
|
||||||
return (tan->TangibleId == gamemode->PlayerId);
|
return (tan->TangibleId == gamemode->PlayerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UlxTangible::SetAutoFinish(AActor *target, const FString &action, const FVector &xyz) {
|
||||||
|
UlxTangible *tan = GetActorTangible(target);
|
||||||
|
tan->AnimTracker.SetAutoFinish(action, xyz);
|
||||||
|
}
|
||||||
@@ -165,6 +165,9 @@ public:
|
|||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex)
|
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex)
|
||||||
static bool IsCurrentPlayer(AActor *target);
|
static bool IsCurrentPlayer(AActor *target);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = Luprex)
|
||||||
|
static void SetAutoFinish(AActor *target, const FString &action, const FVector &xyz);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,14 +37,19 @@ private:
|
|||||||
|
|
||||||
// This event is used to wake up the thread.
|
// This event is used to wake up the thread.
|
||||||
//
|
//
|
||||||
|
// This is an auto-reset event, meaning that each time we
|
||||||
|
// call trigger, the background thread is gated exactly once.
|
||||||
|
//
|
||||||
// Normally, this means we want the worker to run the task
|
// Normally, this means we want the worker to run the task
|
||||||
// once. But if ThreadStopRequested is true, it means we
|
// once. But if ThreadStopRequested is true, it means we
|
||||||
// want the thread to exit.
|
// want the thread to exit.
|
||||||
//
|
//
|
||||||
FEvent* CallEvent;
|
FEvent* CallEvent;
|
||||||
|
|
||||||
// This event is used when the thread is done
|
// This event is used when the thread is done with its work.
|
||||||
// with its work.
|
//
|
||||||
|
// This is not an auto-reset event. This event stays triggered
|
||||||
|
// whenever the background thread is not running.
|
||||||
//
|
//
|
||||||
FEvent* ReturnEvent;
|
FEvent* ReturnEvent;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user