Add charge-up mechanic for more powerful spells
- Implements spell charge-up in ItemWand - Assigns chargeup values in json files for spells that should have one - Adds a charge meter to the crosshair in first-person - Updates some javadoc comments appropriately
This commit is contained in:
@@ -44,7 +44,8 @@ import java.util.Map.Entry;
|
||||
public class GuiSpellDisplay {
|
||||
|
||||
private static final ResourceLocation INDEX = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_hud/_index.json");
|
||||
|
||||
private static final ResourceLocation CHARGE_METER = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_charge_meter.png");
|
||||
|
||||
/** A map which stores all loaded HUD skin objects. This gets wiped on resource pack reload and repopulated with
|
||||
* mappings as specified by {@code _index.json} (these stack between resource packs). The keys in the map correspond
|
||||
* to the keys in {@code _index.json}, and are sorted in that order, with skins belonging to resource packs sorted
|
||||
@@ -55,6 +56,11 @@ public class GuiSpellDisplay {
|
||||
private static final Gson gson = new Gson();
|
||||
private static final Random random = new Random();
|
||||
|
||||
/** Width of the charge meter. */
|
||||
private static final int CHARGE_METER_WIDTH = 25;
|
||||
/** Height of the charge meter. */
|
||||
private static final int CHARGE_METER_HEIGHT = 9;
|
||||
|
||||
/** Width and height of the spell icon (very unlikely to change!) */
|
||||
private static final int SPELL_ICON_SIZE = 32;
|
||||
/** Number of ticks the spell switching animation plays for. */
|
||||
@@ -99,12 +105,7 @@ public class GuiSpellDisplay {
|
||||
@SubscribeEvent
|
||||
public static void draw(RenderGameOverlayEvent.Post event){
|
||||
|
||||
if(event.getType() != RenderGameOverlayEvent.ElementType.TEXT
|
||||
&& event.getType() != RenderGameOverlayEvent.ElementType.HOTBAR) return;
|
||||
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
EntityPlayer player = mc.player;
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
|
||||
if(player.isSpectator()) return; // Spectators shouldn't have the spell HUD!
|
||||
|
||||
@@ -117,12 +118,74 @@ public class GuiSpellDisplay {
|
||||
wand = player.getHeldItemOffhand();
|
||||
mainHand = false;
|
||||
// If the player isn't holding a spellcasting item that shows the HUD, then nothing else needs to be done.
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem && ((ISpellCastingItem)wand.getItem()).showSpellHUD(player, wand))) return;
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem && ((ISpellCastingItem)wand.getItem()).showSpellHUD(player, wand)))
|
||||
return;
|
||||
}
|
||||
|
||||
int width = event.getResolution().getScaledWidth();
|
||||
int height = event.getResolution().getScaledHeight();
|
||||
|
||||
switch(event.getType()){
|
||||
case CROSSHAIRS:
|
||||
renderChargeMeter(player, wand, width, height, event.getPartialTicks());
|
||||
break;
|
||||
case HOTBAR:
|
||||
renderSpellHUD(player, wand, mainHand, width, height, event.getPartialTicks(), false);
|
||||
break;
|
||||
case TEXT:
|
||||
renderSpellHUD(player, wand, mainHand, width, height, event.getPartialTicks(), true);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the spell charge meter around the crosshairs.
|
||||
* @param player A reference to the client player
|
||||
* @param wand The wand the HUD is for
|
||||
* @param width The width of the screen
|
||||
* @param height The height of the screen
|
||||
* @param partialTicks The current partial tick time
|
||||
*/
|
||||
private static void renderChargeMeter(EntityPlayer player, ItemStack wand, int width, int height, float partialTicks){
|
||||
|
||||
if(Minecraft.getMinecraft().gameSettings.showDebugInfo) return; // Don't show charge meter in the debug screen
|
||||
if(Minecraft.getMinecraft().gameSettings.thirdPersonView != 0) return; // Don't show in third person
|
||||
|
||||
Spell spell = WandHelper.getCurrentSpell(wand);
|
||||
|
||||
if(spell.getChargeup() <= 0) return;
|
||||
|
||||
// WHY WHY WHY are these methods named so misleadingly?! Sort yourselves out MCP!
|
||||
// (getItemInUseCount returns the max count MINUS the use count, and getItemInUseMaxCount returns the use count)
|
||||
if(player.getItemInUseMaxCount() == 0) return; // Not charging
|
||||
float charge = (player.getItemInUseMaxCount() + partialTicks) / spell.getChargeup();
|
||||
if(charge > 1) return; // Done charging
|
||||
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(CHARGE_METER);
|
||||
|
||||
int x1 = width/2 - CHARGE_METER_WIDTH/2;
|
||||
int y = height/2 - CHARGE_METER_HEIGHT/2;
|
||||
int w = (int)(CHARGE_METER_WIDTH/2 * charge);
|
||||
int u = CHARGE_METER_WIDTH - w;
|
||||
|
||||
DrawingUtils.drawTexturedRect(x1, y, 0, 0, w, CHARGE_METER_HEIGHT, 32, 32);
|
||||
DrawingUtils.drawTexturedRect(x1 + u, y, u, 0, w, CHARGE_METER_HEIGHT, 32, 32);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the main spell HUD in the corner of the screen.
|
||||
* @param player A reference to the client player
|
||||
* @param wand The wand the HUD is for
|
||||
* @param mainHand True if the wand is in the player's main hand, false if it is in their offhand
|
||||
* @param width The width of the screen
|
||||
* @param height The height of the screen
|
||||
* @param partialTicks The current partial tick time
|
||||
* @param textLayer True to render the text layer, false to render the background (hotbar layer)
|
||||
*/
|
||||
private static void renderSpellHUD(EntityPlayer player, ItemStack wand, boolean mainHand, int width, int height, float partialTicks, boolean textLayer){
|
||||
|
||||
boolean flipX = Wizardry.settings.spellHUDPosition.flipX;
|
||||
boolean flipY = Wizardry.settings.spellHUDPosition.flipY;
|
||||
|
||||
@@ -130,16 +193,16 @@ public class GuiSpellDisplay {
|
||||
// ............. | This bit is true if the wand is on the left, false if it is on the right
|
||||
flipX = flipX == ((mainHand ? player.getPrimaryHand() : player.getPrimaryHand().opposite()) == EnumHandSide.LEFT);
|
||||
}
|
||||
|
||||
|
||||
Skin skin = skins.get(Wizardry.settings.spellHUDSkin);
|
||||
|
||||
|
||||
if(skin == null){
|
||||
|
||||
|
||||
Wizardry.logger.info("The spell HUD skin '" + Wizardry.settings.spellHUDSkin + "' specified in the config"
|
||||
+ " did not match any of the loaded skins; using the default skin as a fallback.");
|
||||
|
||||
|
||||
skin = skins.get(Settings.DEFAULT_HUD_SKIN_KEY);
|
||||
|
||||
|
||||
if(skin == null){
|
||||
Wizardry.logger.warn("The default spell HUD skin is missing! A resource pack must have overridden it"
|
||||
+ " with an invalid JSON file (default.json), please try again without any resource packs.");
|
||||
@@ -148,7 +211,7 @@ public class GuiSpellDisplay {
|
||||
}
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
|
||||
// 'Origin' of the spell hud (bottom left corner of the actual texture, always in the corner of the screen)
|
||||
int x = flipX ? width : 0;
|
||||
int y = flipY ? 0: height;
|
||||
@@ -169,45 +232,46 @@ public class GuiSpellDisplay {
|
||||
y = MathHelper.ceil(y/scale);
|
||||
}
|
||||
|
||||
// TODO: Maybe convert this to use ISpellCastingItem
|
||||
Spell spell = WandHelper.getCurrentSpell(wand);
|
||||
int cooldown = WandHelper.getCurrentCooldown(wand);
|
||||
int maxCooldown = WandHelper.getCurrentMaxCooldown(wand);
|
||||
|
||||
if(event.getType() == RenderGameOverlayEvent.ElementType.TEXT){
|
||||
|
||||
if(textLayer){
|
||||
|
||||
float animationProgress = Math.signum(switchTimer) * ((SPELL_SWITCH_TIME - Math.abs(switchTimer) +
|
||||
event.getPartialTicks()) / SPELL_SWITCH_TIME);
|
||||
|
||||
partialTicks) / SPELL_SWITCH_TIME);
|
||||
|
||||
String prevSpellName = getFormattedSpellName(WandHelper.getPreviousSpell(wand), player, WandHelper.getPreviousCooldown(wand));
|
||||
String spellName = getFormattedSpellName(spell, player, cooldown);
|
||||
String nextSpellName = getFormattedSpellName(WandHelper.getNextSpell(wand), player, WandHelper.getNextCooldown(wand));
|
||||
|
||||
skin.drawText(x, y, flipX, flipY, prevSpellName, spellName, nextSpellName, animationProgress);
|
||||
|
||||
}else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){
|
||||
}else{
|
||||
|
||||
boolean discovered = true;
|
||||
|
||||
if(!player.isCreative() && WizardData.get(player) != null){
|
||||
discovered = WizardData.get(player).hasSpellBeenDiscovered(spell);
|
||||
}
|
||||
|
||||
|
||||
ResourceLocation icon = discovered ? spell.getIcon() : Spells.none.getIcon();
|
||||
|
||||
float progress = 1;
|
||||
// Doesn't really matter what progress is when in creative, but we might as well avoid the calculation.
|
||||
if(!player.isCreative() && !spell.isContinuous){
|
||||
// Subtracted partial tick time to make it smoother
|
||||
progress = maxCooldown == 0 ? 1 : (maxCooldown - (float)cooldown + event.getPartialTicks()) / maxCooldown;
|
||||
progress = maxCooldown == 0 ? 1 : (maxCooldown - (float)cooldown + partialTicks) / maxCooldown;
|
||||
}
|
||||
|
||||
|
||||
skin.drawBackground(x, y, flipX, flipY, icon, progress, player.isCreative(), player.isPotionActive(WizardryPotions.arcane_jammer));
|
||||
|
||||
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the name of the given spell, with formatting added according to its cooldown and whether the given player
|
||||
* has discovered it.
|
||||
|
||||
Reference in New Issue
Block a user