initial commit

This commit is contained in:
Anus 2013-01-22 21:55:20 +04:00
commit 87d2487dac
13 changed files with 1897 additions and 0 deletions

22
.gitattributes vendored Normal file
View file

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

163
.gitignore vendored Normal file
View file

@ -0,0 +1,163 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

View file

@ -0,0 +1,41 @@
package cr0s.WarpDrive;
import java.util.Random;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
public class BlockReactor extends BlockContainer {
BlockReactor(int id, int texture, Material material) {
super(id, texture, material);
}
@Override
public String getTextureFile () {
return CommonProxy.BLOCK_TEXTURE_OFFLINE;
}
@Override
public TileEntity createNewTileEntity(World var1) {
return new TileEntityReactor(var1);
}
/**
* Returns the quantity of items to drop on block destruction.
*/
@Override
public int quantityDropped(Random par1Random)
{
return 1;
}
/**
* Returns the ID of the items to drop on destruction.
*/
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return this.blockID;
}
}

View file

@ -0,0 +1,16 @@
package cr0s.WarpDrive;
import cpw.mods.fml.common.registry.EntityRegistry;
public class CommonProxy {
public static final String BLOCK_TEXTURE_OFFLINE = "/cr0s/WarpDrive/CORE_OFFLINE.png";
public static final String BLOCK_TEXTURE_ONLINE = "/cr0s/WarpDrive/CORE_ONLINE.png";
public void registerJumpEntity() {
//EntityRegistry.registerModEntity(ThreadJump.class, "EntityJump", 1, WarpDrive.instance, 80, 3, false);
}
public void registerRenderers() {
}
}

View file

