Package ru.vagrant_ai.questionmarkgame.obj.mob

Source Code of ru.vagrant_ai.questionmarkgame.obj.mob.Monster

package ru.vagrant_ai.questionmarkgame.obj.mob;

import java.util.Random;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.geom.Point;
import org.newdawn.slick.geom.Rectangle;

import ru.vagrant_ai.questionmarkgame.main.Game;
import ru.vagrant_ai.questionmarkgame.main.GameplayState;
import ru.vagrant_ai.questionmarkgame.obj.Elements;
import ru.vagrant_ai.questionmarkgame.util.Particle;
import ru.vagrant_ai.questionmarkgame.util.list.ITEM;
import ru.vagrant_ai.questionmarkgame.util.list.ML;
import ru.vagrant_ai.questionmarkgame.util.list.MS;
import ru.vagrant_ai.questionmarkgame.util.list.PT;

public class Monster {

/**
* Monster special options:
*   Knockback
*     onDamage(int power)
*     onSpecialDamage(int power)
*/
 
 
    /* CONSTRUCTOR ZONE */
   
    protected short ground_level = GameplayState.ground_level+45;
   
    public Rectangle hitbox;
    public Rectangle hitbox_crit;
    public Point center;
    protected ML id;
   
    protected short hp;
    protected short hp_default;
    protected short power;
    protected float y;
    protected float x;
    protected short height;
    protected short width;
    protected float speed;
    public MS state;
    protected boolean state_damaged;
    protected boolean gravity_rule = true; //true, if monster affected by impulse methods
    protected boolean crit_death = false;

    public boolean opt_knockback = true; //true if monster have knockback upon damage
   
    protected short poison_sec;
    private short poison_frame;
    private byte poison_damage;
   
    protected final void performDefault()
    {
      hp = hp_default;
      x = Game.getAppX()+30+(new Random().nextInt(20));
      hitbox = new Rectangle(x-width, y-height, width, height); //setting hitbox
      hitbox_crit = new Rectangle(x-width+7, y-height+2, 9, 9);
      center = new Point(x-(float)width/2, y+(float)height/2);
      updateFacing();
    }
   
    /* UPDATE ZONE */ 

      boolean direction;
      float speed_scale = 1;

     
      public void update()
      {
        perform();
        checkUtil();
        checkPlayerDamaged();
        checkDamaged();
        if (gravity_rule) checkFalling();
      }
     
      protected void perform()
      {

      }
         
      protected void checkUtil()
      {
        center.setLocation(x-(float)width/2, y-(float)height/2); //set center point
        if (poison_sec > 0) //set poison dmg
        {
          poison_frame--;
          if (poison_frame < 0)
          {
            poison_sec--;
            poison_frame = (short) Game.app.getFPS();
            onDamage(poison_damage, false, false);
          }
        }
      }
     
      protected void checkPlayerDamaged()
      {
        if (hitbox.intersects(GameplayState.player.hitbox) && state != MS.DEAD && state != MS.NULL)
        {
          GameplayState.player.addDamage(power);
          onAttackSuccess();
        }
      }
           
      private float util_special_impulse = 0;
      private float util_special_rand = 0;
      private int knockback_x = 0;
     
      protected void checkDamaged()
      {
        if (util_special_impulse != 0 && state != MS.DEAD && state != MS.NULL)
        {
          x += ((id == ML.KHATUM?1.28f:1.7f)+(id == ML.EEL?0.6f:0)+util_special_rand) * (knockback_x>=center.getX()?-1:1);
          y -= util_special_impulse;
          util_special_impulse -= 0.3f+util_special_rand;
          if (util_special_impulse == 0)
            util_special_impulse -= 0.00001f;
          if (y >= ground_level)
          {
            y = ground_level;
            util_special_impulse = 0;
            knockback_x = 0;
            state = MS.WALK;
          }
        }
      }
     
      private void checkFalling()
      {
        if (state == MS.WALK && (util_velo_x > 0 || util_velo_y > 0)
            && id != ML.WALDO3 //WALDO3 exception 
            && state != MS.NULL && state != MS.DEAD
          )
          state = MS.STOP;
        if (util_velo_x > 0)
        {
          x += util_velo_x + util_impulse_direction;
          util_velo_x -= 0.5f;
          if (util_velo_x <= 0)
          {
            util_velo_x = 0;
            if (util_velo_y <= 0 && state != MS.NULL && state != MS.DEAD)
              state = MS.WALK;
          }
        }
        if (util_velo_y > 0 || (y < ground_level
            && state != MS.JUMP //WALDO3 exception
            && util_special_impulse == 0 //Thorny and poison cloud bonus exception
            && state != MS.DEAD && state != MS.NULL
          )) //if jumping
        {
          y -= util_velo_y;
          util_velo_y -= 0.5f;
          if (y >= ground_level) //checking, if monster reached ground level
          {
            y = ground_level;
            util_velo_y = 0;
            util_velo_x = 0;
            state = MS.WALK;
          }
        }
      }
       
    /* RENDER ZONE */
               
