- 5,018
- 47
- 783
Привет ребят! Я тут просто решил выложить, мож подсобите чем . Это не совсем учебник, это как бы открытая документация одного из классов ракет в галактиккрафте. Я просто не знал, куда это еще запихнуть.Я решил ее для себя сделать, чтобы более -менее разобраться в нем. Мне ж не просто API юзать.
Код:
public abstract class NewEntityTieredRocket extends EntityAutoRocket implements IRocketType, IDockable, IInventory, IWorldTransferCallback, ICameraZoomEntity
{
/*
* Переменная типа enumRocketType. Там как бы написано, что эта ракета должна иметь- Есть перечисление - дефолтная ракета, с инвентарем в 38, 57. 20 слотов. + креативная
*/
public EnumRocketType rocketType;
/*
* Какая то переменная "рокот". наверно что то со звуком связано(громкость?)
*/
public float rumble;
/*
* int стартового отсчета
*/
public int launchCooldown;
/*
* Cписочный массив явовский. Типа BlockVec3. Нафига?
*/
private ArrayList<BlockVec3> preGenList = new ArrayList();
private Iterator<BlockVec3> preGenIterator = null;
static boolean preGenInProgress = false;
/*
* конструктор ракеты
* внутри указываются "установкиРазмера?" Хз ваще)
* потом смещение по y равняется высоте деленной на два флоата
*/
public NewEntityTieredRocket(World par1World)
{
super(par1World);
this.setSize(0.98F, 4F);
this.yOffset = this.height / 2.0F;
}
/*
* Кажется, получение координат Entity ракеты
*/
public NewEntityTieredRocket(World world, double posX, double posY, double posZ)
{
super(world, posX, posY, posZ);
}
/*
* Кажется микдудл что то тырил с кода мода ICBM :D
* Entity инициальзация
*/
@Override
protected void entityInit()
{
super.entityInit();
}
@Override
public void setDead()
{
if (!this.isDead)
super.setDead();
//TODO reimplement once Resonant Engine comes out of alpha, bug DarkGuardsman for info
//if (Loader.isModLoaded("ICBM|Explosion"))
//{
// try
// {
// Class.forName("icbm.api.RadarRegistry").getMethod("register", Entity.class).invoke(null, this);
// }
// catch (Exception e)
// {
// e.printStackTrace();
// }
//}
//TODO reimplement once Resonant Engine comes out of alpha, bug Dark for info
//if (Loader.isModLoaded("ICBM|Explosion"))
//{
// try
// {
// Class.forName("icbm.api.RadarRegistry").getMethod("unregister", Entity.class).invoke(null, this);
// }
// catch (Exception e)
// {
// e.printStackTrace();
// }
//}
}
/*
* Чекается время от запуска ракеты
*/
public void igniteCheckingCooldown()
{
if (!this.worldObj.isRemote && this.launchCooldown <= 0)
{
this.initiatePlanetsPreGen(this.chunkCoordX, this.chunkCoordZ);
this.ignite();
}
}
private void initiatePlanetsPreGen(int cx, int cz)
{
/*
* Снова встречаемся с списочным массивом. Он тут очищается
*/
this.preGenList.clear();
/*
* Хз . Потом напишу. Что то с преГенерацией. Да мне эт и не надо
*/
//Pre-generate terrain on all possible destination planets if the destination is not being controlled by a Launch Controller
//(note: this does NOT include the Moon!)
//This generates with a chunk radius of 12: so for 2 planets that's 1250 chunks to pregen
//It starts at the centre and generates in circles radiating out in case it doesn't have time to finish
//These will be done: 2 chunks per tick during IGNITE phase (so 800 chunks during the 20 second launch countdown)
//then the ones that are left 1 chunk per tick during flight (normally flight will last more than 450 ticks)
//If the server is at less than 20tps then maybe some of the outermost chunks won't be pre-generated but that's probably OK
/*
* пунткт Частоты? 0_o
*/
if (this.destinationFrequency == -1 && !NewEntityTieredRocket.preGenInProgress)
{
ArrayList<Integer> toPreGen = new ArrayList();
//Регистрация переменной Planet с тут же регистрацией ее в галактику
for (Planet planet : GalaxyRegistry.getRegisteredPlanets().values())
{
if (planet.getDimensionID() == this.dimension)
{
continue;
}
if (planet.getReachable() && planet.getTierRequirement() <= this.getRocketTier())
{
toPreGen.add(planet.getDimensionID());
}
}
if (toPreGen.size() > 0)
{
for (Integer dimID : toPreGen)
{
this.preGenList.add(new BlockVec3(cx, dimID, cz));
if (ConfigManagerCore.enableDebug)
{
/*
* Лог -вывод , что начинается пре-Генерация планеты
*/
GCLog.info("Starting terrain pregen for dimension " + dimID + " at " + (cx * 16 + 8) + ", " + (cz * 16 + 8));
}
}
for (int r = 1; r < 12; r++)
{
int xmin = cx - r;
int xmax = cx + r;
int zmin = cz - r;
int zmax = cz + r;
for (int i = -r; i < r; i++)
{
for (Integer dimID : toPreGen)
{
/*
* Возвращение того самого массива. Че ж это?
*
*/
this.preGenList.add(new BlockVec3(xmin, dimID, cz + i));
this.preGenList.add(new BlockVec3(xmax, dimID, cz - i));
this.preGenList.add(new BlockVec3(cx - i, dimID, zmin));
this.preGenList.add(new BlockVec3(cx + i, dimID, zmax));
}
}
}
this.preGenIterator = this.preGenList.iterator();
NewEntityTieredRocket.preGenInProgress = true;
}
}
else
{
this.preGenIterator = null;
}
}
/*
* Метод наАпдейте. Т.е апдейт ентити enable
*/
@Override
public void onUpdate()
{
//Получить... Ожидание для игрока?...
if (this.getWaitForPlayer())
{
//если ты ездил на этой сущности? (но верно - ракета enitity, по сути ракета - это лошадь)
if (this.riddenByEntity != null)
{
//тики чет то там больше сорока
if (this.ticks >= 40)
{
// стандартный ванильный строчка. Честно я до сих пор хз че это
if (!this.worldObj.isRemote)
{
Entity e = this.riddenByEntity;
// Высота сущности, походу. Дословно как "гораСущность"
e.mountEntity(null);
e.mountEntity(this);
// переустановка игрока в ракете. Под конфигом
if (ConfigManagerCore.enableDebug) GCLog.info("Remounting player in rocket.");
}
//установить ожидание для игрока - нет ожидания, false
this.setWaitForPlayer(false);
//Движение по y на -0.5 double
this.motionY = -0.5D;
}
//Иначе, если не if (this.ticks >= 40)
else
{
//все повороты равны 0 double(КЕпОчевидность)
this.motionX = this.motionY = this.motionZ = 0.0D;
//не знаю
this.riddenByEntity.motionX = this.riddenByEntity.motionY = this.riddenByEntity.motionZ = 0;
}
}
else
{//все повороты равны 0 double(КЕпОчевидность)
this.motionX = this.motionY = this.motionZ = 0.0D;
}
}
super.onUpdate();
//Если ракета посажена
if (this.landing)
{
//шаги поворот равны рысканью
this.rotationPitch = this.rotationYaw = 0;
}
if (!this.worldObj.isRemote)
{
//Если кулдаун запуска больше нуля, то вычитать по единичке из кулдауна(эм, а где его значение присваевается?..)
if (this.launchCooldown > 0)
{
this.launchCooldown--;
}
if (this.preGenIterator != null)
{
if (this.preGenIterator.hasNext())
{
MinecraftServer mcserver = FMLCommonHandler.instance().getMinecraftServerInstance();
//mcserver can be null if client switches to a LAN server
if (mcserver != null)
{
BlockVec3 coords = this.preGenIterator.next();
World w = mcserver.worldServerForDimension(coords.y);
if (w != null)
{
w.getChunkFromChunkCoords(coords.x, coords.z);
//Pregen a second chunk if still on launchpad (low strain on server)
if (this.launchPhase != EnumLaunchPhase.LAUNCHED.ordinal() && this.preGenIterator.hasNext())
{
coords = this.preGenIterator.next();
w = mcserver.worldServerForDimension(coords.y);
w.getChunkFromChunkCoords(coords.x, coords.z);
}
}
}
}
else
{
this.preGenIterator = null;
NewEntityTieredRocket.preGenInProgress = false;
}
}
}
//Если то самый рокот больше нуля, то вычитать 1
if (this.rumble > 0)
{
this.rumble--;
}
//иначе Если то самый рокот меньше нуля, то прибавлять 1
else if (this.rumble < 0)
{
this.rumble++;
}
//если Ентити оседлан, походу.
if (this.riddenByEntity != null)
{
//Сумма рокота (*** что это за рокот, то обьясните!)
final double rumbleAmount = this.rumble / (double) (37 - 5 * Math.max(this.getRocketTier(), 5));
this.riddenByEntity.posX += rumbleAmount;
this.riddenByEntity.posZ += rumbleAmount;
}
//если лаунчФаза - "зажигание" или "запуск"
if (this.launchPhase == EnumLaunchPhase.IGNITED.ordinal() || this.launchPhase == EnumLaunchPhase.LAUNCHED.ordinal())
{
//то -проанализировать больно анимация
this.performHurtAnimation();
this.rumble = (float) this.rand.nextInt(3) - 3;
}
if (!this.worldObj.isRemote)
{
this.lastLastMotionY = this.lastMotionY;
this.lastMotionY = this.motionY;
}
}
@Override
public void decodePacketdata(ByteBuf buffer)
{
this.rocketType = EnumRocketType.values()[buffer.readInt()];
super.decodePacketdata(buffer);
if (buffer.readBoolean())
{
this.posX = buffer.readDouble() / 8000.0D;
this.posY = buffer.readDouble() / 8000.0D;
this.posZ = buffer.readDouble() / 8000.0D;
}
}
@Override
public void getNetworkedData(ArrayList<Object> list)
{
list.add(this.rocketType != null ? this.rocketType.getIndex() : 0);
super.getNetworkedData(list);
boolean sendPosUpdates = this.ticks < 25 || this.launchPhase != EnumLaunchPhase.LAUNCHED.ordinal() || this.landing;
list.add(sendPosUpdates);
if (sendPosUpdates)
{
list.add(this.posX * 8000.0D);
list.add(this.posY * 8000.0D);
list.add(this.posZ * 8000.0D);
}
}
//достигаемая скорость в атмосфере, очевидно
@Override
public void onReachAtmosphere()
{
//Ого, первый комментарий. "Запуск контролируемый"
//Launch controlled
if (this.destinationFrequency != -1)
{
if (this.worldObj.isRemote)
{
//остановить звуков на клиенте - но не сброс, ракета может начать снова
//stop the sounds on the client - but do not reset, the rocket may start again
this.stopRocketSound();
return;
}
this.setTarget(true, this.destinationFrequency);
if (this.targetVec != null)
{
if (this.targetDimension != this.worldObj.provider.dimensionId)
{
WorldProvider targetDim = WorldUtil.getProviderForDimensionServer(this.targetDimension);
if (targetDim != null && targetDim.worldObj instanceof WorldServer)
{
boolean dimensionAllowed = this.targetDimension == ConfigManagerCore.idDimensionOverworld;
if (targetDim instanceof IGalacticraftWorldProvider)
{
if (((IGalacticraftWorldProvider) targetDim).canSpaceshipTierPass(this.getRocketTier()))
dimensionAllowed = true;
else
dimensionAllowed = false;
}
else
//Нет полета ракеты не Galacticraft размеры другие, чем на земле возможно, если конфиг
//No rocket flight to non-Galacticraft dimensions other than the Overworld allowed unless config
if (this.targetDimension > 1 || this.targetDimension < -1)
{
try {
Class<?> marsConfig = Class.forName("micdoodle8.mods.galacticraft.planets.mars.ConfigManagerMars");
if (marsConfig.getField("launchControllerAllDims").getBoolean(null))
dimensionAllowed = true;
} catch (Exception e) { e.printStackTrace(); }
}
if (dimensionAllowed)
{
if (this.riddenByEntity != null)
{
WorldUtil.transferEntityToDimension(this.riddenByEntity, this.targetDimension, (WorldServer) targetDim.worldObj, false, this);
}
else
{
Entity e = WorldUtil.transferEntityToDimension(this, this.targetDimension, (WorldServer)targetDim.worldObj, false, null);
if(e instanceof EntityAutoRocket)
{
e.setPosition(this.targetVec.x + 0.5F, this.targetVec.y + 800, this.targetVec.z + 0.5f);
((EntityAutoRocket)e).landing = true;
((EntityAutoRocket)e).setWaitForPlayer(false);
}
else {
GCLog.info("Error: failed to recreate the unmanned rocket in landing mode on target planet.");
e.setDead();
this.setDead();
}
}
return;
}
}
//Не пункт назначения мир найден - в этой ситуации продложать дальше на регулярные взлета(если запуск неконтрлируемый)
//No destination world found - in this situation continue into regular take-off (as if Not launch controlled)
}
else
{
/**
* Как я рад нормальным комментариям!!!
*/
// Некоторые измерения контролируют ракетный полет
//Same dimension controlled rocket flight
this.setPosition(this.targetVec.x + 0.5F, this.targetVec.y + 800, this.targetVec.z + 0.5F);
if (this.riddenByEntity != null)
{
this.setWaitForPlayer(true);
if (ConfigManagerCore.enableDebug) GCLog.info("Rocket repositioned, waiting for player");
}
this.landing = true;
//Не уничтожать ракету, она нам еще нужна!
//Do not destroy the rocket, we still need it!
return;
}
}
else
{
//Тут короче, если ракета запущена, а частота внезапно изменилась, то ракета будет потеряна. Однако он обещает расследование!
//Launch controlled launch but no valid target frequency = rocket loss [INVESTIGATE]
GCLog.info("Error: the launch controlled rocket failed to find a valid landing spot when it reached space.");
this.setDead();
return;
}
}
//Не контролируемый запуск
//Not launch controlled
if (this.riddenByEntity != null && !this.worldObj.isRemote)
{
if (this.riddenByEntity instanceof EntityPlayerMP)
{
EntityPlayerMP player = (EntityPlayerMP) this.riddenByEntity;
this.onTeleport(player);
GCPlayerStats stats = GCPlayerStats.get(player);
WorldUtil.toCelestialSelection(player, stats, this.getRocketTier());
}
}
//Уничтожить! любые ракеты, которая достигла вершины атмосферы и не контролируется контроллером запуска
//Destroy any rocket which reached the top of the atmosphere and is not controlled by a Launch Controller
this.setDead();
}
//Следует отменить взрыв, если прошлый(последний) поворот по Y меньше четырех. Не вдупляю пока
@Override
protected boolean shouldCancelExplosion()
{
return this.hasValidFuel() && Math.abs(this.lastLastMotionY) < 4;
}
public void onTeleport(EntityPlayerMP player)
{
}
//Ракета на земле, тогда запуск начинается с 40 сек?... Не было такого
@Override
protected void onRocketLand(int x, int y, int z)
{
super.onRocketLand(x, y, z);
this.launchCooldown = 40;
}
@Override
public void onLaunch()
{
super.onLaunch();
}
//следует двигаться на стороне клиента - да\нет(true\false)
@Override
protected boolean shouldMoveClientSide()
{
return true;
}
//Первое взаимодействие!
@Override
public boolean interactFirst(EntityPlayer par1EntityPlayer)
{
//если лаунчФаза - запуск то ... - нет? (false)?
if (this.launchPhase == EnumLaunchPhase.LAUNCHED.ordinal())
{
return false;
}
if (this.riddenByEntity != null && this.riddenByEntity instanceof EntityPlayerMP)
{
if (!this.worldObj.isRemote && this.riddenByEntity == par1EntityPlayer)
{
//Пакеты. Ну их нахер, я ужаснулся, когда открыл
GalacticraftCore.packetPipeline.sendTo(new PacketSimple(EnumSimplePacket.C_RESET_THIRD_PERSON, new Object[] { }), (EntityPlayerMP) par1EntityPlayer);
GCPlayerStats stats = GCPlayerStats.get((EntityPlayerMP) par1EntityPlayer);
stats.chatCooldown = 0;
par1EntityPlayer.mountEntity(null);
}
return true;
}
else if (par1EntityPlayer instanceof EntityPlayerMP)
{
if (!this.worldObj.isRemote)
{
GalacticraftCore.packetPipeline.sendTo(new PacketSimple(EnumSimplePacket.C_DISPLAY_ROCKET_CONTROLS, new Object[] { }), (EntityPlayerMP) par1EntityPlayer);
GCPlayerStats stats = GCPlayerStats.get((EntityPlayerMP) par1EntityPlayer);
stats.chatCooldown = 0;
par1EntityPlayer.mountEntity(this);
}
return true;
}
return false;
}
@Override
protected void writeEntityToNBT(NBTTagCompound nbt)
{
nbt.setInteger("Type", this.rocketType.getIndex());
super.writeEntityToNBT(nbt);
}
@Override
protected void readEntityFromNBT(NBTTagCompound nbt)
{
this.rocketType = EnumRocketType.values()[nbt.getInteger("Type")];
super.readEntityFromNBT(nbt);
}
/*
* ъПолучить тип ракеты
* DEFAULT(0, "", false, 2),
INVENTORY27(1, StatCollector.translateToLocal("gui.rocketType.0"), false, 20),
INVENTORY36(2, StatCollector.translateToLocal("gui.rocketType.1"), false, 38),
INVENTORY54(3, StatCollector.translateToLocal("gui.rocketType.2"), false, 56),
PREFUELED(4, StatCollector.translateToLocal("gui.rocketType.3"), true, 2);
*/
@Override
public EnumRocketType getType()
{
return this.rocketType;
}
//Получить размер инвентаря в ракете
@Override
public int getSizeInventory()
{
if (this.rocketType == null) return 2;
return this.rocketType.getInventorySpace();
}
//на мир переносится
@Override
public void onWorldTransferred(World world)
{
if (this.targetVec != null)
{
this.setPosition(this.targetVec.x + 0.5F, this.targetVec.y + 800, this.targetVec.z + 0.5F);
this.landing = true;
this.setWaitForPlayer(true);
this.motionX = this.motionY = this.motionZ = 0.0D;
}
else
{
this.setDead();
}
}
@Override
public void updateRiderPosition()
{
if (this.riddenByEntity != null)
{
this.riddenByEntity.setPosition(this.posX, this.posY + this.getMountedYOffset() + this.riddenByEntity.getYOffset(), this.posZ);
}
}
public float getRotateOffset()
{
return -1.5F;
}
//Имеет игрок ракету?
@Override
public boolean isPlayerRocket()
{
return true;
}
}