Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 0e1ba4c

Browse files
committed
Add LootTableLoadEvent, methods on LootPool/LootTable
The mixin to LootManager is messy, and I'm open to alternative ways to doing it, even if it involves scrapping the 'forge way' of doing it and doing it a different way. For now, I'm going to get this up so that bikeshedding can happen. I'm using the "net.patchworkmc.api.*.Forge<classname>" pattern for interfaces that describe public methods added by Forge for use by mods in this commit. This is up for bikeshedding. This is untested other than starting up Minecraft and opening a world.
1 parent ab71e1b commit 0e1ba4c

File tree

14 files changed

+772
-1
lines changed

14 files changed

+772
-1
lines changed

patchwork-loot/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
archivesBaseName = "patchwork-loot"
22
version = getSubprojectVersion(project, "0.1.0")
3+
4+
dependencies {
5+
compile project(path: ':patchwork-fml', configuration: 'dev')
6+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.event;
21+
22+
import net.minecraftforge.eventbus.api.Event;
23+
24+
import net.minecraft.loot.LootManager;
25+
import net.minecraft.loot.LootTable;
26+
import net.minecraft.util.Identifier;
27+
28+
/**
29+
* Event fired when a LootTable json is loaded from json.
30+
* This event is fired whenever resources are loaded, or when the server starts.
31+
* This event will NOT be fired for LootTables loaded from the world folder, these are
32+
* considered configurations files and should not be modified by mods.
33+
*
34+
* <p>Canceling the event will make it load a empty loot table.</p>
35+
*/
36+
public class LootTableLoadEvent extends Event {
37+
private final Identifier name;
38+
private LootTable table;
39+
private LootManager lootTableManager;
40+
41+
public LootTableLoadEvent(Identifier name, LootTable table, LootManager lootTableManager) {
42+
this.name = name;
43+
this.table = table;
44+
this.lootTableManager = lootTableManager;
45+
}
46+
47+
public Identifier getName() {
48+
return this.name;
49+
}
50+
51+
public LootTable getTable() {
52+
return this.table;
53+
}
54+
55+
public void setTable(LootTable table) {
56+
this.table = table;
57+
}
58+
59+
public LootManager getLootTableManager() {
60+
return this.lootTableManager;
61+
}
62+
63+
@Override
64+
public boolean isCancelable() {
65+
return true;
66+
}
67+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.api.loot;
21+
22+
import net.minecraft.loot.LootPool;
23+
import net.minecraft.loot.LootTableRange;
24+
import net.minecraft.loot.UniformLootTableRange;
25+
26+
/**
27+
* Interface for adding Forge methods added to LootPool and its inner classes.
28+
*/
29+
public interface ForgeLootPool {
30+
// TODO: doesn't include methods having to do with freezing yet
31+
32+
String getName();
33+
LootTableRange getRolls();
34+
LootTableRange getBonusRolls();
35+
void setRolls(UniformLootTableRange v);
36+
void setBonusRolls(UniformLootTableRange v);
37+
38+
public interface Builder {
39+
LootPool.Builder name(String name);
40+
LootPool.Builder bonusRolls(float min, float max);
41+
}
42+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.api.loot;
21+
22+
import net.minecraft.loot.LootPool;
23+
24+
/**
25+
* Interface for adding Forge methods added to LootTable.
26+
*/
27+
public interface ForgeLootTable {
28+
// TODO: doesn't include methods having to do with freezing yet
29+
30+
LootPool getPool(String name);
31+
LootPool removePool(String name);
32+
void addPool(LootPool pool);
33+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.impl.event.loot;
21+
22+
import net.minecraftforge.event.LootTableLoadEvent;
23+
import net.minecraftforge.common.MinecraftForge;
24+
25+
import net.minecraft.loot.LootManager;
26+
import net.minecraft.loot.LootTable;
27+
import net.minecraft.util.Identifier;
28+
29+
public class LootEvents {
30+
public static LootTable loadLootTable(Identifier name, LootTable table, LootManager manager) {
31+
LootTableLoadEvent event = new LootTableLoadEvent(name, table, manager);
32+
33+
if (MinecraftForge.EVENT_BUS.post(event)) {
34+
return LootTable.EMPTY;
35+
}
36+
37+
return event.getTable();
38+
}
39+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.impl.loot;
21+
22+
import java.util.Deque;
23+
import java.util.HashSet;
24+
25+
import javax.annotation.Nullable;
26+
27+
import com.google.common.collect.Queues;
28+
import com.google.common.collect.Sets;
29+
import com.google.gson.Gson;
30+
import com.google.gson.JsonElement;
31+
import com.google.gson.JsonObject;
32+
import com.google.gson.JsonParseException;
33+
import org.spongepowered.asm.mixin.Unique;
34+
35+
import net.minecraft.loot.LootManager;
36+
import net.minecraft.loot.LootTable;
37+
import net.minecraft.util.Identifier;
38+
import net.minecraft.util.JsonHelper;
39+
40+
import net.patchworkmc.impl.event.loot.LootEvents;
41+
42+
public class LootHooks {
43+
@Unique
44+
private static ThreadLocal<Deque<LootTableContext>> lootContext = new ThreadLocal<Deque<LootTableContext>>();
45+
46+
public static LootTable loadLootTable(Gson gson, Identifier name, JsonElement data, boolean custom, LootManager lootTableManager) {
47+
Deque<LootTableContext> que = lootContext.get();
48+
49+
if (que == null) {
50+
que = Queues.newArrayDeque();
51+
lootContext.set(que);
52+
}
53+
54+
LootTable ret = null;
55+
56+
try {
57+
que.push(new LootTableContext(name, custom));
58+
ret = gson.fromJson(data, LootTable.class);
59+
que.pop();
60+
} catch (JsonParseException e) {
61+
que.pop();
62+
throw e;
63+
}
64+
65+
if (!custom) {
66+
ret = LootEvents.loadLootTable(name, ret, lootTableManager);
67+
}
68+
69+
// if (ret != null) {
70+
// ret.freeze();
71+
// }
72+
73+
return ret;
74+
}
75+
76+
private static LootTableContext getLootTableContext() {
77+
LootTableContext ctx = lootContext.get().peek();
78+
79+
if (ctx == null) {
80+
throw new JsonParseException("Invalid call stack, could not grab json context!"); // Should I throw this? Do we care about custom deserializers outside the manager?
81+
}
82+
83+
return ctx;
84+
}
85+
86+
public static String readPoolName(JsonObject json) {
87+
LootTableContext ctx = LootHooks.getLootTableContext();
88+
ctx.resetPoolCtx();
89+
90+
if (json.has("name")) {
91+
return JsonHelper.getString(json, "name");
92+
}
93+
94+
if (ctx.custom) {
95+
return "custom#" + json.hashCode(); //We don't care about custom ones modders shouldn't be editing them!
96+
}
97+
98+
ctx.poolCount++;
99+
100+
if (!ctx.vanilla) {
101+
throw new JsonParseException("Loot Table \"" + ctx.name.toString() + "\" Missing `name` entry for pool #" + (ctx.poolCount - 1));
102+
}
103+
104+
return ctx.poolCount == 1 ? "main" : "pool" + (ctx.poolCount - 1);
105+
}
106+
107+
private static class LootTableContext {
108+
public final Identifier name;
109+
public final boolean custom;
110+
private final boolean vanilla;
111+
public int poolCount = 0;
112+
public int entryCount = 0;
113+
private HashSet<String> entryNames = Sets.newHashSet();
114+
115+
private LootTableContext(Identifier name, boolean custom) {
116+
this.name = name;
117+
this.custom = custom;
118+
this.vanilla = "minecraft".equals(this.name.getNamespace());
119+
}
120+
121+
private void resetPoolCtx() {
122+
this.entryCount = 0;
123+
this.entryNames.clear();
124+
}
125+
126+
public String validateEntryName(@Nullable String name) {
127+
if (name != null && !this.entryNames.contains(name)) {
128+
this.entryNames.add(name);
129+
return name;
130+
}
131+
132+
if (!this.vanilla) {
133+
throw new JsonParseException("Loot Table \"" + this.name.toString() + "\" Duplicate entry name \"" + name + "\" for pool #" + (this.poolCount - 1) + " entry #" + (this.entryCount - 1));
134+
}
135+
136+
int x = 0;
137+
138+
while (this.entryNames.contains(name + "#" + x)) {
139+
x++;
140+
}
141+
142+
name = name + "#" + x;
143+
this.entryNames.add(name);
144+
145+
return name;
146+
}
147+
}
148+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.impl.loot;
21+
22+
/**
23+
* Forge does this through patching the constructor, we just add methods with
24+
* mixins instead.
25+
*/
26+
public interface PatchworkLootPool {
27+
void patchwork$setName(String name);
28+
}

0 commit comments

Comments
 (0)