Greek support, modular weather, command history for console window

Former-commit-id: b72d0b018c084e80cf4fef77e1b1a81101d6daea
Former-commit-id: 32da6a2998826de6519a901dcff7bf058f689b2f
This commit is contained in:
Song Minjae
2016-07-13 21:48:14 +09:00
parent c52015e429
commit 1d1f99605c
74 changed files with 1067 additions and 387 deletions

View File

@@ -6,5 +6,5 @@ import net.torvald.terrarum.gameactors.ai.ActorAI
* Created by minjaesong on 16-03-14.
*/
interface AIControlled {
fun attachAI(ai: ActorAI)
var actorAI: ActorAI
}

View File

@@ -1,6 +1,8 @@
package net.torvald.terrarum.gameactors
/**
* See [res/raw/Creature_raw_doc.md] for information about raw.
*
* Created by minjaesong on 16-04-02.
*/
object AVKey {

View File

@@ -1,7 +1,7 @@
package net.torvald.terrarum.gameactors
import net.torvald.terrarum.*
import net.torvald.terrarum.gamemap.GameMap
import net.torvald.terrarum.gamemap.GameWorld
import net.torvald.terrarum.mapdrawer.MapDrawer
import net.torvald.terrarum.tileproperties.TilePropCodex
import net.torvald.spriteanimation.SpriteAnimation
@@ -24,7 +24,7 @@ open class ActorWithBody : Actor(), Visible {
@Transient var sprite: SpriteAnimation? = null
@Transient var spriteGlow: SpriteAnimation? = null
@Transient private val map: GameMap = Terrarum.ingame.map
@Transient private val world: GameWorld = Terrarum.ingame.world
var hitboxTranslateX: Double = 0.0// relative to spritePosX
var hitboxTranslateY: Double = 0.0// relative to spritePosY
@@ -103,7 +103,13 @@ open class ActorWithBody : Actor(), Visible {
set(value) { elasticity = 1.0 - value }
get() = 1.0 - elasticity
private var density = 1000.0
var density = 1000.0
set(value) {
if (value < 0)
throw IllegalArgumentException("[ActorWithBody] $value: density cannot be negative.")
field = value
}
/**
* Flags and Properties
@@ -145,7 +151,7 @@ open class ActorWithBody : Actor(), Visible {
* s^2 = 1/FPS = 1/60 if FPS is targeted to 60
* meter to pixel : 24/FPS
*/
@Transient private val gravitation: Vector2 = map.gravitation
@Transient private val gravitation: Vector2 = world.gravitation
@Transient val DRAG_COEFF_DEFAULT = 1.2
/** Drag coefficient. Parachutes have much higher value than bare body (1.2) */
private var DRAG_COEFF: Double
@@ -361,9 +367,15 @@ open class ActorWithBody : Actor(), Visible {
}
}
/**
* FIXME the culprit!
* (5566 -> no colliiding but player does not "sink")
* (5567 -> colliding)
* How to fix:
*/
private fun applyNormalForce() {
if (!isNoCollideWorld) {
// axis Y
// axis Y. Use operand >=
if (moveDelta.y >= 0.0) { // was moving downward?
if (isTouchingSide(nextHitbox, COLLIDING_BOTTOM)) { // actor hit something on its bottom
hitAndReflectY()
@@ -493,14 +505,14 @@ open class ActorWithBody : Actor(), Visible {
}
}
val txStart = x1.div(TSIZE).roundInt()
val txEnd = x2.div(TSIZE).roundInt()
val tyStart = y1.div(TSIZE).roundInt()
val tyEnd = y2.div(TSIZE).roundInt()
val txStart = x1.div(TSIZE).floorInt()
val txEnd = x2.div(TSIZE).floorInt()
val tyStart = y1.div(TSIZE).floorInt()
val tyEnd = y2.div(TSIZE).floorInt()
for (y in tyStart..tyEnd) {
for (x in txStart..txEnd) {
val tile = map.getTileFromTerrain(x, y)
val tile = world.getTileFromTerrain(x, y)
if (TilePropCodex.getProp(tile).isSolid)
return true
}
@@ -537,14 +549,14 @@ open class ActorWithBody : Actor(), Visible {
}
else throw IllegalArgumentException()
val txStart = x1.div(TSIZE).roundInt()
val txEnd = x2.div(TSIZE).roundInt()
val tyStart = y1.div(TSIZE).roundInt()
val tyEnd = y2.div(TSIZE).roundInt()
val txStart = x1.plus(1.0).div(TSIZE).floorInt()
val txEnd = x2.plus(1.0).div(TSIZE).floorInt()
val tyStart = y1.plus(1.0).div(TSIZE).floorInt()
val tyEnd = y2.plus(1.0).div(TSIZE).floorInt()
for (y in tyStart..tyEnd) {
for (x in txStart..txEnd) {
val tile = map.getTileFromTerrain(x, y)
val tile = world.getTileFromTerrain(x, y)
if (TilePropCodex.getProp(tile).isSolid)
return true
}
@@ -589,7 +601,7 @@ open class ActorWithBody : Actor(), Visible {
for (y in tyStart..tyEnd) {
for (x in txStart..txEnd) {
val tile = map.getTileFromTerrain(x, y)
val tile = world.getTileFromTerrain(x, y)
if (TilePropCodex.getProp(tile).isSolid)
return true
}
@@ -629,7 +641,7 @@ open class ActorWithBody : Actor(), Visible {
}
// evaluate
if (TilePropCodex.getProp(map.getTileFromTerrain(tileX, tileY)).isFluid) {
if (TilePropCodex.getProp(world.getTileFromTerrain(tileX, tileY)).isFluid) {
contactAreaCounter += 1
}
}
@@ -727,7 +739,7 @@ open class ActorWithBody : Actor(), Visible {
val tilePosXEnd = (hitbox.hitboxEnd.x / TSIZE).roundInt()
val tilePosY = (hitbox.pointedY.plus(1) / TSIZE).roundInt()
for (x in tilePosXStart..tilePosXEnd) {
val tile = map.getTileFromTerrain(x, tilePosY)
val tile = world.getTileFromTerrain(x, tilePosY)
val thisFriction = TilePropCodex.getProp(tile).friction
if (thisFriction > friction) friction = thisFriction
@@ -751,7 +763,7 @@ open class ActorWithBody : Actor(), Visible {
val tilePosYEnd = (hitbox.hitboxEnd.y / TSIZE).roundInt()
for (y in tilePosXStart..tilePosYEnd) {
for (x in tilePosXStart..tilePosXEnd) {
val tile = map.getTileFromTerrain(x, y)
val tile = world.getTileFromTerrain(x, y)
val prop = TilePropCodex.getProp(tile)
if (prop.isFluid && prop.density > density)
@@ -776,7 +788,7 @@ open class ActorWithBody : Actor(), Visible {
val tilePosYEnd = (nextHitbox.hitboxEnd.y / TSIZE).roundInt()
for (y in tilePosYStart..tilePosYEnd) {
for (x in tilePosXStart..tilePosXEnd) {
val tile = map.getTileFromTerrain(x, y)
val tile = world.getTileFromTerrain(x, y)
val thisFluidDensity = TilePropCodex.getProp(tile).density
if (thisFluidDensity > density) density = thisFluidDensity
@@ -849,8 +861,8 @@ open class ActorWithBody : Actor(), Visible {
private fun clampW(x: Double): Double =
if (x < TSIZE + nextHitbox.width / 2) {
TSIZE + nextHitbox.width / 2
} else if (x >= (map.width * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.width / 2) {
(map.width * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.width / 2
} else if (x >= (world.width * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.width / 2) {
(world.width * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.width / 2
} else {
x
}
@@ -858,40 +870,22 @@ open class ActorWithBody : Actor(), Visible {
private fun clampH(y: Double): Double =
if (y < TSIZE + nextHitbox.height) {
TSIZE + nextHitbox.height
} else if (y >= (map.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) {
(map.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height
} else if (y >= (world.height * TSIZE).toDouble() - TSIZE.toDouble() - nextHitbox.height) {
(world.height * TSIZE).toDouble() - 1.0 - TSIZE.toDouble() - nextHitbox.height
} else {
y
}
private fun clampWtile(x: Int): Int =
if (x < 0) {
0
} else if (x >= map.width) {
map.width - 1
} else {
x
}
if (x < 0) 0 else if (x >= world.width) world.width - 1 else x
private fun clampHtile(x: Int): Int =
if (x < 0) {
0
} else if (x >= map.height) {
map.height - 1
} else {
x
}
if (x < 0) 0 else if (x >= world.height) world.height - 1 else x
private val isPlayerNoClip: Boolean
get() = this is Player && this.isNoClip()
fun setDensity(density: Int) {
if (density < 0)
throw IllegalArgumentException("[ActorWithBody] $density: density cannot be negative.")
this.density = density.toDouble()
}
private val AUTO_CLIMB_RATE: Int
get() = Math.min(TSIZE / 8 * Math.sqrt(scale), TSIZE.toDouble()).toInt()
@@ -907,6 +901,17 @@ open class ActorWithBody : Actor(), Visible {
if (this > 0 && this > limit) limit
else if (this < 0 && this < -limit) -limit
else this
fun Double.floorSpecial(): Int {
val threshold = 1.1 / TSIZE.toDouble()
// the idea is 321.0625 would rounded to 321, 320.9375 would rounded to 321,
// and regular flooring for otherwise.
if (this % TSIZE.toDouble() <= threshold) // case: 321.0625
return this.floorInt()
else if (1.0 - this.mod(TSIZE.toDouble()) <= threshold) // case: 320.9375
return this.floorInt() + 1
else
return this.floorInt()
}
private fun assertInit() {
// errors
@@ -929,8 +934,8 @@ open class ActorWithBody : Actor(), Visible {
private fun div16TruncateToMapWidth(x: Int): Int {
if (x < 0)
return 0
else if (x >= Terrarum.ingame.map.width shl 4)
return Terrarum.ingame.map.width - 1
else if (x >= Terrarum.ingame.world.width shl 4)
return Terrarum.ingame.world.width - 1
else
return x and 0x7FFFFFFF shr 4
}
@@ -938,8 +943,8 @@ open class ActorWithBody : Actor(), Visible {
private fun div16TruncateToMapHeight(y: Int): Int {
if (y < 0)
return 0
else if (y >= Terrarum.ingame.map.height shl 4)
return Terrarum.ingame.map.height - 1
else if (y >= Terrarum.ingame.world.height shl 4)
return Terrarum.ingame.world.height - 1
else
return y and 0x7FFFFFFF shr 4
}

View File

@@ -7,8 +7,6 @@ import net.torvald.terrarum.gameitem.InventoryItem
*/
interface CanBeAnItem {
fun attachItemData()
fun getItemWeight(): Double
fun stopUpdateAndDraw()

View File

@@ -19,7 +19,7 @@ class FixturesTikiTorch : FixturesBase(), Luminous {
init {
isVisible = true
super.setDensity(1200)
density = 1200.0
setHitboxDimension(10, 24, 0, 0)

View File

@@ -11,9 +11,9 @@ interface LandHolder {
* Absolute tile index. index(x, y) = y * map.width + x
* The arraylist will be saved in JSON format with GSON.
*/
var houseDesignation: ArrayList<Int>?
fun addHouseTile(x: Int, y: Int);
fun removeHouseTile(x: Int, y: Int);
fun clearHouseDesignation();
var houseDesignation: ArrayList<Long>?
fun addHouseTile(x: Int, y: Int)
fun removeHouseTile(x: Int, y: Int)
fun clearHouseDesignation()
}

View File

@@ -1,10 +1,9 @@
package net.torvald.terrarum.gameactors
import net.torvald.random.HQRNG
import net.torvald.terrarum.gameactors.ai.ActorAI
import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.terrarum.gameitem.InventoryItem
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.realestate.RealEstateUtility.getAbsoluteTileNumber
import org.newdawn.slick.GameContainer
import java.util.*
@@ -14,19 +13,27 @@ import java.util.*
open class NPCIntelligentBase : ActorWithBody()
, AIControlled, Pocketed, CanBeAnItem, Factionable, LandHolder {
override var actorAI: ActorAI = object : ActorAI {
// TODO fully establish ActorAI so that I can implement AI here
}
override var inventory: ActorInventory = ActorInventory()
override var faction: HashSet<Faction> = HashSet()
override var houseDesignation: ArrayList<Long>? = null
// we're having InventoryItem data so that this class could be somewhat universal
override var itemData: InventoryItem = object : InventoryItem {
override var itemID = HQRNG().nextInt()
override var itemID = referenceID
override var mass: Double
get() = actorValue.getAsDouble("mass")!!
get() = actorValue.getAsDouble(AVKey.BASEMASS)!!
set(value) {
actorValue.set("mass", value)
actorValue[AVKey.BASEMASS] = value
}
override var scale: Double
get() = actorValue.getAsDouble("scale")!!
get() = actorValue.getAsDouble(AVKey.SCALE)!!
set(value) {
actorValue.set("scale", value)
actorValue[AVKey.SCALE] = value
}
override fun effectWhileInPocket(gc: GameContainer, delta_t: Int) {
@@ -38,52 +45,32 @@ open class NPCIntelligentBase : ActorWithBody()
}
override fun primaryUse(gc: GameContainer, delta_t: Int) {
// TODO do not allow primary_use
}
override fun secondaryUse(gc: GameContainer, delta_t: Int) {
// TODO place this Actor to the world
}
override fun effectWhenThrownAway(gc: GameContainer, delta_t: Int) {
override fun effectWhenThrown(gc: GameContainer, delta_t: Int) {
}
}
@Transient private var ai: ActorAI? = null
override var inventory: ActorInventory = ActorInventory()
private val factionSet = HashSet<Faction>()
override var referenceID: Int = HQRNG().nextInt()
override var faction: HashSet<Faction> = HashSet()
override var houseDesignation: ArrayList<Int>? = null
/**
* Absolute tile index. index(x, y) = y * map.width + x
* The arraylist will be saved in JSON format with GSON.
*/
private var houseTiles = ArrayList<Int>()
override fun attachItemData() {
}
override fun getItemWeight(): Double {
return mass
}
override fun addHouseTile(x: Int, y: Int) {
houseTiles.add(Terrarum.ingame.map.width * y + x)
if (houseDesignation != null) houseDesignation!!.add(getAbsoluteTileNumber(x, y))
}
override fun removeHouseTile(x: Int, y: Int) {
houseTiles.remove(Terrarum.ingame.map.width * y + x)
if (houseDesignation != null) houseDesignation!!.remove(getAbsoluteTileNumber(x, y))
}
override fun clearHouseDesignation() {
houseTiles.clear()
if (houseDesignation != null) houseDesignation!!.clear()
}
override fun stopUpdateAndDraw() {
@@ -96,7 +83,5 @@ open class NPCIntelligentBase : ActorWithBody()
isVisible = true
}
override fun attachAI(ai: ActorAI) {
this.ai = ai
}
}

View File

@@ -15,7 +15,8 @@ class PhysTestBall : ActorWithBody() {
init {
setHitboxDimension(16, 16, 0, 0)
isVisible = true
actorValue[AVKey.BASEMASS] = 10.0
mass = 10.0
density = 200.0
color = RoguelikeRandomiser.composeColourFrom(RoguelikeRandomiser.POTION_PRIMARY_COLSET)
}

View File

@@ -56,7 +56,7 @@ class Player : ActorWithBody(), Controllable, Pocketed, Factionable, Luminous, L
@Transient private val TSIZE = MapDrawer.TILE_SIZE
@Transient private val BASE_DENSITY = 1020
@Transient private val BASE_DENSITY = 980.0
/** Must be set by PlayerFactory */
override var inventory: ActorInventory = ActorInventory()
@@ -64,7 +64,7 @@ class Player : ActorWithBody(), Controllable, Pocketed, Factionable, Luminous, L
/** Must be set by PlayerFactory */
override var faction: HashSet<Faction> = HashSet()
override var houseDesignation: ArrayList<Int>? = null
override var houseDesignation: ArrayList<Long>? = null
override var luminosity: Int
get() = actorValue.getAsInt(AVKey.LUMINOSITY) ?: 0
@@ -92,7 +92,7 @@ class Player : ActorWithBody(), Controllable, Pocketed, Factionable, Luminous, L
init {
isVisible = true
referenceID = PLAYER_REF_ID // forcibly set ID
super.setDensity(BASE_DENSITY)
density = BASE_DENSITY
collisionType = KINEMATIC
}