Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into OC1.3-MC1.7.10

This commit is contained in:
Florian Nücke 2014-09-10 01:15:44 +02:00
commit 1908043c11
10 changed files with 35 additions and 689 deletions

View File

@ -45,14 +45,14 @@ repositories {
maven { url = "http://maven.cil.li/" } maven { url = "http://maven.cil.li/" }
} }
dependencies { dependencies {
compile group: 'li.cil.oc', name: 'OpenComputers', version: 'MC1.7.10-1.3.3.61', classifier: 'api' compile "li.cil.oc:OpenComputers:MC1.7.10-1.3.+:api"
} }
``` ```
Adjust the version number accordingly to the version you'd like to build against. Adjust the version number accordingly to the version you'd like to build against.
To run the mod in your development environment, download the [`deobf` JAR from the build server][deobf-jar] and drop it into your dev env's `eclipse/mods` folder. To run the mod in your development environment, download the [`dev` JAR from the build server][dev-jar] and drop it into your dev env's `eclipse/mods` folder.
Alternatively, leave out the `api` classifier and you can build against the deobf JAR directly. This way you don't have to add it to your mods folder, but you will have to add `-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader` to the VM options in your run configuration. Alternatively, leave out the `api` classifier and you can build against the dev JAR directly. This way you don't have to add it to your mods folder, but you will have to add `-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader` to the VM options in your run configuration.
If you have any questions, please do not hesitate to ask, either in the [forums][] or in the [IRC][irc]! If you have any questions, please do not hesitate to ask, either in the [forums][] or in the [IRC][irc]!
@ -69,13 +69,13 @@ to setup the workspace, including assets and such, then
`gradlew idea` `gradlew idea`
to create an IntellJ IDEA project. to create an IntellJ IDEA project.
Open the project and you will be asked to import the Gradle project (check your Event Log if you missed the pop-up). Do so. This will configure additionally referenced libraries - at this point CodeChickenLib and ForgeMultipart. Since CCL adn such will download stuff again and you'll get conflicts otherwise, go into the project settings and mark CCL, FMP and NEI if you have it in your mods folder as "provided" (instead of the default, "compile"). Open the project and you will be asked to *import the Gradle project* (check your Event Log if you missed the pop-up). **Do so**. This will configure additionally referenced libraries.
[api]: https://github.com/MightyPirates/OpenComputers/tree/master/src/main/java/li/cil/oc/api [api]: https://github.com/MightyPirates/OpenComputers/tree/master/src/main/java/li/cil/oc/api
[code conventions]: https://github.com/MightyPirates/OpenComputers/wiki/CodeConventions [code conventions]: https://github.com/MightyPirates/OpenComputers/wiki/CodeConventions
[deobf-jar]: http://oc.cil.li/index.php?/page/latest.php?repo=OpenComputers-MC1.7&type=deobf [dev-jar]: http://oc.cil.li/index.php?/page/latest.php?repo=OpenComputers-MC1.7&type=dev
[forums]: http://oc.cil.li/ [forums]: http://oc.cil.li/
[irc]: http://webchat.esper.net/?channels=#oc [irc]: http://webchat.esper.net/?channels=#oc
[issues]: https://github.com/MightyPirates/OpenComputers/issues?state=open [issues]: https://github.com/MightyPirates/OpenComputers/issues?state=open

View File