@ -0,0 +1,760 @@
package cr0s.WarpDrive;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.world.World;
public class EntityJump extends Entity
{
private int moveX;
private int moveZ;
public int xCoord;
public int yCoord;
public int zCoord;
public int distance;
public int dir;
public int shipLeft;
public int shipRight;
public int shipFront;
public int shipBack;
public int shipDown;
public int shipUp;
public int shipLength;
public int Xmax;
public int Zmax;
public int maxY;
public int Xmin;
public int Zmin;
public int minY;
public int dx;
public int dz;
public World worldObj;
public boolean on = false;
public JumpBlock ship[];
public TileEntityReactor reactor;
public EntityJump(World world, int x, int y, int z, int _dist, int _direction, int _dx, int _dz, TileEntityReactor parReactor)
{
super(world);
this.xCoord = x;
this.yCoord = y;
this.zCoord = z;
this.distance = _dist;
this.dir = _direction;
shipLeft = shipRight = shipFront = shipBack = shipDown = shipUp = shipLength = 0;
this.dx = this.dz = 0;
this.dx = _dx;
this.dz = _dz;
Xmax = Zmax = maxY = Xmin = Zmin = minY = 0;
this.worldObj = world;
System.out.println("[JE] Entity created");
this.reactor = parReactor;
}
public void killEntity(String reason) {
if (!reason.isEmpty()) {
System.out.println("[JUMP] Killed: " + reason);
}
worldObj.editingBlocks = false;
worldObj.setEntityDead(this);
}
//@SideOnly(Side.SERVER)
@Override
public void onUpdate()
{
if (worldObj.editingBlocks || !on || minY < 0 || maxY > 255)
{
killEntity("Entity is disabled or Y-coord error! Cannot jump.");
return;
}
System.out.println("[JUMP] onUpdate() called");
// Блокируем мир
worldObj.editingBlocks = true;
distance = getPossibleJumpDistance();
if (distance < 0)
{
killEntity("Not enough space for jump.");
return;
}
if (!checkForBedrockOnShip()) {
killEntity("Is bedrock on the ship. Aborting.");
return;
}
int shipSize = getRealShipSize();
saveShip(shipSize, false);
removeShip();
moveShip();
AxisAlignedBB axisalignedbb = AxisAlignedBB.getBoundingBox(Xmin, minY, Zmin, Xmax, maxY, Zmax);
moveEntity(axisalignedbb, distance, dir);
// Разблокируем мир
worldObj.editingBlocks = false;
// Прыжок окончен
killEntity("");
on = false;
}
public void removeShip() {
for (JumpBlock jb : ship) {
if (jb.blockTileEntity != null) {
worldObj.removeBlockTileEntity(jb.x, jb.y, jb.z);
}
//System.out.println("[EJ] Removing block: " + jb.x + " " + jb.y + " " + jb.z + " " + jb.blockID);
worldObj.setBlockAndMetadata(jb.x, jb.y, jb.z, 0, 0);
}
}
/**
* Сохранение корабля в память
* @param shipSize размер корабля (число блоков для перемещения)
* @param deleteShip удалять ли блоки корабля сразу после сохранения
*/
public void saveShip(int shipSize, boolean deleteShip) {
ship = new JumpBlock[shipSize];
int index = 0;
for (int y = minY; y <= maxY; y++)
{
for (int x = Xmin; x <= Xmax; x++)
{
for (int z = Zmin; z <= Zmax; z++)
{
if (ship == null)
{
killEntity("ship is null!");
return;
}
int blockID = worldObj.getBlockId(x, y, z);
int blockMeta = worldObj.getBlockMetadata(x, y, z);
TileEntity tileentity = worldObj.getBlockTileEntity(x, y, z);
// Пустые блоки пропускаются
if (blockID == 0)
{
continue;
}
if (tileentity != null)
{
ship[index] = new JumpBlock(blockID, blockMeta, tileentity, x, y, z);
}
else
{
ship[index] = new JumpBlock(blockID, blockMeta, x, y, z);
}
if (deleteShip) {
if (tileentity != null) {
worldObj.removeBlockTileEntity(x, y, z);
}
worldObj.setBlockAndMetadata(x, y, z, 0, 0);
}
index++;
}
}
}
System.out.println((new StringBuilder()).append("[JUMP] Ship saved: ").append((new StringBuilder()).append(ship.length).append(" blocks")).toString());
}
/*
* Перемещение корабля
*/
public void moveShip() {
for (int indexInShip = 0; indexInShip <= ship.length - 1; indexInShip++)
{
moveBlock(indexInShip, distance, dir);
}
}
/**
*
* @return Возвращает новую длинну прыжка (для стыковки), либо -1, если прыжок невозможен в принципе
*/
public int getPossibleJumpDistance() {
int testDistance = this.distance;
boolean canJump;
while (true)
{
if (testDistance <= this.shipLength)
{
break;
}
canJump = checkMovement(testDistance);
if (canJump)
{
break;
}
testDistance--;
}
return testDistance;
}
/*
* Проверка на наличие запрещённых блоков на корабле (бедрок)
*
* Применяется для предотвращения возможности зацепить варп-полем корабля бедрок и оторвать его
*/
public boolean checkForBedrockOnShip() {
for (int y = minY; y <= maxY; y++) {
for (int x = Xmin; x <= Xmax; x++) {
for (int z = Zmin; z <= Zmax; z++) {
int blockID = worldObj.getBlockId(x, y, z);
// Пропускаем пустые блоки воздуха
if (blockID == 0) {
continue;
}
// Проверка блока
if (blockID == Block.bedrock.blockID) {
return false;
}
}
}
}
return true;
}
/*
* Получить реальное количество блоков, из которых состоит корабль
*/
public int getRealShipSize() {
int shipSize = 0;
for (int y = minY; y <= maxY; y++) {
for (int x = Xmin; x <= Xmax; x++) {
for (int z = Zmin; z <= Zmax; z++) {
int blockID = worldObj.getBlockId(x, y, z);
// Пропускаем пустые блоки воздуха
if (blockID != 0) {
shipSize++;
}
}
}
}
return shipSize;
}
public boolean moveEntity(AxisAlignedBB axisalignedbb, int distance, int direction)
{
List list = worldObj.getEntitiesWithinAABBExcludingEntity(null, axisalignedbb);
if (list != null)
{
for (int index = 0; index < list.size(); index++)
{
Object obj = list.get(index);
if (obj == null || !(obj instanceof Entity))
{
continue;
}
Entity entity = (Entity)obj;
int oldEntityX = (int)entity.posX;
int oldEntityY = (int)entity.posY;
int oldEntityZ = (int)entity.posZ;
int newEntityX = getNewXCoord(oldEntityX, oldEntityY, oldEntityZ, distance, direction);
int newEntityY = getNewYCoord(oldEntityX, oldEntityY, oldEntityZ, distance, direction);
int newEntityZ = getNewZCoord(oldEntityX, oldEntityY, oldEntityZ, distance, direction);
//System.out.println("Entity moving: old (" + oldEntityX + " " + oldEntityY + " " + oldEntityZ + ") -> new (" + newEntityX + " " + newEntityY + " " + newEntityZ);
if (!(entity instanceof EntityPlayerMP))
{
entity.moveEntity(newEntityX, newEntityY, newEntityZ);
continue;
}
// Если на корабле есть кровать, то передвинуть точку спауна игрока
ChunkCoordinates bedLocation = ((EntityPlayerMP)entity).getBedLocation();
if (bedLocation != null && testBB(axisalignedbb, bedLocation.posX, bedLocation.posY, bedLocation.posZ))
{
bedLocation.posX = getNewXCoord(bedLocation.posX, bedLocation.posY, bedLocation.posZ, distance, direction);
bedLocation.posY = getNewYCoord(bedLocation.posX, bedLocation.posY, bedLocation.posZ, distance, direction);
bedLocation.posZ = getNewZCoord(bedLocation.posX, bedLocation.posY, bedLocation.posZ, distance, direction);
((EntityPlayerMP)entity).setSpawnChunk(bedLocation, false);
}
((EntityPlayerMP)entity).setPositionAndUpdate(newEntityX, newEntityY, newEntityZ);
}
}
return true;
}
/*
* Проверка на вхождение точки в область (bounding-box)
*/
public boolean testBB(AxisAlignedBB axisalignedbb, int x, int y, int z)
{
return axisalignedbb.minX <= (double)x && axisalignedbb.maxX >= (double)x && axisalignedbb.minY <= (double)y && axisalignedbb.maxY >= (double)y && axisalignedbb.minZ <= (double)z && axisalignedbb.maxZ >= (double)z;
}
/**
* Получение новой координаты X (сдвиг)
*
* @param oldX старая координата X
* @param oldY старая координата Y
* @param oldZ старая координата Z
* @param distance расстояние для перемещения
* @param direction направление пермещения
*/
public int getNewXCoord(int oldX, int oldY, int oldZ, int distance, int direction)
{
moveX = 0;
moveZ = 0;
// System.out.println("old: (" + oldX + "; " + oldZ + ") dis: " + distance + " dir: " + direction);
int movementVector[] = getVector(direction);
// System.out.println("Vector: (" + movementVector[0] + "; 0; " + movementVector[2]);
moveX = movementVector[0] * distance;
moveZ = movementVector[2] * distance;
int result = oldX;
if (direction != -1 && direction != -2)
{
result += moveX;
}
//System.out.println("moveX: " + moveX);
return result;
}
/**
* Получение новой координаты Y (сдвиг)
*
* @param oldX старая координата X
* @param oldY старая координата Y
* @param oldZ старая координата Z
* @param distance расстояние для перемещения
* @param direction направление пермещения
*/
public int getNewYCoord(int i, int oldY, int k, int distance, int direction)
{
int result = oldY;
if (direction == -1 || direction == -2)
{
if (direction == -1)
{
result += distance;
}
else
{
result -= distance;
}
}
if (result >= 255)
{
result = 255;
}
if (result <= 0)
{
result = 3;
}
return result;
}
/**
* Получение новой координаты Z (сдвиг)
*
* @param oldX старая координата X
* @param oldY старая координата Y
* @param oldZ старая координата Z
* @param distance расстояние для перемещения
* @param direction направление пермещения
*/
public int getNewZCoord(int oldX, int oldY, int oldZ, int distance, int direction)
{
moveX = 0;
moveZ = 0;
// System.out.println("old: (" + oldX + "; " + oldZ + ") dis: " + distance + " dir: " + direction);
int movementVector[] = getVector(direction);
// System.out.println("Vector: (" + movementVector[0] + "; 0; " + movementVector[2]);
moveX = movementVector[0] * distance;
moveZ = movementVector[2] * distance;
int result = oldZ;
if (direction != -1 && direction != -2)
{
result += moveZ;
}
//System.out.println("moveZ: " + moveZ);
return result;
}
public int rotsincos(int i, boolean flag)
{
// sin
if (flag)
{
switch (i)
{
case 0:
return 0;
case 90:
return 1;
case 180:
return 0;
case 270:
return -1;
}
}
// cos
else
{
switch (i)
{
case 0:
return 1;
case 90:
return 0;
case 180:
return -1;
case 270:
return 0;
}
}
return 0;
}
// Получение вектора в зависимости от направления прыжка
// (3,14здец, конечно)
public int[] getVector(int i)
{
int ai[] =
{
0, 0, 0
};
if (dz == 1)
{
switch (i)
{
case 0:
ai[0] = 0;
ai[1] = 0;
ai[2] = 1;
break;
case 90:
ai[0] = 1;
ai[1] = 0;
ai[2] = 0;
break;
case 180:
ai[0] = 0;
ai[1] = 0;
ai[2] = -1;
break;
case 270:
ai[0] = -1;
ai[1] = 0;
ai[2] = 0;
break;
}
}
else if (dz == -1)
{
switch (i)
{
case 0:
ai[0] = 0;
ai[1] = 0;
ai[2] = -1;
break;
case 90:
ai[0] = -1;
ai[1] = 0;
ai[2] = 0;
break;
case 180:
ai[0] = 0;
ai[1] = 0;
ai[2] = 1;
break;
case 270:
ai[0] = 1;
ai[1] = 0;
ai[2] = 0;
break;
}
}
else if (dx == 1)
{
switch (i)
{
case 0:
ai[0] = 1;
ai[1] = 0;
ai[2] = 0;
break;
case 90:
ai[0] = 0;
ai[1] = 0;
ai[2] = -1;
break;
case 180:
ai[0] = -1;
ai[1] = 0;
ai[2] = 0;
break;
case 270:
ai[0] = 0;
ai[1] = 0;
ai[2] = 1;
break;
}
}
else if (dx == -1)
{
switch (i)
{
case 0:
ai[0] = -1;
ai[1] = 0;
ai[2] = 0;
break;
case 90:
ai[0] = 0;
ai[1] = 0;
ai[2] = 1;
break;
case 180:
ai[0] = 1;
ai[1] = 0;
ai[2] = 0;
break;
case 270:
ai[0] = 0;
ai[1] = 0;
ai[2] = -1;
break;
}
}
return ai;
}
/**
* Проверка возможности установки корабля в месте, удалённом от корабля на определённом расстоянии в сторону прыжка
* @param i
* @return true, если корабль уместился на новом месте
*/
public boolean checkMovement(int testDistance)
{
if (dir == -1 && maxY + testDistance > 255)
{
System.out.println("[JUMP] Reactor will blow due +high limit");
return false;
}
if (dir == -2 && minY - testDistance <= 8)
{
System.out.println("[JUMP] Reactor will blow due -low limit");
return false;
}
for (int y = minY; y <= maxY; y++)
{
for (int x = Xmin; x <= Xmax; x++)
{
for (int z = Zmin; z <= Zmax; z++)
{
int newX = getNewXCoord(x, y, z, testDistance, dir);
int newY = getNewYCoord(x, y, z, testDistance, dir);
int newZ = getNewZCoord(x, y, z, testDistance, dir);
if (isBlockInShip(newX, newY, newZ))
{
continue;
}
int blockID = worldObj.getBlockId(newX, newY, newZ);
int blockOnShipID = worldObj.getBlockId(x, y, z);
if (blockOnShipID == Block.bedrock.blockID)
{
return false;
}
if (blockOnShipID != 0 && blockID != 0 && blockID != 9 && blockID != 8 && blockID != 18)
{
System.out.println((new StringBuilder()).append("[JUMP] Reactor will blow due BlockID ").append((new StringBuilder()).append(blockID).append(" at (").append(newX).append(";").append(newY).append(";").append(newZ).append(")").toString()).toString());
return false;
}
}
}
}
return true;
}
/**
* Точка находится в варп-поле корабля?
*
* @param x
* @param y
* @param z
* @return true, если находится
*/
public boolean isBlockInShip(int x, int y, int z)
{
return x >= Xmin && x <= Xmax && y >= minY && y <= maxY && z >= Zmin && z <= Zmax;
}
/**
* Перемещение одиночного блока на новое место
* @param indexInShip
* @param j
* @param k
* @return
*/
public boolean moveBlock(int indexInShip, int distance, int direction)
{
try
{
JumpBlock shipBlock = ship[indexInShip];
if (shipBlock == null)
{
return false;
}
int oldX = shipBlock.x;
int oldY = shipBlock.y;
int oldZ = shipBlock.z;
int newY = getNewYCoord(oldX, oldY, oldZ, distance, direction);
int newX = getNewXCoord(oldX, oldY, oldZ, distance, direction);
int newZ = getNewZCoord(oldX, oldY, oldZ, distance, direction);
int blockID = shipBlock.blockID;
int blockMeta = shipBlock.blockMeta;
// if (div++ % 16 == 0)
//{
worldObj.setBlockAndMetadataWithNotify(newX, newY, newZ, blockID, blockMeta);
// div = 0;
//}
//else
//{
// worldObj.setBlockAndMetadata(newX, newY, newZ, blockID, blockMeta);
// }
NBTTagCompound oldnbt = new NBTTagCompound();
if (shipBlock.blockTileEntity != null && blockID != 159 && blockID != 149 && blockID != 156 && blockID != 146 && blockID != 145)
{
shipBlock.blockTileEntity.writeToNBT(oldnbt);
TileEntity newTileEntity = worldObj.getBlockTileEntity(newX, newY, newZ);
if (newTileEntity == null) return false; // PIZDEC!!!
newTileEntity.readFromNBT(oldnbt);
worldObj.setBlockTileEntity(newX, newY, newZ, newTileEntity);
worldObj.removeBlockTileEntity(oldX, oldY, oldZ);
}
}
catch (Exception exception) { exception.printStackTrace(); }
return true;
}
@Override
protected void readEntityFromNBT(NBTTagCompound nbttagcompound)
{
}
@Override
protected void entityInit() {
onUpdate();
}
@Override
protected void writeEntityToNBT(NBTTagCompound var1) {
}
/*
@Override
protected void entityInit() {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void readEntityFromNBT(NBTTagCompound var1) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void writeEntityToNBT(NBTTagCompound var1) {
throw new UnsupportedOperationException("Not supported yet.");
}*/
}

