11import { system } from '@minecraft/server'
2- import { MinecraftBlockTypes } from '@minecraft/vanilla-data'
2+ import { MinecraftBlockTypes , MinecraftEntityTypes } from '@minecraft/vanilla-data'
33import {
44 actionGuard ,
55 ActionGuardOrder ,
@@ -13,20 +13,21 @@ import {
1313 registerSaveableRegion ,
1414 Vec ,
1515} from 'lib'
16+ import { form } from 'lib/form/new'
1617import { i18n , noI18n } from 'lib/i18n/text'
1718import { anyPlayerNearRegion } from 'lib/player-move'
18- import { ScheduleBlockPlace } from 'lib/scheduled-block-place '
19+ import { rollChance } from 'lib/rpg/random '
1920import { createLogger } from 'lib/utils/logger'
21+ import { BaseItem } from '../base/base'
2022
21- // TODO Add chest generation
2223const logger = createLogger ( 'warden' )
2324
2425class WardenDungeonRegion extends Region {
2526 protected priority = 3
2627
2728 protected defaultPermissions : RegionPermissions = {
2829 allowedAllItem : true ,
29- allowedEntities : PVP_ENTITIES ,
30+ allowedEntities : [ ... PVP_ENTITIES , MinecraftEntityTypes . Warden ] ,
3031
3132 doors : true ,
3233 gates : true ,
@@ -46,6 +47,8 @@ registerSaveableRegion('wardenDungeon', WardenDungeonRegion)
4647registerRegionType ( noI18n `Данж вардена` , WardenDungeonRegion )
4748
4849interface LinkedDatabase extends JsonObject {
50+ selected : boolean
51+ cleaned : boolean
4952 blocks : { x : number ; y : number ; z : number } [ ]
5053}
5154
@@ -54,7 +57,7 @@ class WardenDungeonLootRegion extends Region {
5457 get displayName ( ) : Text | undefined {
5558 return i18n . nocolor `§dНезеритовая жила`
5659 }
57- ldb : LinkedDatabase = { blocks : [ ] }
60+ ldb : LinkedDatabase = { selected : false , blocks : [ ] , cleaned : false }
5861
5962 protected defaultPermissions : RegionPermissions = {
6063 allowedAllItem : true ,
@@ -93,41 +96,100 @@ actionGuard((player, region, ctx) => {
9396
9497system . runInterval (
9598 ( ) => {
96- const regions = WardenDungeonLootRegion . getAll ( )
99+ let regions = WardenDungeonLootRegion . getAll ( )
97100 if ( ! regions . length ) return
98101
99102 const dungeonRegions = WardenDungeonRegion . getAll ( )
100103 if ( ! dungeonRegions [ 0 ] || ! anyPlayerNearRegion ( dungeonRegions [ 0 ] , 20 ) ) return
101104
102- const placedBefore = regions . find ( e => ! ! e . ldb . blocks . length )
105+ regions . forEach ( e => ( ( e . ldb . selected = false ) , ( e . ldb . cleaned = false ) , e . save ( ) ) )
103106
104- if ( placedBefore ) {
105- for ( const location of placedBefore . ldb . blocks ) {
106- if ( ! ScheduleBlockPlace . deleteAt ( location , placedBefore . dimensionType ) )
107- ScheduleBlockPlace . setAir ( location , placedBefore . dimensionType , 0 )
108- }
109- placedBefore . ldb . blocks = [ ]
110- placedBefore . save ( )
111- }
107+ const percent = 50
108+ const amount = Math . floor ( regions . length * ( percent / 100 ) )
112109
113- const newRegion = regions . randomElement ( )
114- newRegion . area . forEachVector ( ( location , isIn ) => {
115- if ( ! isIn ) return
116- if ( Vec . distance ( location , newRegion . area . center ) > newRegion . area . radius ) return
117- if ( Math . randomInt ( 1 , 6 ) === 1 ) return
118- const below = newRegion . dimension . getBlock ( Vec . add ( location , Vec . down ) )
119- if ( ! below || below . isAir ) return
120-
121- ScheduleBlockPlace . set ( {
122- restoreTime : 0 ,
123- dimension : newRegion . dimensionType ,
124- typeId : MinecraftBlockTypes . AncientDebris ,
125- location,
126- } )
127- newRegion . ldb . blocks . push ( location )
128- newRegion . save ( )
129- } , 1000 )
110+ const selectedRegions : WardenDungeonLootRegion [ ] = [ ]
111+ while ( selectedRegions . length <= amount ) {
112+ const newRegion = regions . randomElement ( )
113+ regions = regions . filter ( e => e !== newRegion )
114+ newRegion . ldb . selected = true
115+ console . log ( 'Debris select' , Vec . string ( newRegion . area . center , false ) )
116+ selectedRegions . push ( newRegion )
117+ }
130118 } ,
131119 'wardenDungeonUpdateLoot' ,
132120 fromMsToTicks ( ms . from ( 'min' , 1 ) ) ,
133121)
122+
123+ system . runInterval (
124+ ( ) => {
125+ const regions = WardenDungeonLootRegion . getAll ( ) . slice ( )
126+ if ( ! regions . length ) return
127+
128+ const dungeonRegions = WardenDungeonRegion . getAll ( )
129+ if ( ! dungeonRegions [ 0 ] || ! anyPlayerNearRegion ( dungeonRegions [ 0 ] , 20 ) ) return
130+
131+ for ( const region of regions ) {
132+ if ( ! anyPlayerNearRegion ( region , 10 ) ) continue
133+
134+ if ( ! region . ldb . cleaned ) {
135+ region . ldb . cleaned = true
136+ for ( const location of region . ldb . blocks ) {
137+ const block = region . dimension . getBlock ( location )
138+ const container = block ?. getComponent ( 'inventory' ) ?. container
139+ if ( container ) container . clearAll ( )
140+ block ?. setType ( MinecraftBlockTypes . Air )
141+ }
142+ region . ldb . blocks = [ ]
143+ region . save ( )
144+ }
145+
146+ if ( ! region . ldb . selected || region . ldb . blocks . length ) continue
147+
148+ let chest = false
149+ region . area . forEachVector ( ( location , isIn ) => {
150+ if ( ! isIn ) return
151+ if ( Vec . distance ( location , region . area . center ) > region . area . radius ) return
152+
153+ const below = region . dimension . getBlock ( Vec . add ( location , Vec . down ) )
154+ if ( ! below || below . isAir ) return
155+
156+ let chance = 50
157+ if ( below . typeId === MinecraftBlockTypes . AncientDebris ) chance -= 20
158+ else if ( below . typeId === MinecraftBlockTypes . Chest ) chance = 100
159+
160+ if ( ! chest && rollChance ( 10 ) ) {
161+ chest = true
162+ const block = region . dimension . getBlock ( location )
163+ block ?. setType ( MinecraftBlockTypes . Chest )
164+ const container = block ?. getComponent ( 'inventory' ) ?. container
165+ if ( container ) container . setItem ( 15 , BaseItem . blueprint )
166+ } else {
167+ if ( chance !== 100 && ! rollChance ( chance ) ) return
168+ region . dimension . setBlockType ( location , MinecraftBlockTypes . AncientDebris )
169+ }
170+ region . ldb . blocks . push ( location )
171+ region . save ( )
172+ } , 1000 )
173+ }
174+ } ,
175+ 'wardenDungeonUpdateLoot' ,
176+ fromMsToTicks ( ms . from ( 'sec' , 3 ) ) ,
177+ )
178+
179+ const cmd = new Command ( 'warden' ) . setPermissions ( 'techAdmin' ) . executes ( ctx => {
180+ ctx . player . teleport ( WardenDungeonRegion . getAll ( ) [ 0 ] ?. area . center ?? ctx . player . location )
181+ ctx . reply ( 'Tp to location' )
182+ } )
183+
184+ const lootForm = form ( ( f , { player } ) => {
185+ f . title ( 'loot' )
186+ for ( const region of WardenDungeonLootRegion . getAll ( ) . sort ( ( a , b ) =>
187+ a . ldb . selected && b . ldb . selected ? 0 : a . ldb . selected && ! b . ldb . selected ? 1 : - 1 ,
188+ ) ) {
189+ f . button ( ( region . ldb . selected ? '§aA!§r ' : '' ) + region . area . toString ( ) , ( ) => {
190+ player . teleport ( region . area . center )
191+ } )
192+ }
193+ } )
194+
195+ cmd . overload ( 'loot' ) . executes ( lootForm . command )
0 commit comments