Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ plugins {
id 'net.minecrell.licenser' version '0.4'
id 'com.github.johnrengelman.shadow' version '2.0.1'
id 'org.spongepowered.plugin' version '0.8.1'
id 'org.jetbrains.kotlin.jvm' version '1.2.61'
id 'org.jetbrains.kotlin.jvm' version '1.2.70'
}

apply from: rootProject.file('gradle/lantern.gradle')
Expand Down Expand Up @@ -76,6 +76,9 @@ dependencies {
// Kotlin
compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
compile 'org.jetbrains.kotlin:kotlin-reflect'
compile 'org.jetbrains.kotlin:kotlin-script-util'
compile 'org.jetbrains.kotlin:kotlin-script-runtime'
compile 'org.jetbrains.kotlin:kotlin-compiler-embeddable'

// Launch Options
compile 'net.sf.jopt-simple:jopt-simple:5.0.4'
Expand Down Expand Up @@ -222,6 +225,7 @@ task theJar(type: ShadowJar) {

def dependencyEntries = new ArrayList<>()
dependencyArtifacts.each { ResolvedArtifact a -> dependencyEntries.add(a.moduleVersion.id.toString()) }
dependencyEntries.sort()

def data = new HashMap<>()
data['repositories'] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.entity.Transform;
import org.spongepowered.api.event.SpongeEventFactory;
import org.spongepowered.api.event.action.LightningEvent;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.event.entity.ConstructEntityEvent;
import org.spongepowered.api.event.entity.SpawnEntityEvent;
Expand Down Expand Up @@ -76,4 +77,10 @@ public static ConstructEntityEvent.Pre createConstructEntityEventPre(
@NotNull Transform transform) {
return SpongeEventFactory.createConstructEntityEventPre(cause, targetType, transform);
}

@NotNull
public static LightningEvent.Pre createLightningEventPre(
@NotNull Cause cause) {
return SpongeEventFactory.createLightningEventPre(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ private boolean setWeather(CauseStack causeStack, Weather weather, long duration
}

@Override
public double getDarkness() {
public double getSkyDarkness() {
return this.darkness;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1014,8 +1014,8 @@ public void setWeather(Weather weather, long duration) {
}

@Override
public double getDarkness() {
return this.weatherUniverse == null ? 0 : this.weatherUniverse.getDarkness();
public double getSkyDarkness() {
return this.weatherUniverse == null ? 0 : this.weatherUniverse.getSkyDarkness();
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/org/lanternpowered/api/Lantern.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ package org.lanternpowered.api
import org.lanternpowered.api.entity.spawn.EntitySpawner
import org.lanternpowered.api.event.EventManager
import org.lanternpowered.api.plugin.PluginManager
import org.lanternpowered.api.text.translation.TranslationRegistry
import org.lanternpowered.api.x.XGameRegistry
import org.lanternpowered.api.x.XServer
import org.lanternpowered.api.x.cause.XCauseStackManager
Expand All @@ -45,4 +46,5 @@ object Lantern {
@JvmStatic inline val scheduler: Scheduler get() = Sponge.getScheduler()
@JvmStatic inline val serviceManager: ServiceManager get() = Sponge.getServiceManager()
@JvmStatic inline val entitySpawner: EntitySpawner get() = this.server.entitySpawner
@JvmStatic inline val translationRegistry: TranslationRegistry get() = this.registry.translations
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of LanternServer, licensed under the MIT License (MIT).
*
* Copyright (c) LanternPowered <https://www.lanternpowered.org>
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the Software), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.lanternpowered.api.catalog

import org.lanternpowered.api.Lantern
import org.lanternpowered.api.ext.*
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty

class CatalogTypeProperty<T : CatalogType>(
private val key: CatalogKey,
private val type: KClass<T>
) : ReadOnlyProperty<Nothing?, T> {

override fun getValue(thisRef: Nothing?, property: KProperty<*>): T = Lantern.registry.getType(this.type, this.key)
?: throw MissingCatalogTypeException("Missing catalog \"$key\" of type ${type.qualifiedName ?: type.java.name}")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* This file is part of LanternServer, licensed under the MIT License (MIT).
*
* Copyright (c) LanternPowered <https://www.lanternpowered.org>
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the Software), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.lanternpowered.api.catalog

/**
* An exception that is thrown when something a catalog type is missing.
*/
class MissingCatalogTypeException : RuntimeException {

/**
* Constructs a new [MissingCatalogTypeException].
*/
constructor() : super()

/**
* Constructs a new [MissingCatalogTypeException] with the
* given message.
*
* @param message The message
*/
constructor(message: String) : super(message)

/**
* Constructs a new [MissingCatalogTypeException] with the
* given message and underlying cause.
*
* @param message The message
* @param cause The underlying cause
*/
constructor(message: String, cause: Throwable) : super(message, cause)

/**
* Constructs a new [MissingCatalogTypeException] with the
* underlying cause.
*
* @param cause The underlying cause
*/
constructor(cause: Throwable) : super(cause)

}
7 changes: 3 additions & 4 deletions src/main/kotlin/org/lanternpowered/api/entity/Entity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
*/
package org.lanternpowered.api.entity

import org.spongepowered.api.entity.Entity
import org.spongepowered.api.entity.Transform

typealias Transform<E> = Transform<E>
typealias Entity = Entity
typealias Transform<E> = org.spongepowered.api.entity.Transform<E>
typealias Entity = org.spongepowered.api.entity.Entity
typealias EntityTypes = org.spongepowered.api.entity.EntityTypes
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.lanternpowered.api.ext.*
import org.lanternpowered.api.world.World
import org.spongepowered.api.entity.Entity
import org.spongepowered.api.entity.EntityType
import org.spongepowered.api.entity.weather.Lightning
import org.spongepowered.api.event.entity.ConstructEntityEvent
import org.spongepowered.api.event.entity.SpawnEntityEvent
import java.util.Collections
Expand Down
96 changes: 96 additions & 0 deletions src/main/kotlin/org/lanternpowered/api/entity/weather/Weather.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* This file is part of LanternServer, licensed under the MIT License (MIT).
*
* Copyright (c) LanternPowered <https://www.lanternpowered.org>
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the Software), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.lanternpowered.api.entity.weather

import com.flowpowered.math.vector.Vector3d
import org.lanternpowered.api.Lantern
import org.lanternpowered.api.cause.CauseStack
import org.lanternpowered.api.entity.EntityTypes
import org.lanternpowered.api.entity.Transform
import org.lanternpowered.api.event.LanternEventFactory
import org.lanternpowered.api.ext.*
import org.lanternpowered.api.util.AABB
import org.lanternpowered.api.world.chunk.Chunk
import org.lanternpowered.api.world.World

typealias Lightning = org.spongepowered.api.entity.weather.Lightning

object LightningSpawner {

/**
* When there are entities in this region around the lightning
* bolt, the bolt will be redirected to the entity.
*/
private val moveToEntityRegion = AABB(-1.5, -3.0, -1.5, 1.5, 256.0, 1.5)

/**
* Spawns [Lightning] randomly across all the loaded [Chunk]s in the [World].
*
* @param world The world to spawn lightning bolts in
* @param chance The chance that a lightning bolt will spawn per attempt in a chunk
* @param attemptsPerChunk The attempts to spawn a bolt per chunk
* @param moveToEntityRegion The region to check for entities around the bolt, if found, move bolt to their location
* @param locationFilter Advanced filtering whether the [Transform] is valid
*/
fun spawnLightning(
world: World,
chance: Double = 0.0000002,
attemptsPerChunk: Int = 2,
moveToEntityRegion: AABB = this.moveToEntityRegion,
locationFilter: (Transform<World>) -> Boolean = { true }
) {
val chunks = world.loadedChunks
val chanceInt = (1f / Math.max(chance, 0.000000000001)).toInt()

for (chunk in chunks) {
for (i in 0 until attemptsPerChunk) {
if (random.nextInt(chanceInt) != 0) {
continue
}

val value = random.nextInt(0x10000)
val x = chunk.x shl 4 or (value and 0xf)
val z = chunk.z shl 4 or (value shr 4 and 0xf)

var pos = Vector3d(x.toDouble(), world.getHighestYAt(x, z).toDouble(), z.toDouble())

// Look for nearby entities to see if the lightning bolt should be moved
world.getIntersectingEntities(moveToEntityRegion.offset(pos)).pickRandom()?.let {
pos = it.location.position
}

val transform = Transform(world, pos)
if (!locationFilter(transform)) continue

val lightningPreEvent = LanternEventFactory.createLightningEventPre(CauseStack.current().currentCause)
Lantern.eventManager.post(lightningPreEvent)
if (!lightningPreEvent.isCancelled) {
Lantern.entitySpawner.spawn(EntityTypes.LIGHTNING, Transform(world, pos))
}
}
}
}
}
16 changes: 16 additions & 0 deletions src/main/kotlin/org/lanternpowered/api/ext/CollectionExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,19 @@ inline fun <T> Iterable<T>.asUnmodifiable(): Iterable<T> = UnmodifiableIterable(
* Creates a unmodifiable [Iterator] view for this iterator.
*/
inline fun <T> Iterator<T>.asUnmodifiable(): Iterator<T> = UnmodifiableIterator(this)

// Random

fun <E> Collection<E>.pickRandom(): E? {
val size = this.size
if (size == 0) {
return null
}
val index = random.nextInt(size)
forEachIndexed { i, element ->
if (i == index) {
return element
}
}
throw IllegalStateException("Should never be reached")
}
4 changes: 4 additions & 0 deletions src/main/kotlin/org/lanternpowered/api/ext/TextExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@

package org.lanternpowered.api.ext

import org.lanternpowered.api.Lantern
import org.lanternpowered.api.text.Text
import org.lanternpowered.api.text.TextBuilder
import org.lanternpowered.api.text.format.TextColor
import org.lanternpowered.api.text.format.TextFormat
import org.lanternpowered.api.text.format.TextStyle
import org.lanternpowered.api.text.serializer.TextSerializers
import org.lanternpowered.api.text.translation.Translation
import org.spongepowered.api.command.CommandSource
import org.spongepowered.api.text.action.ClickAction
import org.spongepowered.api.text.action.TextActions
Expand Down Expand Up @@ -69,3 +71,5 @@ inline operator fun TextFormat.plus(that: TextColor): TextFormat = color(that)
inline operator fun TextStyle.plus(that: TextStyle): TextStyle = and(that)
inline operator fun TextStyle.minus(that: TextStyle): TextStyle = andNot(that)
inline operator fun TextStyle.unaryMinus(): TextStyle = negate()

fun translationOf(id: String): Translation = Lantern.translationRegistry[id]
2 changes: 1 addition & 1 deletion src/main/kotlin/org/lanternpowered/api/ext/WeatherExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ inline val WeatherUniverse.rainStrength: Double get() = (this as XWeatherUnivers
/**
* The current darkness of the sky.
*/
inline val WeatherUniverse.darkness: Double get() = (this as XWeatherUniverse).darkness
inline val WeatherUniverse.skyDarkness: Double get() = (this as XWeatherUniverse).skyDarkness

// We cannot call typeTokenOf here, chaining reified calls and using
// anonymous classes can end up in weird errors. But only in specific
Expand Down
5 changes: 5 additions & 0 deletions src/main/kotlin/org/lanternpowered/api/ext/WorldExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ import org.lanternpowered.api.block.entity.BlockEntity
import org.lanternpowered.api.entity.Transform
import org.lanternpowered.api.world.Location
import org.lanternpowered.api.world.World
import org.lanternpowered.api.world.chunk.Chunk
import org.lanternpowered.api.x.world.XWorld
import org.lanternpowered.api.x.world.chunk.XChunk
import org.lanternpowered.api.x.world.extent.XEntityUniverse
import org.lanternpowered.api.x.world.extent.XExtent
import org.lanternpowered.api.x.world.weather.XWeatherUniverse
Expand Down Expand Up @@ -87,3 +89,6 @@ fun Extent.hasIntersectingEntities(box: AABB)
*/
fun Extent.hasIntersectingEntities(box: AABB, filter: (Entity) -> Boolean)
= (this as XExtent).hasIntersectingEntities(box, filter)

val Chunk.x: Int get() = (this as XChunk).x
val Chunk.z: Int get() = (this as XChunk).z
Loading