📄 monster.java
字号:
package istarion.core;
import java.util.Vector;
import istarion.frontend.Toolkit;
/**
* Ein NPC - ein Monster - in GeekHack
*/
public abstract class Monster extends Mobile
{
public static final int ORC = 0;
public static final int RAT = 1;
public static final int SLIME = 2;
public static final int BAT = 3;
public static final int BRAIN_NONE = 0;//does nothing.
public static final int BRAIN_EVIL = 1;//normal monster.
public static final int BRAIN_UNDEAD = 2; //has no fear.
private int __brain = BRAIN_NONE;
/**
* The experience the player gains when he defeats the Monster.
*/
private int __expgain = 0;
private int __movepoints = 0;
/**
* This number of rounds ago, this monster
* has had the last sight contact to the
* player. -1 means, it cannot remember
* having met the player in the near past.
*/
private int __lastPlayerContact = -1;
private static final int JUST_SEEN = 5;
/**
* The current target x-coordinate of this monster.
* Will charge to this location and/or attack it.
* -1 means no target atm.
*/
private int __targetx = -1;
/**
* The current target y-coordinate of this monster.
* Will charge to this location and/or attack it.
* -1 means no target atm.
*/
private int __targety = -1;
/**
* The current Mobile this monster is about to attack.
*/
private Mobile __targetMobile = null;
/**
* Constructor.
*/
public Monster(String name, char symbol, int color)
{
super(name, symbol, color);
}
public void setBrain(int brain)
{
__brain = brain;
}
public int getBrain()
{
return __brain;
}
public void setExpGain(int xp)
{
__expgain = xp;
}
public int getExpGain()
{
return __expgain;
}
/**
* Called when this monster has sight
* contact to the player.
*/
public void hasPlayerContact(Player p)
{
if (__lastPlayerContact == -1) eventSpotPlayer(p);
__lastPlayerContact = JUST_SEEN;
__targetMobile = p;
__targetx = __targetMobile.getXLocation();
__targety = __targetMobile.getYLocation();
}
/**
* Is exectuted when the monster spots the player for
* the first time.
*/
public void eventSpotPlayer(Player p)
{
}
/**
* Executes an action depending on the Monster's brain.
*/
public void act()
{
//regenerate move points
__movepoints += getSpeed();
//low on move points?
//then pause this turn.
if ((__movepoints - 8) < 0) return;
__movepoints -= 8;
//do nothing if not involved in game atm.
if (__lastPlayerContact == -1) return;
//forget player a little bit more
__lastPlayerContact--;
//ok. now select what action to do. for now simply charge
//and attack.
if (__targetMobile != null)
{
__moveTo(__targetMobile.getXLocation(), __targetMobile.getYLocation(), true);
} else if ((__targetx >= 0) && (__targety >= 0)) {
__moveTo(__targetx, __targety, false);
} else {
__wanderRandomly();
}
//end of turn. clean up:
if (__lastPlayerContact == 0)
{
__targetx = -1;
__targety = -1;
}
}
/**
* Takes one step towards the specified target mobile.
* Monsters are fairly stupid :)
*/
private void __moveTo(int targetx, int targety, boolean attacktarget)
{
int direction[] = new int[4];
int diffX = targetx - getXLocation();
int diffY = targety - getYLocation();
int abstandX = Math.abs(diffX);
int abstandY = Math.abs(diffY);
/*
* compute direction to go to:
* if attacktarget is true and target mobile is in
* adjacent cell, then attack it.
* else move into that cell.
*/
if ((diffY < 0) && (abstandY > abstandX)) //go north
if (attacktarget && (getDungeon().
getMobile(getXLocation(), getYLocation() - 1)
== __targetMobile))
{
__attack(__targetMobile);
return;
} else {
direction[0] = Dungeon.NORTH;
direction[3] = Dungeon.SOUTH;
if (diffX < 0)
{
direction[1] = Dungeon.WEST;
direction[2] = Dungeon.EAST;
} else {
direction[1] = Dungeon.EAST;
direction[2] = Dungeon.WEST;
}
}
else if ((diffY > 0) && (abstandY > abstandX)) //go south
if (attacktarget && (getDungeon().
getMobile(getXLocation(), getYLocation() + 1)
== __targetMobile))
{
__attack(__targetMobile);
return;
} else {
direction[0] = Dungeon.SOUTH;
direction[3] = Dungeon.NORTH;
if (diffX < 0)
{
direction[1] = Dungeon.WEST;
direction[2] = Dungeon.EAST;
} else {
direction[1] = Dungeon.EAST;
direction[2] = Dungeon.WEST;
}
}
else if ((diffX < 0) && (abstandX > abstandY)) //go east
if (attacktarget && (getDungeon().
getMobile(getXLocation() - 1, getYLocation())
== __targetMobile))
{
__attack(__targetMobile);
return;
} else {
direction[0] = Dungeon.WEST;
direction[3] = Dungeon.EAST;
if (diffY < 0)
{
direction[1] = Dungeon.NORTH;
direction[2] = Dungeon.SOUTH;
} else {
direction[1] = Dungeon.SOUTH;
direction[2] = Dungeon.NORTH;
}
}
else if ((diffX > 0) && (abstandX > abstandY)) //go west
if (attacktarget && (getDungeon().
getMobile(getXLocation() + 1, getYLocation())
== __targetMobile))
{
__attack(__targetMobile);
return;
} else {
direction[0] = Dungeon.EAST;
direction[3] = Dungeon.WEST;
if (diffY < 0)
{
direction[1] = Dungeon.NORTH;
direction[2] = Dungeon.SOUTH;
} else {
direction[1] = Dungeon.SOUTH;
direction[2] = Dungeon.NORTH;
}
}
/*
* now move into the calculated direction.
*/
if (move(direction[0])) return;
if (move(direction[1])) return;
if (move(direction[2])) return;
move(direction[3]);
}
/**
* Attacks the specified target.
*/
private void __attack(Mobile target)
{
GameController.gameMessage(getName() + " attacks you!");
//work is done. clean up:
//__targetMobile = null;
}
/**
* Take a step into a random location.
*/
private void __wanderRandomly()
{
int[] dirseq = Toolkit.tk().getRandomIntSequence(5);
int dirnum = 0;
boolean moved = false;
do
{
moved = move(dirseq[dirnum] + 1);
dirnum++;
} while (!moved && (dirnum < 5));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -