package com.game.libgdx.roguelikeengine; /* Copyright (C) 2013 Ferran Fabregas (ferri.fc@gmail.com) 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/>. */ import java.util.Random; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.Sprite; public class Hero implements MovingTileOccupier { private int agility; private int force; //private int relative_x_tile; //private int relative_y_tile; private int abs_x; private int abs_y; private String name; private int life; private int lifePerStep = 1; private int maxlife; private int maxMagic; private int magic; private int magicPerStep = 1; private int magicCost = 11; private int level=1; private int exp; private int resist; private int current_sprite_position; // sprite that will be shown //private Sprite sprite; private Texture texture; private Object head; private Object lefthand; private Object righthand; private Object body; private Object foot; protected Directions direction = Directions.EAST; protected WrapperEngine engine; public Hero(WrapperEngine engine, String name, String file) { this.engine = engine; // initial set-up this.agility=4; this.force=5; // offense this.resist=3; // defense this.life=this.maxlife=100; // hp this.magic=this.maxMagic=100; this.exp=1; // experience //this.relative_y_tile=1; //this.relative_x_tile=1; this.abs_x = 1; this.abs_y = 1; this.name=name; init_sprite_pos(); // initial sprite position, every number corresponds to a sprite. Each set of sprites has different configuration this.head = new Object(); // empty object this.body = new Object(); // empty object this.lefthand = new Object(); // empty object this.righthand = new Object(); // empty object this.foot = new Object(); // empty object this.texture= new Texture(Gdx.files.internal(file)); } // hero gets public String getname() { return this.name; } public int getexperience() { return this.exp; } public int getresist() { return this.resist+this.head.getdefense()+this.lefthand.getdefense()+this.righthand.getdefense()+this.body.getdefense()+this.foot.getdefense()+((int)(this.exp/WrapperEngine.EXPERIENCE_NEXT_LEVEL_LIMIT)); } public int getforce() { return this.force+this.head.getattack()+this.lefthand.getattack()+this.righthand.getattack()+this.body.getattack()+this.foot.getattack()+((int)(this.exp/WrapperEngine.EXPERIENCE_NEXT_LEVEL_LIMIT)); } public int getagility() { return this.agility+((int)(this.exp/WrapperEngine.EXPERIENCE_NEXT_LEVEL_LIMIT)); } public int gethp() { return this.life; } public int getmagic() { return this.magic; } public int getlevel() { return this.level; } public int getrelativextile(Map map) { return this.abs_x - map.getfirstxtile(); } public int getrelativeytile(Map map) { return this.abs_y - map.getfirstytile(); } public Object gethead() { return this.head; } public Object getlefthand() { return this.lefthand; } public Object getrighthand() { return this.righthand; } public Object getbody() { return this.body; } public Object getfoot() { return this.foot; } public Sprite getimage() { return new Sprite(texture); } public float percentlife() { return ((float)(float) this.life / (float)this.maxlife ) * 100; } // hero sets / updates public void sethead(Object obj) { this.head=obj; } public void setlefthand(Object obj) { this.lefthand=obj; } public void setrighthand(Object obj) { this.righthand=obj; } public void setbody(Object obj) { this.body=obj; } public void setfoot(Object obj) { this.foot=obj; } public void decayhead() { if (gethead().getname()!=null) { // if object exist gethead().reducedurability(1); } } public void decaylefthand() { if (getlefthand().getname()!=null) { // if object exist getlefthand().reducedurability(1); } } public void decayrighthand() { if (getrighthand().getname()!=null) { // if object exist getrighthand().reducedurability(1); } } public void decaybody() { if (getbody().getname()!=null) { // if object exist getbody().reducedurability(1); } } public void decayfoot() { if (getfoot().getname()!=null) { // if object exist getfoot().reducedurability(1); } } public void randomdecay() { Random randomGenerator = new Random(); int object_2_decay = randomGenerator.nextInt(5); switch (object_2_decay) { case 0: decayfoot(); break; case 1: decayhead(); break; case 2: decaylefthand(); break; case 3: decayrighthand(); break; case 4: decaybody(); break; } } public void setrelativextile(Map map, int value) { this.abs_x = map.getfirstxtile() + value; } public void setrelativeytile(Map map, int value) { this.abs_y = map.getfirstytile() + value; } public void updateagility(int value) { this.agility=this.agility+value; } public void updateexperience(int value) { this.exp=this.exp+value; // check for level up } public void updatehp(int value) { this.life=Math.min(this.maxlife, this.life+value); } public void updatemagic(int value) { this.magic=Math.max(0, Math.min(this.maxMagic, this.magic+value)); } public void updatelevel() { this.level++; } public void updateforce(int value) { this.force=this.force+value; } public void updateresist(int value) { this.resist=this.resist+value; } // hero position updates public void up(Map map) { this.abs_y = Math.max(0, this.abs_y - 1); changeDirection(Directions.NORTH); } public void down(Map map) { this.abs_y = Math.min(WrapperEngine.TOTAL_Y_TILES - 1, this.abs_y + 1); changeDirection(Directions.SOUTH); } public void left(Map map) { this.abs_x = Math.max(0, this.abs_x - 1); changeDirection(Directions.WEST); } public void right(Map map) { this.abs_x = Math.min(WrapperEngine.TOTAL_X_TILES-1, this.abs_x + 1); changeDirection(Directions.EAST); } // fight // hero hit enemy public String hit(Enemy enemy) { Random randomGenerator = new Random(); int herohit= (((int)(Math.ceil((double)((double)this.agility/(double)3)))*this.force)-enemy.getresist()); int enemyhit=(((int)(Math.ceil((double)((double)enemy.getagility()/(double)3)))*enemy.getforce())-this.resist); int heromodifier = randomGenerator.nextInt(this.agility); // random component based on agility int enemymodifier = randomGenerator.nextInt(enemy.getagility()); // random component based on agility herohit=Math.max(0, herohit+heromodifier); enemyhit=Math.max(0, enemyhit+enemymodifier); enemy.updatehp(herohit); // hero hits enemy randomdecay(); // durability decreases if (enemy.gethp()>0) { // if enemy is alive this.life=Math.max(0, this.life-enemyhit); // enemy hits hero randomdecay(); // durability decreases, twice? } else { return "ENEMYDEAD"; } if (this.life<=0) { return "HERODEAD"; } String result = this.name+" did "+herohit+" damage points to " + enemy.getname() + " \n#FF0000"; for(String namePart : enemy.getname().split(" ")) { result += "#FF0000" + namePart + " "; } result += "#FF0000did #FF0000"+enemyhit+" #FF0000damage #FF0000points #FF0000to #FF0000"+this.name; return result; } // *** BEGIN hero sprite management. you MUST modify it with your own sprite behavior private void init_sprite_pos() { // why does the naming scheme change here? current_sprite_position=7; } private void sprite_godown() { switch(current_sprite_position) { case 10: current_sprite_position=11; break; case 11: current_sprite_position=12; break; case 12: current_sprite_position=10; break; default: current_sprite_position=10; break; } direction = Directions.NORTH; // libgdx y is inverted } private void sprite_goup() { switch(current_sprite_position) { case 1: current_sprite_position=2; break; case 2: current_sprite_position=3; break; case 3: current_sprite_position=1; break; default: current_sprite_position=1; break; } direction = Directions.SOUTH; } private void sprite_goleft() { switch(current_sprite_position) { case 4: current_sprite_position=5; break; case 5: current_sprite_position=6; break; case 6: current_sprite_position=4; break; default: current_sprite_position=4; break; } direction = Directions.WEST; } private void sprite_goright() { switch(current_sprite_position) { case 7: current_sprite_position=8; break; case 8: current_sprite_position=9; break; case 9: current_sprite_position=7; break; default: current_sprite_position=7; break; } direction = Directions.EAST; } public int getyspriteposition() { if (current_sprite_position==1 || current_sprite_position==2 || current_sprite_position==3) { return WrapperEngine.TILE_Y_SIZE*0; } if (current_sprite_position==4 || current_sprite_position==5 || current_sprite_position==6) { return WrapperEngine.TILE_Y_SIZE*1; } if (current_sprite_position==7 || current_sprite_position==8 || current_sprite_position==9) { return WrapperEngine.TILE_Y_SIZE*2; } if (current_sprite_position==10 || current_sprite_position==11 || current_sprite_position==12) { return WrapperEngine.TILE_Y_SIZE*3; } return 0; } public int getxspriteposition() { if (current_sprite_position==1 || current_sprite_position==4 || current_sprite_position==7 || current_sprite_position==10 ) { return WrapperEngine.TILE_X_SIZE*0; } if (current_sprite_position==2 || current_sprite_position==5 || current_sprite_position==8 || current_sprite_position==11) { return WrapperEngine.TILE_X_SIZE*1; } if (current_sprite_position==3 || current_sprite_position==6 || current_sprite_position==9 || current_sprite_position==12) { return WrapperEngine.TILE_X_SIZE*2; } return 0; } public Sprite getsprite() { return new Sprite(texture,getxspriteposition(),getyspriteposition(),WrapperEngine.TILE_X_SIZE,WrapperEngine.TILE_Y_SIZE); } // *** END hero sprite management. you MUST modify it with your own sprite behavior @Override public String getdescription() { return "The Hero of our tale."; } public int getabsolutex(Map map) { return this.abs_x; } public int getabsolutey(Map map) { return this.abs_y; } public Tile gettile(Map map) { return map.gettileat(getabsolutex(map), getabsolutey(map)); } protected void onStep() { this.updatemagic(magicPerStep); this.updatehp(lifePerStep); } public Bullet fireBullet() { Bullet result = null; if(this.magic >= this.magicCost) { result = new Fireball(engine.getactivemap(), this, this.direction); this.magic -= this.magicCost; } return result; } public void changeDirection(Directions direction) { switch (direction) { case NORTH: this.sprite_goup(); break; case SOUTH: this.sprite_godown(); break; case EAST: this.sprite_goright(); break; case WEST: default: this.sprite_goleft(); } this.direction = direction; } @Override public int getabsolutecolumn(Map map) { return this.getabsolutex(map); } @Override public int getabsoluterow(Map map) { return this.getabsolutey(map); } public int getlayer() { return engine.getlayer(); } public float percentmagic() { return ((float)(float) this.magic / (float)this.maxMagic ) * 100; } public Directions getDirection() { return direction; } public boolean hasKey() { Object[] inv = GameplayScreen.instance.getobjinv().getinventory(); for(Object obj : inv) { if(obj != null && obj.getname().toLowerCase().contains("key")) { return true; } } return false; } public boolean removeKey() { Object toRemove = null; Object[] inv = GameplayScreen.instance.getobjinv().getinventory(); for(Object obj : inv) { if(obj != null && obj.getname().toLowerCase().contains("key")) { toRemove = obj; break; } } if(toRemove != null) { GameplayScreen.instance.getobjinv().delete_object(toRemove); return true; } return false; } public void update() {} @Override public boolean goLeft(Map map) { //return engine.heroleft(); return GameplayScreen.instance.goleft(); } @Override public boolean goRight(Map map) { //return engine.heroright(); return GameplayScreen.instance.goright(); } @Override public boolean goUp(Map map) { //return engine.herodown(); return GameplayScreen.instance.godown(); } @Override public boolean goDown(Map map) { //return engine.heroup(); return GameplayScreen.instance.goup(); } public void moveInto(Map map, Chest chest) { if(chest.getabsolutecolumn(map) < getabsolutecolumn(map)) { goLeft(map); } else if(chest.getabsolutecolumn(map) < getabsolutecolumn(map)) { goRight(map); } if(chest.getabsoluterow(map) < getabsoluterow(map)) { goDown(map); } else if(chest.getabsoluterow(map) < getabsoluterow(map)) { goUp(map); } } }