Implemented ammo ressuplying

This commit is contained in:
Anuken
2018-04-24 21:38:57 -04:00
parent 8581213126
commit deefab8a5b
25 changed files with 259 additions and 114 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

After

Width:  |  Height:  |  Size: 254 B

View File

@@ -41,9 +41,9 @@ io.anuke.ucore.scene.Skin$TintedDrawable: {
invis: {name: white, color: {r: 0, g: 0, b: 0, a: 0} } invis: {name: white, color: {r: 0, g: 0, b: 0, a: 0} }
loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} }, loadDim: {name: white, color: {r: 0, g: 0, b: 0, a: 0.8} },
chatfield: {name: white, color: {r: 0, g: 0, b: 0, a: 0.2}}, chatfield: {name: white, color: {r: 0, g: 0, b: 0, a: 0.2}},
clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.75}}, clear: {name: white, color: {r: 0.1, g: 0.1, b: 0.1, a: 0.75}},
clear-over: {name: white, color: {r: 1, g: 1, b: 1, a: 0.2} }, clear-over: {name: white, color: {r: 1, g: 1, b: 1, a: 0.2} },
clear-down: {name: white, color: {r: 1, g: 1, b: 1, a: 0.4} } clear-down: {name: white, color: {r: 1, g: 1, b: 1, a: 0.4} }
}, },
io.anuke.ucore.scene.ui.Button$ButtonStyle: { io.anuke.ucore.scene.ui.Button$ButtonStyle: {
default: {down: button-down, up: button }, default: {down: button-down, up: button },
@@ -68,10 +68,6 @@ io.anuke.ucore.scene.ui.ImageButton$ImageButtonStyle: {
select: {checked: button-select, up: clear }, select: {checked: button-select, up: clear },
close-window: {up: button, imageUp: icon-close, imageOver: icon-close-over, imageDown: icon-close-down, disabled: button } close-window: {up: button, imageUp: icon-close, imageOver: icon-close-over, imageDown: icon-close-down, disabled: button }
}, },
io.anuke.ucore.scene.ui.ImageTextButton$ImageTextButtonStyle: {
default: {down: button-down, up: button, over: button-over, disabled: button, font: default-font, fontColor: white, disabledFontColor: grey },
toggle: {checked: button-down, down: button-down, up: button, font: default-font, fontColor: white, over: button-over, disabled: button, disabledFontColor: grey }
},
io.anuke.ucore.scene.ui.ScrollPane$ScrollPaneStyle: { io.anuke.ucore.scene.ui.ScrollPane$ScrollPaneStyle: {
default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical}, default: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical},
horizontal: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical, hScroll: scroll-horizontal, hScrollKnob: scroll-knob-horizontal}, horizontal: {background: border, vScroll: scroll, vScrollKnob: scroll-knob-vertical, hScroll: scroll-horizontal, hScrollKnob: scroll-knob-horizontal},
@@ -102,8 +98,5 @@ io.anuke.ucore.scene.ui.TextField$TextFieldStyle: {
} }
io.anuke.ucore.scene.ui.CheckBox$CheckBoxStyle: { io.anuke.ucore.scene.ui.CheckBox$CheckBoxStyle: {
default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOnOver: check-on-over, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: grey } default: {checkboxOn: check-on, checkboxOff: check-off, checkboxOnOver: check-on-over, checkboxOver: check-over, font: default-font, fontColor: white, disabledFontColor: grey }
},
io.anuke.ucore.scene.ui.List$ListStyle: {
default: {fontColorUnselected: white, fontColorSelected: white, font: default-font }
} }
} }

View File

@@ -1,7 +1,7 @@
#Autogenerated file. Do not modify. #Autogenerated file. Do not modify.
#Mon Apr 23 21:27:41 EDT 2018 #Tue Apr 24 21:35:40 EDT 2018
version=pre-alpha version=pre-alpha
androidBuildCode=1090 androidBuildCode=1094
name=Mindustry name=Mindustry
code=4.0 code=4.0
build=custom build build=custom build

View File

