So much lint
This commit is contained in:
parent
2e1cbf32c1
commit
f4c056c233
29 changed files with 886 additions and 85 deletions
|
@ -1,7 +1,7 @@
|
|||
# PotRogue
|
||||
### A WIP, opensource, roguelike project built in [Kotlin](https://kotlinlang.org/), utilizing [Zircon](https://hexworks.org/projects/zircon/).
|
||||
|
||||
The plan is to be able to self-contain the entire game on a DVD/Blue-Ray once "completed." thatd be so cool and so epic.
|
||||
### For now, please make issues on [The mirror repo](https://next.forgejo.org/Ouroboros/potrogue/issues) as ForgeFed has not yet been implemented in mainline ForgeJo, and this instance does not have an open registration
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@ val version: String by project
|
|||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.9.10"
|
||||
`kotlin-dsl`
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("io.gitlab.arturbosch.detekt") version("1.23.1")
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
784
config/detekt/detekt.yml
Normal file
784
config/detekt/detekt.yml
Normal file
|
@ -0,0 +1,784 @@
|
|||
build:
|
||||
maxIssues: 0
|
||||
excludeCorrectable: false
|
||||
weights:
|
||||
# complexity: 2
|
||||
# LongParameterList: 1
|
||||
# style: 1
|
||||
# comments: 1
|
||||
|
||||
config:
|
||||
validation: true
|
||||
warningsAsErrors: false
|
||||
checkExhaustiveness: false
|
||||
# when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]'
|
||||
excludes: ''
|
||||
|
||||
processors:
|
||||
active: true
|
||||
exclude:
|
||||
- 'DetektProgressListener'
|
||||
# - 'KtFileCountProcessor'
|
||||
# - 'PackageCountProcessor'
|
||||
# - 'ClassCountProcessor'
|
||||
# - 'FunctionCountProcessor'
|
||||
# - 'PropertyCountProcessor'
|
||||
# - 'ProjectComplexityProcessor'
|
||||
# - 'ProjectCognitiveComplexityProcessor'
|
||||
# - 'ProjectLLOCProcessor'
|
||||
# - 'ProjectCLOCProcessor'
|
||||
# - 'ProjectLOCProcessor'
|
||||
# - 'ProjectSLOCProcessor'
|
||||
# - 'LicenseHeaderLoaderExtension'
|
||||
|
||||
console-reports:
|
||||
active: true
|
||||
exclude:
|
||||
- 'ProjectStatisticsReport'
|
||||
- 'ComplexityReport'
|
||||
- 'NotificationReport'
|
||||
- 'FindingsReport'
|
||||
- 'FileBasedFindingsReport'
|
||||
# - 'LiteFindingsReport'
|
||||
|
||||
output-reports:
|
||||
active: true
|
||||
exclude:
|
||||
# - 'TxtOutputReport'
|
||||
# - 'XmlOutputReport'
|
||||
# - 'HtmlOutputReport'
|
||||
# - 'MdOutputReport'
|
||||
# - 'SarifOutputReport'
|
||||
|
||||
comments:
|
||||
active: true
|
||||
AbsentOrWrongFileLicense:
|
||||
active: false
|
||||
licenseTemplateFile: 'license.template'
|
||||
licenseTemplateIsRegex: false
|
||||
CommentOverPrivateFunction:
|
||||
active: false
|
||||
CommentOverPrivateProperty:
|
||||
active: false
|
||||
DeprecatedBlockTag:
|
||||
active: false
|
||||
EndOfSentenceFormat:
|
||||
active: false
|
||||
endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)'
|
||||
KDocReferencesNonPublicProperty:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
OutdatedDocumentation:
|
||||
active: false
|
||||
matchTypeParameters: true
|
||||
matchDeclarationsOrder: true
|
||||
allowParamOnConstructorProperties: false
|
||||
UndocumentedPublicClass:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
searchInNestedClass: true
|
||||
searchInInnerClass: true
|
||||
searchInInnerObject: true
|
||||
searchInInnerInterface: true
|
||||
searchInProtectedClass: false
|
||||
UndocumentedPublicFunction:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
searchProtectedFunction: false
|
||||
UndocumentedPublicProperty:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
searchProtectedProperty: false
|
||||
|
||||
complexity:
|
||||
active: true
|
||||
CognitiveComplexMethod:
|
||||
active: false
|
||||
threshold: 15
|
||||
ComplexCondition:
|
||||
active: true
|
||||
threshold: 4
|
||||
ComplexInterface:
|
||||
active: false
|
||||
threshold: 10
|
||||
includeStaticDeclarations: false
|
||||
includePrivateDeclarations: false
|
||||
ignoreOverloaded: false
|
||||
CyclomaticComplexMethod:
|
||||
active: true
|
||||
threshold: 15
|
||||
ignoreSingleWhenExpression: false
|
||||
ignoreSimpleWhenEntries: false
|
||||
ignoreNestingFunctions: false
|
||||
nestingFunctions:
|
||||
- 'also'
|
||||
- 'apply'
|
||||
- 'forEach'
|
||||
- 'isNotNull'
|
||||
- 'ifNull'
|
||||
- 'let'
|
||||
- 'run'
|
||||
- 'use'
|
||||
- 'with'
|
||||
LabeledExpression:
|
||||
active: false
|
||||
ignoredLabels: []
|
||||
LargeClass:
|
||||
active: true
|
||||
threshold: 600
|
||||
LongMethod:
|
||||
active: true
|
||||
threshold: 60
|
||||
LongParameterList:
|
||||
active: true
|
||||
functionThreshold: 6
|
||||
constructorThreshold: 7
|
||||
ignoreDefaultParameters: false
|
||||
ignoreDataClasses: true
|
||||
ignoreAnnotatedParameter: []
|
||||
MethodOverloading:
|
||||
active: false
|
||||
threshold: 6
|
||||
NamedArguments:
|
||||
active: false
|
||||
threshold: 3
|
||||
ignoreArgumentsMatchingNames: false
|
||||
NestedBlockDepth:
|
||||
active: true
|
||||
threshold: 4
|
||||
NestedScopeFunctions:
|
||||
active: false
|
||||
threshold: 1
|
||||
functions:
|
||||
- 'kotlin.apply'
|
||||
- 'kotlin.run'
|
||||
- 'kotlin.with'
|
||||
- 'kotlin.let'
|
||||
- 'kotlin.also'
|
||||
ReplaceSafeCallChainWithRun:
|
||||
active: false
|
||||
StringLiteralDuplication:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
threshold: 3
|
||||
ignoreAnnotation: true
|
||||
excludeStringsWithLessThan5Characters: true
|
||||
ignoreStringsRegex: '$^'
|
||||
TooManyFunctions:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
thresholdInFiles: 11
|
||||
thresholdInClasses: 11
|
||||
thresholdInInterfaces: 11
|
||||
thresholdInObjects: 11
|
||||
thresholdInEnums: 11
|
||||
ignoreDeprecated: false
|
||||
ignorePrivate: false
|
||||
ignoreOverridden: false
|
||||
|
||||
coroutines:
|
||||
active: true
|
||||
GlobalCoroutineUsage:
|
||||
active: false
|
||||
InjectDispatcher:
|
||||
active: true
|
||||
dispatcherNames:
|
||||
- 'IO'
|
||||
- 'Default'
|
||||
- 'Unconfined'
|
||||
RedundantSuspendModifier:
|
||||
active: true
|
||||
SleepInsteadOfDelay:
|
||||
active: true
|
||||
SuspendFunSwallowedCancellation:
|
||||
active: false
|
||||
SuspendFunWithCoroutineScopeReceiver:
|
||||
active: false
|
||||
SuspendFunWithFlowReturnType:
|
||||
active: true
|
||||
|
||||
empty-blocks:
|
||||
active: true
|
||||
EmptyCatchBlock:
|
||||
active: true
|
||||
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||
EmptyClassBlock:
|
||||
active: true
|
||||
EmptyDefaultConstructor:
|
||||
active: true
|
||||
EmptyDoWhileBlock:
|
||||
active: true
|
||||
EmptyElseBlock:
|
||||
active: true
|
||||
EmptyFinallyBlock:
|
||||
active: true
|
||||
EmptyForBlock:
|
||||
active: true
|
||||
EmptyFunctionBlock:
|
||||
active: true
|
||||
ignoreOverridden: false
|
||||
EmptyIfBlock:
|
||||
active: true
|
||||
EmptyInitBlock:
|
||||
active: true
|
||||
EmptyKtFile:
|
||||
active: true
|
||||
EmptySecondaryConstructor:
|
||||
active: true
|
||||
EmptyTryBlock:
|
||||
active: true
|
||||
EmptyWhenBlock:
|
||||
active: true
|
||||
EmptyWhileBlock:
|
||||
active: true
|
||||
|
||||
exceptions:
|
||||
active: true
|
||||
ExceptionRaisedInUnexpectedLocation:
|
||||
active: true
|
||||
methodNames:
|
||||
- 'equals'
|
||||
- 'finalize'
|
||||
- 'hashCode'
|
||||
- 'toString'
|
||||
InstanceOfCheckForException:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
NotImplementedDeclaration:
|
||||
active: false
|
||||
ObjectExtendsThrowable:
|
||||
active: false
|
||||
PrintStackTrace:
|
||||
active: true
|
||||
RethrowCaughtException:
|
||||
active: true
|
||||
ReturnFromFinally:
|
||||
active: true
|
||||
ignoreLabeled: false
|
||||
SwallowedException:
|
||||
active: true
|
||||
ignoredExceptionTypes:
|
||||
- 'InterruptedException'
|
||||
- 'MalformedURLException'
|
||||
- 'NumberFormatException'
|
||||
- 'ParseException'
|
||||
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||
ThrowingExceptionFromFinally:
|
||||
active: true
|
||||
ThrowingExceptionInMain:
|
||||
active: false
|
||||
ThrowingExceptionsWithoutMessageOrCause:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
exceptions:
|
||||
- 'ArrayIndexOutOfBoundsException'
|
||||
- 'Exception'
|
||||
- 'IllegalArgumentException'
|
||||
- 'IllegalMonitorStateException'
|
||||
- 'IllegalStateException'
|
||||
- 'IndexOutOfBoundsException'
|
||||
- 'NullPointerException'
|
||||
- 'RuntimeException'
|
||||
- 'Throwable'
|
||||
ThrowingNewInstanceOfSameException:
|
||||
active: true
|
||||
TooGenericExceptionCaught:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
exceptionNames:
|
||||
- 'ArrayIndexOutOfBoundsException'
|
||||
- 'Error'
|
||||
- 'Exception'
|
||||
- 'IllegalMonitorStateException'
|
||||
- 'IndexOutOfBoundsException'
|
||||
- 'NullPointerException'
|
||||
- 'RuntimeException'
|
||||
- 'Throwable'
|
||||
allowedExceptionNameRegex: '_|(ignore|expected).*'
|
||||
TooGenericExceptionThrown:
|
||||
active: true
|
||||
exceptionNames:
|
||||
- 'Error'
|
||||
- 'Exception'
|
||||
- 'RuntimeException'
|
||||
- 'Throwable'
|
||||
|
||||
naming:
|
||||
active: true
|
||||
BooleanPropertyNaming:
|
||||
active: false
|
||||
allowedPattern: '^(is|has|are)'
|
||||
ClassNaming:
|
||||
active: true
|
||||
classPattern: '[A-Z][a-zA-Z0-9]*'
|
||||
ConstructorParameterNaming:
|
||||
active: true
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
privateParameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
EnumNaming:
|
||||
active: true
|
||||
enumEntryPattern: '[A-Z][_a-zA-Z0-9]*'
|
||||
ForbiddenClassName:
|
||||
active: false
|
||||
forbiddenName: []
|
||||
FunctionMaxLength:
|
||||
active: false
|
||||
maximumFunctionNameLength: 30
|
||||
FunctionMinLength:
|
||||
active: false
|
||||
minimumFunctionNameLength: 3
|
||||
FunctionNaming:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
functionPattern: '[a-z][a-zA-Z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
FunctionParameterNaming:
|
||||
active: true
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
InvalidPackageDeclaration:
|
||||
active: true
|
||||
rootPackage: ''
|
||||
requireRootInDeclaration: false
|
||||
LambdaParameterNaming:
|
||||
active: false
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*|_'
|
||||
MatchingDeclarationName:
|
||||
active: true
|
||||
mustBeFirst: true
|
||||
MemberNameEqualsClassName:
|
||||
active: true
|
||||
ignoreOverridden: true
|
||||
NoNameShadowing:
|
||||
active: true
|
||||
NonBooleanPropertyPrefixedWithIs:
|
||||
active: false
|
||||
ObjectPropertyNaming:
|
||||
active: true
|
||||
constantPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||
privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
|
||||
PackageNaming:
|
||||
active: true
|
||||
packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*'
|
||||
TopLevelPropertyNaming:
|
||||
active: true
|
||||
constantPattern: '[A-Z][_A-Z0-9]*'
|
||||
propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
|
||||
privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*'
|
||||
VariableMaxLength:
|
||||
active: false
|
||||
maximumVariableNameLength: 64
|
||||
VariableMinLength:
|
||||
active: false
|
||||
minimumVariableNameLength: 1
|
||||
VariableNaming:
|
||||
active: true
|
||||
variablePattern: '[a-z][A-Za-z0-9]*'
|
||||
privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
|
||||
excludeClassPattern: '$^'
|
||||
|
||||
performance:
|
||||
active: true
|
||||
ArrayPrimitive:
|
||||
active: true
|
||||
CouldBeSequence:
|
||||
active: false
|
||||
threshold: 3
|
||||
ForEachOnRange:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
SpreadOperator:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
UnnecessaryPartOfBinaryExpression:
|
||||
active: false
|
||||
UnnecessaryTemporaryInstantiation:
|
||||
active: true
|
||||
|
||||
potential-bugs:
|
||||
active: true
|
||||
AvoidReferentialEquality:
|
||||
active: true
|
||||
forbiddenTypePatterns:
|
||||
- 'kotlin.String'
|
||||
CastNullableToNonNullableType:
|
||||
active: false
|
||||
CastToNullableType:
|
||||
active: false
|
||||
Deprecation:
|
||||
active: false
|
||||
DontDowncastCollectionTypes:
|
||||
active: false
|
||||
DoubleMutabilityForCollection:
|
||||
active: true
|
||||
mutableTypes:
|
||||
- 'kotlin.collections.MutableList'
|
||||
- 'kotlin.collections.MutableMap'
|
||||
- 'kotlin.collections.MutableSet'
|
||||
- 'java.util.ArrayList'
|
||||
- 'java.util.LinkedHashSet'
|
||||
- 'java.util.HashSet'
|
||||
- 'java.util.LinkedHashMap'
|
||||
- 'java.util.HashMap'
|
||||
ElseCaseInsteadOfExhaustiveWhen:
|
||||
active: false
|
||||
ignoredSubjectTypes: []
|
||||
EqualsAlwaysReturnsTrueOrFalse:
|
||||
active: true
|
||||
EqualsWithHashCodeExist:
|
||||
active: true
|
||||
ExitOutsideMain:
|
||||
active: false
|
||||
ExplicitGarbageCollectionCall:
|
||||
active: true
|
||||
HasPlatformType:
|
||||
active: true
|
||||
IgnoredReturnValue:
|
||||
active: true
|
||||
restrictToConfig: true
|
||||
returnValueAnnotations:
|
||||
- 'CheckResult'
|
||||
- '*.CheckResult'
|
||||
- 'CheckReturnValue'
|
||||
- '*.CheckReturnValue'
|
||||
ignoreReturnValueAnnotations:
|
||||
- 'CanIgnoreReturnValue'
|
||||
- '*.CanIgnoreReturnValue'
|
||||
returnValueTypes:
|
||||
- 'kotlin.sequences.Sequence'
|
||||
- 'kotlinx.coroutines.flow.*Flow'
|
||||
- 'java.util.stream.*Stream'
|
||||
ignoreFunctionCall: []
|
||||
ImplicitDefaultLocale:
|
||||
active: true
|
||||
ImplicitUnitReturnType:
|
||||
active: false
|
||||
allowExplicitReturnType: true
|
||||
InvalidRange:
|
||||
active: true
|
||||
IteratorHasNextCallsNextMethod:
|
||||
active: true
|
||||
IteratorNotThrowingNoSuchElementException:
|
||||
active: true
|
||||
LateinitUsage:
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
ignoreOnClassesPattern: ''
|
||||
MapGetWithNotNullAssertionOperator:
|
||||
active: true
|
||||
MissingPackageDeclaration:
|
||||
active: false
|
||||
excludes: ['**/*.kts']
|
||||
NullCheckOnMutableProperty:
|
||||
active: false
|
||||
NullableToStringCall:
|
||||
active: false
|
||||
PropertyUsedBeforeDeclaration:
|
||||
active: false
|
||||
UnconditionalJumpStatementInLoop:
|
||||
active: false
|
||||
UnnecessaryNotNullCheck:
|
||||
active: false
|
||||
UnnecessaryNotNullOperator:
|
||||
active: true
|
||||
UnnecessarySafeCall:
|
||||
active: true
|
||||
UnreachableCatchBlock:
|
||||
active: true
|
||||
UnreachableCode:
|
||||
active: true
|
||||
UnsafeCallOnNullableType:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
UnsafeCast:
|
||||
active: true
|
||||
UnusedUnaryOperator:
|
||||
active: true
|
||||
UselessPostfixExpression:
|
||||
active: true
|
||||
WrongEqualsTypeParameter:
|
||||
active: true
|
||||
|
||||
style:
|
||||
active: true
|
||||
AlsoCouldBeApply:
|
||||
active: false
|
||||
BracesOnIfStatements:
|
||||
active: false
|
||||
singleLine: 'never'
|
||||
multiLine: 'always'
|
||||
BracesOnWhenStatements:
|
||||
active: false
|
||||
singleLine: 'necessary'
|
||||
multiLine: 'consistent'
|
||||
CanBeNonNullable:
|
||||
active: false
|
||||
CascadingCallWrapping:
|
||||
active: false
|
||||
includeElvis: true
|
||||
ClassOrdering:
|
||||
active: false
|
||||
CollapsibleIfStatements:
|
||||
active: false
|
||||
DataClassContainsFunctions:
|
||||
active: false
|
||||
conversionFunctionPrefix:
|
||||
- 'to'
|
||||
allowOperators: false
|
||||
DataClassShouldBeImmutable:
|
||||
active: false
|
||||
DestructuringDeclarationWithTooManyEntries:
|
||||
active: true
|
||||
maxDestructuringEntries: 3
|
||||
DoubleNegativeLambda:
|
||||
active: false
|
||||
negativeFunctions:
|
||||
- reason: 'Use `takeIf` instead.'
|
||||
value: 'takeUnless'
|
||||
- reason: 'Use `all` instead.'
|
||||
value: 'none'
|
||||
negativeFunctionNameParts:
|
||||
- 'not'
|
||||
- 'non'
|
||||
EqualsNullCall:
|
||||
active: true
|
||||
EqualsOnSignatureLine:
|
||||
active: false
|
||||
ExplicitCollectionElementAccessMethod:
|
||||
active: false
|
||||
ExplicitItLambdaParameter:
|
||||
active: true
|
||||
ExpressionBodySyntax:
|
||||
active: false
|
||||
includeLineWrapping: false
|
||||
ForbiddenAnnotation:
|
||||
active: false
|
||||
annotations:
|
||||
- reason: 'it is a java annotation. Use `Suppress` instead.'
|
||||
value: 'java.lang.SuppressWarnings'
|
||||
- reason: 'it is a java annotation. Use `kotlin.Deprecated` instead.'
|
||||
value: 'java.lang.Deprecated'
|
||||
- reason: 'it is a java annotation. Use `kotlin.annotation.MustBeDocumented` instead.'
|
||||
value: 'java.lang.annotation.Documented'
|
||||
- reason: 'it is a java annotation. Use `kotlin.annotation.Target` instead.'
|
||||
value: 'java.lang.annotation.Target'
|
||||
- reason: 'it is a java annotation. Use `kotlin.annotation.Retention` instead.'
|
||||
value: 'java.lang.annotation.Retention'
|
||||
- reason: 'it is a java annotation. Use `kotlin.annotation.Repeatable` instead.'
|
||||
value: 'java.lang.annotation.Repeatable'
|
||||
- reason: 'Kotlin does not support @Inherited annotation, see https://youtrack.jetbrains.com/issue/KT-22265'
|
||||
value: 'java.lang.annotation.Inherited'
|
||||
ForbiddenComment:
|
||||
active: true
|
||||
comments:
|
||||
- reason: 'Forbidden FIXME todo marker in comment, please fix the problem.'
|
||||
value: 'FIXME:'
|
||||
- reason: 'Forbidden STOPSHIP todo marker in comment, please address the problem before shipping the code.'
|
||||
value: 'STOPSHIP:'
|
||||
- reason: 'Forbidden TODO todo marker in comment, please do the changes.'
|
||||
value: 'TODO:'
|
||||
allowedPatterns: ''
|
||||
ForbiddenImport:
|
||||
active: false
|
||||
imports: []
|
||||
forbiddenPatterns: ''
|
||||
ForbiddenMethodCall:
|
||||
active: false
|
||||
methods:
|
||||
- reason: 'print does not allow you to configure the output stream. Use a logger instead.'
|
||||
value: 'kotlin.io.print'
|
||||
- reason: 'println does not allow you to configure the output stream. Use a logger instead.'
|
||||
value: 'kotlin.io.println'
|
||||
ForbiddenSuppress:
|
||||
active: false
|
||||
rules: []
|
||||
ForbiddenVoid:
|
||||
active: true
|
||||
ignoreOverridden: false
|
||||
ignoreUsageInGenerics: false
|
||||
FunctionOnlyReturningConstant:
|
||||
active: true
|
||||
ignoreOverridableFunction: true
|
||||
ignoreActualFunction: true
|
||||
excludedFunctions: []
|
||||
LoopWithTooManyJumpStatements:
|
||||
active: true
|
||||
maxJumpCount: 1
|
||||
MagicNumber:
|
||||
active: true
|
||||
excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts']
|
||||
ignoreNumbers:
|
||||
- '-1'
|
||||
- '0'
|
||||
- '1'
|
||||
- '2'
|
||||
ignoreHashCodeFunction: true
|
||||
ignorePropertyDeclaration: false
|
||||
ignoreLocalVariableDeclaration: false
|
||||
ignoreConstantDeclaration: true
|
||||
ignoreCompanionObjectPropertyDeclaration: true
|
||||
ignoreAnnotation: false
|
||||
ignoreNamedArgument: true
|
||||
ignoreEnums: false
|
||||
ignoreRanges: false
|
||||
ignoreExtensionFunctions: true
|
||||
MandatoryBracesLoops:
|
||||
active: false
|
||||
MaxChainedCallsOnSameLine:
|
||||
active: false
|
||||
maxChainedCalls: 5
|
||||
MaxLineLength:
|
||||
active: true
|
||||
maxLineLength: 120
|
||||
excludePackageStatements: true
|
||||
excludeImportStatements: true
|
||||
excludeCommentStatements: false
|
||||
excludeRawStrings: true
|
||||
MayBeConst:
|
||||
active: true
|
||||
ModifierOrder:
|
||||
active: true
|
||||
MultilineLambdaItParameter:
|
||||
active: false
|
||||
MultilineRawStringIndentation:
|
||||
active: false
|
||||
indentSize: 4
|
||||
trimmingMethods:
|
||||
- 'trimIndent'
|
||||
- 'trimMargin'
|
||||
NestedClassesVisibility:
|
||||
active: true
|
||||
NewLineAtEndOfFile:
|
||||
active: true
|
||||
NoTabs:
|
||||
active: false
|
||||
NullableBooleanCheck:
|
||||
active: false
|
||||
ObjectLiteralToLambda:
|
||||
active: true
|
||||
OptionalAbstractKeyword:
|
||||
active: true
|
||||
OptionalUnit:
|
||||
active: false
|
||||
PreferToOverPairSyntax:
|
||||
active: false
|
||||
ProtectedMemberInFinalClass:
|
||||
active: true
|
||||
RedundantExplicitType:
|
||||
active: false
|
||||
RedundantHigherOrderMapUsage:
|
||||
active: true
|
||||
RedundantVisibilityModifierRule:
|
||||
active: false
|
||||
ReturnCount:
|
||||
active: true
|
||||
max: 2
|
||||
excludedFunctions:
|
||||
- 'equals'
|
||||
excludeLabeled: false
|
||||
excludeReturnFromLambda: true
|
||||
excludeGuardClauses: false
|
||||
SafeCast:
|
||||
active: true
|
||||
SerialVersionUIDInSerializableClass:
|
||||
active: true
|
||||
SpacingBetweenPackageAndImports:
|
||||
active: false
|
||||
StringShouldBeRawString:
|
||||
active: false
|
||||
maxEscapedCharacterCount: 2
|
||||
ignoredCharacters: []
|
||||
ThrowsCount:
|
||||
active: true
|
||||
max: 2
|
||||
excludeGuardClauses: false
|
||||
TrailingWhitespace:
|
||||
active: false
|
||||
TrimMultilineRawString:
|
||||
active: false
|
||||
trimmingMethods:
|
||||
- 'trimIndent'
|
||||
- 'trimMargin'
|
||||
UnderscoresInNumericLiterals:
|
||||
active: false
|
||||
acceptableLength: 4
|
||||
allowNonStandardGrouping: false
|
||||
UnnecessaryAbstractClass:
|
||||
active: true
|
||||
UnnecessaryAnnotationUseSiteTarget:
|
||||
active: false
|
||||
UnnecessaryApply:
|
||||
active: true
|
||||
UnnecessaryBackticks:
|
||||
active: false
|
||||
UnnecessaryBracesAroundTrailingLambda:
|
||||
active: false
|
||||
UnnecessaryFilter:
|
||||
active: true
|
||||
UnnecessaryInheritance:
|
||||
active: true
|
||||
UnnecessaryInnerClass:
|
||||
active: false
|
||||
UnnecessaryLet:
|
||||
active: false
|
||||
UnnecessaryParentheses:
|
||||
active: false
|
||||
allowForUnclearPrecedence: false
|
||||
UntilInsteadOfRangeTo:
|
||||
active: false
|
||||
UnusedImports:
|
||||
active: false
|
||||
UnusedParameter:
|
||||
active: true
|
||||
allowedNames: 'ignored|expected'
|
||||
UnusedPrivateClass:
|
||||
active: true
|
||||
UnusedPrivateMember:
|
||||
active: true
|
||||
allowedNames: ''
|
||||
UnusedPrivateProperty:
|
||||
active: true
|
||||
allowedNames: '_|ignored|expected|serialVersionUID'
|
||||
UseAnyOrNoneInsteadOfFind:
|
||||
active: true
|
||||
UseArrayLiteralsInAnnotations:
|
||||
active: true
|
||||
UseCheckNotNull:
|
||||
active: true
|
||||
UseCheckOrError:
|
||||
active: true
|
||||
UseDataClass:
|
||||
active: false
|
||||
allowVars: false
|
||||
UseEmptyCounterpart:
|
||||
active: false
|
||||
UseIfEmptyOrIfBlank:
|
||||
active: false
|
||||
UseIfInsteadOfWhen:
|
||||
active: false
|
||||
ignoreWhenContainingVariableDeclaration: false
|
||||
UseIsNullOrEmpty:
|
||||
active: true
|
||||
UseLet:
|
||||
active: false
|
||||
UseOrEmpty:
|
||||
active: true
|
||||
UseRequire:
|
||||
active: true
|
||||
UseRequireNotNull:
|
||||
active: true
|
||||
UseSumOfInsteadOfFlatMapSize:
|
||||
active: false
|
||||
UselessCallOnNotNull:
|
||||
active: true
|
||||
UtilityClassWithPublicConstructor:
|
||||
active: true
|
||||
VarCouldBeVal:
|
||||
active: true
|
||||
ignoreLateinitVar: false
|
||||
WildcardImport:
|
||||
active: true
|
||||
excludeImports:
|
||||
- 'java.util.*'
|
|
@ -5,14 +5,13 @@ import group.ouroboros.potrogue.data.config.GameConfig
|
|||
import group.ouroboros.potrogue.view.StartView
|
||||
import org.hexworks.zircon.api.SwingApplications
|
||||
|
||||
//Important Values
|
||||
const val GAME_ID = "PotRogue";
|
||||
const val GAME_VER = "0.1.0-DEV";
|
||||
// Important Values
|
||||
const val GAME_ID = "PotRogue"
|
||||
const val GAME_VER = "0.1.0-DEV"
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
fun main() {
|
||||
Config()
|
||||
//Start Application
|
||||
// Start Application
|
||||
val grid = SwingApplications.startTileGrid(GameConfig.buildAppConfig())
|
||||
StartView(grid).dock()
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ import org.hexworks.zircon.api.data.base.BaseBlock
|
|||
|
||||
class GameBlock(
|
||||
private var defaultTile: Tile = WALL,
|
||||
// We added currentEntities which is just a mutable list of Entity objects which is empty by default
|
||||
// We added currentEntities, which is just a mutable list of Entity objects, which is empty by default
|
||||
private val currentEntities: MutableList<GameEntity<EntityType>> = mutableListOf(),
|
||||
) : BaseBlock<Tile>(
|
||||
emptyTile = Tile.empty(),
|
||||
|
@ -44,10 +44,12 @@ class GameBlock(
|
|||
get() = Maybe.ofNullable(currentEntities.firstOrNull { it.occupiesBlock })
|
||||
|
||||
val isOccupied: Boolean
|
||||
get() = occupier.isPresent // Note how we tell whether a block is occupied by checking for the presence of an occupier
|
||||
get() = occupier.isPresent
|
||||
// Note how we tell whether a block is occupied by checking for the presence of an occupier
|
||||
|
||||
// Exposed a getter for entities which takes a snapshot (defensive copy) of the current entities and returns them.
|
||||
// We do this because we don’t want to expose the internals of GameBlock which would make currentEntities mutable to the outside world
|
||||
// We do this because we don’t want to expose the internals of
|
||||
// GameBlock which would make currentEntities mutable to the outside world
|
||||
val entities: Iterable<GameEntity<EntityType>>
|
||||
get() = currentEntities.toList()
|
||||
|
||||
|
@ -67,15 +69,12 @@ class GameBlock(
|
|||
private fun updateContent() {
|
||||
val entityTiles = currentEntities.map { it.tile }
|
||||
content = when {
|
||||
// Checking if the player is at this block. If yes it is displayed on top
|
||||
// Checking if the player is at this block. If yes, it is displayed on top
|
||||
entityTiles.contains(PLAYER) -> PLAYER
|
||||
// Otherwise the first Entity is displayed if present
|
||||
// Otherwise, the first Entity is displayed if present
|
||||
entityTiles.isNotEmpty() -> entityTiles.first()
|
||||
// Or the default tile if not
|
||||
else -> defaultTile
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@ import org.hexworks.amethyst.api.builder.EntityBuilder
|
|||
import org.hexworks.amethyst.api.entity.EntityType
|
||||
import org.hexworks.amethyst.api.newEntityOfType
|
||||
|
||||
// We add a function which calls Entities.newEntityOfType and pre-fills the generic type parameter for Context with GameContext.
|
||||
// We add a function which calls Entities.newEntityOfType
|
||||
// and pre-fills the generic type parameter for Context with GameContext.
|
||||
fun <T : EntityType> newGameEntityOfType(
|
||||
type: T,
|
||||
init: EntityBuilder<T, GameContext>.() -> Unit
|
||||
|
@ -34,7 +35,7 @@ object EntityFactory {
|
|||
|
||||
// We add a function for creating a newPlayer and call newGameEntityOfType with our previously created Player type.
|
||||
fun newPlayer() = newGameEntityOfType(Player) {
|
||||
// We specify our Attributes, Behaviors and Facets. We only have Attributes so far though.
|
||||
// We specify our Attributes, Behaviors, and Facets. We only have Attributes so far though.
|
||||
attributes(
|
||||
EntityPosition(),
|
||||
EntityTile(GameTileRepository.PLAYER),
|
||||
|
|
|
@ -10,7 +10,8 @@ import org.hexworks.zircon.api.data.Tile
|
|||
import org.hexworks.zircon.api.graphics.Symbols
|
||||
|
||||
object GameTileRepository {
|
||||
//Factory for creating tile objects, we use basic CharacterTiles here but Zircon can indeed use GraphicalTiles(textured) which will come later.
|
||||
// Factory for creating tile objects, we use basic CharacterTiles here,
|
||||
// but Zircon can indeed use GraphicalTiles(textured) which will come later.
|
||||
|
||||
//Empty Tile
|
||||
val EMPTY: CharacterTile = Tile.empty()
|
||||
|
|
|
@ -44,7 +44,7 @@ class WorldBuilder (private val worldSize: Size3D) {
|
|||
var rocks = 0
|
||||
// Here we iterate over a list of the current position and all its neighbors
|
||||
pos.sameLevelNeighborsShuffled().plus(pos).forEach { neighbor ->
|
||||
// And we only care about the positions which have a corresponding block (when they are not outside of the game world)
|
||||
// And we only care about the positions which have a corresponding block (when they are not outside the game world)
|
||||
blocks.whenPresent(neighbor) { block ->
|
||||
if (block.isFloor) {
|
||||
floors++
|
||||
|
|
|
@ -21,7 +21,7 @@ class Config {
|
|||
if(fileExists){
|
||||
FileInputStream(file).use { prop.load(it) }
|
||||
}
|
||||
//Otherwise create necesssary directories
|
||||
//Otherwise create necessary directories
|
||||
//TODO: Check for directories individually as well?
|
||||
else{
|
||||
Files.createDirectories(Paths.get("./run"))
|
||||
|
@ -42,17 +42,17 @@ class Config {
|
|||
|
||||
//Adds comments
|
||||
val out: OutputStream = FileOutputStream(file)
|
||||
prop.store(out, "PotRogue Configuartion File, restart game if changed value.")
|
||||
prop.store(out, "PotRogue Configuration File, restart game if changed value.")
|
||||
}
|
||||
}
|
||||
//Convert values from the config file to in-code variables, so we can use them later, also make them public.
|
||||
val WINDOW_WIDTH: Int = (prop.getProperty("WINDOW_WIDTH")).toInt()
|
||||
val windowWidth: Int = (prop.getProperty("WINDOW_WIDTH")).toInt()
|
||||
|
||||
val WINDOW_HEIGHT: Int = (prop.getProperty("WINDOW_HEIGHT")).toInt()
|
||||
val windowHeight: Int = (prop.getProperty("WINDOW_HEIGHT")).toInt()
|
||||
|
||||
val DUNGEON_LEVELS: Int = (prop.getProperty("DUNGEON_LEVELS")).toInt()
|
||||
val dungeonLevels: Int = (prop.getProperty("DUNGEON_LEVELS")).toInt()
|
||||
|
||||
val SIDEBAR_WIDTH: Int = (prop.getProperty("SIDEBAR_WIDTH")).toInt()
|
||||
val sidebarWidth: Int = (prop.getProperty("SIDEBAR_WIDTH")).toInt()
|
||||
|
||||
val LOG_AREA_HEIGHT: Int = (prop.getProperty("LOG_AREA_HEIGHT")).toInt()
|
||||
val logAreaHeight: Int = (prop.getProperty("LOG_AREA_HEIGHT")).toInt()
|
||||
}
|
|
@ -12,16 +12,16 @@ object GameConfig {
|
|||
var TILESET = CP437TilesetResources.rogueYun16x16()
|
||||
val THEME = ColorThemes.cyberpunk()
|
||||
|
||||
val WORLD_SIZE = Size3D.create(Config().WINDOW_WIDTH * 3, Config().WINDOW_HEIGHT * 3 , Config().DUNGEON_LEVELS)
|
||||
val WORLD_SIZE = Size3D.create(Config().windowWidth * 3, Config().windowHeight * 3 , Config().dungeonLevels)
|
||||
val GAME_AREA_SIZE = Size3D.create(
|
||||
xLength = Config().WINDOW_WIDTH - Config().SIDEBAR_WIDTH,
|
||||
yLength = Config().WINDOW_HEIGHT - Config().LOG_AREA_HEIGHT,
|
||||
zLength = Config().DUNGEON_LEVELS
|
||||
xLength = Config().windowWidth - Config().sidebarWidth,
|
||||
yLength = Config().windowHeight - Config().logAreaHeight,
|
||||
zLength = Config().dungeonLevels
|
||||
)
|
||||
|
||||
fun buildAppConfig() = AppConfig.newBuilder()
|
||||
.withDefaultTileset(TILESET)
|
||||
.withSize(Config().WINDOW_WIDTH, Config().WINDOW_HEIGHT)
|
||||
.withSize(Config().windowWidth, Config().windowHeight)
|
||||
.withTitle("$GAME_ID | $GAME_VER")
|
||||
.withIcon("assets/icon.png")
|
||||
.build()
|
||||
|
|
|
@ -5,19 +5,22 @@ import org.hexworks.cobalt.databinding.api.extension.toProperty
|
|||
import org.hexworks.zircon.api.data.Position3D
|
||||
class EntityPosition(
|
||||
// We add initialPosition as a constructor parameter to our class and its default value is unknown.
|
||||
// What’s this? Position3D comes from Zircon and can be used to represent a point in 3D space (as we have discussed before),
|
||||
// and unknown impelments the Null Object Pattern for us.
|
||||
// What’s this? Position3D comes from Zircon
|
||||
// and can be used to represent a point in 3D space (as we have discussed before),
|
||||
// and unknown implements the Null Object Pattern for us.
|
||||
initialPosition: Position3D = Position3D.unknown()
|
||||
) : BaseAttribute() {
|
||||
|
||||
// Here we create a private Property from the initialPosition.
|
||||
// What’s a Property you might ask? Well, it is used for data binding.
|
||||
// A Property is a wrapper for a value that can change over time.
|
||||
// It can be bound to other Property objects so their values change together and you can also add change listeners to them.
|
||||
// Property comes from the Cobalt library we use and it works in a very similar way as properties work in JavaFX.
|
||||
// It can be bound to other Property objects
|
||||
// so their values change together, and you can also add change listeners to them.
|
||||
// Property comes from the Cobalt library we use, and it works in a very similar way as properties work in JavaFX.
|
||||
private val positionProperty = initialPosition.toProperty()
|
||||
|
||||
// We create a Kotlin delegate from our Property.
|
||||
// This means that position will be accessible to the outside world as if it was a simple field, but it takes its value from our Property under the hood.
|
||||
// This means that position will be accessible to the outside world
|
||||
// as if it was a simple field, but it takes its value from our Property under the hood.
|
||||
var position: Position3D by positionProperty.asDelegate()
|
||||
}
|
|
@ -3,5 +3,5 @@ package group.ouroboros.potrogue.entity.attributes
|
|||
import org.hexworks.amethyst.api.base.BaseAttribute
|
||||
import org.hexworks.zircon.api.data.Tile
|
||||
|
||||
// EntityTile is an Attribute which holds the Tile of an Entity we use to display it in our world
|
||||
// EntityTile is an Attribute that holds the Tile of an Entity we use to display it in our world
|
||||
data class EntityTile(val tile: Tile = Tile.empty()) : BaseAttribute()
|
||||
|
|
|
@ -5,7 +5,7 @@ import group.ouroboros.potrogue.extensions.GameMessage
|
|||
import org.hexworks.amethyst.api.entity.EntityType
|
||||
|
||||
// Our EntityAction is different from a regular GameMessage in a way that it also has a target.
|
||||
// So an EntityAction represents source trying to perform an action on target.
|
||||
// So an EntityAction represents a source trying to perform an action on target.
|
||||
|
||||
// We have two generic type parameters, S and T.
|
||||
// S is the EntityType of the source, T is the EntityType of the target.
|
||||
|
@ -17,8 +17,8 @@ interface EntityAction <S : EntityType, T : EntityType> : GameMessage {
|
|||
|
||||
// The component1, component2 … componentN methods implement destructuring in Kotlin.
|
||||
// Since destructuring is positional as we’ve seen previously by implementing the
|
||||
// component* functions we can control how an EntityAction can be destructured.
|
||||
// In our case with these 3 operator functions we can destructure any EntityActions like this:
|
||||
// component* functions, we can control how an EntityAction can be destructured.
|
||||
// In our case with these 3 operator functions, we can destructure any EntityActions like this:
|
||||
//
|
||||
//val (context, source, target) = entityAction
|
||||
operator fun component1() = context
|
||||
|
|
|
@ -12,14 +12,18 @@ object CameraMover : BaseFacet<GameContext, MoveCamera>(MoveCamera::class) {
|
|||
override suspend fun receive(message: MoveCamera): Response {
|
||||
val (context, source, previousPosition) = message
|
||||
val world = context.world
|
||||
// The player’s position on the screen can be calculated by subtracting the World’s visibleOffset from the player’s position.
|
||||
// The visibleOffset is the top left position of the visible part of the World relative to the top left corner of the whole World (which is 0, 0).
|
||||
// The player’s position on the screen can be calculated
|
||||
// by subtracting the World’s visibleOffset from the player’s position.
|
||||
|
||||
// The visibleOffset is the top left position of the
|
||||
// visible part of the World relative to the top left corner of the whole World (which is 0, 0).
|
||||
val screenPos = source.position - world.visibleOffset
|
||||
// We calculate the center position of the visible part of the world here
|
||||
val halfHeight = world.visibleSize.yLength / 2
|
||||
val halfWidth = world.visibleSize.xLength / 2
|
||||
val currentPosition = source.position
|
||||
// And we only move the camera if we moved in a certain direction (left for example) and the Entity’s position on the screen is left of the middle position.
|
||||
// And we only move the camera if we moved in a certain direction
|
||||
// (left, for example) and the Entity’s position on the screen is left of the middle position.
|
||||
// The logic is the same for all directions, but we use the corresponding x or y coordinate
|
||||
when {
|
||||
previousPosition.y > currentPosition.y && screenPos.y < halfHeight -> {
|
||||
|
|
|
@ -9,11 +9,11 @@ import org.hexworks.amethyst.api.entity.EntityType
|
|||
import org.hexworks.zircon.api.uievent.KeyCode
|
||||
import org.hexworks.zircon.api.uievent.KeyboardEvent
|
||||
|
||||
// InputReceiver is pretty simple, it just checks for WASD, and acts accordingly
|
||||
// InputReceiver checks for WASD, and acts accordingly
|
||||
object InputReceiver : BaseBehavior<GameContext>() {
|
||||
|
||||
override suspend fun update(entity: Entity<EntityType, GameContext>, context: GameContext): Boolean {
|
||||
// We destructure our context object so its properties are easy to access.
|
||||
// We destructure our context object so its properties are easier to access.
|
||||
// Destructuring is positional, so here _ means that we don’t care about that specific property.
|
||||
val (_, _, uiEvent, player) = context
|
||||
val currentPos = player.position
|
||||
|
|
|
@ -29,7 +29,7 @@ object Movable : BaseFacet<GameContext, MoveTo>(MoveTo::class) {
|
|||
* This might be familiar for Python folks and what it does is that it unpacks the values from an object which supports it. So writing this:
|
||||
* val (context, entity, position) = myObj
|
||||
*
|
||||
* is the equivalent of writing this:
|
||||
* Is the equivalent of writing this:
|
||||
* val context = myObj.context
|
||||
* val entity = myObj.entity
|
||||
* val position = myObj.position
|
||||
|
|
|
@ -12,16 +12,17 @@ val AnyGameEntity.occupiesBlock: Boolean
|
|||
|
||||
// We define this function as an extension function on AnyGameEntity.
|
||||
// This means that from now on we can call tryActionsOn on any of our entities!
|
||||
// It is also a suspend fun because the receiveMessage function we call later is also a suspending function.
|
||||
// Suspending is part of the Kotlin Coroutines API and it is a deep topic.
|
||||
// It is also suspending fun because the receiveMessage function we call later is also a suspending function.
|
||||
// Suspending is part of the Kotlin Coroutines API, and it is a deep topic.
|
||||
// We’re not going to cover it here as we don’t take advantage of it
|
||||
suspend fun AnyGameEntity.tryActionsOn(context: GameContext, target: AnyGameEntity): Response {
|
||||
var result: Response = Pass
|
||||
// We can only try the actions of an entity which has at least one, so we try to find the attribute.
|
||||
findAttributeOrNull(EntityActions::class)?.let {
|
||||
// if we find the attribute we just create the actions for our context/source/target combination
|
||||
// if we find the attribute, we just create the actions for our context/source/target combination
|
||||
it.createActionsFor(context, this, target).forEach { action ->
|
||||
// And we then send the message to the target for immediate processing and if the message is Consumed it means that
|
||||
// And we then send the message to the target for
|
||||
// immediate processing, and if the message is Consumed, it means that
|
||||
if (target.receiveMessage(action) is Consumed) {
|
||||
result = Consumed
|
||||
// We can break out of the forEach block.
|
||||
|
|
|
@ -2,14 +2,19 @@ package group.ouroboros.potrogue.extensions
|
|||
|
||||
import org.hexworks.zircon.api.data.Position3D
|
||||
|
||||
// We add the extension function to Position3D. We do it by defining a function not with a simple name, but by the format: fun <target class>.<function name>: return type { // ....
|
||||
// We add the extension function to Position3D.
|
||||
// We do it by defining a function not with a simple name, but by the format:
|
||||
// fun <target class>.<function name>: return type { // ....
|
||||
fun Position3D.sameLevelNeighborsShuffled(): List<Position3D> {
|
||||
return (-1..1).flatMap { x ->
|
||||
// We use functional programming here. flatMap and map works in a similar way as you might've been used to it in Java 8’s Stream API.
|
||||
// We use functional programming here.
|
||||
// flatMap and map work in a similar way as you might've been used to it in Java 8’s Stream API.
|
||||
(-1..1).map { y ->
|
||||
// When you write extension functions this will be bound to the class being extended. So this here will point to the Position3D instance on which sameLevelNeighborsShuffled is called.
|
||||
// When you write extension functions, this will be bound to the class being extended.
|
||||
// So this here will point to the Position3D instance on which sameLevelNeighborsShuffled is called.
|
||||
this.withRelativeX(x).withRelativeY(y)
|
||||
}
|
||||
// minus here will remove this position from the List and return a new List. shuffled will also return a new list which contains the same elements but shuffled.
|
||||
// minus here will remove this position from the List and return a new List.
|
||||
// shuffled will also return a new list which contains the same elements but shuffled.
|
||||
}.minus(this).shuffled()
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ typealias GameMessage = Message<GameContext>
|
|||
|
||||
// Create an extension property (works the same way as an extension function) on AnyGameEntity.
|
||||
var AnyGameEntity.position
|
||||
// Define a getter for it which tries to find the EntityPosition attribute in our Entity and throws and exception if the Entity has no position.
|
||||
// Define a getter for it which tries to find the
|
||||
// EntityPosition attribute in our Entity and throws and exception if the Entity has no position.
|
||||
get() = tryToFindAttribute(EntityPosition::class).position
|
||||
// We also define a setter for it which sets the Property we defined before
|
||||
set(value) {
|
||||
|
|
|
@ -25,7 +25,7 @@ class ConfigView (private val grid: TileGrid, theme: ColorTheme = GameConfig.TH
|
|||
.addNewLine()
|
||||
// and align it to center
|
||||
.withAlignmentWithin(screen, ComponentAlignment.TOP_CENTER)
|
||||
.build() // finally we build the component
|
||||
.build() // finally, we build the component
|
||||
|
||||
//TODO: Options: world size, character tile (smiley, @, &), character customizations (class, looks, stats, start),
|
||||
|
||||
|
@ -45,7 +45,7 @@ class ConfigView (private val grid: TileGrid, theme: ColorTheme = GameConfig.TH
|
|||
GameConfig.TILESET = CP437TilesetResources.anikki16x16()
|
||||
}
|
||||
|
||||
//Once the back button is activated go back to startView
|
||||
//Once the back button is activated, go back to startView
|
||||
backButton.onActivated {
|
||||
replaceWith(StartView(grid))
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class LoseView (private val grid: TileGrid, theme: ColorTheme = GameConfig.THEME
|
|||
replaceWith(PlayView(grid))
|
||||
}
|
||||
|
||||
//On Quit BUtton activated, exit program
|
||||
//On Quit BButton activated, exit program
|
||||
exitButton.onActivated {
|
||||
exitProcess(0)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.hexworks.zircon.api.component.ComponentAlignment
|
|||
import org.hexworks.zircon.api.grid.TileGrid
|
||||
import org.hexworks.zircon.api.view.base.BaseView
|
||||
|
||||
class PauseView(public val grid: TileGrid, theme: ColorTheme = GameConfig.THEME) : BaseView(grid, theme) {
|
||||
class PauseView(private val grid: TileGrid, theme: ColorTheme = GameConfig.THEME) : BaseView(grid, theme) {
|
||||
init {
|
||||
val msg = "Pre-Game Configuration"
|
||||
|
||||
|
@ -24,7 +24,7 @@ class PauseView(public val grid: TileGrid, theme: ColorTheme = GameConfig.THEME)
|
|||
.addNewLine()
|
||||
// and align it to center
|
||||
.withAlignmentWithin(screen, ComponentAlignment.TOP_CENTER)
|
||||
.build() // finally we build the component
|
||||
.build() // finally, we build the component
|
||||
|
||||
val backButton = Components.button()
|
||||
.withAlignmentWithin(screen, ComponentAlignment.BOTTOM_CENTER)
|
||||
|
@ -38,7 +38,7 @@ class PauseView(public val grid: TileGrid, theme: ColorTheme = GameConfig.THEME)
|
|||
.withDecorations(ComponentDecorations.box(), ComponentDecorations.shadow())
|
||||
.build()
|
||||
|
||||
//Once the back button is activated go back to startView
|
||||
//Once the back button is activated, go back to startView
|
||||
backButton.onActivated {
|
||||
replaceWith(StartView(grid))
|
||||
}
|
||||
|
|
|
@ -21,20 +21,20 @@ class PlayView (private val grid: TileGrid, private val game: Game = GameBuilder
|
|||
init {
|
||||
//Create Sidebar
|
||||
val sidebar = Components.panel()
|
||||
.withSize(Config().SIDEBAR_WIDTH, Config().WINDOW_HEIGHT - Config().LOG_AREA_HEIGHT)
|
||||
.withPreferredSize(Config().sidebarWidth, Config().windowHeight - Config().logAreaHeight)
|
||||
.withDecorations(box())
|
||||
.build()
|
||||
|
||||
//Create area for logging
|
||||
val logArea = Components.logArea()
|
||||
.withDecorations(box(title = "Log"))
|
||||
.withSize(Config().WINDOW_WIDTH, Config().LOG_AREA_HEIGHT)
|
||||
.withPreferredSize(Config().windowWidth, Config().logAreaHeight)
|
||||
.withAlignmentWithin(screen, ComponentAlignment.BOTTOM_RIGHT)
|
||||
.build()
|
||||
|
||||
//Create Game view
|
||||
val gameComponent = Components.panel()
|
||||
.withSize(game.world.visibleSize.to2DSize())
|
||||
.withPreferredSize(game.world.visibleSize.to2DSize())
|
||||
.withComponentRenderer(
|
||||
GameAreaComponentRenderer(
|
||||
gameArea = game.world,
|
||||
|
|
|
@ -27,7 +27,7 @@ class StartView (private val grid: TileGrid, theme: ColorTheme = GameConfig.THEM
|
|||
.addNewLine()
|
||||
// and align it to center
|
||||
.withAlignmentWithin(screen, ComponentAlignment.CENTER)
|
||||
.build() // finally we build the component
|
||||
.build() // finally, we build the component
|
||||
|
||||
val startButton = Components.button()
|
||||
// we align the button to the bottom center of our header
|
||||
|
@ -50,7 +50,9 @@ class StartView (private val grid: TileGrid, theme: ColorTheme = GameConfig.THEM
|
|||
.withDecorations(box(), shadow())
|
||||
.build()
|
||||
|
||||
//TODO: move this on to a configuration screen for world/player customization before PlayView, for now basic gameplay is in order though.
|
||||
//TODO: move this on to a configuration screen for world/player customization before PlayView,
|
||||
// for now basic gameplay is in order though.
|
||||
|
||||
//Once the start button is pressed, move on to the PlayView
|
||||
startButton.onActivated {
|
||||
replaceWith(PlayView(grid))
|
||||
|
|
|
@ -9,42 +9,41 @@ import org.hexworks.zircon.api.grid.TileGrid
|
|||
import org.hexworks.zircon.api.view.base.BaseView
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
// For if winning.... obviously just a test.
|
||||
class WinView (private val grid: TileGrid, theme: ColorTheme = GameConfig.THEME) : BaseView(grid, theme) {
|
||||
// For if winning… just a test.
|
||||
class WinView(private val grid: TileGrid, theme: ColorTheme = GameConfig.THEME) : BaseView(grid, theme) {
|
||||
|
||||
init {
|
||||
//Title
|
||||
// Title
|
||||
val header = Components.header()
|
||||
.withText("You won!")
|
||||
.withAlignmentWithin(screen, ComponentAlignment.CENTER)
|
||||
.build()
|
||||
|
||||
//Create Reset Button
|
||||
// Create Reset Button
|
||||
val restartButton = Components.button()
|
||||
.withAlignmentAround(header, ComponentAlignment.BOTTOM_LEFT)
|
||||
.withText("Restart")
|
||||
.withDecorations(box())
|
||||
.build()
|
||||
|
||||
|
||||
//Create Quit Button
|
||||
// Create Quit Button
|
||||
val exitButton = Components.button()
|
||||
.withAlignmentAround(header, ComponentAlignment.BOTTOM_RIGHT)
|
||||
.withText("Quit")
|
||||
.withDecorations(box())
|
||||
.build()
|
||||
|
||||
//On Reset Button activated, move back to PlayView
|
||||
// On Reset Button activated, move back to PlayView
|
||||
restartButton.onActivated {
|
||||
replaceWith(PlayView(grid))
|
||||
}
|
||||
|
||||
//On Quit Button activated, exit program
|
||||
// On Quit Button activated, exit program
|
||||
exitButton.onActivated {
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
//Bake The Cake
|
||||
// Bake The Cake
|
||||
screen.addComponents(header, restartButton, exitButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import group.ouroboros.potrogue.extensions.GameEntity
|
|||
* The TL;DR for DIP is this: By stating what we need (the World here) but not how we get it we let the outside world decide how to provide it for us.
|
||||
* This is also called “Wishful Thinking”.
|
||||
* This kind of dependency inversion lets the users of our program inject any kind of object that corresponds to the World contract.
|
||||
* For example we can create an in-memory world, one which is stored in a database or one which is generated on the fly. Game won’t care!
|
||||
* For example, we can create an in-memory world, one which is stored in a database or one which is generated on the fly. Game won’t care!
|
||||
* This is in stark contrast to what we had before: an explicit instantiation of World by using the WorldBuilder.
|
||||
*/
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@ import org.hexworks.zircon.api.data.Position3D
|
|||
import org.hexworks.zircon.api.data.Size3D
|
||||
|
||||
// Take the size of the World as a parameter
|
||||
class GameBuilder (val worldSize: Size3D) {
|
||||
class GameBuilder(val worldSize: Size3D) {
|
||||
|
||||
// We define the visible size which is our viewport of the world
|
||||
private val visibleSize = Size3D.create(
|
||||
xLength = Config().WINDOW_WIDTH - Config().SIDEBAR_WIDTH,
|
||||
yLength = Config().WINDOW_HEIGHT - Config().LOG_AREA_HEIGHT,
|
||||
xLength = Config().windowWidth - Config().sidebarWidth,
|
||||
yLength = Config().windowHeight - Config().logAreaHeight,
|
||||
zLength = 1
|
||||
)
|
||||
|
||||
|
@ -25,7 +25,6 @@ class GameBuilder (val worldSize: Size3D) {
|
|||
.build(visibleSize = visibleSize)
|
||||
|
||||
fun buildGame(): Game {
|
||||
|
||||
prepareWorld()
|
||||
|
||||
val player = addPlayer()
|
||||
|
@ -48,7 +47,7 @@ class GameBuilder (val worldSize: Size3D) {
|
|||
// We immediately add the player to the World which takes an offset and a size as a parameter
|
||||
player,
|
||||
// offset determines the position where the search for empty positions will start. Here we specify that the top level will be searched starting at (0, 0)
|
||||
offset = Position3D.create(0, 0, Config().DUNGEON_LEVELS - 1),
|
||||
offset = Position3D.create(0, 0, Config().dungeonLevels - 1),
|
||||
size = world.visibleSize.copy(zLength = 0)
|
||||
) // And we also determine that we should search only the throughout the viewport. This ensures that the player will be visible on the screen when we start the game
|
||||
return player
|
||||
|
@ -60,4 +59,4 @@ class GameBuilder (val worldSize: Size3D) {
|
|||
worldSize = WORLD_SIZE
|
||||
).buildGame()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,4 +16,4 @@ data class GameContext(
|
|||
// The object representing the player. This is optional, but because we use the player in a lot of places it makes sense to add it here
|
||||
val player: GameEntity<Player>
|
||||
|
||||
) : Context
|
||||
) : Context
|
||||
|
|
|
@ -36,7 +36,8 @@ class World (
|
|||
|
||||
init {
|
||||
startingBlocks.forEach { (pos, block) ->
|
||||
// a World takes a Map of GameBlocks, so we need to add them to the GameArea. Where these blocks come from? We’ll see soon enough wen we implement the WorldBuilder!
|
||||
// A World takes a Map of GameBlocks, so we need to add them to the GameArea.
|
||||
// Where these blocks come from? We’ll see soon enough wen we implement the WorldBuilder!
|
||||
setBlockAt(pos, block)
|
||||
block.entities.forEach { entity ->
|
||||
// Also added the Entities in the starting blocks to our engine
|
||||
|
|
Loading…
Reference in a new issue