A RetroSearch Logo

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

Search Query:

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

completed implementation of QuestService, closes #848 · AlmasB/FXGL@a9c8e04 · GitHub

6 6 7 7

package com.almasb.fxgl.quest

8 8 9 +

import com.almasb.fxgl.core.Updatable

9 10

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

10 11

import com.almasb.fxgl.logging.Logger

11 12

import javafx.beans.binding.Bindings

@@ -27,10 +28,19 @@ import java.util.concurrent.Callable

27 28

*

28 29

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

29 30

*/

30 -

class Quest(val name: String) {

31 +

class Quest

32 +

@JvmOverloads constructor(name: String, val vars: PropertyMap = PropertyMap()) : Updatable {

31 33 32 34

private val log = Logger.get(javaClass)

33 35 36 +

private val nameProp = SimpleStringProperty(name)

37 + 38 +

var name: String

39 +

get() = nameProp.value

40 +

set(value) { nameProp.value = value }

41 + 42 +

fun nameProperty() = nameProp

43 + 34 44

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

35 45

private val objectivesReadOnly = FXCollections.unmodifiableObservableList(objectives)

36 46

@@ -49,49 +59,66 @@ class Quest(val name: String) {

49 59

/**

50 60

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

51 61

*/

52 -

val hasStarted: Boolean

62 +

val isStarted: Boolean

53 63

get() = state != QuestState.NOT_STARTED

54 64 55 65

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

56 -

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

66 +

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

57 67

}

58 68 59 69

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

60 -

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

70 +

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

61 71

}

62 72 63 73

private fun addObjective(objective: QuestObjective) {

64 74

objectives += objective

65 75 66 -

if (hasStarted)

76 +

if (isStarted)

67 77

rebindStateToObjectives()

68 78

}

69 79 70 80

fun removeObjective(objective: QuestObjective) {

71 81

objectives -= objective

72 82 73 -

if (hasStarted)

83 +

if (isStarted)

74 84

rebindStateToObjectives()

75 85

}

76 86 77 87

/**

78 88

* Can only be called from NOT_STARTED state.

89 +

* Binds quest state to the combined state of its objectives.

79 90

*/

80 91

internal fun start() {

81 92

if (objectives.isEmpty()) {

82 93

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

83 94

return

84 95

}

85 96 86 -

if (hasStarted) {

97 +

if (isStarted) {

87 98

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

88 99

return

89 100

}

90 101 91 102

rebindStateToObjectives()

92 103

}

93 104 105 +

override fun onUpdate(tpf: Double) {

106 +

objectives.forEach { it.onUpdate(tpf) }

107 +

}

108 + 109 +

/**

110 +

* Sets the state to NOT_STARTED and unbinds objectives from the variables they are tracking.

111 +

*/

112 +

internal fun stop() {

113 +

stateProp.unbind()

114 +

stateProp.value = QuestState.NOT_STARTED

115 + 116 +

objectives.forEach { it.unbindFromVars() }

117 +

}

118 + 94 119

private fun rebindStateToObjectives() {

120 +

objectives.forEach { it.bindToVars() }

121 + 95 122

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

96 123

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

97 124

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

@@ -126,11 +153,16 @@ constructor(

126 153

*/

127 154

val description: String,

128 155 156 +

/**

157 +

* Variables map, from which to check whether the objective is complete.

158 +

*/

159 +

protected val vars: PropertyMap,

160 + 129 161

/**

130 162

* How much time is given to complete this objective.

131 163

* Default: 0 - unlimited.

132 164

*/

133 -

val expireDuration: Duration = Duration.ZERO) {

165 +

val expireDuration: Duration = Duration.ZERO) : Updatable {

134 166 135 167

private val stateProp = ReadOnlyObjectWrapper(QuestState.ACTIVE)

136 168

@@ -139,6 +171,17 @@ constructor(

139 171 140 172

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

141 173 174 +

private val timeRemainingProp = ReadOnlyDoubleWrapper(expireDuration.toSeconds())

175 + 176 +

/**

177 +

* @return time remaining (in seconds) to complete this objective,

178 +

* returns 0.0 if unlimited

179 +

*/

180 +

val timeRemaining: Double

181 +

get() = timeRemainingProp.value

182 + 183 +

fun timeRemainingProperty(): ReadOnlyDoubleProperty = timeRemainingProp.readOnlyProperty

184 + 142 185

protected val successProp = ReadOnlyBooleanWrapper()

143 186 144 187

private val successListener = javafx.beans.value.ChangeListener<Boolean> { _, _, isReached ->

@@ -152,12 +195,30 @@ constructor(

152 195

successProp.addListener(successListener)

153 196

}

154 197 198 +

override fun onUpdate(tpf: Double) {

199 +

if (state != QuestState.ACTIVE)

200 +

return

201 + 202 +

// ignore if no duration is set

203 +

if (expireDuration.lessThanOrEqualTo(Duration.ZERO))

204 +

return

205 + 206 +

val remaining = timeRemaining - tpf

207 + 208 +

if (remaining <= 0) {

209 +

timeRemainingProp.value = 0.0

210 +

fail()

211 +

} else {

212 +

timeRemainingProp.value = remaining

213 +

}

214 +

}

215 + 155 216

fun complete() {

156 217

if (state != QuestState.ACTIVE) {

157 218

return

158 219

}

159 220 160 -

unbind()

221 +

unbindFromVars()

161 222

successProp.value = true

162 223

}

163 224

@@ -166,7 +227,7 @@ constructor(

166 227

return

167 228

}

168 229 169 -

unbind()

230 +

unbindFromVars()

170 231

successProp.value = false

171 232

clean()

172 233

stateProp.value = QuestState.FAILED

@@ -175,19 +236,24 @@ constructor(

175 236

/**

176 237

* Transition from FAILED -> ACTIVE.

177 238

*/

178 -

fun reactivate(vars: PropertyMap) {

239 +

fun reactivate() {

179 240

if (state != QuestState.FAILED) {

180 241

return

181 242

}

182 243 183 244

stateProp.value = QuestState.ACTIVE

245 +

timeRemainingProp.value = expireDuration.toSeconds()

184 246

successProp.addListener(successListener)

185 -

bindTo(vars)

247 +

bindToVars()

186 248

}

187 249 188 -

abstract fun bindTo(vars: PropertyMap)

250 +

/**

251 +

* Bind the state to variables, so that the state

252 +

* is updated as variables change.

253 +

*/

254 +

internal abstract fun bindToVars()

189 255 190 -

internal fun unbind() {

256 +

internal fun unbindFromVars() {

191 257

successProp.unbind()

192 258

}

193 259

@@ -203,6 +269,8 @@ private class IntQuestObjective

203 269

*/

204 270

description: String,

205 271 272 +

vars: PropertyMap,

273 + 206 274

/**

207 275

* Variable name of an int property from the world properties to track.

208 276

*/

@@ -220,9 +288,9 @@ private class IntQuestObjective

220 288

*/

221 289

expireDuration: Duration = Duration.ZERO

222 290 223 -

) : QuestObjective(description, expireDuration) {

291 +

) : QuestObjective(description, vars, expireDuration) {

224 292 225 -

override fun bindTo(vars: PropertyMap) {

293 +

override fun bindToVars() {

226 294

successProp.bind(

227 295

vars.intProperty(varName).greaterThanOrEqualTo(varValue)

228 296

)

@@ -236,6 +304,8 @@ private class BooleanQuestObjective

236 304

*/

237 305

description: String,

238 306 307 +

vars: PropertyMap,

308 + 239 309

/**

240 310

* Variable name of a boolean property from the world properties to track.

241 311

*/

@@ -252,9 +322,9 @@ private class BooleanQuestObjective

252 322

*/

253 323

expireDuration: Duration = Duration.ZERO

254 324 255 -

) : QuestObjective(description, expireDuration) {

325 +

) : QuestObjective(description, vars, expireDuration) {

256 326 257 -

override fun bindTo(vars: PropertyMap) {

327 +

override fun bindToVars() {

258 328

successProp.bind(

259 329

vars.booleanProperty(varName).isEqualTo(SimpleBooleanProperty(varValue))

260 330

)


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