View file

@ -0,0 +1,39 @@
package cr0s.WarpDrive;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
public class JumpBlock
{
public int blockID;
public int blockMeta;
public TileEntity blockTileEntity;
public NBTTagCompound blockNBT;
public int x;
public int y;
public int z;
public JumpBlock()
{
}
public JumpBlock(int i, int j, int k, int l, int i1)
{
blockID = i;
blockMeta = j;
blockTileEntity = null;
x = k;
y = l;
z = i1;
}
public JumpBlock(int i, int j, TileEntity tileentity, int k, int l, int i1)
{
blockID = i;
blockMeta = j;
blockTileEntity = tileentity;
x = k;
y = l;
z = i1;
}
}

View file

@ -0,0 +1,542 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cr0s.WarpDrive;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import ic2.api.Direction;
import ic2.api.energy.tile.IEnergySink;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
/**
*
* @author user
*/
public class TileEntityReactor extends TileEntity implements IEnergySink {
TileEntityReactor(World var1) {
worldObj = var1;
}
// = Настройки ядра =
// Счётчики габаритов, переключатель режимов, переключатель длинны прыжка
TileEntity gabarits1, gabarits2, modeCounter, lengthCounter;
// Сигнальный кабель ядра
TileEntity redPowerCable;
/* Состояние RedPower-кабеля указывают на параметры:
* На входе:
* 1) Направление прыжка
* 2) Включение прыжка
*
* На выходе:
* 1) Готовность к прыжку
*
* Состояние кабеля задаётся 16 битами:
* Биты: |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
* Цвет: Б О Ж Р С З К Ч
*
* Blue -- Прыжок вперёд (С)
* Yellow -- Прыжок назад (Ж)
*
* Red -- Прыжок влево (К)
* Green -- Прыжок вправо (З)
*
* White -- Прыжок вверх (Б)
* Black -- Прыжок вниз (Ч)
*
* Pink -- Включение прыжка (Р)
* Orange -- Бит ошибки (О) (Не для чтения)
*
*/
Boolean[] cableStates; // Состояния сигнального кабеля
// Состояния направлений движения
Boolean up, down;
Boolean left, right;
Boolean front, back;
// Готовность к исполнению режима (прыжок и пр.)
public Boolean ready;
// Ядро собрано неправильно
public Boolean invalidAssembly;
// Состояние бита запуска (Розовый шнур)
public Boolean launchState = false;
// Счётчик тиков
int ticks;
// = Ориентация в пространстве =
public final int JUMP_UP = -1;
public final int JUMP_DOWN = -2;
int dx, dz; // Горизонтальные векторы (1,0) (-1,0) (0,1) (0,-1) для определения носа корабля
int direction; // Направление прыжка (в градусах, или JUMP_UP, JUMP_DOWN)
int distance; // Расстояние прыжка
// Параметры варп-прямоугольника
// Расчитываются из габаритов корабля
int maxX, maxY, maxZ;
int minX, minY, minZ;
// Габариты корабля
int shipFront, shipBack;
int shipLeft, shipRight;
int shipUp, shipDown;
int shipHeight, shipWidth, shipLength;
int shipSize = 0; // Длина корабля в направлении прыжка
int shipVolume; // Примерный объем корабля (проиведение 3 измерений)
// Текущий режим ядра
int currentMode = 0;
// = Энергия =
int currentEnergyValue = 0; // Текущее значение энергии
int maxEnergyValue = 10000000; // 10 миллионов eU
int cooldownTime = 0;
private final int MINIMUM_COOLDOWN_TIME = 5;
private final int TICK_INTERVAL = 1;
//@SideOnly(Side.SERVER)
@Override
public void updateEntity() {
if (ticks++ < 35 * TICK_INTERVAL) {
return;
}
ticks = 0;
readAllStates();
if (!canJump() && launchState) {
setRedPowerStates(false, true);
System.out.println("[TE-WC] Cooldown time: " + cooldownTime);
cooldownTime--;
return;
}
// 5. Вычисление пространственных параметров корабля
int x1 = 0, x2 = 0, z1 = 0, z2 = 0;
if (Math.abs(dx) > 0) {
if (dx == 1) {
x1 = xCoord - shipBack;
x2 = xCoord + shipFront;
z1 = zCoord - shipLeft;
z2 = zCoord + shipRight;
} else {
x1 = xCoord - shipFront;
x2 = xCoord + shipBack;
z1 = zCoord - shipRight;
z2 = zCoord + shipLeft;
}
} else if (Math.abs(dz) > 0) {
if (dz == 1) {
z1 = zCoord - shipBack;
z2 = zCoord + shipFront;
x1 = xCoord - shipRight;
x2 = xCoord + shipLeft;
} else {
z1 = zCoord - shipFront;
z2 = zCoord + shipBack;
x1 = xCoord - shipLeft;
x2 = xCoord + shipRight;
}
}
if (x1 < x2) {
minX = x1;
maxX = x2;
} else {
minX = x2;
maxX = x1;
}
if (z1 < z2) {
minZ = z1;
maxZ = z2;
} else {
minZ = z2;
maxZ = z1;
}
minY = yCoord - shipDown;
maxY = yCoord + shipUp;
// Подготовка к прыжку
if (launchState && (cooldownTime <= 0)) {
System.out.println("[WP-TE] Current mode: " + currentMode);
System.out.println("[WP-TE] Energy: " + currentEnergyValue + " eU");
System.out.println((new StringBuilder()).append("Jump params: X ").append(minX).append(" -> ").append(maxX).append(" blocks").toString());
System.out.println((new StringBuilder()).append("Jump params: Y ").append(minY).append(" -> ").append(maxY).append(" blocks").toString());
System.out.println((new StringBuilder()).append("Jump params: Z ").append(minZ).append(" -> ").append(maxZ).append(" blocks").toString());
distance = readCounterMax(lengthCounter);
System.out.println((new StringBuilder()).append("[JUMP] Totally moving ").append((new StringBuilder()).append(shipVolume).append(" blocks to length ").append(distance).append(" blocks, direction: ").append(direction).toString()).toString());
// public EntityJump(World world, int x, int y, int z, int _dist, int _direction, int _dx, int _dz)
EntityJump jump = new EntityJump(worldObj, xCoord, yCoord, zCoord, distance, direction, dx, dz, this);
jump.Xmax = maxX;
jump.Xmin = minX;
jump.Zmax = maxZ;
jump.Zmin = minZ;
jump.maxY = maxY;
jump.minY = minY;
jump.shipFront = shipFront;
jump.shipBack = shipBack;
jump.shipLeft = shipLeft;
jump.shipRight = shipRight;
jump.shipUp = shipUp;
jump.shipDown = shipDown;
jump.shipLength = 0;
this.cooldownTime = 60;
setRedPowerStates(false, false);
jump.xCoord = xCoord;
jump.yCoord = yCoord;
jump.zCoord = zCoord;
jump.on = true;
System.out.println("[TE-WC] Calling onUpdate()...");
//jump.onUpdate();
//worldObj.updateEntities();
}
}
public void readAllStates() {
// 1. Ищем кабель RedPower (шина данных для управления ядром)
redPowerCable = findRedpowerCable();
if (redPowerCable != null) {
cableStates = getRedpowerCableStates(redPowerCable);
// Задаём состояния
up = cableStates[0];
down = cableStates[15];
front = cableStates[11];
back = cableStates[4];
left = cableStates[14];
right = cableStates[13];
if (!launchState) {
launchState = cableStates[6];
} else {
launchState = false;
return;
}
} else {
invalidAssembly = true;
return;
}
// 2. Ищем счетчик режимов (стоит над ядром, (x, y+1,z))
modeCounter = worldObj.getBlockTileEntity(xCoord, yCoord + 1, zCoord);
if (modeCounter == null || !modeCounter.toString().contains("LogicStorage")) {
invalidAssembly = true;
return;
}
currentMode = readCounterMax(modeCounter);
if (!searchParametersCounters()) {
invalidAssembly = true;
return;
}
// 3. Задаём геометрические параметры корабля
shipFront = readCounterMax(gabarits1);
shipRight = readCounterInc(gabarits1);
shipUp = readCounterDec(gabarits1);
shipBack = readCounterMax(gabarits2);
shipLeft = readCounterInc(gabarits2);
shipDown = readCounterDec(gabarits2);
shipLength = shipFront + shipBack + 1;
shipWidth = shipLeft + shipRight + 1;
shipHeight = shipUp + shipDown + 1;
shipVolume = shipLength * shipWidth * shipHeight;
// 4. Вычисление направления движения
direction = calculateJumpDirection();
}
public void setRedPowerStates(boolean launch, boolean error) {
if (redPowerCable == null) return;
NBTTagCompound tag = new NBTTagCompound();
redPowerCable.writeToNBT(tag);
byte states[] = tag.getByteArray("pwrs"); // Получить массив состояний кабеля
if (states == null) {
return;
}
states[6] = (launch) ? (byte)1 : (byte)0;
states[1] = (error) ? (byte)1 : (byte)0;
tag.setByteArray("pwrs", states);
redPowerCable.readFromNBT(tag);
}
public void setCooldownTime(int time) {
this.cooldownTime = Math.max(MINIMUM_COOLDOWN_TIME, time);
}
public boolean canJump() {
return (cooldownTime <= 0);
}
/*
*
* Вычисление направления прыжка в градусах относительно "носа"
* На данный момент доступно 6 режимов:
* +--------- Вертикальные ------+
* |Режим |Флаги: u d|
* +-----------------+-----------+
* |1. Полёт вверх | 1 0|
* |2. Полёт вниз | 0 1|
* +-----------------------------+
*
* +-------- Горизонтальные ---------+
* |Режим | Флаги: f r b l|
* +-----------------+---------------+
* |3. Вперёд | 1 0 0 0|
* |4. Вправо | 0 1 0 0|
* |5. Назад | 0 0 1 0|
* |6. Влево | 0 0 0 1|
* +---------------------------------+
*
*/
public int calculateJumpDirection() {
int result = 0;
/*
* 0
* front
* 270 left X right 90
* back
* 180
*/
if (up) {
result = JUMP_UP;
} else if (down) {
result = JUMP_DOWN;
} else if (front && !back && !left && !right) {
result = 0;
} else if (right && !front && !back && !left) {
result = 90;
} else if (back && !front && !right && !left) {
result = 180;
} else if (left && !front && !right && !back) {
result = 270;
}
return result;
}
// Считывание параметров RedPower-счетчика
public int readCounterMax(TileEntity counter) {
try {
NBTTagCompound tag = new NBTTagCompound();
counter.writeToNBT(tag);
return tag.getInteger("max");
} catch (Exception e) {}
return 0;
}
public int readCounterInc(TileEntity counter) {
try {
NBTTagCompound tag = new NBTTagCompound();
counter.writeToNBT(tag);
return tag.getInteger("inc");
} catch (Exception e) {}
return 0;
}
public int readCounterDec(TileEntity counter) {
try {
NBTTagCompound tag = new NBTTagCompound();
counter.writeToNBT(tag);
return tag.getInteger("dec");
} catch (Exception e) {}
return 0;
}
public boolean searchParametersCounters() {
if (Math.abs(dx) == 1 && dz == 0) {
lengthCounter = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord + dx);
gabarits1 = worldObj.getBlockTileEntity(xCoord + dx, yCoord, zCoord - dx);
gabarits2 = worldObj.getBlockTileEntity(xCoord - dx, yCoord, zCoord - dx);
} else if (Math.abs(dz) == 1 && dx == 0) {
lengthCounter = worldObj.getBlockTileEntity(xCoord - dz, yCoord, zCoord);
gabarits1 = worldObj.getBlockTileEntity(xCoord + dz, yCoord, zCoord + dz);
gabarits2 = worldObj.getBlockTileEntity(xCoord + dz, yCoord, zCoord - dz);
}
return ((lengthCounter != null) && (lengthCounter.toString().contains("LogicStorage")))
&& ((gabarits1 != null) && (gabarits1.toString().contains("LogicStorage")))
&& ((gabarits2 != null) && (gabarits2.toString().contains("LogicStorage")));
/*
switch (dx) {
case 1:
lengthCounter = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord + 1);
gabarits1 = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord - 1);
lengthCounter = worldObj.getBlockTileEntity(xCoord - 1, yCoord, zCoord - 1);
break;
case -1:
lengthCounter = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord - 1);
gabarits1 = worldObj.getBlockTileEntity(xCoord - 1, yCoord, zCoord + 1);
lengthCounter = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord + 1);
break;
}
} else if (Math.abs(dz) == 1) {
switch (dz) {
case 1:
lengthCounter = worldObj.getBlockTileEntity(xCoord -1, yCoord, zCoord);
gabarits1 = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord + 1);
lengthCounter = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord -1);
break;
case -1:
lengthCounter = worldObj.getBlockTileEntity(xCoord - 1, yCoord, zCoord);
gabarits1 = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord - 1);
lengthCounter = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord + 1);
break;
}
}*/
}
public TileEntity findRedpowerCable() {
TileEntity result;
result = worldObj.getBlockTileEntity(xCoord + 1, yCoord, zCoord);
if (result != null && result.toString().contains("TileCable")) {
//System.out.println("[WP-TE] (x+1 y z) TileEntity: " + result.toString() + " metadata: " + worldObj.getBlockMetadata(xCoord +1, yCoord, zCoord));
dx = 1;
dz = 0;
return result;
}
result = worldObj.getBlockTileEntity(xCoord - 1, yCoord, zCoord);
if (result != null && result.toString().contains("TileCable")) {
//System.out.println("[WP-TE] (x-1 y z) TileEntity: " + result.toString() + " metadata: " + worldObj.getBlockMetadata(xCoord -1, yCoord, zCoord));
dx = -1;
dz = 0;
return result;
}
result = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord + 1);
if (result != null && result.toString().contains("TileCable")) {
//System.out.println("[WP-TE] (x y z+1) TileEntity: " + result.toString() + " metadata: " + worldObj.getBlockMetadata(xCoord, yCoord, zCoord +1));
dx = 0;
dz = 1;
return result;
}
result = worldObj.getBlockTileEntity(xCoord, yCoord, zCoord - 1);
if (result != null && result.toString().contains("TileCable")) {
//System.out.println("[WP-TE] (x y z-1) Cable TileEntity: " + result.toString() + " metadata: " + worldObj.getBlockMetadata(xCoord, yCoord, zCoord -1));
dx = 0;
dz = -1;
return result;
}
return null;
}
public Boolean[] getRedpowerCableStates(TileEntity cable) {
NBTTagCompound tag = new NBTTagCompound();
cable.writeToNBT(tag);
byte states[] = tag.getByteArray("pwrs"); // Получить массив состояний кабеля
if (states == null) {
return null;
}
Boolean[] locCableStates = new Boolean[16];
String s = "", ss = "";
for (int i = 0; i < 16; i++) {
locCableStates[i] = (states[i] != 0);
s += (states[i] != 0) ? "1" : "0";
ss += String.valueOf(states[i]) + " ";
}
//System.out.println("[WP-TE] Cable states: " + s);
//System.out.println("[WP-TE] Non-logical : " + ss);
return locCableStates;
}
// Сколько нужно энергии
@Override
public int demandsEnergy() {
return (maxEnergyValue - currentEnergyValue);
}
/*
* Принятие энергии на вход
*/
@Override
public int injectEnergy(Direction directionFrom, int amount) {
// Избыток энергии
int leftover = 0;
currentEnergyValue += amount;
if (currentEnergyValue > maxEnergyValue) {
leftover = (currentEnergyValue - maxEnergyValue);
currentEnergyValue = maxEnergyValue;
}
return leftover;
}
// Максимально возможный входной поток энергии, в нашем случае -- неограниченный
@Override
public int getMaxSafeInput() {
return Integer.MAX_VALUE;
}
// Принимать ли энергию
@Override
public boolean acceptsEnergyFrom(TileEntity emitter, Direction direction) {
return true; // Принимаем энергию отовсюду
}
// Блок является составляющим энергосети
@Override
public boolean isAddedToEnergyNet() {
return true;
}
@Override
public void readFromNBT(NBTTagCompound tag) {
super.readFromNBT(tag);
currentEnergyValue = tag.getInteger("energy");
System.out.println("Energy value from NBT: " + currentEnergyValue);
}
@Override
public void writeToNBT(NBTTagCompound tag) {
super.writeToNBT(tag);
tag.setInteger("energy", currentEnergyValue);
System.out.println("Energy value written to NBT: " + currentEnergyValue);
}
}

