idea for combat ranges

  • Nerian
  • Nerian's Avatar Topic Author
  • Offline
  • Senior Boarder
  • Senior Boarder
More
5 years 3 months ago #1721 by Nerian
idea for combat ranges was created by Nerian
I'm not a very great coder, but I had an idea I wish I could code. I would like to have my players have to actually enter combat and go through different ranges like missile, pole then finally get to melee range. .. of course only the certain types of weapons can be used to attack at those ranges. ...


Does anybody know if a snippet or something that does this?

Please Log in or Create an account to join the conversation.

  • zusuk
  • zusuk's Avatar
  • Offline
  • Gold Boarder
  • Gold Boarder
  • LuminariMUD Developer
More
5 years 3 months ago #1731 by zusuk
Replied by zusuk on topic idea for combat ranges
I remember seeing ranged-combat snippet on the old circlemud ftp.. But I think its more for out-of-room ranged combat as opposed to 'stages' of ranged combat same-room like you are suggesting.

Website
www.luminariMUD.com

Main Game Port
luminariMUD.com:4100

Please Log in or Create an account to join the conversation.

More
5 years 2 months ago #1957 by Kewlb
Replied by Kewlb on topic idea for combat ranges
I am going to be implementing this into my MUD.

I have already implemented a full events based combat system in a previous MUD I coded. I will be tweaking this system for use in my new project. The way it worked is that various weapons had speeds and ranges and there were no more set "combat rounds" as you attacked as needed based on the speed of the weapon. I implemented multi-room combat, but that became a bit cumbersome. I will still use some multi-room combat features here (grenades, sniper rifles, launchers, bows/crossbows), but whereas before range was defined by rooms away from target, I will base it off a virtual distance in each room.

This way as a battle ensues in a room certain mobs/players can move away from melee to ranged distance or move into melee distance, or spear distance, etc... it will flow a lot better than trying to deal with multi-room ranged combat and will add some new depth and strategy to what is otherwise mundane spamming of skills/spells to kill. Add this with my FF7 materia-like skill system with skill/spell cooldowns and delayed effects you will have a pretty unique and rewarding mud combat system.

Nothing like seeing that player/mob start to reload their weapon and you rush into melee range, kick the weapon out of their hand, get behind them, stab them in the back, kick them over, put a steak into them so they are held down while while they bleed out and you move on to the next mob/player.

Please Log in or Create an account to join the conversation.

More
5 years 2 months ago #2020 by Kewlb
Replied by Kewlb on topic idea for combat ranges
I started putting the basics together for this system, today. At first I was just going to use a single integer to represent depth. I have since decided that a better way is to use a grid. Based on the sector type, rooms will have a certain depth and height. I will let 0,0 be the center of the room. A room with a depth of 50 will be x: -25,25 y: -25,25. I will include height as well, but not for every cell of the room grid. It will just be a height cap based on sector type with objects, skills, etc.. that can modify each individuals own height. It wouldn't be too hard to code randomized inclines / hills, etc.. as well. I will also code in direction characters/objects can be facing.

I will change code so that visibility/interaction with objects/mobiles/players takes their position and range into consideration. There will be many ways to move around in the room and the goal is to make them as player friendly as possible. There will also be passive and hostile ways of coming into range of mobiles.

Obviously doing such a thing is really changing the entire nature of how the mud works/plays. Given this and how customized my code already is, I will not be releasing any type of patch for this system. I will, however, help any proficient coder implement such a system into their game.

Please Log in or Create an account to join the conversation.

  • Nerian
  • Nerian's Avatar Topic Author
  • Offline
  • Senior Boarder
  • Senior Boarder
More
5 years 2 months ago - 5 years 2 months ago #2034 by Nerian
Replied by Nerian on topic idea for combat ranges
heh unfortunately I'm not a proficient coder by any stress of the imagination


but what I was hoping for

in the room the only distance that actually would matter would be the distance between the PC and the mobs

this would mean that you could be at different ranges with different mobs

so if you engage a mob it would then put you at missle range with that particular mob, but still out of combat with other mobs unless something happens

if you advanced on your engaged mob you would move up to pole range then melee range, being able to stop advancing at any distance

casting a spell or shooting a bow at a mob automatically puts you at missile

some mobs would be able to charge straight to melee





honestly I don't even know how to begin implementing that system.
Last edit: 5 years 2 months ago by Nerian.

Please Log in or Create an account to join the conversation.

More
5 years 2 months ago #2035 by Kewlb
Replied by Kewlb on topic idea for combat ranges
There is a circleMUD snippet for linear distance, I would just advise against it. I thought about it and it is not much more work to just go ahead and add a full grid based system. Since this isn't graphical you shouldn't have to write any A* algorithm, but I guess you still could and I might still do that. I have one I wrote in C# that I might port to C.

