summaryrefslogtreecommitdiff
path: root/src/main/java/jp/plusplus/fbs/storage/ChunkLoadManager.java
blob: bb9a1f5b2baca0121d26fe740deeb794bd754de2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package jp.plusplus.fbs.storage;

import com.google.common.collect.ImmutableSetMultimap;
import jp.plusplus.fbs.FBS;
import net.minecraft.block.Block;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeChunkManager;

import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by plusplus_F on 2016/03/07.
 */
public class ChunkLoadManager implements ForgeChunkManager.LoadingCallback{
    private static ChunkLoadManager obj=new ChunkLoadManager();
    private static HashMap<Pos, ForgeChunkManager.Ticket> tickets=new HashMap<Pos, ForgeChunkManager.Ticket>();

    //インスタンスの取得
    public static ChunkLoadManager instance(){
        return obj;
    }

    //チャンクローダの登録
    public static void setChunkLoader(World w, int x, int y, int z){
        if(w==null){
            FBS.logger.error("Error! World is null.");
            return;
        }

        Pos p=new Pos(x,y,z);
        for(Pos pos : tickets.keySet()){
            if(pos.equals(p)){
                FBS.logger.error("Error! Already registered.");
                return;
            }
        }

        //チケットの要求
        ForgeChunkManager.Ticket t=ForgeChunkManager.requestTicket(FBS.instance, w, ForgeChunkManager.Type.NORMAL);
        if(t==null){
            FBS.logger.error("Error! Couldn't get ticket.");
            return;
        }

        //チケットに情報書き込み
        t.getModData().setString("type", "block");
        t.getModData().setInteger("x", x);
        t.getModData().setInteger("y", y);
        t.getModData().setInteger("z", z);

        //チケットをどうたら
        tickets.put(p, t);
        ForgeChunkManager.forceChunk(t, w.getChunkFromBlockCoords(x, z).getChunkCoordIntPair());
        FBS.logger.info("Added ChunkLoader at "+w.provider.getDimensionName()+"("+x+","+y+","+z+")");
    }

    //チャンクローダの削除
    public static void removeChunkLoader(World world, int x, int y, int z){
        Pos p=new Pos(x,y,z);

        //チケットが存在するか確認
        for(Pos pos : tickets.keySet()){
            if(pos.equals(p)){
                //チャンクロードの停止
                ForgeChunkManager.Ticket t=tickets.get(pos);

                World w=t.world;
                if(w!=null){
                    ImmutableSetMultimap<ChunkCoordIntPair, ForgeChunkManager.Ticket> map=ForgeChunkManager.getPersistentChunksFor(t.world);
                    if(map!=null && !map.isEmpty()){
                        ForgeChunkManager.unforceChunk(t, world.getChunkFromBlockCoords(x, z).getChunkCoordIntPair());
                        FBS.logger.info("Removed chunk loader at "+world.provider.getDimensionName()+"("+x+","+y+","+z+")");
                    }
                }

                //削除
                tickets.remove(p);
                return;
            }
        }

        FBS.logger.error("Error! Couldn't found chunk loader at "+world.provider.getDimensionName()+"("+x+","+y+","+z+")");
    }

    @Override
    public void ticketsLoaded(List<ForgeChunkManager.Ticket> tickets, World world) {
        ChunkLoadManager.tickets.clear();

        //チケット全部見てなんか処理してる
        for(ForgeChunkManager.Ticket t : tickets){
            if(t.getModData().getString("type").equals("block")){
                int x = t.getModData().getInteger("x");
                int y = t.getModData().getInteger("y");
                int z = t.getModData().getInteger("z");
                Block b=world.getBlock(x,y,z);

                //チャンクローダか判定してそれぞれ処理
                if(b instanceof IChunkLoader){
                    if(((IChunkLoader)b).canLoad(world, x, y, z)){
                        setChunkLoader(world, x, y, z);
                    }
                }
            }
        }
    }

    public static HashMap<Pos, ForgeChunkManager.Ticket> getTickets(){
        return tickets;
    }

    public static World getWorld(int dId){
        for(ForgeChunkManager.Ticket t : tickets.values()){
            if(t.world.provider.dimensionId==dId){
                return t.world;
            }
        }
        return null;
    }

    public interface IChunkLoader{
        public boolean canLoad(World w, int x, int y, int z);
    }

    private static class Pos{
        int x,y,z;

        public Pos(int x, int y, int z){
            this.x=x;
            this.y=y;
            this.z=z;
        }

        @Override
        public boolean equals(Object obj){
            if(!(obj instanceof Pos)) return false;
            Pos p=(Pos)obj;
            return x==p.x && y==p.y && z==p.z;
        }
    }
}