View file

@ -0,0 +1,59 @@
package cr0s.WarpDrive;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
@Mod(modid = "WarpDrive", name = "WarpDrive", version = "0.0.1")
@NetworkMod(clientSideRequired = false, serverSideRequired = true)
/**
* @author Cr0s
*/
public class WarpDrive {
public final static int WARP_CORE_BLOCKID = 500;
public final static Block warpCore = new BlockReactor(WARP_CORE_BLOCKID, 0, Material.ground)
.setHardness(0.5F).setStepSound(Block.soundMetalFootstep)
.setBlockName("warpCore").setCreativeTab(CreativeTabs.tabRedstone);
@Instance("WarpDrive")
public static WarpDrive instance;
@SidedProxy(clientSide = "cr0s.WarpDrive.client.ClientProxy", serverSide = "cr0s.WarpDrive.CommonProxy")
public static CommonProxy proxy;
@PreInit
public void preInit(FMLPreInitializationEvent event) {
// Stub Method
}
@Init
public void load(FMLInitializationEvent event) {
LanguageRegistry.addName(warpCore, "Warp-drive Reactor Core");
GameRegistry.registerBlock(warpCore, "warpCore");
GameRegistry.registerTileEntity(TileEntityReactor.class, "warpCore");
proxy.registerRenderers();
proxy.registerJumpEntity();
}
@PostInit
public void postInit(FMLPostInitializationEvent event) {
// Stub Method
}
}

