Fix ore dropping and implement subfields

This commit is contained in:
StartForKiller 2023-06-03 15:16:24 -04:00 committed by KingRainbow44
parent 9dae3cbcc7
commit 56f09e87a1
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
8 changed files with 174 additions and 3 deletions

View File

@ -37,8 +37,11 @@ import emu.grasscutter.data.excels.world.WeatherData;
import emu.grasscutter.data.excels.world.WorldAreaData; import emu.grasscutter.data.excels.world.WorldAreaData;
import emu.grasscutter.data.excels.world.WorldLevelData; import emu.grasscutter.data.excels.world.WorldLevelData;
import emu.grasscutter.data.server.ActivityCondGroup; import emu.grasscutter.data.server.ActivityCondGroup;
import emu.grasscutter.data.server.DropSubfieldMapping;
import emu.grasscutter.data.server.DropTableExcelConfigData;
import emu.grasscutter.data.server.GadgetMapping; import emu.grasscutter.data.server.GadgetMapping;
import emu.grasscutter.data.server.MonsterMapping; import emu.grasscutter.data.server.MonsterMapping;
import emu.grasscutter.data.server.SubfieldMapping;
import emu.grasscutter.game.dungeons.DungeonDropEntry; import emu.grasscutter.game.dungeons.DungeonDropEntry;
import emu.grasscutter.game.quest.QuestEncryptionKey; import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.game.quest.RewindData; import emu.grasscutter.game.quest.RewindData;
@ -451,6 +454,10 @@ public final class GameData {
private static final Int2ObjectMap<GadgetMapping> gadgetMappingMap = private static final Int2ObjectMap<GadgetMapping> gadgetMappingMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<SubfieldMapping> subfieldMappingMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DropSubfieldMapping> dropSubfieldMappingMap = new Int2ObjectOpenHashMap<>();
@Getter private static final Int2ObjectMap<DropTableExcelConfigData> dropTableExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
@Getter @Getter
private static final Int2ObjectMap<MonsterMapping> monsterMappingMap = private static final Int2ObjectMap<MonsterMapping> monsterMappingMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();

View File

@ -116,6 +116,7 @@ public final class ResourceLoader {
loadConfigLevelEntityData(); loadConfigLevelEntityData();
loadQuestShareConfig(); loadQuestShareConfig();
loadGadgetMappings(); loadGadgetMappings();
loadSubfieldMappings();
loadMonsterMappings(); loadMonsterMappings();
loadActivityCondGroups(); loadActivityCondGroups();
loadGroupReplacements(); loadGroupReplacements();
@ -805,6 +806,38 @@ public final class ResourceLoader {
} }
} }
private static void loadSubfieldMappings() {
try {
val subfieldMap = GameData.getSubfieldMappingMap();
try {
JsonUtils.loadToList(getResourcePath("Server/SubfieldMapping.json"), SubfieldMapping.class).forEach(entry -> subfieldMap.put(entry.getEntityId(), entry));;
} catch (IOException | NullPointerException ignored) {}
Grasscutter.getLogger().debug("Loaded {} subfield mappings.", subfieldMap.size());
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load subfield mappings.", e);
}
try {
val dropSubfieldMap = GameData.getDropSubfieldMappingMap();
try {
JsonUtils.loadToList(getResourcePath("Server/DropSubfieldMapping.json"), DropSubfieldMapping.class).forEach(entry -> dropSubfieldMap.put(entry.getDropId(), entry));;
} catch (IOException | NullPointerException ignored) {}
Grasscutter.getLogger().debug("Loaded {} drop subfield mappings.", dropSubfieldMap.size());
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load drop subfield mappings.", e);
}
try {
val dropTableExcelConfigDataMap = GameData.getDropTableExcelConfigDataMap();
try {
JsonUtils.loadToList(getResourcePath("Server/DropTableExcelConfigData.json"), DropTableExcelConfigData.class).forEach(entry -> dropTableExcelConfigDataMap.put(entry.getId(), entry));;
} catch (IOException | NullPointerException ignored) {}
Grasscutter.getLogger().debug("Loaded {} drop table configs.", dropTableExcelConfigDataMap.size());
} catch (Exception e) {
Grasscutter.getLogger().error("Unable to load drop table config data.", e);
}
}
private static void loadMonsterMappings() { private static void loadMonsterMappings() {
try { try {
var monsterMap = GameData.getMonsterMappingMap(); var monsterMap = GameData.getMonsterMappingMap();

View File

@ -0,0 +1,10 @@
package emu.grasscutter.data.server;
import lombok.Data;
@Data
public class DropSubfieldMapping {
private int dropId;
private int levelLimit;
private int itemId;
}

View File

@ -0,0 +1,24 @@
package emu.grasscutter.data.server;
import lombok.Data;
@Data
public class DropTableExcelConfigData {
private int id;
private int randomType;
private int dropLevel;
private DropVectorEntry[] dropVec;
private int nodeType;
private boolean fallToGround;
private int sourceType;
private int everydayLimit;
private int historyLimit;
private int activityLimit;
@Data
public class DropVectorEntry {
private int itemId;
private String countRange;
private int weight;
}
}

View File

@ -0,0 +1,15 @@
package emu.grasscutter.data.server;
import lombok.Data;
@Data
public class SubfieldMapping {
private int entityId;
private SubfieldMappingEntry[] subfields;
@Data
public class SubfieldMappingEntry {
private String subfieldName;
private int drop_id;
}
}

View File

@ -42,9 +42,9 @@ public class AbilityLocalIdGenerator {
if(actions[i].actions != null) this.initializeActionLocalIds(actions[i].actions, localIdToAction); if(actions[i].actions != null) this.initializeActionLocalIds(actions[i].actions, localIdToAction);
else { else {
if (actions[i].successActions[i] != null) if (actions[i].successActions != null)
this.initializeActionLocalIds(actions[i].successActions, localIdToAction); //Need to check this specific order this.initializeActionLocalIds(actions[i].successActions, localIdToAction); //Need to check this specific order
if (actions[i].failActions[i] != null) if (actions[i].failActions != null)
this.initializeActionLocalIds(actions[i].failActions, localIdToAction); this.initializeActionLocalIds(actions[i].failActions, localIdToAction);
} }
} }

View File

@ -1,5 +1,6 @@
package emu.grasscutter.game.entity; package emu.grasscutter.game.entity;
import emu.grasscutter.data.GameData;
import emu.grasscutter.game.ability.*; import emu.grasscutter.game.ability.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.*; import emu.grasscutter.game.props.*;
@ -14,9 +15,10 @@ import emu.grasscutter.scripts.data.controller.EntityController;
import emu.grasscutter.server.event.entity.*; import emu.grasscutter.server.event.entity.*;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import java.util.*;
import lombok.*; import lombok.*;
import java.util.*;
public abstract class GameEntity { public abstract class GameEntity {
@Getter private final Scene scene; @Getter private final Scene scene;
@Getter protected int id; @Getter protected int id;
@ -226,6 +228,76 @@ public abstract class GameEntity {
public void onRemoved() {} public void onRemoved() {}
private int[] parseCountRange(String range) {
var split = range.split(";");
if(split.length == 1) return new int[] {Integer.parseInt(split[0]), Integer.parseInt(split[0])};
return new int[] {Integer.parseInt(split[0]), Integer.parseInt(split[1])};
}
public boolean dropSubfieldItem(int dropId) {
var drop = GameData.getDropSubfieldMappingMap().get(dropId);
if(drop == null) return false;
var dropTableEntry = GameData.getDropTableExcelConfigDataMap().get(drop.getItemId());
if(dropTableEntry == null) return false;
Int2ObjectMap<Integer> itemsToDrop = new Int2ObjectOpenHashMap<>();
switch (dropTableEntry.getRandomType()) {
case 0: //select one
{
int weightCount = 0;
for(var entry : dropTableEntry.getDropVec()) weightCount += entry.getWeight();
int randomValue = new Random().nextInt(weightCount);
weightCount = 0;
for(var entry : dropTableEntry.getDropVec()) {
if(randomValue >= weightCount && randomValue < (weightCount + entry.getWeight())) {
var countRange = parseCountRange(entry.getCountRange());
itemsToDrop.put(entry.getItemId(), Integer.valueOf((new Random().nextBoolean() ? countRange[0] : countRange[1])));
}
}
}
break;
case 1: //Select various
{
for(var entry : dropTableEntry.getDropVec()) {
if(entry.getWeight() < new Random().nextInt(10000)) {
var countRange = parseCountRange(entry.getCountRange());
itemsToDrop.put(entry.getItemId(), Integer.valueOf((new Random().nextBoolean() ? countRange[0] : countRange[1])));
}
}
}
break;
}
for (var entry : itemsToDrop.int2ObjectEntrySet()) {
var item = new EntityItem(
scene,
null,
GameData.getItemDataMap().get(entry.getIntKey()),
getPosition().nearby2d(1f).addY(0.5f),
entry.getValue(),
true);
scene.addEntity(item);
}
return true;
}
public boolean dropSubfield(String subfieldName) {
var subfieldMapping = GameData.getSubfieldMappingMap().get(getEntityTypeId());
if (subfieldMapping == null || subfieldMapping.getSubfields() == null) return false;
for (var entry : subfieldMapping.getSubfields()) {
if (entry.getSubfieldName().compareTo(subfieldName) == 0) {
return dropSubfieldItem(entry.getDrop_id());
}
}
return false;
}
public void onTick(int sceneTime) { public void onTick(int sceneTime) {
if (entityController != null) { if (entityController != null) {
entityController.onTimer(this, sceneTime); entityController.onTimer(this, sceneTime);

View File

@ -1599,6 +1599,16 @@ public class ScriptLib {
return 0; return 0;
} }
public int DropSubfield(LuaTable table) {
String subfield_name = table.get("subfield_name").toString();
var entity = getCurrentEntity();
if(!entity.isPresent()) return -1;
entity.get().dropSubfield(subfield_name);
return -1;
}
public int[] GetGatherConfigIdList() { public int[] GetGatherConfigIdList() {
EntityGadget gadget = getCurrentEntityGadget(); EntityGadget gadget = getCurrentEntityGadget();