Files
shattered-pixel-dungeon-web…/src/com/shatteredpixel/shatteredpixeldungeon/items/weapon/Weapon.java
2014-10-26 17:30:23 -04:00

249 lines
6.9 KiB
Java

/*
* Pixel Dungeon
* Copyright (C) 2012-2014 Oleg Dolya
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.shatteredpixel.shatteredpixeldungeon.items.weapon;
import com.shatteredpixel.shatteredpixeldungeon.Badges;
import com.shatteredpixel.shatteredpixeldungeon.actors.Char;
import com.shatteredpixel.shatteredpixeldungeon.actors.buffs.Buff;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.Hero;
import com.shatteredpixel.shatteredpixeldungeon.actors.hero.HeroClass;
import com.shatteredpixel.shatteredpixeldungeon.items.Item;
import com.shatteredpixel.shatteredpixeldungeon.items.KindOfWeapon;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfFuror;
import com.shatteredpixel.shatteredpixeldungeon.items.rings.RingOfSharpshooting;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.enchantments.*;
import com.shatteredpixel.shatteredpixeldungeon.items.weapon.missiles.MissileWeapon;
import com.shatteredpixel.shatteredpixeldungeon.sprites.ItemSprite;
import com.shatteredpixel.shatteredpixeldungeon.utils.GLog;
import com.shatteredpixel.shatteredpixeldungeon.utils.Utils;
import com.watabou.utils.Bundlable;
import com.watabou.utils.Bundle;
import com.watabou.utils.Random;
public class Weapon extends KindOfWeapon {
private static final String TXT_IDENTIFY =
"You are now familiar enough with your %s to identify it. It is %s.";
private static final String TXT_INCOMPATIBLE =
"Interaction of different types of magic has negated the enchantment on this weapon!";
private static final String TXT_TO_STRING = "%s :%d";
public int STR = 10;
public float ACU = 1; // Accuracy modifier
public float DLY = 1f; // Speed modifier
public enum Imbue {
NONE, LIGHT, HEAVY
}
public Imbue imbue = Imbue.NONE;
private int hitsToKnow = 20;
protected Enchantment enchantment;
@Override
public void proc( Char attacker, Char defender, int damage ) {
if (enchantment != null) {
enchantment.proc( this, attacker, defender, damage );
}
if (!levelKnown) {
if (--hitsToKnow <= 0) {
levelKnown = true;
GLog.i( TXT_IDENTIFY, name(), toString() );
Badges.validateItemLevelAquired( this );
}
}
}
private static final String ENCHANTMENT = "enchantment";
private static final String IMBUE = "imbue";
@Override
public void storeInBundle( Bundle bundle ) {
super.storeInBundle( bundle );
bundle.put( ENCHANTMENT, enchantment );
bundle.put( IMBUE, imbue );
}
@Override
public void restoreFromBundle( Bundle bundle ) {
super.restoreFromBundle( bundle );
enchantment = (Enchantment)bundle.get( ENCHANTMENT );
imbue = bundle.getEnum( IMBUE, Imbue.class );
}
@Override
public float acuracyFactor( Hero hero ) {
int encumbrance = STR - hero.STR();
float ACU = this.ACU;
if (this instanceof MissileWeapon) {
switch (hero.heroClass) {
case WARRIOR:
encumbrance += 3;
break;
case HUNTRESS:
encumbrance -= 2;
break;
default:
}
int bonus = 0;
for (Buff buff : hero.buffs(RingOfSharpshooting.Aim.class)) {
bonus += ((RingOfSharpshooting.Aim)buff).level;
}
ACU *= (float)(Math.pow(1.1, bonus));
}
return encumbrance > 0 ? (float)(ACU / Math.pow( 1.5, encumbrance )) : ACU;
}
@Override
public float speedFactor( Hero hero ) {
int encumrance = STR - hero.STR();
if (this instanceof MissileWeapon && hero.heroClass == HeroClass.HUNTRESS) {
encumrance -= 2;
}
int bonus = 0;
for (Buff buff : hero.buffs(RingOfFuror.Furor.class)) {
bonus += ((RingOfFuror.Furor)buff).level;
}
float DLY = (float)(0.25 + (this.DLY - 0.25)*Math.pow(0.8, bonus));
return
(encumrance > 0 ? (float)(DLY * Math.pow( 1.2, encumrance )) : DLY) *
(imbue == Imbue.LIGHT ? 0.667f : (imbue == Imbue.HEAVY ? 1.667f : 1.0f));
}
@Override
public int damageRoll( Hero hero ) {
int damage = super.damageRoll( hero );
if ((hero.rangedWeapon != null) == (hero.heroClass == HeroClass.HUNTRESS)) {
int exStr = hero.STR() - STR;
if (exStr > 0) {
damage += Random.IntRange( 0, exStr );
}
}
return Math.round(damage * (imbue == Imbue.LIGHT ? 0.7f : (imbue == Imbue.HEAVY ? 1.5f : 1f)));
}
public Item upgrade( boolean enchant ) {
if (enchantment != null) {
if (!enchant && Random.Int( level ) > 0) {
GLog.w( TXT_INCOMPATIBLE );
enchant( null );
}
} else {
if (enchant) {
enchant( Enchantment.random() );
}
}
return super.upgrade();
}
@Override
public String toString() {
return levelKnown ? Utils.format( TXT_TO_STRING, super.toString(), STR ) : super.toString();
}
@Override
public String name() {
return enchantment == null ? super.name() : enchantment.name( super.name() );
}
@Override
public Item random() {
if (Random.Float() < 0.4) {
int n = 1;
if (Random.Int( 3 ) == 0) {
n++;
if (Random.Int( 3 ) == 0) {
n++;
}
}
if (Random.Int( 2 ) == 0) {
upgrade( n );
} else {
degrade( n );
cursed = true;
}
}
return this;
}
public Weapon enchant( Enchantment ench ) {
this.enchantment = ench;
return this;
}
public boolean isEnchanted() {
return enchantment != null;
}
@Override
public ItemSprite.Glowing glowing() {
return enchantment != null ? enchantment.glowing() : null;
}
public static abstract class Enchantment implements Bundlable {
private static final Class<?>[] enchants = new Class<?>[]{
Fire.class, Poison.class, Death.class, Paralysis.class, Leech.class,
Slow.class, Swing.class, Piercing.class, Instability.class, Horror.class, Luck.class };
private static final float[] chances= new float[]{ 10, 10, 1, 2, 1, 2, 3, 3, 3, 2, 2 };
public abstract boolean proc( Weapon weapon, Char attacker, Char defender, int damage );
public String name( String weaponName ) {
return weaponName;
}
@Override
public void restoreFromBundle( Bundle bundle ) {
}
@Override
public void storeInBundle( Bundle bundle ) {
}
public ItemSprite.Glowing glowing() {
return ItemSprite.Glowing.WHITE;
}
@SuppressWarnings("unchecked")
public static Enchantment random() {
try {
return ((Class<Enchantment>)enchants[ Random.chances( chances ) ]).newInstance();
} catch (Exception e) {
return null;
}
}
}
}