@@ -1,16 +1,16 @@
package io.anuke.mindustry.content; package io.anuke.mindustry.content;
import io.anuke.mindustry.content.bullets.TurretBullets;
import io.anuke.mindustry.content.fx.ShootFx; import io.anuke.mindustry.content.fx.ShootFx;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
public class Weapons { public class Weapons {
public static final Weapon public static final Weapon
blaster = new Weapon("blaster", 12, TurretBullets.basicIron) { blaster = new Weapon("blaster") {{
{ length = 1.5f;
effect = ShootFx.shootSmall; reload = 15f;
length = 2f; roundrobin = true;
} ejectEffect = ShootFx.shellEjectSmall;
}; setAmmo(AmmoTypes.basicIron);
}};
} }

View File

@@ -90,15 +90,16 @@ public class ShootFx {
shellEjectSmall = new GroundEffect(30f, 400f, e -> { shellEjectSmall = new GroundEffect(30f, 400f, e -> {
Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin()); Draw.color(Palette.lightOrange, Color.LIGHT_GRAY, Palette.lightishGray, e.fin());
float rot = e.rotation + 90f; float rot = Math.abs(e.rotation) + 90f;
for(int i : Mathf.signs){
float len = (2f + e.finpow()*6f) * i; int i = Mathf.sign(e.rotation);
float lr = rot + e.fin()*30f*i;
Draw.rect("white", float len = (2f + e.finpow()*6f) * i;
e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()), float lr = rot + e.fin()*30f*i;
e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()), Draw.rect("white",
1f, 2f, rot + e.fin()*50f*i); e.x + Angles.trnsx(lr, len) + Mathf.randomSeedRange(e.id + i + 7, 3f * e.fin()),
} e.y + Angles.trnsy(lr, len) + Mathf.randomSeedRange(e.id + i + 8, 3f * e.fin()),
1f, 2f, rot + e.fin()*50f*i);
Draw.color(); Draw.color();
}), }),

View File

