Migration
This commit is contained in:
15
Source/Howling.Target.cs
Normal file
15
Source/Howling.Target.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class HowlingTarget : TargetRules
|
||||
{
|
||||
public HowlingTarget(TargetInfo Target) : base(Target)
|
||||
{
|
||||
Type = TargetType.Game;
|
||||
DefaultBuildSettings = BuildSettingsVersion.V2;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "Howling" } );
|
||||
}
|
||||
}
|
||||
23
Source/Howling/Howling.Build.cs
Normal file
23
Source/Howling/Howling.Build.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class Howling : ModuleRules
|
||||
{
|
||||
public Howling(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(new string[] { });
|
||||
|
||||
// Uncomment if you are using Slate UI
|
||||
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
|
||||
|
||||
// Uncomment if you are using online features
|
||||
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
|
||||
|
||||
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
|
||||
}
|
||||
}
|
||||
6
Source/Howling/Howling.cpp
Normal file
6
Source/Howling/Howling.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "Howling.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Howling, "Howling" );
|
||||
5
Source/Howling/Howling.h
Normal file
5
Source/Howling/Howling.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
31
Source/Howling/MyBlueprintFunctionLibrary.cpp
Normal file
31
Source/Howling/MyBlueprintFunctionLibrary.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "MyBlueprintFunctionLibrary.h"
|
||||
|
||||
void UMyBlueprintFunctionLibrary::UnregisterComponentFromOwner(UActorComponent* Component)
|
||||
{
|
||||
if (Component)
|
||||
{
|
||||
Component->UnregisterComponent();
|
||||
Component->DestroyComponent();
|
||||
}
|
||||
}
|
||||
|
||||
void UMyBlueprintFunctionLibrary::ClientTravel(APlayerController* PlayerController, FString LevelName, ETravelType TravelType)
|
||||
{
|
||||
if (PlayerController)
|
||||
{
|
||||
PlayerController->ClientTravel(LevelName, TravelType);
|
||||
}
|
||||
}
|
||||
|
||||
bool UMyBlueprintFunctionLibrary::IsActorOwnedByActor(AActor* Actor, AActor* OwningActor)
|
||||
{
|
||||
if (Actor && OwningActor)
|
||||
{
|
||||
return Actor->IsOwnedBy(OwningActor);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
28
Source/Howling/MyBlueprintFunctionLibrary.h
Normal file
28
Source/Howling/MyBlueprintFunctionLibrary.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "MyBlueprintFunctionLibrary.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class HOWLING_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, DisplayName = "Unregister Component From Owner", Category = "Components")
|
||||
static void UnregisterComponentFromOwner(UActorComponent* Component);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static void ClientTravel(APlayerController* PlayerController, FString LevelName, ETravelType TravelType);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "Actor")
|
||||
static bool IsActorOwnedByActor(AActor* Actor, AActor* OwningActor);
|
||||
|
||||
};
|
||||
55
Source/Howling/Private/Animation/HumanoidAnimInstance.cpp
Normal file
55
Source/Howling/Private/Animation/HumanoidAnimInstance.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Animation/HumanoidAnimInstance.h"
|
||||
#include "Kismet/KismetMathLibrary.h"
|
||||
#include "GameFramework/CharacterMovementComponent.h"
|
||||
|
||||
void UHumanoidAnimInstance::NativeInitializeAnimation()
|
||||
{
|
||||
Super::NativeInitializeAnimation();
|
||||
|
||||
if (APawn* Owner = TryGetPawnOwner()) {
|
||||
CharacterMovementComponent = Owner->GetComponentByClass<UCharacterMovementComponent>();
|
||||
_PreviousYaw = Owner->GetActorRotation().Yaw;
|
||||
}
|
||||
}
|
||||
|
||||
void UHumanoidAnimInstance::NativeUpdateAnimation(float DeltaTime)
|
||||
{
|
||||
Super::NativeUpdateAnimation(DeltaTime);
|
||||
|
||||
if (APawn* Owner = TryGetPawnOwner())
|
||||
{
|
||||
FRotator Rotation = Owner->GetActorRotation();
|
||||
TurnVelocity = (Rotation.Yaw - _PreviousYaw) / DeltaTime;
|
||||
|
||||
if (CharacterMovementComponent)
|
||||
{
|
||||
bFalling = CharacterMovementComponent->IsFalling();
|
||||
bCrouching = CharacterMovementComponent->IsCrouching();
|
||||
bSwimming = CharacterMovementComponent->IsSwimming();
|
||||
|
||||
LocalVelocity = Rotation.UnrotateVector(CharacterMovementComponent->Velocity);
|
||||
LocalVelocityAngle = LocalVelocity.IsNearlyZero() ? 0 : FMath::RadiansToDegrees(FMath::Atan2(LocalVelocity.Y, LocalVelocity.X));
|
||||
|
||||
}
|
||||
|
||||
_PreviousYaw = Rotation.Yaw;
|
||||
}
|
||||
}
|
||||
|
||||
bool UHumanoidAnimInstance::IsPawnMoving() const
|
||||
{
|
||||
return LocalVelocity.SquaredLength() > 10;
|
||||
}
|
||||
|
||||
bool UHumanoidAnimInstance::IsJumpingUp() const
|
||||
{
|
||||
return LocalVelocity.Z > 0 && bFalling;
|
||||
}
|
||||
|
||||
bool UHumanoidAnimInstance::IsFallingDown() const
|
||||
{
|
||||
return LocalVelocity.Z <= 0 && bFalling;
|
||||
}
|
||||
34
Source/Howling/Private/Characters/CharacterBase.cpp
Normal file
34
Source/Howling/Private/Characters/CharacterBase.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Characters/CharacterBase.h"
|
||||
|
||||
// Sets default values
|
||||
ACharacterBase::ACharacterBase()
|
||||
{
|
||||
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void ACharacterBase::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
}
|
||||
|
||||
// Called every frame
|
||||
void ACharacterBase::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
|
||||
}
|
||||
|
||||
// Called to bind functionality to input
|
||||
void ACharacterBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||
{
|
||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||
|
||||
}
|
||||
|
||||
34
Source/Howling/Private/Components/BoxSceneComponent.cpp
Normal file
34
Source/Howling/Private/Components/BoxSceneComponent.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Components/BoxSceneComponent.h"
|
||||
|
||||
// Sets default values for this component's properties
|
||||
UBoxSceneComponent::UBoxSceneComponent()
|
||||
{
|
||||
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
||||
// off to improve performance if you don't need them.
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
// Called when the game starts
|
||||
void UBoxSceneComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Called every frame
|
||||
void UBoxSceneComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "InteractionSystem/InteractableInterface.h"
|
||||
|
||||
// Add default functionality here for any IInteractableInterface functions that are not pure virtual.
|
||||
|
||||
FInteractionInfos IInteractableInterface::GetInteractionInfos_Implementation() const
|
||||
{
|
||||
FInteractionInfos Infos;
|
||||
|
||||
Infos.ActionName = FText::FromString("Use");
|
||||
if (const AActor* SelfActor = Cast<AActor>(this))
|
||||
{
|
||||
Infos.WorldLocation = SelfActor->GetActorLocation();
|
||||
SelfActor->GetComponents<UPrimitiveComponent>(Infos.OutlineComponents);
|
||||
}
|
||||
else if (const USceneComponent* SelfComponent = Cast<USceneComponent>(this))
|
||||
{
|
||||
Infos.WorldLocation = SelfComponent->GetComponentLocation();
|
||||
}
|
||||
return Infos;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "InteractionSystem/InteractiveBoxComponent.h"
|
||||
|
||||
UInteractiveBoxComponent::UInteractiveBoxComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
PrimaryComponentTick.TickInterval = 0.25;
|
||||
}
|
||||
|
||||
void UInteractiveBoxComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
}
|
||||
|
||||
void UInteractiveBoxComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "InteractionSystem/TriggerableInterface.h"
|
||||
|
||||
// Add default functionality here for any ITriggerableInterface functions that are not pure virtual.
|
||||
54
Source/Howling/Public/Animation/HumanoidAnimInstance.h
Normal file
54
Source/Howling/Public/Animation/HumanoidAnimInstance.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Animation/AnimInstance.h"
|
||||
#include "HumanoidAnimInstance.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class HOWLING_API UHumanoidAnimInstance : public UAnimInstance
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
float _PreviousYaw = 0;
|
||||
|
||||
public:
|
||||
|
||||
virtual void NativeInitializeAnimation() override;
|
||||
virtual void NativeUpdateAnimation(float DeltaTime) override;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = Movement)
|
||||
class UCharacterMovementComponent* CharacterMovementComponent;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
FVector LocalVelocity;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = Movement)
|
||||
bool IsPawnMoving() const;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
float LocalVelocityAngle = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
float TurnVelocity = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
bool bFalling = false;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = Movement)
|
||||
bool IsJumpingUp() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = Movement)
|
||||
bool IsFallingDown() const;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
bool bCrouching = false;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
bool bSwimming = false;
|
||||
|
||||
};
|
||||
29
Source/Howling/Public/Characters/CharacterBase.h
Normal file
29
Source/Howling/Public/Characters/CharacterBase.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "CharacterBase.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class HOWLING_API ACharacterBase : public ACharacter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this character's properties
|
||||
ACharacterBase();
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
// Called to bind functionality to input
|
||||
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
||||
|
||||
};
|
||||
27
Source/Howling/Public/Components/BoxSceneComponent.h
Normal file
27
Source/Howling/Public/Components/BoxSceneComponent.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "BoxSceneComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent), Blueprintable )
|
||||
class HOWLING_API UBoxSceneComponent : public UBoxComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this component's properties
|
||||
UBoxSceneComponent();
|
||||
|
||||
protected:
|
||||
// Called when the game starts
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "TriggerableInterface.h"
|
||||
#include "InteractableInterface.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FInteractionInfos
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FVector WorldLocation;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FText ActionName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TArray<class UPrimitiveComponent*> OutlineComponents;
|
||||
};
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalAPI)
|
||||
class UInteractableInterface : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class HOWLING_API IInteractableInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Interaction)
|
||||
void GetTriggerable(TScriptInterface<ITriggerableInterface>& Triggerable) const;
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Interaction)
|
||||
FInteractionInfos GetInteractionInfos() const;
|
||||
virtual FInteractionInfos GetInteractionInfos_Implementation() const;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "InteractiveBoxComponent.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent), Blueprintable )
|
||||
class HOWLING_API UInteractiveBoxComponent : public UBoxComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UInteractiveBoxComponent();
|
||||
|
||||
protected:
|
||||
// Called when the game starts
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "TriggerableInterface.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ETriggerMode : uint8 {
|
||||
Server UMETA(DisplayName = "Server Only"),
|
||||
Client UMETA(DisplayName = "Triggering Client"),
|
||||
Multicast UMETA(DisplayName = "Multicast From Server"),
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FTriggerActionData
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
UObject *TriggeringObject;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TSet<FName> Tags;
|
||||
};
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalApi, BlueprintType)
|
||||
// UCLASS(Blueprintable, BlueprintType)
|
||||
class UTriggerableInterface : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class HOWLING_API ITriggerableInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Trigger)
|
||||
void Trigger(FTriggerActionData Action);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Trigger)
|
||||
void TriggerRelease(FTriggerActionData Action);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Trigger)
|
||||
ETriggerMode GetTriggerMode() const;
|
||||
};
|
||||
15
Source/HowlingEditor.Target.cs
Normal file
15
Source/HowlingEditor.Target.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class HowlingEditorTarget : TargetRules
|
||||
{
|
||||
public HowlingEditorTarget(TargetInfo Target) : base(Target)
|
||||
{
|
||||
Type = TargetType.Editor;
|
||||
DefaultBuildSettings = BuildSettingsVersion.V2;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "Howling" } );
|
||||
}
|
||||
}
|
||||
15
Source/HowlingServer.Target.cs
Normal file
15
Source/HowlingServer.Target.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class HowlingServerTarget : TargetRules
|
||||
{
|
||||
public HowlingServerTarget(TargetInfo Target) : base(Target)
|
||||
{
|
||||
Type = TargetType.Server;
|
||||
DefaultBuildSettings = BuildSettingsVersion.V2;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "Howling" } );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user