@ -9,10 +9,6 @@ buildscript {
name = "sonatype" name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/" url = "https://oss.sonatype.org/content/repositories/snapshots/"
} }
maven {
name = "ic2"
url = "http://maven.ic2.player.to/"
}
} }
dependencies { dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
@ -44,32 +40,47 @@ version = "MC${config.minecraft.version}-${project.version}"
repositories { repositories {
maven { maven {
name = "ic2" name = "bc"
url = "http://maven.ic2.player.to/" url = "http://mod-buildcraft.com/"
}
maven {
name = "ue"
url = "http://calclavia.com/maven/"
} }
maven { maven {
name = "chickenbones" name = "chickenbones"
url = "http://chickenbones.net/maven/" url = "http://chickenbones.net/maven/"
} }
maven {
name = "ic2"
url = "http://maven.ic2.player.to/"
}
maven { maven {
name = "mobius" name = "mobius"
url = "http://mobiusstrip.eu/maven" url = "http://mobiusstrip.eu/maven"
} }
maven {
name = "ue"
url = "http://calclavia.com/maven/"
}
} }
// From http://stackoverflow.com/questions/10405970/how-do-i-define-a-compile-time-only-classpath-in-gradle
configurations {
provided
}
dependencies { dependencies {
compile "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:dev" provided "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:dev"
compile "codechicken:ForgeMultipart:${config.minecraft.version}-${config.fmp.version}:dev" provided "codechicken:ForgeMultipart:${config.minecraft.version}-${config.fmp.version}:dev"
compile "codechicken:NotEnoughItems:${config.minecraft.version}-${config.nei.version}:dev" provided "codechicken:NotEnoughItems:${config.minecraft.version}-${config.nei.version}:dev"
compile "codechicken:WR-CBE:1.6.4-${config.wrcbe.version}:dev" provided "codechicken:WR-CBE:1.6.4-${config.wrcbe.version}:dev"
compile "net.industrial-craft:industrialcraft-2:${config.ic2.version}:api" provided "com.mod-buildcraft:buildcraft:${config.bc.version}:dev"
compile "dev.calclavia.universalelectricity:universal-electricity:+:dev" provided "dev.calclavia.universalelectricity:universal-electricity:+:dev"
compile "mcp.mobius.waila:Waila:1.5.+:dev" provided "mcp.mobius.waila:Waila:1.5.+:dev"
provided "net.industrial-craft:industrialcraft-2:${config.ic2.version}:api"
} }
sourceSets.main.compileClasspath += configurations.provided
idea.module.scopes.PROVIDED.plus += configurations.provided
eclipse.classpath.plusConfigurations += configurations.provided
minecraft { minecraft {
version = "${config.minecraft.version}-${config.forge.version}" version = "${config.minecraft.version}-${config.forge.version}"

View File

@ -4,7 +4,8 @@ oc.version=1.3.4
oc.subversion= oc.subversion=
ccl.version=1.1.1.95 ccl.version=1.1.1.95
fmp.version=1.1.0.299 fmp.version=1.1.0.299
ic2.version=2.2.616-experimental
nei.version=1.0.3.51 nei.version=1.0.3.51
wrcbe.version=1.4.0.7 wrcbe.version=1.4.0.7
bc.version=6.0.18
ic2.version=2.2.+
maven.url=file:///var/www/users/fnuecke/maven.cil.li maven.url=file:///var/www/users/fnuecke/maven.cil.li

View File

@ -1,84 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.core;
import net.minecraft.world.World;
public class SafeTimeTracker {
private long lastMark = Long.MIN_VALUE;
private long duration = -1;
private long randomRange = 0;
private long lastRandomDelay = 0;
private long internalDelay = 1;
/**
* @deprecated should use constructors with parameters instead
*/
public SafeTimeTracker () {
}
public SafeTimeTracker (long delay) {
internalDelay = delay;
}
/**
* In many situations, it is a bad idea to have all objects of the same
* kind to be waiting for the exact same amount of time, as that can lead
* to some situation where they're all synchronized and got to work all
* at the same time. When created with a random range, the mark that is set
* when reaching the expect delay will be added with a random number
* between [0, range[, meaning that the event will take between 0 and range
* more tick to run.
*/
public SafeTimeTracker (long delay, long random) {
internalDelay = delay;
randomRange = random;
}
public boolean markTimeIfDelay(World world) {
return markTimeIfDelay(world, internalDelay);
}
/**
* Return true if a given delay has passed since last time marked was called
* successfully.
*
* @deprecated should use the constructor with a delay instead, and call
* this function without a parameter
*/
public boolean markTimeIfDelay(World world, long delay) {
if (world == null)
return false;
long currentTime = world.getTotalWorldTime();
if (currentTime < lastMark) {
lastMark = currentTime;
return false;
} else if (lastMark + delay + lastRandomDelay <= currentTime) {
duration = currentTime - lastMark;
lastMark = currentTime;
lastRandomDelay = (int) (Math.random() * randomRange);
return true;
} else {
return false;
}
}
public long durationOfLastDelay() {
return duration > 0 ? duration : 0;
}
public void markTime(World world) {
lastMark = world.getTotalWorldTime();
}
}

View File

@ -1,3 +0,0 @@
@API(apiVersion="1.0",owner="BuildCraft|Core",provides="BuildCraftAPI|core")
package buildcraft.api.core;
import cpw.mods.fml.common.API;

View File

@ -1,22 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.power;
import net.minecraftforge.common.util.ForgeDirection;
/**
* Essentially only used for Wooden Power Pipe connection rules.
*
* This Tile Entity interface allows you to indicate that a block can emit power
* from a specific side.
*/
public interface IPowerEmitter {
public boolean canEmitPowerFrom(ForgeDirection side);
}

View File

@ -1,45 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.power;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
/**
* This interface should be implemented by any Tile Entity that wishes to be
* able to receive power.
*/
public interface IPowerReceptor {
/**
* Get the PowerReceiver for this side of the block. You can return the same
* PowerReceiver for all sides or one for each side.
*
* You should NOT return null to this method unless you mean to NEVER
* receive power from that side. Returning null, after previous returning a
* PowerReceiver, will most likely cause pipe connections to derp out and
* engines to eventually explode.
*
* @param side
* @return
*/
public PowerHandler.PowerReceiver getPowerReceiver(ForgeDirection side);
/**
* Call back from the PowerHandler that is called when the stored power
* exceeds the activation power.
*
* It can be triggered by update() calls or power modification calls.
*
* @param workProvider
*/
public void doWork(PowerHandler workProvider);
public World getWorld();
}

View File

@ -1,469 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.power;
import buildcraft.api.core.SafeTimeTracker;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
/**
* The PowerHandler is similar to FluidTank in that it holds your power and
* allows standardized interaction between machines.
*
* To receive power to your machine you needs create an instance of PowerHandler
* and implement IPowerReceptor on the TileEntity.
*
* If you plan emit power, you need only implement IPowerEmitter. You do not
* need a PowerHandler. Engines have a PowerHandler because they can also
* receive power from other Engines.
*
* See TileRefinery for a simple example of a power using machine.
*
* @see IPowerReceptor
* @see IPowerEmitter
*/
public final class PowerHandler {
public static enum Type {
ENGINE, GATE, MACHINE, PIPE, STORAGE;
public boolean canReceiveFromPipes() {
switch (this) {
case MACHINE:
case STORAGE:
return true;
default:
return false;
}
}
public boolean eatsEngineExcess() {
switch (this) {
case MACHINE:
case STORAGE:
return true;
default:
return false;
}
}
}
/**
* Extend this class to create custom Perdition algorithms (its not final).
*
* NOTE: It is not possible to create a Zero perdition algorithm.
*/
public static class PerditionCalculator {
public static final float DEFAULT_POWERLOSS = 1F;
public static final float MIN_POWERLOSS = 0.01F;
private final double powerLoss;
public PerditionCalculator() {
powerLoss = DEFAULT_POWERLOSS;
}
/**
* Simple constructor for simple Perdition per tick.
*
* @param powerLoss power loss per tick
*/
public PerditionCalculator(double powerLoss) {
if (powerLoss < MIN_POWERLOSS) {
powerLoss = MIN_POWERLOSS;
}
this.powerLoss = powerLoss;
}
/**
* Apply the perdition algorithm to the current stored energy. This
* function can only be called once per tick, but it might not be called
* every tick. It is triggered by any manipulation of the stored energy.
*
* @param powerHandler the PowerHandler requesting the perdition update
* @param current the current stored energy
* @param ticksPassed ticks since the last time this function was called
* @return
*/
public double applyPerdition(PowerHandler powerHandler, double current, long ticksPassed) {
current -= powerLoss * ticksPassed;
if (current < 0) {
current = 0;
}
return current;
}
/**
* Taxes a flat rate on all incoming power.
*
* Defaults to 0% tax rate.
*
* @return percent of input to tax
*/
public double getTaxPercent() {
return 0;
}
}
public static final PerditionCalculator DEFAULT_PERDITION = new PerditionCalculator();
public static final double ROLLING_AVERAGE_WEIGHT = 100.0;
public static final double ROLLING_AVERAGE_NUMERATOR = ROLLING_AVERAGE_WEIGHT - 1;
public static final double ROLLING_AVERAGE_DENOMINATOR = 1.0 / ROLLING_AVERAGE_WEIGHT;
private double minEnergyReceived;
private double maxEnergyReceived;
private double maxEnergyStored;
private double activationEnergy;
private double energyStored = 0;
private final SafeTimeTracker doWorkTracker = new SafeTimeTracker();
private final SafeTimeTracker sourcesTracker = new SafeTimeTracker();
private final SafeTimeTracker perditionTracker = new SafeTimeTracker();
public final int[] powerSources = new int[6];
public final IPowerReceptor receptor;
private PerditionCalculator perdition;
private final PowerReceiver receiver;
private final Type type;
// Tracking
private double averageLostPower = 0;
private double averageReceivedPower = 0;
private double averageUsedPower = 0;
public PowerHandler(IPowerReceptor receptor, Type type) {
this.receptor = receptor;
this.type = type;
this.receiver = new PowerReceiver();
this.perdition = DEFAULT_PERDITION;
}
public PowerReceiver getPowerReceiver() {
return receiver;
}
public double getMinEnergyReceived() {
return minEnergyReceived;
}
public double getMaxEnergyReceived() {
return maxEnergyReceived;
}
public double getMaxEnergyStored() {
return maxEnergyStored;
}
public double getActivationEnergy() {
return activationEnergy;
}
public double getEnergyStored() {
return energyStored;
}
/**
* Setup your PowerHandler's settings.
*
* @param minEnergyReceived This is the minimum about of power that will be
* accepted by the PowerHandler. This should generally be greater than the
* activationEnergy if you plan to use the doWork() callback. Anything
* greater than 1 will prevent Redstone Engines from powering this Provider.
* @param maxEnergyReceived The maximum amount of power accepted by the
* PowerHandler. This should generally be less than 500. Too low and larger
* engines will overheat while trying to power the machine. Too high, and
* the engines will never warm up. Greater values also place greater strain
* on the power net.
* @param activationEnergy If the stored energy is greater than this value,
* the doWork() callback is called (once per tick).
* @param maxStoredEnergy The maximum amount of power this PowerHandler can
* store. Values tend to range between 100 and 5000. With 1000 and 1500
* being common.
*/
public void configure(double minEnergyReceived, double maxEnergyReceived, double activationEnergy, double maxStoredEnergy) {
if (minEnergyReceived > maxEnergyReceived) {
maxEnergyReceived = minEnergyReceived;
}
this.minEnergyReceived = minEnergyReceived;
this.maxEnergyReceived = maxEnergyReceived;
this.maxEnergyStored = maxStoredEnergy;
this.activationEnergy = activationEnergy;
}
/**
* Allows you define perdition in terms of loss/ticks.
*
* This function is mostly for legacy implementations. See
* PerditionCalculator for more complex perdition formulas.
*
* @param powerLoss
* @param powerLossRegularity
* @see PerditionCalculator
*/
public void configurePowerPerdition(int powerLoss, int powerLossRegularity) {
if (powerLoss == 0 || powerLossRegularity == 0) {
perdition = new PerditionCalculator(0);
return;
}
perdition = new PerditionCalculator((float) powerLoss / (float) powerLossRegularity);
}
/**
* Allows you to define a new PerditionCalculator class to handler perdition
* calculations.
*
* For example if you want exponentially increasing loss based on amount
* stored.
*
* @param perdition
*/
public void setPerdition(PerditionCalculator perdition) {
if (perdition == null)
perdition = DEFAULT_PERDITION;
this.perdition = perdition;
}
public PerditionCalculator getPerdition() {
if (perdition == null)
return DEFAULT_PERDITION;
return perdition;
}
/**
* Ticks the power handler. You should call this if you can, but its not
* required.
*
* If you don't call it, the possibility exists for some weirdness with the
* perdition algorithm and work callback as its possible they will not be
* called on every tick they otherwise would be. You should be able to
* design around this though if you are aware of the limitations.
*/
public void update() {
applyPerdition();
applyWork();
validateEnergy();
}
private void applyPerdition() {
if (perditionTracker.markTimeIfDelay(receptor.getWorld(), 1) && energyStored > 0) {
double prev = energyStored;
double newEnergy = getPerdition().applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
if (newEnergy == 0 || newEnergy < energyStored)
energyStored = newEnergy;
else
energyStored = DEFAULT_PERDITION.applyPerdition(this, energyStored, perditionTracker.durationOfLastDelay());
validateEnergy();
averageLostPower = (averageLostPower * ROLLING_AVERAGE_NUMERATOR + (prev - energyStored)) * ROLLING_AVERAGE_DENOMINATOR;
}
}
private void applyWork() {
if (energyStored >= activationEnergy) {
if (doWorkTracker.markTimeIfDelay(receptor.getWorld(), 1)) {
receptor.doWork(this);
}
}
}
private void updateSources(ForgeDirection source) {
if (sourcesTracker.markTimeIfDelay(receptor.getWorld(), 1)) {
for (int i = 0; i < 6; ++i) {
powerSources[i] -= sourcesTracker.durationOfLastDelay();
if (powerSources[i] < 0) {
powerSources[i] = 0;
}
}
}
if (source != null)
powerSources[source.ordinal()] = 10;
}
/**
* Extract energy from the PowerHandler. You must call this even if doWork()
* triggers.
*
* @param min
* @param max
* @param doUse
* @return amount used
*/
public double useEnergy(double min, double max, boolean doUse) {
applyPerdition();
double result = 0;
if (energyStored >= min) {
if (energyStored <= max) {
result = energyStored;
if (doUse) {
energyStored = 0;
}
} else {
result = max;
if (doUse) {
energyStored -= max;
}
}
}
validateEnergy();
if (doUse)
averageUsedPower = (averageUsedPower * ROLLING_AVERAGE_NUMERATOR + result) * ROLLING_AVERAGE_DENOMINATOR;
return result;
}
public void readFromNBT(NBTTagCompound data) {
readFromNBT(data, "powerProvider");
}
public void readFromNBT(NBTTagCompound data, String tag) {
NBTTagCompound nbt = data.getCompoundTag(tag);
energyStored = nbt.getDouble("energyStored");
}
public void writeToNBT(NBTTagCompound data) {
writeToNBT(data, "powerProvider");
}
public void writeToNBT(NBTTagCompound data, String tag) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setDouble("energyStored", energyStored);
data.setTag(tag, nbt);
}
public final class PowerReceiver {
private PowerReceiver() {
}
public double getMinEnergyReceived() {
return minEnergyReceived;
}
public double getMaxEnergyReceived() {
return maxEnergyReceived;
}
public double getMaxEnergyStored() {
return maxEnergyStored;
}
public double getActivationEnergy() {
return activationEnergy;
}
public double getEnergyStored() {
return energyStored;
}
public double getAveragePowerReceived() {
return averageReceivedPower;
}
public double getAveragePowerUsed() {
return averageUsedPower;
}
public double getAveragePowerLost() {
return averageLostPower;
}
public Type getType() {
return type;
}
public void update() {
PowerHandler.this.update();
}
/**
* The amount of power that this PowerHandler currently needs.
*
* @return
*/
public double powerRequest() {
update();
return Math.min(maxEnergyReceived, maxEnergyStored - energyStored);
}
/**
* Add power to the PowerReceiver from an external source.
*
* IPowerEmitters are responsible for calling this themselves.
*
* @param quantity
* @param from
* @return the amount of power used
*/
public double receiveEnergy(Type source, final double quantity, ForgeDirection from) {
double used = quantity;
if (source == Type.ENGINE) {
if (used < minEnergyReceived) {
return 0;
} else if (used > maxEnergyReceived) {
used = maxEnergyReceived;
}
}
updateSources(from);
used -= used * getPerdition().getTaxPercent();
used = addEnergy(used);
applyWork();
if (source == Type.ENGINE && type.eatsEngineExcess()) {
used = Math.min(quantity, maxEnergyReceived);
}
averageReceivedPower = (averageReceivedPower * ROLLING_AVERAGE_NUMERATOR + used) * ROLLING_AVERAGE_DENOMINATOR;
return used;
}
}
/**
*
* @return the amount the power changed by
*/
public double addEnergy(double quantity) {
energyStored += quantity;
if (energyStored > maxEnergyStored) {
quantity -= energyStored - maxEnergyStored;
energyStored = maxEnergyStored;
} else if (energyStored < 0) {
quantity -= energyStored;
energyStored = 0;
}
applyPerdition();
return quantity;
}
public void setEnergy(double quantity) {
this.energyStored = quantity;
validateEnergy();
}
public boolean isPowerSource(ForgeDirection from) {
return powerSources[from.ordinal()] != 0;
}
private void validateEnergy() {
if (energyStored < 0) {
energyStored = 0;
}
if (energyStored > maxEnergyStored) {
energyStored = maxEnergyStored;
}
}
}

View File

@ -1,3 +0,0 @@
@API(apiVersion="1.1",owner="BuildCraftAPI|core",provides="BuildCraftAPI|power")
package buildcraft.api.power;
import cpw.mods.fml.common.API;

View File

@ -1,40 +0,0 @@
/**
* Copyright (c) 2011-2014, SpaceToad and the BuildCraft Team
* http://www.mod-buildcraft.com
*
* BuildCraft is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.api.tools;
import net.minecraft.entity.player.EntityPlayer;
/***
* Implement this interface on subclasses of Item to have that item work as a wrench for buildcraft
*/
public interface IToolWrench {
/***
* Called to ensure that the wrench can be used. To get the ItemStack that is used, check player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates for the block being wrenched
*
* @return true if wrenching is allowed, false if not
*/
public boolean canWrench(EntityPlayer player, int x, int y, int z);
/***
* Callback after the wrench has been used. This can be used to decrease durability or for other purposes. To get the ItemStack that was used, check
* player.inventory.getCurrentItem()
*
* @param player
* - The player doing the wrenching
* @param x
* ,y,z - The coordinates of the block being wrenched
*/
public void wrenchUsed(EntityPlayer player, int x, int y, int z);
}