Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
63b6b805
Commit
63b6b805
authored
Jun 21, 2022
by
GanyusLeftHorn
Committed by
Melledy
Jun 21, 2022
Browse files
Bring back dungeon drops.
parent
b01a29c1
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/Grasscutter.java
View file @
63b6b805
...
...
@@ -8,6 +8,7 @@ import emu.grasscutter.auth.DefaultAuthentication;
import
emu.grasscutter.command.CommandMap
;
import
emu.grasscutter.command.DefaultPermissionHandler
;
import
emu.grasscutter.command.PermissionHandler
;
import
emu.grasscutter.game.dungeons.challenge.DungeonChallenge
;
import
emu.grasscutter.game.managers.energy.EnergyManager
;
import
emu.grasscutter.game.managers.stamina.StaminaManager
;
import
emu.grasscutter.plugin.PluginManager
;
...
...
@@ -113,6 +114,7 @@ public final class Grasscutter {
ResourceLoader
.
loadAll
();
ScriptLoader
.
init
();
EnergyManager
.
initialize
();
DungeonChallenge
.
initialize
();
// Initialize database.
DatabaseManager
.
initialize
();
...
...
src/main/java/emu/grasscutter/game/dungeons/DungeonDrop.java
0 → 100644
View file @
63b6b805
package
emu.grasscutter.game.dungeons
;
import
java.util.List
;
public
class
DungeonDrop
{
private
int
dungeonId
;
private
List
<
DungeonDropEntry
>
drops
;
public
int
getDungeonId
()
{
return
dungeonId
;
}
public
void
setDungeonId
(
int
dungeonId
)
{
this
.
dungeonId
=
dungeonId
;
}
public
List
<
DungeonDropEntry
>
getDrops
()
{
return
drops
;
}
public
void
setDrops
(
List
<
DungeonDropEntry
>
drops
)
{
this
.
drops
=
drops
;
}
}
src/main/java/emu/grasscutter/game/dungeons/DungeonDropEntry.java
0 → 100644
View file @
63b6b805
package
emu.grasscutter.game.dungeons
;
import
java.util.List
;
public
class
DungeonDropEntry
{
private
List
<
Integer
>
counts
;
private
List
<
Integer
>
items
;
private
List
<
Integer
>
probabilities
;
private
List
<
Integer
>
itemProbabilities
;
private
boolean
mpDouble
;
public
List
<
Integer
>
getCounts
()
{
return
counts
;
}
public
void
setCounts
(
List
<
Integer
>
counts
)
{
this
.
counts
=
counts
;
}
public
List
<
Integer
>
getItems
()
{
return
items
;
}
public
void
setItems
(
List
<
Integer
>
items
)
{
this
.
items
=
items
;
}
public
List
<
Integer
>
getProbabilities
()
{
return
probabilities
;
}
public
void
setProbabilities
(
List
<
Integer
>
probabilities
)
{
this
.
probabilities
=
probabilities
;
}
public
List
<
Integer
>
getItemProbabilities
()
{
return
itemProbabilities
;
}
public
void
setItemProbabilities
(
List
<
Integer
>
itemProbabilities
)
{
this
.
itemProbabilities
=
itemProbabilities
;
}
public
boolean
isMpDouble
()
{
return
mpDouble
;
}
public
void
setMpDouble
(
boolean
mpDouble
)
{
this
.
mpDouble
=
mpDouble
;
}
}
src/main/java/emu/grasscutter/game/dungeons/challenge/DungeonChallenge.java
View file @
63b6b805
package
emu.grasscutter.game.dungeons.challenge
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.DataLoader
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.data.excels.DungeonData
;
import
emu.grasscutter.game.dungeons.DungeonDrop
;
import
emu.grasscutter.game.dungeons.DungeonDropEntry
;
import
emu.grasscutter.game.dungeons.challenge.trigger.ChallengeTrigger
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.inventory.ItemType
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.scripts.constants.EventType
;
import
emu.grasscutter.scripts.data.SceneGroup
;
import
emu.grasscutter.scripts.data.ScriptArgs
;
import
emu.grasscutter.server.packet.send.PacketGadgetAutoPickDropInfoNotify
;
import
emu.grasscutter.utils.Utils
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
import
java.io.InputStreamReader
;
import
java.io.Reader
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
import
com.google.gson.reflect.TypeToken
;
public
class
DungeonChallenge
extends
WorldChallenge
{
...
...
@@ -25,6 +41,24 @@ public class DungeonChallenge extends WorldChallenge {
private
boolean
stage
;
private
IntSet
rewardedPlayers
;
private
final
static
Int2ObjectMap
<
List
<
DungeonDropEntry
>>
dungeonDropData
=
new
Int2ObjectOpenHashMap
<>();
public
static
void
initialize
()
{
// Read the data we need for dungeon rewards drops.
try
(
Reader
fileReader
=
new
InputStreamReader
(
DataLoader
.
load
(
"DungeonDrop.json"
)))
{
List
<
DungeonDrop
>
dungeonDropList
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
DungeonDrop
.
class
).
getType
());
for
(
DungeonDrop
entry
:
dungeonDropList
)
{
dungeonDropData
.
put
(
entry
.
getDungeonId
(),
entry
.
getDrops
());
}
Grasscutter
.
getLogger
().
info
(
"Loaded {} dungeon drop data entries."
,
dungeonDropData
.
size
());
}
catch
(
Exception
ex
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load dungeon drop data."
,
ex
);
}
}
public
DungeonChallenge
(
Scene
scene
,
SceneGroup
group
,
int
challengeId
,
int
challengeIndex
,
List
<
Integer
>
paramList
,
...
...
@@ -67,8 +101,64 @@ public class DungeonChallenge extends WorldChallenge {
}
}
public
void
getStatueDrops
(
Player
player
)
{
private
List
<
GameItem
>
rollRewards
(
boolean
useCondensed
)
{
List
<
GameItem
>
rewards
=
new
ArrayList
<>();
int
dungeonId
=
this
.
getScene
().
getDungeonData
().
getId
();
// If we have specific drop data for this dungeon, we use it.
if
(
dungeonDropData
.
containsKey
(
dungeonId
))
{
List
<
DungeonDropEntry
>
dropEntries
=
dungeonDropData
.
get
(
dungeonId
);
// Roll for each drop group.
for
(
var
entry
:
dropEntries
)
{
// Determine the number of drops we get for this entry.
int
start
=
entry
.
getCounts
().
get
(
0
);
int
end
=
entry
.
getCounts
().
get
(
entry
.
getCounts
().
size
()
-
1
);
var
candidateAmounts
=
IntStream
.
range
(
start
,
end
+
1
).
boxed
().
collect
(
Collectors
.
toList
());
int
amount
=
Utils
.
drawRandomListElement
(
candidateAmounts
,
entry
.
getProbabilities
());
if
(
useCondensed
)
{
amount
+=
Utils
.
drawRandomListElement
(
candidateAmounts
,
entry
.
getProbabilities
());
}
// Double rewards in multiplay mode, if specified.
if
(
entry
.
isMpDouble
()
&&
this
.
getScene
().
getPlayerCount
()
>
1
)
{
amount
*=
2
;
}
// Roll items for this group.
// Here, we have to handle stacking, or the client will not display results correctly.
// For now, we use the following logic: If the possible drop item are a list of multiple items,
// we roll them separately. If not, we stack them. This should work out in practice, at least
// for the currently existing set of dungeons.
if
(
entry
.
getItems
().
size
()
==
1
)
{
rewards
.
add
(
new
GameItem
(
entry
.
getItems
().
get
(
0
),
amount
));
}
else
{
for
(
int
i
=
0
;
i
<
amount
;
i
++)
{
// int itemIndex = ThreadLocalRandom.current().nextInt(0, entry.getItems().size());
// int itemId = entry.getItems().get(itemIndex);
int
itemId
=
Utils
.
drawRandomListElement
(
entry
.
getItems
(),
entry
.
getItemProbabilities
());
rewards
.
add
(
new
GameItem
(
itemId
,
1
));
}
}
}
}
// Otherwise, we fall back to the preview data.
else
{
Grasscutter
.
getLogger
().
info
(
"No drop data found or dungeon {}, falling back to preview data ..."
,
dungeonId
);
for
(
ItemParamData
param
:
getScene
().
getDungeonData
().
getRewardPreview
().
getPreviewItems
())
{
rewards
.
add
(
new
GameItem
(
param
.
getId
(),
Math
.
max
(
param
.
getCount
(),
1
)));
}
}
return
rewards
;
}
public
void
getStatueDrops
(
Player
player
,
GadgetInteractReq
request
)
{
DungeonData
dungeonData
=
getScene
().
getDungeonData
();
int
resinCost
=
dungeonData
.
getStatueCostCount
()
!=
0
?
dungeonData
.
getStatueCostCount
()
:
20
;
if
(!
isSuccess
()
||
dungeonData
==
null
||
dungeonData
.
getRewardPreview
()
==
null
||
dungeonData
.
getRewardPreview
().
getPreviewItems
().
length
==
0
)
{
return
;
}
...
...
@@ -78,11 +168,42 @@ public class DungeonChallenge extends WorldChallenge {
return
;
}
// Get rewards.
List
<
GameItem
>
rewards
=
new
ArrayList
<>();
for
(
ItemParamData
param
:
getScene
().
getDungeonData
().
getRewardPreview
().
getPreviewItems
())
{
rewards
.
add
(
new
GameItem
(
param
.
getId
(),
Math
.
max
(
param
.
getCount
(),
1
)));
if
(
request
.
getIsUseCondenseResin
())
{
// Check if condensed resin is usable here.
// For this, we use the following logic for now:
// The normal resin cost of the dungeon has to be 20.
if
(
resinCost
!=
20
)
{
return
;
}
// Make sure the player has condensed resin.
GameItem
condensedResin
=
player
.
getInventory
().
getInventoryTab
(
ItemType
.
ITEM_MATERIAL
).
getItemById
(
220007
);
if
(
condensedResin
==
null
||
condensedResin
.
getCount
()
<=
0
)
{
return
;
}
// Deduct.
player
.
getInventory
().
removeItem
(
condensedResin
,
1
);
// Roll rewards.
rewards
.
addAll
(
this
.
rollRewards
(
true
));
}
else
{
// If the player used regular resin, try to deduct.
// Stop if insufficient resin.
boolean
success
=
player
.
getResinManager
().
useResin
(
resinCost
);
if
(!
success
)
{
return
;
}
// Roll rewards.
rewards
.
addAll
(
this
.
rollRewards
(
false
));
}
// Add rewards to player and send notification.
player
.
getInventory
().
addItems
(
rewards
,
ActionReason
.
DungeonStatueDrop
);
player
.
sendPacket
(
new
PacketGadgetAutoPickDropInfoNotify
(
rewards
));
...
...
src/main/java/emu/grasscutter/game/entity/gadget/GadgetChest.java
View file @
63b6b805
...
...
@@ -4,7 +4,7 @@ import emu.grasscutter.Grasscutter;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.BossChestInfoOuterClass.BossChestInfo
;
import
emu.grasscutter.net.proto.
InterOpTypeOuterClass
;
import
emu.grasscutter.net.proto.
GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.net.proto.InterOpTypeOuterClass.InterOpType
;
import
emu.grasscutter.net.proto.InteractTypeOuterClass
;
import
emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType
;
...
...
@@ -18,7 +18,7 @@ public class GadgetChest extends GadgetContent {
super
(
gadget
);
}
public
boolean
onInteract
(
Player
player
,
InterOpType
opType
)
{
public
boolean
onInteract
(
Player
player
,
GadgetInteractReq
req
)
{
var
chestInteractHandlerMap
=
getGadget
().
getScene
().
getWorld
().
getServer
().
getWorldDataManager
().
getChestInteractHandlerMap
();
var
handler
=
chestInteractHandlerMap
.
get
(
getGadget
().
getGadgetData
().
getJsonName
());
if
(
handler
==
null
){
...
...
@@ -26,7 +26,7 @@ public class GadgetChest extends GadgetContent {
return
false
;
}
if
(
o
pType
==
InterOpType
.
INTER_OP_TYPE_START
&&
handler
.
isTwoStep
()){
if
(
req
.
getO
pType
()
==
InterOpType
.
INTER_OP_TYPE_START
&&
handler
.
isTwoStep
()){
player
.
sendPacket
(
new
PacketGadgetInteractRsp
(
getGadget
(),
InteractType
.
INTERACT_TYPE_OPEN_CHEST
,
InterOpType
.
INTER_OP_TYPE_START
));
return
false
;
}
else
{
...
...
src/main/java/emu/grasscutter/game/entity/gadget/GadgetContent.java
View file @
63b6b805
...
...
@@ -3,6 +3,7 @@ package emu.grasscutter.game.entity.gadget;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.InterOpTypeOuterClass
;
import
emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo
;
public
abstract
class
GadgetContent
{
...
...
@@ -16,7 +17,7 @@ public abstract class GadgetContent {
return
gadget
;
}
public
abstract
boolean
onInteract
(
Player
player
,
InterOpTypeOuterClass
.
InterOpType
opType
);
public
abstract
boolean
onInteract
(
Player
player
,
GadgetInteractReq
req
);
public
abstract
void
onBuildProto
(
SceneGadgetInfo
.
Builder
gadgetInfo
);
}
src/main/java/emu/grasscutter/game/entity/gadget/GadgetGatherPoint.java
View file @
63b6b805
...
...
@@ -7,7 +7,7 @@ import emu.grasscutter.game.inventory.GameItem;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo
;
import
emu.grasscutter.net.proto.
InterOpTypeOuterClass
;
import
emu.grasscutter.net.proto.
GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo
;
public
class
GadgetGatherPoint
extends
GadgetContent
{
...
...
@@ -26,7 +26,7 @@ public class GadgetGatherPoint extends GadgetContent {
return
getGatherData
().
getItemId
();
}
public
boolean
onInteract
(
Player
player
,
InterOpTypeOuterClass
.
InterOpType
opType
)
{
public
boolean
onInteract
(
Player
player
,
GadgetInteractReq
req
)
{
GameItem
item
=
new
GameItem
(
gatherData
.
getItemId
(),
1
);
player
.
getInventory
().
addItem
(
item
,
ActionReason
.
Gather
);
...
...
src/main/java/emu/grasscutter/game/entity/gadget/GadgetRewardStatue.java
View file @
63b6b805
...
...
@@ -3,7 +3,7 @@ package emu.grasscutter.game.entity.gadget;
import
emu.grasscutter.game.dungeons.challenge.DungeonChallenge
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.
InterOpTypeOuterClass
;
import
emu.grasscutter.net.proto.
GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType
;
import
emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo
;
import
emu.grasscutter.server.packet.send.PacketGadgetInteractRsp
;
...
...
@@ -14,9 +14,9 @@ public class GadgetRewardStatue extends GadgetContent {
super
(
gadget
);
}
public
boolean
onInteract
(
Player
player
,
InterOpTypeOuterClass
.
InterOpType
opType
)
{
public
boolean
onInteract
(
Player
player
,
GadgetInteractReq
req
)
{
if
(
player
.
getScene
().
getChallenge
()
!=
null
&&
player
.
getScene
().
getChallenge
()
instanceof
DungeonChallenge
dungeonChallenge
)
{
dungeonChallenge
.
getStatueDrops
(
player
);
dungeonChallenge
.
getStatueDrops
(
player
,
req
);
}
player
.
sendPacket
(
new
PacketGadgetInteractRsp
(
getGadget
(),
InteractType
.
INTERACT_TYPE_OPEN_STATUE
));
...
...
src/main/java/emu/grasscutter/game/entity/gadget/GadgetWorktop.java
View file @
63b6b805
...
...
@@ -4,7 +4,7 @@ import java.util.Arrays;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.
InterOpTypeOuterClass
;
import
emu.grasscutter.net.proto.
GadgetInteractReqOuterClass.GadgetInteractReq
;
import
emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo
;
import
emu.grasscutter.net.proto.WorktopInfoOuterClass.WorktopInfo
;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
...
...
@@ -35,7 +35,7 @@ public class GadgetWorktop extends GadgetContent {
this
.
worktopOptions
.
remove
(
option
);
}
public
boolean
onInteract
(
Player
player
,
InterOpTypeOuterClass
.
InterOpType
opType
)
{
public
boolean
onInteract
(
Player
player
,
GadgetInteractReq
req
)
{
return
false
;
}
...
...
src/main/java/emu/grasscutter/game/player/Player.java
View file @
63b6b805
...
...
@@ -990,7 +990,7 @@ public class Player {
}
public
void
interactWith
(
int
gadgetEntityId
,
InterOpTypeOuterClass
.
InterOpType
opType
)
{
public
void
interactWith
(
int
gadgetEntityId
,
GadgetInteractReq
req
)
{
GameEntity
entity
=
getScene
().
getEntityById
(
gadgetEntityId
);
if
(
entity
==
null
)
{
return
;
...
...
@@ -1023,7 +1023,7 @@ public class Player {
return
;
}
boolean
shouldDelete
=
gadget
.
getContent
().
onInteract
(
this
,
opType
);
boolean
shouldDelete
=
gadget
.
getContent
().
onInteract
(
this
,
req
);
if
(
shouldDelete
)
{
entity
.
getScene
().
removeEntity
(
entity
);
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerGadgetInteractReq.java
View file @
63b6b805
...
...
@@ -13,7 +13,7 @@ public class HandlerGadgetInteractReq extends PacketHandler {
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
GadgetInteractReq
req
=
GadgetInteractReq
.
parseFrom
(
payload
);
session
.
getPlayer
().
interactWith
(
req
.
getGadgetEntityId
(),
req
.
getOpType
()
);
session
.
getPlayer
().
interactWith
(
req
.
getGadgetEntityId
(),
req
);
}
}
src/main/java/emu/grasscutter/utils/Utils.java
View file @
63b6b805
...
...
@@ -7,6 +7,7 @@ import java.nio.file.StandardCopyOption;
import
java.time.*
;
import
java.time.temporal.TemporalAdjusters
;
import
java.util.*
;
import
java.util.concurrent.ThreadLocalRandom
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.DataLoader
;
...
...
@@ -61,7 +62,7 @@ public final class Utils {
BufferedInputStream
bis
=
new
BufferedInputStream
(
inputStream
);
ByteArrayOutputStream
buf
=
new
ByteArrayOutputStream
();
for
(
int
result
=
bis
.
read
();
result
!=
-
1
;
result
=
bis
.
read
())
{
buf
.
write
((
byte
)
result
);
buf
.
write
((
byte
)
result
);
}
return
buf
.
toString
();
}
...
...
@@ -75,17 +76,17 @@ public final class Utils {
private
static
final
char
[]
HEX_ARRAY
=
"0123456789abcdef"
.
toCharArray
();
public
static
String
bytesToHex
(
byte
[]
bytes
)
{
if
(
bytes
==
null
)
return
""
;
char
[]
hexChars
=
new
char
[
bytes
.
length
*
2
];
for
(
int
j
=
0
;
j
<
bytes
.
length
;
j
++)
{
int
v
=
bytes
[
j
]
&
0xFF
;
hexChars
[
j
*
2
]
=
HEX_ARRAY
[
v
>>>
4
];
hexChars
[
j
*
2
+
1
]
=
HEX_ARRAY
[
v
&
0x0F
];
}
return
new
String
(
hexChars
);
char
[]
hexChars
=
new
char
[
bytes
.
length
*
2
];
for
(
int
j
=
0
;
j
<
bytes
.
length
;
j
++)
{
int
v
=
bytes
[
j
]
&
0xFF
;
hexChars
[
j
*
2
]
=
HEX_ARRAY
[
v
>>>
4
];
hexChars
[
j
*
2
+
1
]
=
HEX_ARRAY
[
v
&
0x0F
];
}
return
new
String
(
hexChars
);
}
public
static
String
bytesToHex
(
ByteBuf
buf
)
{
return
bytesToHex
(
byteBufToArray
(
buf
));
return
bytesToHex
(
byteBufToArray
(
buf
));
}
public
static
byte
[]
byteBufToArray
(
ByteBuf
buf
)
{
...
...
@@ -97,10 +98,10 @@ public final class Utils {
public
static
int
abilityHash
(
String
str
)
{
int
v7
=
0
;
int
v8
=
0
;
while
(
v8
<
str
.
length
())
{
v7
=
str
.
charAt
(
v8
++)
+
131
*
v7
;
}
return
v7
;
while
(
v8
<
str
.
length
())
{
v7
=
str
.
charAt
(
v8
++)
+
131
*
v7
;
}
return
v7
;
}
/**
...
...
@@ -377,4 +378,35 @@ public final class Utils {
return
null
;
}
}
/***
* Draws a random element from the given list, following the given probability distribution, if given.
* @param list The list from which to draw the element.
* @param probabilities The probability distribution. This is given as a list of probabilities of the same length it `list`.
* @return A randomly drawn element from the given list.
*/
public
static
<
T
>
T
drawRandomListElement
(
List
<
T
>
list
,
List
<
Integer
>
probabilities
)
{
// If we don't have a probability distribution, or the size of the distribution does not match
// the size of the list, we assume uniform distribution.
if
(
probabilities
==
null
||
probabilities
.
size
()
<=
1
||
probabilities
.
size
()
!=
list
.
size
())
{
int
index
=
ThreadLocalRandom
.
current
().
nextInt
(
0
,
list
.
size
());
return
list
.
get
(
index
);
}
// Otherwise, we roll with the given distribution.
int
totalProbabilityMass
=
probabilities
.
stream
().
reduce
(
Integer:
:
sum
).
get
();
int
roll
=
ThreadLocalRandom
.
current
().
nextInt
(
1
,
totalProbabilityMass
+
1
);
int
currentTotalChance
=
0
;
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
currentTotalChance
+=
probabilities
.
get
(
i
);
if
(
roll
<=
currentTotalChance
)
{
return
list
.
get
(
i
);
}
}
// Should never happen.
return
list
.
get
(
0
);
}
}
src/main/resources/defaults/data/DungeonDrop.json
0 → 100644
View file @
63b6b805
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment