⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 players.cpp

📁 with vxworks we can develope a group of control software for industry.
💻 CPP
字号:
/*    BladeMaster 2, a text, rougelike(kinda), arena combat simulation game.   Copyright (C) 2002 Blademaster 2 Team, see CREDITS   Clone of BladeMaster by Logicom, Inc. Copyright(C) 1990/1993   In no means affliated with the original Blademaster or the original   Blademaster creators/programmers.   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 2 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, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   Useful contact information:       Website: blademaster2.sourceforge.net       Project page: www.sf.net/projects/blademaster2/   Project Lead (see CREDITS for other members of the developement team)       E-Mail: ilswyn@users.sourceforge.net       AIM: ilswyn*//* *------------------------------------------------------*   |                players.cpp players.h                 |   |                                                      |   |   Contain all classes for human and computer players |   |  and methods of those classes, the classes contain   |   |  all the values and attributes. (stats etc.)         |    *------------------------------------------------------* */#include <string>#include <cstdlib>#include <ncurses.h>#include <stdlib.h> // need this for exit() - Sairax#include "menus.h"#include "textgfx.h"#include "main.h"#include "arena.h"#include "items.h" // Attack functions, Armor, Weapon classes#include "players.h"#include "shops.h"#include "globals.h"Player::Player(){  obj_pos.setPos_X(getrandom(0, arena_boundary.getPos_X()));  obj_pos.setPos_Y(getrandom(0, arena_boundary.getPos_Y()));  obj_last_pos = obj_pos;  melee_weapon = new Weapon;  melee_weapon->setWeaponName("Hands") ;  melee_weapon->setMinDmg(1);  melee_weapon->setMaxDmg(4);  range_weapon = new RangeWeapon;  range_weapon->setWeaponName("None");  range_weapon->setMinDmg(1);  range_weapon->setMaxDmg(4);  current_health = 10;  max_health = 10;  projectiles = 0;  body_armor = new Armor;  body_armor->setArmorName("Loin Cloth");  body_armor->setArmorClass(1);}Player::~Player(){}//   Takes the numpad # (direction), start position of the player, and the// amount of spaces to move (or attack). Goes the amount of spaces in the// specified direction.Position Player::follow_direction(Position start_pos, int direction, int spaces){  Position newpos; // New position after following direction  switch(direction)    {    case 9: // 9 key = upright      newpos.setPos_X( start_pos.getPos_X() + spaces);      newpos.setPos_Y( start_pos.getPos_Y() - spaces);      break;          case 7: // 7 key = upleft      newpos.setPos_X(start_pos.getPos_X() - spaces);      newpos.setPos_Y(start_pos.getPos_Y() - spaces);      break;          case 3: // 3 key = downright      newpos.setPos_X(start_pos.getPos_X() + spaces);      newpos.setPos_Y(start_pos.getPos_Y() + spaces);      break;    case 1: // 1 key = downleft      newpos.setPos_X(start_pos.getPos_X() - spaces);      newpos.setPos_Y(start_pos.getPos_Y() + spaces);      break;    case 8: // 8 key = up      newpos.setPos_X(start_pos.getPos_X());      newpos.setPos_Y(start_pos.getPos_Y() - spaces);      break;          case 2: // 2 key = down      newpos.setPos_X(start_pos.getPos_X());      newpos.setPos_Y(start_pos.getPos_Y() + spaces);      break;          case 6: // 6 key = right      newpos.setPos_X(start_pos.getPos_X() + spaces);      newpos.setPos_Y(start_pos.getPos_Y());      break;    case 4: // 4 key = left      newpos.setPos_X(start_pos.getPos_X() - spaces);      newpos.setPos_Y(start_pos.getPos_Y());      break;    default: // 5 is pass or if any other keys are pressed      newpos.setPos_X(start_pos.getPos_X());      newpos.setPos_Y(start_pos.getPos_Y());      break;    }  return newpos;}void Player::melee_attack(){}//   This game is turn based, both the computer and human // players take turns in which they can move once, or perform // an action once (plead for mercy, attack). take_turn() has// to be specialized for human and comp players. No general// actions by just Player are taken.void Player::take_turn(){}//   Takes a delta (diffrence between your position and the// destination) and moves that amount. void Player::move_amount(Position delta){   obj_pos.setPos_X(obj_pos.getPos_X() + delta.getPos_X());   obj_pos.setPos_Y(obj_pos.getPos_Y() + delta.getPos_Y());  }//   Takes coordinates and moves the player to that specific// spot.void Player::move_to(Position p){  obj_pos = p;}HumanPlayer::HumanPlayer(){  setName("PLAYER X");  obj_char = '@';  draw();  setGoldInHand(300);  setGoldInBank(0);  setExp(0);  setLevel(0);  setHealth(10);  setProjectiles(0);}HumanPlayer::~HumanPlayer(){}// Directional input by numpad// *** NUMLOCK MUST BE OFF ***// 7 8 9     upleft up upright//  \|/           \ | /// 4-5-6      left pass right//  /|\           / | \// 1 2 3  downleft down downright//   Waits for player to input a numpad key and returns the// numpad # for that direction. This has advantages, generally// it is easier to read these numbers than KEY_NPAGE etc. and// now we can check if the command is not a direction, returning// 0 if that is the case.int HumanPlayer::get_direction(int command){  switch(command)    {    case KEY_PPAGE:      return 9;      break;    case KEY_HOME:      return 7;      break;    case KEY_NPAGE:      return 3;      break;    case KEY_END:      return 1;      break;    case KEY_LEFT:      return 4;      break;    case KEY_RIGHT:      return 6;      break;    case KEY_UP:      return 8;      break;    case KEY_DOWN:      return 2;      break;    default: // If the input is any other key return 0 (false)      return 0;       break;    }}void HumanPlayer::melee_attack(Position dest_pos){  ArenaObject* victim;   // less code, increased speed - Sairax  // This whole stuff caused a segmentation fault, fixed it up  if ((victim = check_for_obstacle(dest_pos.getPos_X(), dest_pos.getPos_Y())) != NULL) // if is an object    {        // if is for debuggin	// melee_weapon from class Player (melee_weapon does not exist in HumanPlayer (defined in base class)	// it is null in this class	// fixed it up 	// -Sairax        if (!Player::melee_weapon) {	  mvwprintw(inventory, 3, 2, "Cannot hit %s (NULL melee_weapon)", victim->getName());	  return;	}	int damage = Player::melee_weapon->do_attack(victim);                     if (victim->getCurrentHealth() <= 0) // If dead	{	  draw_victory();	   current_exp += victim->getExpValue();	  	  if ((current_exp % 100) == 0)	    {	      level++;	      max_health += 10;	      current_health += 10;	    }	  	  clear();	  main_screen_loop();	}      else	{	  mvwprintw(inventory, 3, 2, "You hit the %s for %d damage!", victim->getName(), damage);	  wrefresh(inventory);	}    }  else     {      mvwprintw(inventory, 2, 2, "There was no one there!");      wrefresh(inventory);    }}// Takes two indicators that tell what direction the range attack is in.// For example, if the input was -1, 0 the attack would be all the way to// the left. If it was -1, -1 then the attack would be to the upleftvoid HumanPlayer::range_attack(int x_indicator, int y_indicator){  ArenaObject* victim;  // The arrow or bullet or whatever you shoot is auctually a ArenaObject  // that travels.  ArenaObject* shot;  shot->getObjPos().setPos_X( obj_pos.getPos_X() + x_indicator);  shot->getObjPos().setPos_Y( obj_pos.getPos_Y() + y_indicator);  shot->setObjChar( (char)"/");  // Path in which the projectile is going to be shot  int x_path = obj_pos.getPos_X() + x_indicator;  int y_path = obj_pos.getPos_Y() + y_indicator;  // Returns the victim if the victim is in the path of the shot else it  // returns 0.  while (in_arena_boundary(shot->getObjPos()))    {      victim = check_for_obstacle(x_path, y_path);            if (victim != NULL && victim->getObjPos().getPos_X() != obj_pos.getPos_X()        && victim->getObjPos().getPos_Y() != obj_pos.getPos_Y())      	{	  int damage = Player::range_weapon->do_attack(victim);  	  if (victim->getCurrentHealth() <= 0) // If dead	    {	      draw_victory();	      	      current_exp += victim->getExpValue();	      if ((current_exp % 100) == 0)		{		  level++;		  max_health += 10;		  current_health += 10;		}	      	      clear();	      main_screen_loop();	    }	  else	    {	      mvwprintw(inventory, 3, 2, "You shot the %s for %d damage!", victim->getName(), damage);	      	      wrefresh(inventory);	    }	  	  while (in_arena_boundary(shot->getObjPos()))	    {	      shot->draw();	      //shot->obj_pos.x += x_indicator;	      //shot->obj_pos.y += y_indicator;	      shot->getObjPos().setPos_X( shot->getObjPos().getPos_X() + x_indicator);	      shot->getObjPos().setPos_Y( shot->getObjPos().getPos_Y() + y_indicator);	    }	}      else	{	  x_path += x_indicator;	  y_path += y_indicator;	}    }}void HumanPlayer::plead_for_mercy(){}void HumanPlayer::take_turn(){  int command = get_input();  // Will output the code for the direction if a direction is inputted  int direction = get_direction(command);  // dest_pos is the destined position to move/attack  Position dest_pos = follow_direction(obj_pos, direction, 1);	      if (direction)    {      if ((check_for_obstacle(dest_pos.getPos_X(), dest_pos.getPos_Y())) == 0)	{	  move_to(dest_pos);	}    }  else if (!direction)    {      switch(command)	{	case 'A':	case 'a':	  {	    wattron(inventory, A_BOLD);	    wattron(inventory, COLOR_PAIR(3)); 	    mvwprintw(inventory, 1, 2, "Choose direction of attack: ");	    wrefresh(inventory);	    direction = get_direction(get_input());	    	    if (direction)	      {		dest_pos = follow_direction(obj_pos, direction, 1);		if ((check_for_obstacle(dest_pos.getPos_X(), dest_pos.getPos_Y())) != 0)		  {		    melee_attack(dest_pos);		  }		// Melee attack messes up the colors..		wattron(inventory, COLOR_PAIR(3));		wattron(inventory, A_BOLD);		// Clear the Choose direction...		mvwprintw(inventory, 1, 2, "                            ");		mvwprintw(inventory, 1, 2, "BATTLE COMMAND:");		wrefresh(inventory);		wattroff(inventory, A_BOLD);		wattroff(inventory, COLOR_PAIR(3));	      }	    else 	      {		wattroff(inventory, A_BOLD);		wattroff(inventory, COLOR_PAIR(3));	      }	  }	case 'F':	case 'f':	  direction = get_direction(get_input());	  if (direction)	    {	      dest_pos = follow_direction(obj_pos, direction, 1);	      	      // Used for the indicator of range attack	      int x_diff = (obj_pos.getPos_X() - dest_pos.getPos_X());	      int y_diff = (obj_pos.getPos_Y() - dest_pos.getPos_Y());	      range_attack(x_diff, y_diff);	    }	  break;	case 'P':	case 'p':	  break;	}    }  draw();}CompPlayer::CompPlayer(){  setName("PLAYER Y");  obj_char = 'X';  draw();}CompPlayer::~CompPlayer(){}void CompPlayer::melee_attack(ArenaObject* obj){        // if is for debuggin	// melee_weapon from class Player (melee_weapon does not exist in HumanPlayer (defined in base class)	// it is null in this class	// fixed it up 	// -Sairax	if (!Player::melee_weapon) {	  mvwprintw(inventory, 3, 2, "Compuer cannot hit %s (NULL melee_weapon)", obj->getName());		  return;	}				      int damage = Player::melee_weapon->do_attack(obj);  if (obj->getCurrentHealth() <= 0) // If dead    {      draw_loss();      clear();      main_screen_loop();    }  else    {      wattron(inventory, COLOR_PAIR(1));      mvwprintw(inventory, 2, 2, "%s hits you for %d damage!", name.c_str(), damage);            wrefresh(inventory);    }}void CompPlayer::take_turn(){  ArenaObject* nearest_human;  nearest_human = main_arena->get_nearest_type(obj_pos, HUMAN);  // Just incase no humans are in the arena (for some reason ;P)  ArenaObject* nearest_comp;  nearest_comp = main_arena->get_nearest_type(obj_pos, COMP);  //   Destination, difference between coordinates is the amount of   // spaces the comp has left to move go towards nearest human player.  int xdest;  int ydest;  if (nearest_human != 0)     {      // random stupidness      // - Sairax      xdest = obj_pos.getPos_X() - nearest_human->getObjPos().getPos_X() + getrandom(-1, 1);      ydest = obj_pos.getPos_Y() - nearest_human->getObjPos().getPos_Y() + getrandom(-1, 1);    }  else if (nearest_comp != 0)    {      xdest = obj_pos.getPos_X() - nearest_comp->getObjPos().getPos_X();      ydest = obj_pos.getPos_Y() - nearest_comp->getObjPos().getPos_Y();    }  else    {      clear();      main_screen_loop();    }  ArenaObject* aobj;  //   Checks if there is an obstacle in the place ahead, behind, up,  // or down.. if not it tracks xdest, and follows to the destination.  // if xdest is positive then the comp needs to move backwards (obj_pos.x--)  // and if xdest is negative the comp needs to move forwards (obj_pos.x++),  // same goes with ydest.  aobj = check_for_obstacle(obj_pos.getPos_X()-1, obj_pos.getPos_Y());    if (aobj == 0)    {      if (xdest > 0)	{	  int tempint = obj_pos.getPos_X();	  obj_pos.setPos_X(--tempint);	  xdest--;	}    }  else melee_attack(aobj);  aobj = check_for_obstacle(obj_pos.getPos_X()+1, obj_pos.getPos_Y());    if (aobj == 0)    {      if (xdest < 0)	{	  int tempint2 = obj_pos.getPos_X();	  tempint2 = obj_pos.getPos_X();	  obj_pos.setPos_X(++tempint2);	  xdest++;	}    }  else melee_attack(aobj);  aobj = check_for_obstacle(obj_pos.getPos_X(), obj_pos.getPos_Y()-1);  if (aobj == 0)    {      if (ydest > 0)	{	  int temp3 = obj_pos.getPos_Y();	    obj_pos.setPos_Y(--temp3);	  ydest--;	}    }  else melee_attack(aobj);  aobj = check_for_obstacle(obj_pos.getPos_X(), obj_pos.getPos_Y()+1);  if (aobj == 0)    {      if (ydest < 0)	{	  int temp4 = obj_pos.getPos_Y();	  obj_pos.setPos_Y(++temp4);	  ydest++;	}    }  else melee_attack(aobj);    draw();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -