Welcome to the Builder Academy

Question idea for combat ranges

More
30 Apr 2013 23:10 #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
01 May 2013 00:03 #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.

More
01 May 2013 01:52 #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


Code:
/* 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
01 May 2013 03:02 - 01 May 2013 04:45 #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.
Code:
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.
Code:
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[].
Code:
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: 01 May 2013 04:45 by Kewlb. Reason: add additional comments

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

More
03 May 2013 06:06 #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: 0.189 seconds