mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-17 14:04:05 +09:00
Greek support, modular weather, command history for console window
Former-commit-id: b72d0b018c084e80cf4fef77e1b1a81101d6daea Former-commit-id: 32da6a2998826de6519a901dcff7bf058f689b2f
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import net.torvald.terrarum.gameitem.InventoryItem
|
||||
*/
|
||||
interface CanBeAnItem {
|
||||
|
||||
fun attachItemData()
|
||||
|
||||
fun getItemWeight(): Double
|
||||
|
||||
fun stopUpdateAndDraw()
|
||||
|
||||
@@ -19,7 +19,7 @@ class FixturesTikiTorch : FixturesBase(), Luminous {
|
||||
|
||||
init {
|
||||
isVisible = true
|
||||
super.setDensity(1200)
|
||||
density = 1200.0
|
||||
|
||||
setHitboxDimension(10, 24, 0, 0)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user