      public void render(Graphics g)
      {
        renderMain(g);
        if (state != MS.DEAD && state != MS.NULL) renderHP(g);
        g.setColor(Color.red);
        g.setLineWidth(1);
      }
     
      protected void renderMain(Graphics g)
      {
       
      }
     
      protected void renderHP(Graphics g)
      {
        g.setColor(new Color(185, 80, 80));
        g.setLineWidth(1);
        g.drawRect(x-width-(36-width)/2, y-height-15, 36, 4);
        g.setColor(Color.red);
        g.fillRect(x-width-(36-width)/2+1, y-height-14, (float)35/hp_default*hp, 3);
      }

    /* EXTERNAL-USE METHDOS */
         
    public void onDamage(int power, boolean crit)
    {
      onDamage(power, true, crit);
    }
   
    public void onDamage(int power, boolean knockback, boolean crit)
    {
      if (hp < 1 || state == MS.DEAD) return;
      if (id == ML.EEL && state == MS.JUMP)
        state = MS.WALK;
      hp -= power;
      if (hp < 1)
      {
        crit_death = crit;
        state = MS.DEAD;
        if (Elements.kamikaze)
          Elements.addExplosion((int)center.getX(), (int)center.getY());
        if (poison_sec > 0)
        {
          if (GameplayState.player.util_poison_cloud && Elements.extractLevel(ITEM.P_GUN_POISON_BULLET)+Elements.extractLevel(ITEM.P_UPG_POISON_CLOUD) >= 2)
            Particle.addNew(PT.POISON_CLOUD, (int) center.getX(), (int) center.getY());
          for (int i = 0; i < 6; ++i)
            Particle.addNew(PT.POISON_EFFECT, (short) (x-new Random().nextInt(width)), (short) (y-new Random().nextInt(height)));
        }
        for (int i = 0; i < id.getMoneyAmt(); ++i)
          Elements.addMoney((int)center.getX(), (int)center.getY(), (byte) 1);
      }
      else if (knockback)
      {
        if (id == ML.KHATUMaddImpulse(1,1);
        else if (id == ML.EEL) addImpulse(1.9f,1.9f);
        else addImpulse(1.7f,1.7f);
      }
    }
   
    public void onSpecialDamage(float power, int hp, int knockback_source)
    {
      if (state == MS.DEAD) return;
      knockback_x = knockback_source;
      util_velo_y = 0; //nullify current falling state
      if (state != MS.DEAD && state != MS.NULL) state = MS.STOP; //prevent monster from moving
      util_special_impulse = 3+power; //add special knockback
      onDamage(hp, true, false); //add damage
      float rand = (float)new Random().nextInt(100)+50;
      util_special_rand = 10f/rand; //random factor
    }
   
    public void addPoison(byte sec, byte damage)
    {
      if (poison_sec > 0 && damage < poison_damage)
        poison_sec += (sec*damage)/poison_damage;
      else
      {
        poison_sec = sec;
        poison_damage = damage;
        poison_frame = (short) Game.app.getFPS();
        onDamage(damage, false, false);
      }
    }
       
    protected void onAttackSuccess()
    {

    }
   
    /* UTIL */
    private float util_velo_x, util_velo_y;
    private float util_impulse_direction;
     
    public void addImpulse(float impulse_x, float impulse_y)
    {
      if (state == MS.DEAD) return;
      util_velo_x = impulse_x; 
      util_impulse_direction = (GameplayState.player.pl_center.getX()>=center.getX()?-1:1) * (1.2f/(float)Game.getAppX()*getDistance());

      util_velo_y = impulse_y;
    }
   
    public float getDistance()
    {
      float distance = GameplayState.player.pl_center.getX()-center.getX();
      if (distance < 0) distance *= -1;
      return distance;
    }
   
/**
* Sets direction to true if monster must go left or to false if monster must go right
*/
    public void updateFacing()
    {
      if (GameplayState.player.pl_center.getX() >= center.getX())
        direction = false;
      else
        direction = true;
    }
   
/**
* Returns true if current facing is ok, returns false otherwise
*/
    public boolean checkFacing()
    {
      if ((direction == false && GameplayState.player.pl_center.getX() >= center.getX()) || (direction == true && GameplayState.player.pl_center.getX() < center.getX())) return true;
      else return false;
    }
   
/**
* Monster instant silent suicide
* @param rule 0 - monster suicide w/ dying anim, rule 1 - monster suicide w/o dying anim
*/
    public void Suicide(int rule)
    {
      hp = 0;
      if (rule == 0) state = MS.NULL;
    }
   
    public boolean getDirection()
    {
      return direction;
    }

    public ML getId()
    {
      return id;
    }
   
    public float getX()
    {
      return x;
    }
   
    protected void drawImage(Image img, short x, short y)
    {
      if (poison_sec > 0)
        img.setImageColor(0, 255, 0);
      img.draw(x, y);
    }
   
   
}
TOP

Related Classes of ru.vagrant_ai.questionmarkgame.obj.mob.Monster

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.