@@ -143,7 +143,7 @@ public class Control extends Module{
Events.on(ResetEvent.class, () -> { Events.on(ResetEvent.class, () -> {
upgrades.reset(); upgrades.reset();
player.weaponLeft = player.weaponRight = Weapons.blaster; player.weapon = Weapons.blaster;
player.team = Team.blue; player.team = Team.blue;
player.inventory.clear(); player.inventory.clear();

View File

@@ -26,8 +26,8 @@ public class NetCommon extends Module {
if (player == null) return; if (player == null) return;
player.weaponLeft = Upgrade.getByID(packet.left); player.weapon = Upgrade.getByID(packet.weapon);
player.weaponRight = Upgrade.getByID(packet.right); player.weapon = Upgrade.getByID(packet.weapon);
}); });
Net.handle(BlockTapPacket.class, (packet) -> { Net.handle(BlockTapPacket.class, (packet) -> {

View File

@@ -35,6 +35,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EffectEntity; import io.anuke.ucore.entities.EffectEntity;
import io.anuke.ucore.entities.Entities; import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.function.Callable; import io.anuke.ucore.function.Callable;
import io.anuke.ucore.graphics.*; import io.anuke.ucore.graphics.*;
@@ -65,7 +66,7 @@ public class Renderer extends RendererModule{
Lines.setCircleVertices(14); Lines.setCircleVertices(14);
Core.cameraScale = baseCameraScale; Core.cameraScale = baseCameraScale;
Effects.setEffectProvider((effect, color, x, y, rotation) -> { Effects.setEffectProvider((effect, color, x, y, rotation, data) -> {
if(effect == Fx.none) return; if(effect == Fx.none) return;
if(Settings.getBool("effects")){ if(Settings.getBool("effects")){
Rectangle view = rect.setSize(camera.viewportWidth, camera.viewportHeight) Rectangle view = rect.setSize(camera.viewportWidth, camera.viewportHeight)
@@ -82,6 +83,10 @@ public class Renderer extends RendererModule{
entity.rotation = rotation; entity.rotation = rotation;
entity.lifetime = effect.lifetime; entity.lifetime = effect.lifetime;
id = entity.set(x, y).add(effectGroup).id; id = entity.set(x, y).add(effectGroup).id;
if(data instanceof Entity){
entity.setParent((Entity)data);
}
} }
if(effect instanceof GroundEffect){ if(effect instanceof GroundEffect){

View File

@@ -27,6 +27,7 @@ public class Bullet extends BulletEntity<BulletType>{
bullet.owner = owner; bullet.owner = owner;
bullet.velocity.set(0, type.speed).setAngle(angle); bullet.velocity.set(0, type.speed).setAngle(angle);
bullet.velocity.add(owner instanceof Unit ? ((Unit)owner).velocity : Vector2.Zero);
bullet.hitbox.setSize(type.hitsize); bullet.hitbox.setSize(type.hitsize);
bullet.team = team; bullet.team = team;

View File

@@ -11,10 +11,7 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.net.NetEvents;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.resource.Mech;
import io.anuke.mindustry.resource.Upgrade;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor; import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
@@ -23,10 +20,7 @@ import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.*;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer;
import io.anuke.ucore.util.Translator;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -46,8 +40,7 @@ public class Player extends Unit{
public boolean isAdmin; public boolean isAdmin;
public Color color = new Color(); public Color color = new Color();
public Weapon weaponLeft = Weapons.blaster; public Weapon weapon = Weapons.blaster;
public Weapon weaponRight = Weapons.blaster;
public Mech mech = Mechs.standard; public Mech mech = Mechs.standard;
public float targetAngle = 0f; public float targetAngle = 0f;
@@ -72,8 +65,8 @@ public class Player extends Unit{
@Override @Override
public void onRemoteShoot(BulletType type, float x, float y, float rotation, short data) { public void onRemoteShoot(BulletType type, float x, float y, float rotation, short data) {
Weapon weapon = Upgrade.getByID((byte)data); Weapon weapon = Upgrade.getByID(Bits.getLeftByte(data));
weapon.shoot(player, x, y, rotation); weapon.shoot(player, x, y, rotation, Bits.getRightByte(data) == 1);
} }
@Override @Override
@@ -184,8 +177,7 @@ public class Player extends Unit{
Draw.rect(mname, x, y, rotation -90); Draw.rect(mname, x, y, rotation -90);
for (int i : Mathf.signs) { for (int i : Mathf.signs) {
Weapon weapon = i < 0 ? weaponLeft : weaponRight; tr.trns(rotation - 90, 4*i, 3 - weapon.getRecoil(this, i > 0)*1.5f);
tr.trns(rotation - 90, 4*i, 3);
float w = i > 0 ? -8 : 8; float w = i > 0 ? -8 : 8;
Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, rotation - 90); Draw.rect(weapon.name + "-equip", x + tr.x, y + tr.y, w, 8, rotation - 90);
} }
@@ -269,8 +261,8 @@ public class Player extends Unit{
boolean shooting = control.input().canShoot() && control.input().isShooting(); boolean shooting = control.input().canShoot() && control.input().isShooting();
if(shooting){ if(shooting){
weaponLeft.update(player, true); weapon.update(player, true);
weaponRight.update(player, false); weapon.update(player, false);
} }
if(dashing && timer.get(timerDash, 3) && movement.len() > 0){ if(dashing && timer.get(timerDash, 3) && movement.len() > 0){
@@ -302,6 +294,16 @@ public class Player extends Unit{
rotation = Mathf.slerpDelta(rotation, targetAngle, 0.2f); rotation = Mathf.slerpDelta(rotation, targetAngle, 0.2f);
} }
@Override
public boolean acceptsAmmo(Item item) {
return weapon.getAmmoType(item) != null && inventory.canAcceptAmmo(weapon.getAmmoType(item));
}
@Override
public void addAmmo(Item item) {
inventory.addAmmo(weapon.getAmmoType(item));
}
@Override @Override
public Player add(){ public Player add(){
return add(playerGroup); return add(playerGroup);
@@ -339,8 +341,7 @@ public class Player extends Unit{
public void writeSpawn(ByteBuffer buffer) { public void writeSpawn(ByteBuffer buffer) {
buffer.put((byte)name.getBytes().length); buffer.put((byte)name.getBytes().length);
buffer.put(name.getBytes()); buffer.put(name.getBytes());
buffer.put(weaponLeft.id); buffer.put(weapon.id);
buffer.put(weaponRight.id);
buffer.put(mech.id); buffer.put(mech.id);
buffer.put(isAdmin ? 1 : (byte)0); buffer.put(isAdmin ? 1 : (byte)0);
buffer.putInt(Color.rgba8888(color)); buffer.putInt(Color.rgba8888(color));
@@ -355,8 +356,7 @@ public class Player extends Unit{
byte[] n = new byte[nlength]; byte[] n = new byte[nlength];
buffer.get(n); buffer.get(n);
name = new String(n); name = new String(n);
weaponLeft = Upgrade.getByID(buffer.get()); weapon = Upgrade.getByID(buffer.get());
weaponRight = Upgrade.getByID(buffer.get());
mech = Upgrade.getByID(buffer.get()); mech = Upgrade.getByID(buffer.get());
isAdmin = buffer.get() == 1; isAdmin = buffer.get() == 1;
color.set(buffer.getInt()); color.set(buffer.getInt());

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor; import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
@@ -18,12 +19,13 @@ import static io.anuke.mindustry.Vars.state;
import static io.anuke.mindustry.Vars.world; import static io.anuke.mindustry.Vars.world;
public abstract class Unit extends SyncEntity implements SerializableEntity { public abstract class Unit extends SyncEntity implements SerializableEntity {
//total duration of hit effect /**total duration of hit flash effect*/
public static final float hitDuration = 9f; public static final float hitDuration = 9f;
public StatusController status = new StatusController(); public StatusController status = new StatusController();
public UnitInventory inventory = new UnitInventory(100); public UnitInventory inventory = new UnitInventory(100, 100);
public Team team = Team.blue; public Team team = Team.blue;
public Vector2 velocity = new Vector2(); public Vector2 velocity = new Vector2();
public float hitTime; public float hitTime;
public float drownTime; public float drownTime;
@@ -146,6 +148,8 @@ public abstract class Unit extends SyncEntity implements SerializableEntity {
} }
} }
public abstract boolean acceptsAmmo(Item item);
public abstract void addAmmo(Item item);
public abstract float getMass(); public abstract float getMass();
public abstract boolean isFlying(); public abstract boolean isFlying();
public abstract float getSize(); public abstract float getSize();

View File

@@ -5,10 +5,37 @@ import io.anuke.mindustry.resource.*;
public class UnitInventory { public class UnitInventory {
private final AmmoEntry ammo = new AmmoEntry(AmmoType.getByID(0), 0); private final AmmoEntry ammo = new AmmoEntry(AmmoType.getByID(0), 0);
private ItemStack item; private ItemStack item;
private int capacity; private int capacity, ammoCapacity;
public UnitInventory(int capacity) { public UnitInventory(int capacity, int ammoCapacity) {
this.capacity = capacity; this.capacity = capacity;
this.ammoCapacity = ammoCapacity;
}
public AmmoType getAmmo() {
return ammo.type;
}
public boolean hasAmmo(){
return ammo.amount > 0;
}
public void useAmmo(){
ammo.amount --;
}
public int ammoCapacity(){
return ammoCapacity;
}
public boolean canAcceptAmmo(AmmoType type){
return ammo.amount + type.quantityMultiplier <= ammoCapacity;
}
public void addAmmo(AmmoType type){
if(ammo.type != type) ammo.amount = 0;
ammo.type = type;
ammo.amount += Math.min((int)type.quantityMultiplier, ammoCapacity - ammo.amount);
} }
public int capacity(){ public int capacity(){
@@ -33,6 +60,8 @@ public class UnitInventory {
public void clear(){ public void clear(){
item = null; item = null;
ammo.amount = 0;
ammo.type = AmmoType.getByID(0);
} }
public boolean hasItem(){ public boolean hasItem(){
@@ -48,7 +77,6 @@ public class UnitInventory {
} }
} }
public ItemStack getItem(){ public ItemStack getItem(){
if(!hasItem()) throw new RuntimeException("This inventory has no item! Check hasItem() first."); if(!hasItem()) throw new RuntimeException("This inventory has no item! Check hasItem() first.");
return item; return item;

View File

@@ -96,6 +96,20 @@ public class Units {
return result[0]; return result[0];
} }
/**Iterates over all units in a rectangle.*/
public static void getNearby(Team team, Rectangle rect, Consumer<Unit> cons){
EntityGroup<BaseUnit> group = unitGroups[team.ordinal()];
if(!group.isEmpty()){
Entities.getNearby(group, rect, entity -> cons.accept((Unit)entity));
}
//now check all enemy players
Entities.getNearby(playerGroup, rect, player -> {
if(((Unit)player).team == team) cons.accept((Unit)player);
});
}
/**Iterates over all units in a rectangle.*/ /**Iterates over all units in a rectangle.*/
public static void getNearby(Rectangle rect, Consumer<Unit> cons){ public static void getNearby(Rectangle rect, Consumer<Unit> cons){
@@ -128,4 +142,6 @@ public class Units {
} }
}); });
} }
} }

View File

@@ -47,7 +47,7 @@ public class GroundEffectEntity extends EffectEntity {
public GroundEffect(float life, float staticLife, EffectRenderer draw) { public GroundEffect(float life, float staticLife, EffectRenderer draw) {
super(life, draw); super(life, draw);
this.staticLife = staticLife; this.staticLife = staticLife;
this.isStatic = false; this.isStatic = true;
} }
public GroundEffect(boolean isStatic, float life, EffectRenderer draw) { public GroundEffect(boolean isStatic, float life, EffectRenderer draw) {

View File

@@ -0,0 +1,44 @@
package io.anuke.mindustry.entities.effect;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.Item;
import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.util.Mathf;
public class ItemTransferEffect extends Entity {
private static final float size = 5f;
private static final float alpha = 0.1f;
private final Item item;
private final Entity target;
public ItemTransferEffect(Item item, float x, float y, Entity target) {
this.x = x;
this.y = y;
this.item = item;
this.target = target;
}
@Override
public void update() {
x = Mathf.lerpDelta(x, target.x, alpha);
y = Mathf.lerpDelta(y, target.y, alpha);
if(distanceTo(target) <= 2f){
remove();
}
}
@Override
public void draw() {
float s = size;
Draw.rect(item.region, x, y, s, s);
}
@Override
public <T extends Entity> T add() {
return super.add(Vars.effectGroup);
}
}

View File

@@ -6,6 +6,7 @@ import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.resource.Item;
import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timer; import io.anuke.ucore.util.Timer;
@@ -39,6 +40,16 @@ public class BaseUnit extends Unit{
rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed); rotation = Mathf.slerpDelta(rotation, angle, type.rotatespeed);
} }
//TODO
@Override
public boolean acceptsAmmo(Item item) {
return false;
}
@Override
public void addAmmo(Item item) {
}
//TODO //TODO
@Override @Override
public float getSize() { public float getSize() {

View File

@@ -106,7 +106,7 @@ public class DesktopInput extends InputHandler{
for(int i = 1; i <= 6 && i <= control.upgrades().getWeapons().size; i ++){ for(int i = 1; i <= 6 && i <= control.upgrades().getWeapons().size; i ++){
if(Inputs.keyTap("weapon_" + i)){ if(Inputs.keyTap("weapon_" + i)){
player.weaponLeft = player.weaponRight = control.upgrades().getWeapons().get(i - 1); player.weapon = control.upgrades().getWeapons().get(i - 1);
if(Net.active()) NetEvents.handleWeaponSwitch(); if(Net.active()) NetEvents.handleWeaponSwitch();
} }
} }

View File

@@ -63,8 +63,7 @@ public class NetEvents {
public static void handleWeaponSwitch(){ public static void handleWeaponSwitch(){
WeaponSwitchPacket packet = new WeaponSwitchPacket(); WeaponSwitchPacket packet = new WeaponSwitchPacket();
packet.left = Vars.player.weaponLeft.id; packet.weapon = Vars.player.weapon.id;
packet.right = Vars.player.weaponRight.id;
packet.playerid = Vars.player.id; packet.playerid = Vars.player.id;
Net.send(packet, SendMode.tcp); Net.send(packet, SendMode.tcp);
} }

View File

@@ -123,7 +123,7 @@ public class NetworkIO {
control.upgrades().getWeapons().add(Upgrade.getByID(stream.readByte())); control.upgrades().getWeapons().add(Upgrade.getByID(stream.readByte()));
} }
player.weaponLeft = player.weaponRight = control.upgrades().getWeapons().peek(); player.weapon = control.upgrades().getWeapons().peek();
Entities.clear(); Entities.clear();
player.id = pid; player.id = pid;

View File

@@ -376,20 +376,18 @@ public class Packets {
public static class WeaponSwitchPacket implements Packet{ public static class WeaponSwitchPacket implements Packet{
public int playerid; public int playerid;
public byte left, right; public byte weapon;
@Override @Override
public void write(ByteBuffer buffer) { public void write(ByteBuffer buffer) {
buffer.putInt(playerid); buffer.putInt(playerid);
buffer.put(left); buffer.put(weapon);
buffer.put(right);
} }
@Override @Override
public void read(ByteBuffer buffer) { public void read(ByteBuffer buffer) {
playerid = buffer.getInt(); playerid = buffer.getInt();
left = buffer.get(); weapon = buffer.get();
right = buffer.get();
} }
} }

View File

@@ -1,21 +1,30 @@
package io.anuke.mindustry.resource; package io.anuke.mindustry.resource;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.Bullet;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.net.NetEvents;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Bits;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Translator; import io.anuke.ucore.util.Translator;
public class Weapon extends Upgrade{ public class Weapon extends Upgrade{
/**minimum cursor distance from player, fixes 'cross-eyed' shooting.*/
protected static float minPlayerDist = 20f;
/**ammo type map. set with setAmmo()*/
protected ObjectMap<Item, AmmoType> ammoMap = new ObjectMap<>();
/**shell ejection effect*/
protected Effect ejectEffect = Fx.none;
/**weapon reload in frames*/ /**weapon reload in frames*/
protected float reload; protected float reload;
/**sound made when shooting*/
protected String shootsound = "shoot";
/**amount of shots per fire*/ /**amount of shots per fire*/
protected int shots = 1; protected int shots = 1;
/**spacing in degrees between multiple shots, if applicable*/ /**spacing in degrees between multiple shots, if applicable*/
@@ -24,56 +33,79 @@ public class Weapon extends Upgrade{
protected float inaccuracy = 0f; protected float inaccuracy = 0f;
/**intensity and duration of each shot's screen shake*/ /**intensity and duration of each shot's screen shake*/
protected float shake = 0f; protected float shake = 0f;
/**effect displayed when shooting*/
protected Effect effect;
/**shoot barrel length*/ /**shoot barrel length*/
protected float length = 3f; protected float length = 3f;
/**whether to shoot the weapons in different arms one after another, rather an all at once*/ /**whether to shoot the weapons in different arms one after another, rather than all at once*/
protected boolean roundrobin = false; protected boolean roundrobin = false;
/**translator for vector calulations*/ /**translator for vector calulations*/
protected Translator tr = new Translator(); protected Translator tr = new Translator();
protected Weapon(String name, float reload){ protected Weapon(String name){
super(name); super(name);
this.reload = reload;
} }
public void update(Player p, boolean left){ public void update(Player p, boolean left){
int t = left ? 1 : 2; int t = left ? 1 : 2;
int t2 = !left ? 1 : 2; int t2 = !left ? 1 : 2;
if(p.timer.get(t, reload)){ if(p.inventory.hasAmmo() && p.timer.get(t, reload)){
if(roundrobin){ if(roundrobin){
p.timer.reset(t2, reload/2f); p.timer.reset(t2, reload/2f);
} }
float ang = Angles.mouseAngle(p.x, p.y);
tr.set(Graphics.mouseWorld()).sub(p.x, p.y);
if(tr.len() < minPlayerDist) tr.setLength(minPlayerDist);
float cx = tr.x + p.x, cy = tr.y + p.y;
float ang = tr.angle();
tr.trns(ang - 90, 4f * Mathf.sign(left), length + 1f); tr.trns(ang - 90, 4f * Mathf.sign(left), length + 1f);
shoot(p, p.x + tr.x, p.y + tr.y, Angles.mouseAngle(p.x + tr.x, p.y + tr.y));
shoot(p, p.x + tr.x, p.y + tr.y, Angles.angle(p.x + tr.x, p.y + tr.y, cx, cy), left);
} }
} }
void shootInternal(Player p, float x, float y, float rotation){ public float getRecoil(Player player, boolean left){
Angles.shotgun(shots, spacing, rotation, f -> bullet(p, x, y, f + Mathf.range(inaccuracy))); return 1f-Mathf.clamp(player.timer.getTime(left ? 1 : 2)/reload);
tr.trns(rotation, 3f);
if(effect != null) Effects.effect(effect, x + tr.x, y + tr.y, rotation);
Effects.shake(shake, shake, x, y);
Effects.sound(shootsound, x, y);
} }
public float getReload(){ public float getReload(){
return reload; return reload;
} }
public void shoot(Player p, float x, float y, float angle){ public void shoot(Player p, float x, float y, float angle, boolean left){
shootInternal(p, x, y, angle); shootInternal(p, x, y, angle, left);
if(Net.active() && p == Vars.player){ if(Net.active() && p == Vars.player){
NetEvents.handleShoot(Vars.player, x, y, angle, id); NetEvents.handleShoot(Vars.player, x, y, angle, Bits.packShort(id, (byte)(left ? 1 : 0)));
} }
p.inventory.useAmmo();
}
public AmmoType getAmmoType(Item item){
return ammoMap.get(item);
}
protected void setAmmo(AmmoType... types){
for(AmmoType type : types){
ammoMap.put(type.item, type);
}
}
void shootInternal(Player p, float x, float y, float rotation, boolean left){
Angles.shotgun(shots, spacing, rotation, f -> bullet(p, x, y, f + Mathf.range(inaccuracy)));
tr.trns(rotation, 3f);
AmmoType type = p.inventory.getAmmo();
Effects.shake(shake, shake, x, y);
Effects.effect(ejectEffect, x, y, rotation * -Mathf.sign(left));
Effects.effect(type.shootEffect, x + tr.x, y + tr.y, rotation, p);
Effects.effect(type.smokeEffect, x + tr.x, y + tr.y, rotation, p);
} }
void bullet(Unit owner, float x, float y, float angle){ void bullet(Unit owner, float x, float y, float angle){
tr.trns(angle, 3f); tr.trns(angle, 3f);
//TODO implement! Bullet.create(owner.inventory.getAmmo().bullet, owner, x + tr.x, y + tr.y, angle);
//Bullet.create(type, owner, x + tr.x, y + tr.y, angle);
} }
} }

View File

@@ -104,7 +104,7 @@ public class PlayerListFragment implements Fragment{
public void draw(){ public void draw(){
float s = getWidth() / 12f; float s = getWidth() / 12f;
for(int i : Mathf.signs){ for(int i : Mathf.signs){
Draw.rect((i < 0 ? player.weaponLeft.name : player.weaponRight.name) Draw.rect((player.weapon.name)
+ "-equip", x + s * 6 + i * 3*s, y + s*6 + 2*s, -8*s*i, 8*s); + "-equip", x + s * 6 + i * 3*s, y + s*6 + 2*s, -8*s*i, 8*s);
} }
} }

View File

@@ -38,7 +38,6 @@ public abstract class Turret extends Block{
protected Effect shootEffect = Fx.none; protected Effect shootEffect = Fx.none;
protected Effect smokeEffect = Fx.none; protected Effect smokeEffect = Fx.none;
protected Effect ammoUseEffect = Fx.none; protected Effect ammoUseEffect = Fx.none;
protected String shootsound = "shoot";
protected int ammoPerShot = 1; protected int ammoPerShot = 1;
protected float ammoEjectBack = 1f; protected float ammoEjectBack = 1f;

View File

@@ -1,24 +1,43 @@
package io.anuke.mindustry.world.blocks.types.storage; package io.anuke.mindustry.world.blocks.types.storage;
import com.badlogic.gdx.math.Rectangle;
import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.effect.ItemTransferEffect;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Lines;
import static io.anuke.mindustry.Vars.state; import static io.anuke.mindustry.Vars.state;
public class CoreBlock extends StorageBlock { public class CoreBlock extends StorageBlock {
private static Rectangle rect = new Rectangle();
protected int timerSupply = timers ++;
protected float supplyRadius = 50f;
protected float supplyInterval = 5f;
public CoreBlock(String name) { public CoreBlock(String name) {
super(name); super(name);
solid = true; solid = true;
destructible = true; update = true;
unbreakable = true; unbreakable = true;
size = 3; size = 3;
hasItems = true; hasItems = true;
itemCapacity = 2000; itemCapacity = 2000;
} }
@Override
public void drawSelect(Tile tile){
Draw.color("accent");
Lines.dashCircle(tile.drawx(), tile.drawy(), supplyRadius);
Draw.color();
}
@Override
public void onDestroyed(Tile tile){ public void onDestroyed(Tile tile){
//TODO more dramatic effects //TODO more dramatic effects
super.onDestroyed(tile); super.onDestroyed(tile);
@@ -32,31 +51,26 @@ public class CoreBlock extends StorageBlock {
public void handleItem(Item item, Tile tile, Tile source){ public void handleItem(Item item, Tile tile, Tile source){
if(Net.server() || !Net.active()) super.handleItem(item, tile, source); if(Net.server() || !Net.active()) super.handleItem(item, tile, source);
} }
/*
@Override @Override
public boolean acceptItem(Item item, Tile tile, Tile source){ public void update(Tile tile) {
return item.material && state.inventory.getAmount(item) < capacity;
}
@Override if(tile.entity.timer.get(timerSupply, supplyInterval)){
public Item removeItem(Tile tile, Item item){ rect.setSize(supplyRadius*2).setCenter(tile.drawx(), tile.drawy());
for(int i = 0; i < state.inventory.getItems().length; i ++){
if(state.inventory.getItems()[i] > 0 && (item == null || item.id == i)){ Units.getNearby(tile.getTeam(), rect, unit -> {
if(Net.server() || !Net.active()) state.inventory.getItems()[i] --; if(unit.distanceTo(tile.drawx(), tile.drawy()) > supplyRadius) return;
return Item.getByID(i);
} for(int i = 0; i < tile.entity.items.items.length; i ++){
Item item = Item.getByID(i);
if(tile.entity.items.items[i] > 0 && unit.acceptsAmmo(item)){
tile.entity.items.items[i] --;
unit.addAmmo(item);
new ItemTransferEffect(item, tile.drawx(), tile.drawy(), unit).add();
return;
}
}
});
} }
return null;
} }
@Override
public boolean hasItem(Tile tile, Item item){
for(int i = 0; i < state.inventory.getItems().length; i ++){
if(state.inventory.getItems()[i] > 0 && (item == null || item.id == i)){
return true;
}
}
return false;
}*/
} }

View File

@@ -49,7 +49,7 @@ public class ServerControl extends Module {
mode = ShuffleMode.valueOf(Settings.getString("shufflemode")); mode = ShuffleMode.valueOf(Settings.getString("shufflemode"));
Effects.setScreenShakeProvider((a, b) -> {}); Effects.setScreenShakeProvider((a, b) -> {});
Effects.setEffectProvider((a, b, c, d, e) -> {}); Effects.setEffectProvider((a, b, c, d, e, f) -> {});
Sounds.setHeadless(true); Sounds.setHeadless(true);
//override default handling of chat packets //override default handling of chat packets