Datafix: thrown potion item field; legacy scene additions for 1.13.2 to 1.15
This commit is contained in:
@@ -177,6 +177,17 @@ pub(super) fn register(out: &mut Vec<(Key, FixFn)>) {
|
||||
)
|
||||
}));
|
||||
out.push((key(2511, 0), projectile_owner));
|
||||
// `SplashPotionItemFieldRenameFix` casts the thrown potion to the type whose
|
||||
// item stack field is `Item`: the typed `Potion` value takes its place, and
|
||||
// writing the entity gives `Potion` back from the map it was read from.
|
||||
out.push((key(2511, 1), |cx| {
|
||||
cx.entity("minecraft:potion", |e| {
|
||||
if let Some(item) = e.get("Potion").cloned() {
|
||||
set(e, "Item", item);
|
||||
}
|
||||
super::drop_typed(e, "Potion");
|
||||
})
|
||||
}));
|
||||
out.push((key(2514, 0), entity_uuids));
|
||||
out.push((key(2514, 0), block_entity_uuids));
|
||||
out.push((key(2514, 0), player_uuids));
|
||||
|
||||
@@ -138,6 +138,9 @@ def experiments(version):
|
||||
def items(e, version=None):
|
||||
"""The sample stacks of an era, in the exact component formats `version` accepts."""
|
||||
stacks = ITEMS_A if e == A else ITEMS_B if e == B else ITEMS_C
|
||||
if version is not None and version < 2586: # 1.13.2 to 1.15
|
||||
import datafix_scene_old
|
||||
stacks = stacks + datafix_scene_old.items(version)
|
||||
if version is None:
|
||||
return stacks
|
||||
return [v for v in (versioned(s, version) for s in stacks) if available(v, version)]
|
||||
@@ -237,6 +240,9 @@ def block_entities(e, version):
|
||||
out = [(b, '{SpawnData:{id:"minecraft:zombie",ArmorItems:[{},{},{},{id:"minecraft:iron_helmet",Count:1b}]},'
|
||||
'SpawnPotentials:[{Weight:1,Entity:{id:"minecraft:skeleton"}}]}') if b == 'spawner' else (b, nbt)
|
||||
for b, nbt in out]
|
||||
if version < 2586:
|
||||
import datafix_scene_old
|
||||
out += datafix_scene_old.block_entities(version)
|
||||
if version >= 3682:
|
||||
out.append(('crafter', '{Items:[{Slot:0b,id:"minecraft:stone",Count:1b}],triggered:1,crafting_ticks_remaining:2}'))
|
||||
# Blocks the 1.20 experiment brought in 1.19.3 and 1.19.4.
|
||||
@@ -312,6 +318,9 @@ def entities(e, version):
|
||||
]
|
||||
since = {'allay': 3105, 'chest_boat': 3105, 'text_display': 3325, 'item_display': 3325, 'goat': 2700}
|
||||
out = [(k, x) for k, x in out if version >= since.get(k, 0)]
|
||||
if version < 2586: # 1.13.2 to 1.15: entities in the formats those versions write
|
||||
import datafix_scene_old
|
||||
out += datafix_scene_old.entities(version)
|
||||
if version < 3086: # cats before 1.19 have a numeric CatType
|
||||
out = [(k, 'CatType:1' if k == 'cat' else x) for k, x in out]
|
||||
if 3105 <= version < 3322: # darkness counts its factor from a timestamp before 1.19.4
|
||||
@@ -363,6 +372,14 @@ def entities(e, version):
|
||||
return out
|
||||
|
||||
|
||||
def blocks(version):
|
||||
"""Plain blocks whose states changed over the versions."""
|
||||
if version < 2586:
|
||||
import datafix_scene_old
|
||||
return datafix_scene_old.blocks(version)
|
||||
return []
|
||||
|
||||
|
||||
def player_commands(e, name, version=None):
|
||||
"""Give the joined bot a varied inventory and ender chest."""
|
||||
out = []
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
"""Scene additions for worlds saved by 1.13.2 to 1.16.5 (DataVersion 1631 to 2586): the entities, block
|
||||
entities and items whose save format those versions changed, in the syntax and format of the version
|
||||
that writes them (numeric UUIDMost/UUIDLeast, string owner UUIDs, Profession/Career villagers, ...).
|
||||
|
||||
Every entry is (minimum DataVersion, maximum DataVersion exclusive, value); datafix_scene.py adds the
|
||||
ones valid for the world's version to its general scene.
|
||||
"""
|
||||
|
||||
U1 = '11111111-2222-3333-4444-555555555555'
|
||||
U2 = '66666666-7777-8888-9999-aaaaaaaaaaaa'
|
||||
MODIFIERS = ('[{Name:"horse.jumpStrength",Base:0.7d},{Name:"generic.maxHealth",Base:20.0d,'
|
||||
'Modifiers:[{Name:"m",Amount:1.0d,Operation:0,UUIDMost:5L,UUIDLeast:6L}]}]')
|
||||
TRADES = ('{buy:{id:"minecraft:wheat",Count:20b},sell:{id:"minecraft:emerald",Count:1b},maxUses:16,uses:1,rewardExp:1b},'
|
||||
'{buy:{id:"minecraft:paper",Count:24b},sell:{id:"minecraft:emerald",Count:1b},maxUses:16,uses:0},'
|
||||
'{buy:{id:"minecraft:book",Count:4b},sell:{id:"minecraft:emerald",Count:1b},maxUses:12,uses:0},'
|
||||
'{buy:{id:"minecraft:ink_sac",Count:5b},sell:{id:"minecraft:emerald",Count:1b},maxUses:12,uses:0}')
|
||||
|
||||
# (since, until, entity, fields)
|
||||
ENTITIES = [
|
||||
# 1.13.2: professions are numbers
|
||||
(1631, 1900, 'villager', 'Profession:1,Career:2,CareerLevel:2,Offers:{Recipes:[%s]},Inventory:[{id:"minecraft:bread",Count:3b}]' % TRADES),
|
||||
(1631, 1900, 'villager', 'Profession:3,Career:3,CareerLevel:1'),
|
||||
(1631, 1900, 'zombie_villager', 'Profession:4,Career:2'),
|
||||
(1631, 1900, 'ocelot', 'CatType:2,OwnerUUID:"%s"' % U1),
|
||||
(1631, 1900, 'ocelot', 'CatType:0'),
|
||||
(1631, 1900, 'ocelot', 'CatType:0,OwnerUUID:"%s"' % U2),
|
||||
# 1.14: VillagerData and Xp; some without them
|
||||
(1900, 2100, 'villager', 'VillagerData:{profession:"minecraft:farmer",level:1,type:"minecraft:plains"},'
|
||||
'Offers:{Recipes:[%s]},Gossips:[{Type:"golem",Value:5},{Type:"major_positive",Value:2}]' % TRADES),
|
||||
(1900, 2100, 'villager', 'VillagerData:{profession:"minecraft:armorer",level:3,type:"minecraft:desert"},Xp:70'),
|
||||
(1900, 2100, 'zombie_villager', 'VillagerData:{profession:"minecraft:cleric",level:2,type:"minecraft:plains"}'),
|
||||
(1900, 2100, 'cat', 'CatType:9'),
|
||||
(1900, 2100, 'cat', 'CatType:3,CollarColor:5b'),
|
||||
(1900, 2100, 'pillager', 'Inventory:[{id:"minecraft:arrow",Count:2b}]'),
|
||||
(1900, 2100, 'fox', 'Type:"red",TrustedUUIDs:[{M:3L,L:4L}]'),
|
||||
(1631, 2586, 'wolf', 'Owner:"%s",OwnerUUID:"%s",CollarColor:3b,Health:15.0f' % ('Steve', U1)),
|
||||
(1631, 2586, 'horse', 'Tame:1b,OwnerUUID:"%s",SaddleItem:{id:"minecraft:saddle",Count:1b},'
|
||||
'ArmorItem:{id:"minecraft:iron_horse_armor",Count:1b},Attributes:%s' % (U2, MODIFIERS)),
|
||||
(1631, 2586, 'armor_stand', 'Attributes:%s' % MODIFIERS),
|
||||
(1631, 2586, 'cow', 'Leash:{UUIDMost:7L,UUIDLeast:8L}'),
|
||||
(1631, 2586, 'zombie_pigman', 'Anger:100s,HurtBy:"%s"' % U1),
|
||||
(1631, 2586, 'item', 'Item:{id:"minecraft:diamond",Count:3b},Owner:{M:9L,L:10L},Thrower:{M:11L,L:12L}'),
|
||||
(1631, 2586, 'area_effect_cloud', 'OwnerUUIDMost:13L,OwnerUUIDLeast:14L,Particle:"entity_effect",Radius:2.0f,Duration:600'),
|
||||
(1631, 2586, 'arrow', 'OwnerUUIDMost:15L,OwnerUUIDLeast:16L,inGround:1b'),
|
||||
(1631, 2586, 'trident', 'OwnerUUIDMost:17L,OwnerUUIDLeast:18L,Trident:{id:"minecraft:trident",Count:1b}'),
|
||||
(1631, 2586, 'potion', 'Potion:{id:"minecraft:splash_potion",Count:1b,tag:{Potion:"minecraft:swiftness"}},owner:{M:19L,L:20L}'),
|
||||
(1631, 2586, 'snowball', 'owner:{M:21L,L:22L}'),
|
||||
(1631, 2586, 'egg', 'owner:{M:23L,L:24L}'),
|
||||
(1631, 2586, 'ender_pearl', 'owner:{M:25L,L:26L}'),
|
||||
(1631, 2586, 'experience_bottle', 'owner:{M:27L,L:28L}'),
|
||||
(1631, 2586, 'llama_spit', 'Owner:{OwnerUUIDMost:29L,OwnerUUIDLeast:30L}'),
|
||||
(1631, 2586, 'shulker_bullet', 'Owner:{M:31L,L:32L},Target:{M:33L,L:34L}'),
|
||||
(1631, 2586, 'evoker_fangs', 'OwnerUUIDMost:35L,OwnerUUIDLeast:36L'),
|
||||
(1631, 2586, 'shulker', 'Rotation:[40.0f,0.0f],Peek:0b'),
|
||||
(1631, 2586, 'bat', ''),
|
||||
(2100, 2586, 'bee', 'HurtBy:"%s",HasNectar:1b,Anger:50' % U1),
|
||||
(2100, 2586, 'villager', 'VillagerData:{profession:"minecraft:farmer",level:2,type:"minecraft:plains"},Xp:20,'
|
||||
'Brain:{memories:{"minecraft:job_site":{pos:[I;1,2,3],dimension:"minecraft:overworld"}}}'),
|
||||
(2500, 2586, 'piglin', 'IsBaby:0b,Brain:{memories:{"minecraft:angry_at":"%s"}}' % U1),
|
||||
(2500, 2586, 'strider', 'NoGravity:1b,Saddle:1b'),
|
||||
(2500, 2586, 'zombified_piglin', 'HurtBy:"%s",Anger:60' % U2),
|
||||
(2500, 2586, 'hoglin', 'IsImmuneToZombification:1b'),
|
||||
]
|
||||
|
||||
# (since, until, block, nbt)
|
||||
BLOCK_ENTITIES = [
|
||||
(1631, 2586, 'white_banner', '{CustomName:\'{"translate":"block.minecraft.illager_banner","color":"gold"}\','
|
||||
'Patterns:[{Pattern:"cre",Color:15}]}'),
|
||||
(1631, 2586, 'chest', '{LootTable:"minecraft:chests/village_blacksmith"}'),
|
||||
(1631, 2586, 'furnace', '{BurnTime:100s,CookTime:20s,CookTimeTotal:200s,RecipesUsedSize:2,RecipeLocation0:"minecraft:iron_ingot",'
|
||||
'RecipeAmount0:3,RecipeLocation1:"minecraft:glass",RecipeAmount1:1}'),
|
||||
(1631, 2586, 'blast_furnace', '{RecipesUsedSize:1,RecipeLocation0:"minecraft:iron_ingot",RecipeAmount0:2}') if False else None,
|
||||
(1631, 2586, 'player_head', '{Owner:{Id:"%s",Name:"Notch"}}' % U1),
|
||||
(1631, 2586, 'conduit', '{target_uuid:{M:5L,L:6L},Target:{M:5L,L:6L}}'),
|
||||
(1631, 2586, 'oak_sign', '{Text1:\'{"text":"one"}\',Text2:\'{"text":"two"}\'}'),
|
||||
(1900, 2586, 'jigsaw[facing=up]', '{attachement_type:"minecraft:bottom",target_pool:"minecraft:village/plains/houses",'
|
||||
'final_state:"minecraft:air"}'),
|
||||
(1900, 2586, 'jigsaw[facing=east]', '{attachement_type:"minecraft:empty",target_pool:"minecraft:empty"}'),
|
||||
(1900, 2586, 'lectern', '{Book:{id:"minecraft:written_book",Count:1b,tag:{title:"L",author:"A",pages:[\'"x"\']}},Page:0}'),
|
||||
(2100, 2586, 'beehive', '{Bees:[{EntityData:{id:"minecraft:bee"},TicksInHive:3,MinOccupationTicks:600}]}'),
|
||||
]
|
||||
BLOCK_ENTITIES = [b for b in BLOCK_ENTITIES if b]
|
||||
|
||||
# Plain blocks whose states changed: (since, until, command tail after "setblock x y z")
|
||||
BLOCKS = [
|
||||
(1900, 2500, 'cobblestone_wall[east=true,west=false,north=true,south=false]'),
|
||||
(1900, 2500, 'andesite_wall[east=true,west=true,north=false,south=false,up=true]'),
|
||||
(1631, 2500, 'redstone_wire[east=none,west=none,north=none,south=none,power=0]'),
|
||||
(1631, 2500, 'redstone_wire[east=up,west=none,north=none,south=none,power=3]'),
|
||||
(1631, 2500, 'redstone_wire[east=none,west=none,north=side,south=none,power=1]'),
|
||||
(1631, 2500, 'oak_sign[rotation=3]'),
|
||||
(1631, 1900, 'stone_slab[type=bottom]'),
|
||||
(1631, 2100, 'bee_nest') if False else None,
|
||||
]
|
||||
BLOCKS = [b for b in BLOCKS if b]
|
||||
|
||||
ITEMS = [
|
||||
(1631, 2586, '{id:"minecraft:white_banner",Count:1b,tag:{display:{Name:\'{"translate":"block.minecraft.illager_banner","color":"gold"}\','
|
||||
'Lore:[\'first\',\'{"text":"second"}\']},BlockEntityTag:{Patterns:[{Pattern:"cre",Color:15}]}}}'),
|
||||
(1631, 2586, '{id:"minecraft:player_head",Count:1b,tag:{SkullOwner:{Id:"%s",Name:"Notch"}}}' % U2),
|
||||
(1631, 2586, '{id:"minecraft:diamond_sword",Count:1b,tag:{AttributeModifiers:[{AttributeName:"generic.attackDamage",Name:"x",Amount:2.5d,'
|
||||
'Operation:0,UUIDMost:41L,UUIDLeast:42L,Slot:"mainhand"}]}}'),
|
||||
(1631, 2586, '{id:"minecraft:filled_map",Count:1b,tag:{map:0}}'),
|
||||
(1631, 2586, '{id:"minecraft:cactus_green",Count:1b}') if False else None,
|
||||
(1631, 2586, '{id:"minecraft:stone_slab",Count:2b}') if False else None,
|
||||
]
|
||||
ITEMS = [i for i in ITEMS if i]
|
||||
|
||||
|
||||
def entities(version):
|
||||
return [(kind, fields) for since, until, kind, fields in ENTITIES if since <= version < until]
|
||||
|
||||
|
||||
def block_entities(version):
|
||||
return [(block, nbt) for since, until, block, nbt in BLOCK_ENTITIES if since <= version < until]
|
||||
|
||||
|
||||
def blocks(version):
|
||||
return [block for since, until, block in BLOCKS if since <= version < until]
|
||||
|
||||
|
||||
def items(version):
|
||||
return [stack for since, until, stack in ITEMS if since <= version < until]
|
||||
+10
-1
@@ -348,6 +348,13 @@ def uuid_nbt(i):
|
||||
return f'[I;{UUID_BASE},0,0,{i}]'
|
||||
|
||||
|
||||
def uuid_fields(data_version, i):
|
||||
"""The UUID of a summoned entity: an int array since 1.16, two longs before."""
|
||||
if data_version >= 2514:
|
||||
return f'UUID:{uuid_nbt(i)}'
|
||||
return f'UUIDMost:{UUID_BASE << 32}L,UUIDLeast:{i + 1}L'
|
||||
|
||||
|
||||
def build(version, force=False):
|
||||
jar, data_version, protocol = server_jar(version)
|
||||
target = SHARED / 'worlds' / version
|
||||
@@ -376,8 +383,10 @@ def build(version, force=False):
|
||||
run(f'setblock {x} 100 {z} minecraft:{block}{nbt}')
|
||||
for i, (kind, extra) in enumerate(scene.entities(era, data_version)):
|
||||
x, z = 1.5 + 3 * (i % 15), 25.5 + 3 * (i // 15)
|
||||
fields = f'UUID:{uuid_nbt(i)},NoAI:1b,Silent:1b,NoGravity:1b,Invulnerable:1b,PersistenceRequired:1b'
|
||||
fields = f'{uuid_fields(data_version, i)},NoAI:1b,Silent:1b,NoGravity:1b,Invulnerable:1b,PersistenceRequired:1b'
|
||||
run(f'summon minecraft:{kind} {x} 100 {z} {{{fields}' + (',' + extra if extra else '') + '}')
|
||||
for i, block in enumerate(scene.blocks(data_version)):
|
||||
run(f'setblock {1 + 3 * (i % 15)} 100 {19 + 3 * (i // 15)} minecraft:{block}')
|
||||
run('setworldspawn 20 101 20')
|
||||
bot = Bot(port, protocol, BOT)
|
||||
time.sleep(3)
|
||||
|
||||
Reference in New Issue
Block a user