I am not going to fully organize it, but i'll post up what I am writing when I am done.

For linear distance its pretty straight forward. Add a new variable to the room structs for int depth. Add one to objects and one to char_data. When a mob loads put them at a random distance and change wander to allow them to also move around distances in a room and set the distance when they enter a new room, summon, goto, transfer, etc.. . The issue I have with linear is what happens if someone comes in from the east or west are you just going to have them land at the center between the two end points? If you do a grid system you can actually have them land where appropriate based on the direction they came from. (e.g. given 0,0 as center in a size 50 room traveling east puts you at -25,0 (far west side center of the next room). If you just go with a linear distance there is no real way to account for true depth and being able to move around inside a room.

Please Log in or Create an account to join the conversation.

  • Nerian
  • Nerian's Avatar Topic Author
  • Offline
  • Senior Boarder
  • Senior Boarder
More
5 years 2 months ago #2037 by Nerian
Replied by Nerian on topic idea for combat ranges
I can definitely see the purpose of putting a full grid for room depth. This would also allow you to put objects into different parts of the room, secrets in certain parts of the room, etc.

So I definitely see where you are coming from and I would definitely appreciate anything that you write to be posted.





My original want for this was strictly for combat.

Please Log in or Create an account to join the conversation.

More
5 years 2 months ago #2038 by Papaya Pete
Replied by Papaya Pete on topic idea for combat ranges
I think there was a snippet that was the start of a grid system in combat. I think it's called form fighting on the old circlemud ftp sight. I haven't really looked at it in depth, but it could point your compass, so to speak.

Please Log in or Create an account to join the conversation.

  • Nerian
  • Nerian's Avatar Topic Author
  • Offline
  • Senior Boarder
  • Senior Boarder
More
5 years 2 months ago #2039 by Nerian
Replied by Nerian on topic idea for combat ranges
Thanks Pete following that I think I have found exactly what I was looking for

interesting enough it was called ranged


here is the code if anybody is interested


/* Ranged Room Combat V2.2
   Tres`ni (aka Brian Hartvigsen)
   tresni@ikickass.org

   (c) Brian Hartvigsen 2001
   WARNING: NOTHING IS MY FAULT!

  COMMANDS:
    retreat - FIGHT retreat from opponent
    advance - FIGHT advance on opponent
    range   - !FIGHT set range

  NOTES:  Uses the value[0] of weapons for range.  (It is unused in stock
          CircleMUDs)
*/

/*  Things to Add:
act.movement.c [163] do_simple_move
   was_in = ch->in_room;
   char_from_room(ch);
   char_to_room(ch, world[was_in].dir_option[dir]->to_room);
 + set_range_enter(ch,dir); //BAH


fight.c [658] damage
   if (ch != victim && ROOM_FLAGGED(ch->in_room, ROOM_PEACEFUL)) {
     send_to_char("This room just has such a peaceful, easy feeling...\r\n", ch);
     return (0);
   }

 + if(!in_range(ch,victim)){ //BAH
 +	  act("$N is out of range!",FALSE,ch,NULL,victim,TO_CHAR);
 +	  return(0);
 + }


interpreter.c
 + { "range"    , POS_STANDING, do_range_set, 0, 0 }, //BAH
 + { "retreat"  , POS_FIGHTING, do_range_retreat,0,0}, //BAH
 + { "advance"  , POS_FIGHTING,do_range_advance,0,0}, //BAH


structs.h [719] char_player_data
   ubyte weight;       * PC / NPC's weight                    *
   ubyte height;       * PC / NPC's height                    *
 + int range[2];       * PC / NPC Range Placement BAH         *


structs.h [930] char_file_u
   ubyte weight;
   ubyte height;
 + int range[2]; // BAH Ranged Combat


utils.h [263]
   #define GET_WEIGHT(ch)	((ch)->player.weight)
   #define GET_SEX(ch)	((ch)->player.sex)
 + #define GET_RANGE(ch,i) ((ch)->player.range[i])  //BAH Ranged Combate
*/

#include "conf.h"
#include "sysdep.h"


#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"

#define X 0
#define Y 1

ACMD(do_range_set){
	int x,y;
	char arg1[MAX_INPUT_LENGTH];
    char arg2[MAX_INPUT_LENGTH];

	two_arguments(argument,arg1,arg2);
	
	if(FIGHTING(ch)) {
		send_to_char("Use advance or retreat!\r\n",ch);
		return;
	}

	if(!*arg2 || !*arg1) {
		send_to_char("syntax: range X Y\r\n",ch);
		return;
	}
	x = atoi(arg1);
	y = atoi(arg2);

	if(x < 0 || x > 6 || y<0 || y > 6) {
		send_to_char("Range must be 0 - 6!\r\n",ch);
		return;
	}
	
	GET_RANGE(ch,X) = x;
	GET_RANGE(ch,Y) = y;
}


ACMD(do_range_advance) {
  struct char_data *vict;

  if(!FIGHTING(ch)) {
    send_to_char("You must be fighting to retreat!\r\n",ch);
    return;
  }

  if (FIGHTING(ch) && IN_ROOM(ch) != IN_ROOM(FIGHTING(ch))) {
	send_to_char("You can not advance on someone you can't see!\r\n", ch);
    return;
  }
  vict = FIGHTING(ch);
  if(GET_RANGE(ch,X) > GET_RANGE(vict,X))
	GET_RANGE(ch,X) += 1;
  else if(GET_RANGE(ch,X) < GET_RANGE(vict,X))
	GET_RANGE(ch,X) += -1;

  if(GET_RANGE(ch,Y) > GET_RANGE(vict,Y))
	GET_RANGE(ch,Y) += 1;
  else if(GET_RANGE(ch,Y) < GET_RANGE(vict,Y))
	GET_RANGE(ch,Y) += -1;

  act("$N advances on you!", FALSE, vict, 0, ch, TO_CHAR);
  act("You advance on $n!", FALSE, vict, 0, ch, TO_VICT);
  act("$N advances on $n!", FALSE, vict, 0, ch, TO_NOTVICT);
}


ACMD(do_range_retreat) {
  struct char_data *vict;
  int room_hash[7][7],x,y,victX,victY,win[3]={0,0,100};

  if(!FIGHTING(ch)) {
    send_to_char("You must be fighting to retreat!\r\n",ch);
    return;
  }

  if (FIGHTING(ch) && IN_ROOM(ch) != IN_ROOM(FIGHTING(ch))) {
	send_to_char("You can not retreat from someone you can't see!\r\n", ch);
    return;
  }

  vict = FIGHTING(ch);

  victX = GET_RANGE(vict,X);
  victY = GET_RANGE(vict,Y);

  for(x=0;x<7;x++) {
	for(y=0;y<7;y++) {
	  room_hash[x][y] = number(0,5);//Randomization
	  if(x == 3 || y == 3)
		  room_hash[x][y] += 0;
	  else if ((x == 0 || x == 6) && (y==0 || y ==6))
		  room_hash[x][y] += 3;
	  else if ((x <=1 || x >= 5) && (y <= 1 || y >= 5))
		  room_hash[x][y] += 2;
	  else
		  room_hash[x][y] += 1;
	  if((victX - x) >= (victY - y))
		  room_hash[x][y] -= (victX - x);
	  else
		  room_hash[x][y] -= (victY - y);

	}
  }
  for(x=GET_RANGE(ch,X)-1;x<=GET_RANGE(ch,X) + 1;x++){
	if(x < 1 || x > 7)
	  continue;
	else
	  for(y=GET_RANGE(ch,Y)-1;y<=GET_RANGE(ch,Y) +1;y++){
		if(y <1 || y > 7)
		  continue;
		else {
			if (room_hash[x][y] < win[3]) {
				win[X] = x;
				win[Y] = y;
				win[3] = room_hash[x][y];
			}
			else continue;
		}
	  }
  }

  GET_RANGE(ch,X) = win[X];
  GET_RANGE(ch,Y) = win[Y];

  act("$N retreats from you!", FALSE, vict, 0, ch, TO_CHAR);
  act("You retreat from $n!", FALSE, vict, 0, ch, TO_VICT);
  act("$N retreats from $n!", FALSE, vict, 0, ch, TO_NOTVICT);
}

void set_range_enter(struct char_data *ch, int direction){
	switch(direction){
	case NORTH:
		GET_RANGE(ch,X) = 0;
		GET_RANGE(ch,Y) = 3;
		break;
	case EAST:
		GET_RANGE(ch,X) = 6;
		GET_RANGE(ch,Y) = 3;
		break;
	case SOUTH:
		GET_RANGE(ch,X) = 3;
		GET_RANGE(ch,Y) = 6;
		break;
	case WEST:
		GET_RANGE(ch,X) = 3;
		GET_RANGE(ch,Y) = 0;
		break;
	case UP:
	case DOWN:
	default:
		GET_RANGE(ch,X) = 3;
		GET_RANGE(ch,Y) = 3;
		break;
	}
}

int in_range(struct char_data *ch, struct char_data *vict) {
	int x,y,range;
	struct obj_data *wielded = GET_EQ(ch, WEAR_WIELD);

	x = abs(GET_RANGE(ch,X) - GET_RANGE(vict,X));
	y = abs(GET_RANGE(ch,Y) - GET_RANGE(vict,Y));

	if(x<y)
		range = x;
	else
		range = y;

	if(range > GET_OBJ_VAL(wielded,0))
		return FALSE;
	else
		return TRUE;
}

Please Log in or Create an account to join the conversation.

More
5 years 2 months ago - 5 years 2 months ago #2042 by Kewlb
Replied by Kewlb on topic idea for combat ranges
I looked at that code. It is certainly a solid start. If you add <math.h> to sysdep.h and add -lm in Makefile flags you can replace his distance function with the actual real way to find the distance between two points. Not really a problem with his grid being 7x7 but if you went larger his method of figuring it out would not be very accurate.
float find_char_distance(struct char_data *ch, struct char_data *vict)
{
	int x, y;
	float distance = 0;

	if (IN_ROOM(ch) != IN_ROOM(vict))
		return -1;

	x = abs(GET_X(vict) - GET_X(ch));
	y = abs(GET_Y(vict) - GET_Y(ch));
	distance = sqrtf((x*x)+(y*y));
	return distance;
}

Also expanding his set_range_enter function here is one that accounts for all directions and allows for dynamic sizing of the room based on adding size to the room struct in structs.h. I also added facing so I could keep track of what direction a player is facing.. but that is easy enough to remove.
void set_initial_room_coords(struct char_data *ch, room_rnum room, int direction)
{
	int size;
	size = GET_ROOM_SIZE(room);
	int oldface = GET_FACING(ch);
	GET_FACING(ch) = direction;

	switch (direction)
	{
	case NORTH:
		GET_X(ch) = 0;
		GET_Y(ch) = (-size / 2);
		break;
	case SOUTH:
		GET_X(ch) = 0;
		GET_Y(ch) = (size / 2);
		break;
	case EAST:
		GET_X(ch) = (-size / 2);
		GET_Y(ch) = 0;
		break;
	case WEST:
		GET_X(ch) = (size / 2);
		GET_Y(ch) = 0;
		break;
	case UP:
		GET_X(ch) = 0;
		GET_Y(ch) = 0;
		GET_FACING(ch) = oldface;
		break;
	case DOWN:
		GET_X(ch) = 0;
		GET_Y(ch) = 0;
		GET_FACING(ch) = oldface;
		break;
	case NORTHEAST:
		GET_X(ch) = (-size / 2);
		GET_Y(ch) = (-size / 2);
		break;
	case NORTHWEST:
		GET_X(ch) = (size / 2);
		GET_Y(ch) = (-size / 2);
		break;
	case SOUTHEAST:
		GET_X(ch) = (-size / 2);
		GET_Y(ch) = (size / 2);
		break;
	case SOUTHWEST:
		GET_X(ch) = (size / 2);
		GET_Y(ch) = (size / 2);
		break;
	default:
		GET_X(ch) = 0;
		GET_Y(ch) = 0;
		break;
	}
}

You can use the below to find the direction of something relative to the player's location on the grid. I am going to be using it simply to alter the look_at_char so you might see something "far off to the northeast"
where this would be used an probably passed to dirs[].
int location_relative_to_ch(struct char_data *ch, int targetX, int targetY)
{
	int targetDir = 0; 

	if (GET_Y(ch) == targetY)
	{
		if (GET_X(ch) == targetX)
			targetDir = -1; /* same space as ch */
		else if (GET_X(ch) > targetX)
			targetDir = WEST;
		else if (GET_X(ch) < targetX)
			targetDir = EAST;
	}
	else if (GET_Y(ch) > targetY)
	{
		if (GET_X(ch) == targetX ||
			GET_X(ch) + 1 == targetX ||
			GET_X(ch) - 1 == targetX)
			targetDir = SOUTH;
		else if (GET_X(ch) > targetX)
			targetDir = SOUTHWEST;
		else if (GET_X(ch) < targetX)
			targetDir = SOUTHEAST;
	}
	else
	{
		if (GET_X(ch) == targetX ||
			GET_X(ch) + 1 == targetX ||
			GET_X(ch) - 1 == targetX)
			targetDir = NORTH;
		else if (GET_X(ch) > targetX)
			targetDir = NORTHWEST;
		else if (GET_X(ch) < targetX)
			targetDir = NORTHEAST;
	}

	return targetDir;

}

Also you will probably want to find every instance of char_to_room and randomize or intelligently set the coordinates of that character.
Last edit: 5 years 2 months ago by Kewlb. Reason: add additional comments

Please Log in or Create an account to join the conversation.

  • zusuk
  • zusuk's Avatar
  • Offline
  • Gold Boarder
  • Gold Boarder
  • LuminariMUD Developer
More
5 years 2 months ago #2077 by zusuk
Replied by zusuk on topic idea for combat ranges
I've always liked this idea, great to see a code snippet for it :)

Website
www.luminariMUD.com

Main Game Port
luminariMUD.com:4100

Please Log in or Create an account to join the conversation.

Time to create page: 1.538 seconds