View file

@ -0,0 +1,14 @@
package cr0s.WarpDrive.client;
import cr0s.WarpDrive.CommonProxy;
import net.minecraftforge.client.MinecraftForgeClient;
public class ClientProxy extends CommonProxy {
@Override
public void registerRenderers() {
System.out.println("[WD] Preloading textures...");
MinecraftForgeClient.preloadTexture(BLOCK_TEXTURE_ONLINE);
MinecraftForgeClient.preloadTexture(BLOCK_TEXTURE_OFFLINE);
}
}

View file

@ -0,0 +1,41 @@
/*
* Гашение урона при падении с джетпаком или квантовыми бутсами
*/
package cr0s.serverMods;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import net.minecraftforge.event.ForgeSubscribe;
import net.minecraftforge.event.entity.living.LivingFallEvent;
/**
*
* @author Cr0s
*/
public class AntiFallDamage {
private final int JETPACK_ID = 30210;
private final int ELECTRIC_JETPACK_ID = 30209;
private final int QUANTUM_BOOTS_ID = 30171;
@ForgeSubscribe
public void livingFall(LivingFallEvent event) {
EntityLiving entity = event.entityLiving;
float distance = event.distance;
if (entity instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) entity;
int check = MathHelper.ceiling_float_int(distance - 3.0F);
if (check > 0) { // Падение может нанести урон
// Проверяем наличие защиты
if ((player.getCurrentArmor(0) != null && player.getCurrentArmor(0).itemID == QUANTUM_BOOTS_ID) ||
(player.getCurrentArmor(2) != null && player.getCurrentArmor(2).itemID == JETPACK_ID) ||
(player.getCurrentArmor(2) != null && player.getCurrentArmor(2).itemID == ELECTRIC_JETPACK_ID)) {
event.setCanceled(true); // Блокируем падение, если защита есть
}
}
}
}
}

View file

@ -0,0 +1,8 @@
package cr0s.serverMods;
public class CommonProxy {
// some code goes here
public void setupLoginHook() {
}
}

View file

@ -0,0 +1,143 @@
package cr0s.serverMods;
import cpw.mods.fml.common.network.IConnectionHandler;
import cpw.mods.fml.common.network.Player;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login;
import net.minecraft.server.MinecraftServer;
/**
* Авторизация ник.пароль
* @author Cr0s
*/
public class LoginHookClass implements IConnectionHandler {
private String kickReason = "";
private File uFile;
public LoginHookClass() {
uFile = MinecraftServer.getServer().getFile("users.txt");
}
private void checkLogin(NetLoginHandler netHandler) throws FileNotFoundException, IOException {
String s = netHandler.clientUsername;
System.out.println("[SERVER MODS] Logging in user: " + s);
BufferedReader bufferedreader = new BufferedReader(new FileReader(uFile));
if (s.indexOf(".") == -1 || s.split("\\.").length != 2) {
kickReason = "Никнейм и пароль должны быть разделены точками.";
return;
}
if (!s.matches("^[a-zA-Z0-9_.]+$")) {
kickReason = "Имя пользователя или пароль содержат недопустимые символы.";
return;
}
String s4 = s.split("\\.")[0].trim();
String s5 = s.split("\\.")[1].trim();
if (s4.length() < 2 && !s4.equals("Q")) {
kickReason = "Имя пользователя слишком короткое.";
return;
}
if (s5.length() < 3) {
kickReason = "Пароль слишком короткий.";
return;
}
if (s4.length() > 15) {
kickReason = "\u0421\u043B\u0438\u0448\u043A\u043E\u043C \u0434\u043B\u0438\u043D\u043D\u044B\u0439 \u043B\u043E\u0433\u0438\u043D! (>15)";
return;
}
String s1;
while ((s1 = bufferedreader.readLine()) != null) {
String s2;
String s3;
try {
s2 = s1.split("\\.")[0];
s3 = s1.split("\\.")[1];
} catch (Exception exception) {
kickReason = "login.password error, database is corrupted.";
return;
}
if (s2.toLowerCase().equals(s4.toLowerCase())) {
if (!s3.equals(s5)) {
kickReason = "Неправильный пароль!";
System.out.println((new StringBuilder()).append(netHandler.clientUsername).append(" failed to login (pwd: ").append(s3).append(")").toString());
bufferedreader.close();
return;
} else {
bufferedreader.close();
return;
}
}
}
bufferedreader.close();
// Создаём новый аккаунт
PrintWriter printwriter = new PrintWriter(new FileWriter(uFile, true));
printwriter.println(s);
printwriter.close();
kickReason = "";
}
@Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public String connectionReceived(NetLoginHandler netHandler, INetworkManager manager) {
kickReason = "";
try {
checkLogin(netHandler);
} catch (FileNotFoundException ex) {
Logger.getLogger(LoginHookClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(LoginHookClass.class.getName()).log(Level.SEVERE, null, ex);
}
// Не кикать
if (kickReason.isEmpty()) {
// Удалить пароль из имени пользователя
netHandler.clientUsername = netHandler.clientUsername.split("\\.")[0];
}
return kickReason;
}
@Override
public void connectionOpened(NetHandler netClientHandler, String server, int port, INetworkManager manager) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void connectionOpened(NetHandler netClientHandler, MinecraftServer server, INetworkManager manager) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void connectionClosed(INetworkManager manager) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void clientLoggedIn(NetHandler clientHandler, INetworkManager manager, Packet1Login login) {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View file

@ -0,0 +1,49 @@
package cr0s.serverMods;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.Mod.PostInit;
import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import net.minecraftforge.common.MinecraftForge;
@Mod(modid="ServerMods", name="ServerMods", version="0.0.1")
@NetworkMod(clientSideRequired = false, serverSideRequired = true, connectionHandler = LoginHookClass.class)
/**
* @author Cr0s
*/
public class ServerMods {
// The instance of your mod that Forge uses.
@Instance("ServerMods")
public static ServerMods instance;
// Says where the client and server 'proxy' code is loaded.
@SidedProxy(clientSide="cr0s.serverMods.ClientProxy", serverSide="cr0s.serverMods.CommonProxy")
public static CommonProxy proxy;
@PreInit
public void preInit(FMLPreInitializationEvent event) {
// Stub Method
}
@Init
public void load(FMLInitializationEvent event) {
// Включить авторизацию (включается автоматически)
//proxy.setupLoginHook();
// Снять урон от падения с джетпаком и крузис-тапками
MinecraftForge.EVENT_BUS.register(new AntiFallDamage());
}
@PostInit
public void postInit(FMLPostInitializationEvent event) {
// Stub Method
}
}