A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/AlmasB/FXGL/commit/83ea661f8 below:

refine Quest API · AlmasB/FXGL@83ea661 · GitHub

7 7

package com.almasb.fxgl.quest

8 8 9 9

import com.almasb.fxgl.core.collection.PropertyMap

10 +

import com.almasb.fxgl.logging.Logger

10 11

import javafx.beans.binding.Bindings

11 12

import javafx.beans.property.*

13 +

import javafx.collections.FXCollections

14 +

import javafx.collections.ObservableList

12 15

import javafx.util.Duration

13 16

import java.util.concurrent.Callable

14 17 15 18

/**

16 -

* TODO: allow adding / removing objectives after construction.

17 -

*

18 19

* A single quest.

19 -

* A quest can have multiple objectives but at least 1.

20 +

* A quest can have multiple objectives but to start, it needs at least 1.

20 21

* A quest is always in one of four states [QuestState].

22 +

* Valid transitions:

23 +

* NOT_STARTED -> ACTIVE

24 +

* ACTIVE -> COMPLETED

25 +

* ACTIVE -> FAILED

26 +

* FAILED -> ACTIVE

21 27

*

22 28

* @author Almas Baimagambetov (almaslvl@gmail.com)

23 29

*/

24 -

class Quest(val name: String,

25 -

val objectives: List<QuestObjective>) {

30 +

class Quest(val name: String) {

31 + 32 +

private val log = Logger.get(javaClass)

33 + 34 +

private val objectives = FXCollections.observableArrayList<QuestObjective>()

35 +

private val objectivesReadOnly = FXCollections.unmodifiableObservableList(objectives)

36 + 37 +

/**

38 +

* @return read-only copy of the quest's objectives

39 +

*/

40 +

fun objectivesProperty(): ObservableList<QuestObjective> = objectivesReadOnly

26 41 27 42

private val stateProp = ReadOnlyObjectWrapper(QuestState.NOT_STARTED)

28 43

@@ -31,12 +46,52 @@ class Quest(val name: String,

31 46 32 47

fun stateProperty(): ReadOnlyObjectProperty<QuestState> = stateProp.readOnlyProperty

33 48 34 -

// TODO: check transitions between states

49 +

/**

50 +

* @return true if any of the states apart from NOT_STARTED

51 +

*/

52 +

val hasStarted: Boolean

53 +

get() = state != QuestState.NOT_STARTED

54 + 55 +

@JvmOverloads fun addIntObjective(desc: String, varName: String, varValue: Int, duration: Duration = Duration.ZERO): QuestObjective {

56 +

return IntQuestObjective(desc, varName, varValue, duration).also { addObjective(it) }

57 +

}

58 + 59 +

@JvmOverloads fun addBooleanObjective(desc: String, varName: String, varValue: Boolean, duration: Duration = Duration.ZERO): QuestObjective {

60 +

return BooleanQuestObjective(desc, varName, varValue, duration).also { addObjective(it) }

61 +

}

62 + 63 +

private fun addObjective(objective: QuestObjective) {

64 +

objectives += objective

65 + 66 +

if (hasStarted)

67 +

rebindStateToObjectives()

68 +

}

69 + 70 +

fun removeObjective(objective: QuestObjective) {

71 +

objectives -= objective

72 + 73 +

if (hasStarted)

74 +

rebindStateToObjectives()

75 +

}

76 + 77 +

/**

78 +

* Can only be called from NOT_STARTED state.

79 +

*/

35 80

internal fun start() {

36 -

stateProp.value = QuestState.ACTIVE

81 +

if (objectives.isEmpty()) {

82 +

log.warning("Cannot start quest $name because it has no objectives")

83 +

return

84 +

}

85 + 86 +

if (hasStarted) {

87 +

log.warning("Cannot start quest $name because it has already been started")

88 +

return

89 +

}

37 90 38 -

require(objectives.isNotEmpty()) { "Quest must have at least 1 objective" }

91 +

rebindStateToObjectives()

92 +

}

39 93 94 +

private fun rebindStateToObjectives() {

40 95

val failedBinding = objectives.map { it.stateProperty() }

41 96

.foldRight(Bindings.createBooleanBinding(Callable { false })) { state, binding ->

42 97

state.isEqualTo(QuestState.FAILED).or(binding)

@@ -57,7 +112,10 @@ class Quest(val name: String,

57 112

/**

58 113

* A single quest objective.

59 114

*

60 -

* TODO: allow user to manually fail an objective.

115 +

* Valid transitions:

116 +

* ACTIVE -> COMPLETED

117 +

* ACTIVE -> FAILED

118 +

* FAILED -> ACTIVE

61 119

*/

62 120

sealed class QuestObjective

63 121

@JvmOverloads

@@ -68,13 +126,14 @@ constructor(

68 126

*/

69 127

val description: String,

70 128 129 +

// TODO:

71 130

/**

72 131

* How much time is given to complete this objective.

73 132

* Default: 0 - unlimited.

74 133

*/

75 134

val expireDuration: Duration = Duration.ZERO) {

76 135 77 -

private val stateProp = ReadOnlyObjectWrapper(QuestState.NOT_STARTED)

136 +

private val stateProp = ReadOnlyObjectWrapper(QuestState.ACTIVE)

78 137 79 138

val state: QuestState

80 139

get() = stateProp.get()

@@ -94,6 +153,39 @@ constructor(

94 153

successProp.addListener(successListener)

95 154

}

96 155 156 +

fun complete() {

157 +

if (state != QuestState.ACTIVE) {

158 +

return

159 +

}

160 + 161 +

unbind()

162 +

successProp.value = true

163 +

}

164 + 165 +

fun fail() {

166 +

if (state != QuestState.ACTIVE) {

167 +

return

168 +

}

169 + 170 +

unbind()

171 +

successProp.value = false

172 +

clean()

173 +

stateProp.value = QuestState.FAILED

174 +

}

175 + 176 +

/**

177 +

* Transition from FAILED -> ACTIVE.

178 +

*/

179 +

fun reactivate(vars: PropertyMap) {

180 +

if (state != QuestState.FAILED) {

181 +

return

182 +

}

183 + 184 +

stateProp.value = QuestState.ACTIVE

185 +

successProp.addListener(successListener)

186 +

bindTo(vars)

187 +

}

188 + 97 189

abstract fun bindTo(vars: PropertyMap)

98 190 99 191

internal fun unbind() {

@@ -102,27 +194,10 @@ constructor(

102 194 103 195

private fun clean() {

104 196

successProp.removeListener(successListener)

105 -

//failBinding?.expire()

106 197

}

107 - 108 -

// TODO:

109 -

// private fun setState(state: QuestState) {

110 -

// require(state != QuestState.ACTIVE) { "Quest objective cannot be reactivated!" }

111 -

//

112 -

// clean()

113 -

// this.state.set(state)

114 -

// }

115 -

//

116 -

// private var failBinding: com.almasb.fxgl.time.TimerAction? = null

117 -

//

118 -

// init {

119 -

// if (expireDuration !== Duration.ZERO) {

120 -

// //failBinding = FXGL.getMasterTimer().runOnceAfter({ setState(QuestState.FAILED) }, expireDuration)

121 -

// }

122 -

// }

123 198

}

124 199 125 -

class IntQuestObjective

200 +

private class IntQuestObjective

126 201

@JvmOverloads constructor(

127 202

/**

128 203

* Text that tells the player how to achieve this objective.

@@ -155,7 +230,7 @@ class IntQuestObjective

155 230

}

156 231

}

157 232 158 -

class BooleanQuestObjective

233 +

private class BooleanQuestObjective

159 234

@JvmOverloads constructor(

160 235

/**

161 236

* Text that tells the player how to achieve this objective.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4