Picking a random room from ALL rooms on the MUD

Login to reply  Page: « < 1 of 1 > »
15 Jul 2010 - 03:262861
Picking a random room from ALL rooms on the MUD
Any easy way to do this? Or do I need to create a loop with random.65535 and keep generating random numbers till one is a valid room?


__________________
Owner/Coder/Head Admin
Caer Dubrin
15 Jul 2010 - 07:382863
Rather that trying to generate a random room by vnum, do it by rnum and convert it to vnum:
room_vnum get_random_room(void)
{
  rnum = rand_number(0, top_of_world);
  return (world[rnum].number);
}


__________________
15 Jul 2010 - 14:132865
I wanted this in DG though ;)
Quote Jamdog:
Rather that trying to generate a random room by vnum, do it by rnum and convert it to vnum:
room_vnum get_random_room(void)
{
  rnum = rand_number(0, top_of_world);
  return (world[rnum].number);
}


I was looking for a solution in DG though. Unless you were suggesting to code a random.room to complement random.char and have this be a part of the code?


__________________
Owner/Coder/Head Admin
Caer Dubrin
15 Jul 2010 - 15:542871
yeah, a %random.room% variable would do it, just throw this into dg_variables.c near line 525:
                snprintf(str, slen, "%s", dirs[doors]);
              }
            }
          }
+         else if (!str_cmp(field, "room")) {
+           room_rnum rn;
+           rn = rand_number(0, top_of_world);
+ #ifdef ACTOR_ROOM_IS_UID
+           snprintf(str, slen, "%c%ld",UID_CHAR, (long) world[rn].number + ROOM_ID_BASE);
+ #else
+           snprintf(str, slen, "%d", world[rn].number);
+ #endif
+         }
          else
            snprintf(str, slen, "%d", ((num = atoi(field)) > 0) ? rand_number(1, num) : 0);

          return;


__________________
15 Jul 2010 - 17:122873
Ok, thanks. I'm still using a modified DG 1.0.13 for OasisOLC 2.0.6, since I'm not working with tbaMUD having created my MUD's code years ago before tbaMUD branched off. So that would be dg_scripts.c I think, instead of variables. I'll figure it out though. Thanks much :)

Probably a good idea to add a random.object too, with subfields for both .room and .obj with the subfields being zone or world, if not set defaults to zone


__________________
Owner/Coder/Head Admin
Caer Dubrin
15 Jul 2010 - 17:592878
Code for hitroll/damroll
This is from my own MUD, the 50000 will need adjusted for stock code

Hitroll:
		  else if (!str_cmp(field, "hitroll")) {
		    if (subfield && *subfield) {
			  int addition = atoi(subfield);
			  GET_HITROLL(c) = MIN(50000, MAX(0, GET_HITROLL(c) + addition));
			}
			snprintf(str, slen, "%d", GET_HITROLL(c));
		  }

Damroll:
		  if (!str_cmp(field, "damroll")) {
		    if (subfield && *subfield) {
			  int addition = atoi(subfield);
			  GET_DAMROLL(c) = MIN(50000, MAX(0, GET_DAMROLL(c) + addition));
			}
			snprintf(str, slen, "%d", GET_DAMROLL(c));
		  }


__________________
Owner/Coder/Head Admin
Caer Dubrin
16 Jul 2010 - 00:502880
Jam, I improved your room random to include zone only code via subfield. Doing objects shortly, I'll post that after.

~~~~CODE REMOVED UNTIL I FIX IT~~~~
~~~~Forgot I was dealing with rnums~~~~

However, I'm curious why the script is returning things like this: I have generated the following random room number: }1051530

Actually, I know that the } is the UID_CHAR and the number is actually 1530 because it has the ROOM_ID_BASE added to it. What I really want to know is what the purpose of those are, especially if I want a real vnum returned for use with %teleport%


__________________
Owner/Coder/Head Admin
Caer Dubrin

Last edited by ralgith (16 Jul 2010 - 01:09)
16 Jul 2010 - 06:382881
Ok, I figured out the UID_CHAR & ROOM_ID_BASE...
Ok, I figured out the UID_CHAR & ROOM_ID_BASE on my own, including how they're used. I learned quite a lot about how DG Scripts works internally in the past several hours.

Anyways, here's what I've created for random.room, random.obj, and random.mob to complement the random.char function.
random.room returns a random room id from anywhere in the mud.
random.room(zone) returns a random room id from anywhere in the zone that the "thing" this trigger is attached to is from.
random.obj returns a random object VNUM from anywhere in the mud.
random.obj(zone) returns a random object VNUM from anywhere in the zone that the "thing" this trigger is attached to is from.
random.mob returns a random mobile VNUM from anywhere in the mud.
random.mob(zone) returns a random mobile VNUM from anywhere in the zone that the "thing" this trigger is attached to is from.
Any other subfield to any of them is ignored and it just defaults to returning it from anywhere in the world.

I went with the room id on the room trigger if those are in usage, otherwise it also returns a VNUM, however...
On both mobs and objs I have it returning JUST the VNUM since we want it to work for objs and mobs that may not physically exist yet; especially if our next command is %load% obj %objvn% after doing eval objvn %random.obj%.

Also, if using random.room you can get the vnum with:
eval rnd_room %random.room%
%echo% Your room's vnum is: %rnd_room.vnum%

else if (!str_cmp(field, "room")) {
			room_rnum rn = NOWHERE;
			if (subfield && *subfield && !str_cmp(subfield, "zone")) {
				int zone = NOTHING, top = NOTHING, bot = NOTHING;
				if (type == MOB_TRIGGER)
					zone = real_zone_by_thing(GET_MOB_VNUM((char_data *)go));
				if (type == OBJ_TRIGGER)
					zone = real_zone_by_thing(GET_OBJ_VNUM((obj_data *)go));
				if (type == WLD_TRIGGER)
					zone = real_zone_by_thing(((struct room_data *)go)->number);
				bot = zone_table[zone].bot;
				top = zone_table[zone].top;
				while (real_room(rn) == NOWHERE) {
					rn = rand_number(bot, top);
				}
				rn = real_room(rn);
			}
			else {
				rn = rand_number(0, top_of_world);
			}
#ifdef ACTOR_ROOM_IS_UID
			snprintf(str, slen, "%c%ld",UID_CHAR, (long) world[rn].number + ROOM_ID_BASE);
#else
			snprintf(str, slen, "%d", world[rn].number);
#endif
		}

        else if (!str_cmp(field, "obj")) {
			obj_rnum rn = NOTHING;
			if (subfield && *subfield && !str_cmp(subfield, "zone")) {
				int zone = NOTHING, top = NOTHING, bot = NOTHING;
				if (type == MOB_TRIGGER)
					zone = real_zone_by_thing(GET_MOB_VNUM((char_data *)go));
				if (type == OBJ_TRIGGER)
					zone = real_zone_by_thing(GET_OBJ_VNUM((obj_data *)go));
				if (type == WLD_TRIGGER)
					zone = real_zone_by_thing(((struct room_data *)go)->number);
				bot = zone_table[zone].bot;
				top = zone_table[zone].top;
				while (real_object(rn) == NOTHING) {
					rn = rand_number(bot, top);
				}
				rn = real_object(rn);
			}
			else {
				rn = rand_number(0, top_of_objt);
			}
			snprintf(str, slen, "%d", obj_index[rn].vnum);
		}

        else if (!str_cmp(field, "mob")) {
			mob_rnum rn = NOBODY;
			if (subfield && *subfield && !str_cmp(subfield, "zone")) {
				int zone = NOTHING, top = NOTHING, bot = NOTHING;
				if (type == MOB_TRIGGER)
					zone = real_zone_by_thing(GET_MOB_VNUM((char_data *)go));
				if (type == OBJ_TRIGGER)
					zone = real_zone_by_thing(GET_OBJ_VNUM((obj_data *)go));
				if (type == WLD_TRIGGER)
					zone = real_zone_by_thing(((struct room_data *)go)->number);
				bot = zone_table[zone].bot;
				top = zone_table[zone].top;
				while (real_mobile(rn) == NOBODY) {
					rn = rand_number(bot, top);
				}
				rn = real_mobile(rn);
			}
			else {
				rn = rand_number(0, top_of_objt);
			}
			snprintf(str, slen, "%d", mob_index[rn].vnum);
		}


__________________
Owner/Coder/Head Admin
Caer Dubrin

Last edited by ralgith (16 Jul 2010 - 06:40) Reason: Another note on returning the room as an id...
16 Jul 2010 - 13:582882
Missed an edit when copy and pasting, in the mob code the top_of_objt needs changed to a top_of_mobt. Oops.


__________________
Owner/Coder/Head Admin
Caer Dubrin
16 Jul 2010 - 14:582883
Nice work, Ralgith!
3 really useful script functions...


__________________
16 Jul 2010 - 15:092884
Quote Jamdog:
Nice work, Ralgith!
3 really useful script functions...


Not done either, I'm adding 2 more subfields for objects and mobs that look for only LOADED objs, either in world or in game. :D

As a note though, if this is added to stock tbaMUD's DG Scripts, I would like Jamdog credited with the original code for the random.room, myself with the original concept, modifications to the .room and creation of .obj and .mob based on the .room - need to be fair to everyone after all :)

I suggested waiting though until I post the final result, with the extra .obj and .mob subfields.

Anything else anyone would like to see added to this?


__________________
Owner/Coder/Head Admin
Caer Dubrin
16 Jul 2010 - 17:472885
Example Script that I needed this for:

Mob Help Caller~
0 k 100
~
*
* Mob Help Caller v1
* Ulath of Caer Dubrin
* On generation of a random number that equals an arbitrary magic number:
* This script will choose a random mob in the zone that isn't already fighting.
* Then teleport that mob here.
* Then have that mob assist us.
* If the first random does not equal our arbitrary magic number, we try again.
* This time looking for a weapon to wield if we don't already have one.
* If that fails as well, we don't do anything.
*
* Known issues:
* Ideally this should be checking to make sure the chosen mob isn't a sentinel as well.
* Weapon searching is unfinished... read: broken
*
if %random.15% == 3
  * Generate our mob...
  eval mob %random.mob(in_zone)%
  while %mob.fighting%
    eval mob %random.mob(in_zone)%
  done
  * Ok, we have our mob, now bring them here.
  eval rm %self.room%
  %teleport% %mob% %rm.vnum%
  %echoaround% %mob% %self.name% summons %mob.name% to help %self.himher%!
  eval target %self.fighting%
  %force% %mob% mkill %target.name%
*else if %random.5% == 3 && !%self.eq(wield)%
*  eval weap %random.obj(in_game)%
*  while !%weap.is_inroom% || %weap.type% != WEAPON
*    eval weap %random.obj(in_game)%
*  done
*  eval rm %weap.room%
*  %at% %rm.vnum% get %weap.name%
*  %echo% %self.name% grabs a weapon to use!
*  wield %weap.name%
end
~


__________________
Owner/Coder/Head Admin
Caer Dubrin
17 Jul 2010 - 00:162886
Unless someone sees something wrong with this...
Unless someone sees something wrong with this or has more ideas, I'll consider it a final version of it my suggested random additions to tbaMUD

else if (!str_cmp(field, "room")) {
			room_rnum rn = NOWHERE;
			if (subfield && *subfield && !str_cmp(subfield, "zone")) {
				int zone = NOTHING, top = NOTHING, bot = NOTHING;
				if (type == MOB_TRIGGER)
					zone = real_zone_by_thing(GET_MOB_VNUM((char_data *)go));
				if (type == OBJ_TRIGGER)
					zone = real_zone_by_thing(GET_OBJ_VNUM((obj_data *)go));
				if (type == WLD_TRIGGER)
					zone = real_zone_by_thing(((struct room_data *)go)->number);
				bot = zone_table[zone].bot;
				top = zone_table[zone].top;
				while (real_room(rn) == NOWHERE) {
					rn = rand_number(bot, top);
				}
				rn = real_room(rn);
			}
			else {
				rn = rand_number(0, top_of_world);
			}
#ifdef ACTOR_ROOM_IS_UID
			snprintf(str, slen, "%c%ld",UID_CHAR, (long) world[rn].number + ROOM_ID_BASE);
#else
			snprintf(str, slen, "%d", world[rn].number);
#endif
		}

        else if (!str_cmp(field, "obj")) {
			obj_rnum rn = NOTHING;
			if (subfield && *subfield && (!str_cmp(subfield, "zone") || !str_cmp(subfield, "in_zone"))) {
				int zone = NOTHING, top = NOTHING, bot = NOTHING;
				if (type == MOB_TRIGGER)
					zone = real_zone_by_thing(GET_MOB_VNUM((char_data *)go));
				if (type == OBJ_TRIGGER)
					zone = real_zone_by_thing(GET_OBJ_VNUM((obj_data *)go));
				if (type == WLD_TRIGGER)
					zone = real_zone_by_thing(((struct room_data *)go)->number);
				bot = zone_table[zone].bot;
				top = zone_table[zone].top;
				if (!str_cmp(subfield, "zone")) {
					while (real_object(rn) == NOTHING) {
						rn = rand_number(bot, top);
					}
					rn = real_object(rn);
				}
				else if (!str_cmp(subfield, "in_zone")) {
					while (!get_obj_num(rn) || rn == NOTHING) {
						rn = rand_number(bot, top);
						rn = real_object(rn);
					}
				}
			}
			else if (subfield && *subfield && !str_cmp(subfield, "in_game")) {
				while (!get_obj_num(rn) || rn == NOTHING) {
					rn = rand_number(0, top_of_objt);
				}
			}
			else {
				rn = rand_number(0, top_of_objt);
			}
#ifdef ACTOR_ROOM_IS_UID
			if (!str_cmp(subfield, "in_game") || !str_cmp(subfield, "in_zone"))
				snprintf(str, slen, "%c%ld",UID_CHAR, get_obj_num(rn)->id);
			else
				snprintf(str, slen, "%d", obj_index[rn].vnum);
#else
			snprintf(str, slen, "%d", obj_index[rn].vnum);
#endif
		}

        else if (!str_cmp(field, "mob")) {
			mob_rnum rn = NOBODY;
			if (subfield && *subfield && (!str_cmp(subfield, "zone") || !str_cmp(subfield, "in_zone"))) {
				int zone = NOBODY, top = NOBODY, bot = NOBODY;
				if (type == MOB_TRIGGER)
					zone = real_zone_by_thing(GET_MOB_VNUM((char_data *)go));
				if (type == OBJ_TRIGGER)
					zone = real_zone_by_thing(GET_OBJ_VNUM((obj_data *)go));
				if (type == WLD_TRIGGER)
					zone = real_zone_by_thing(((struct room_data *)go)->number);
				bot = zone_table[zone].bot;
				top = zone_table[zone].top;
				if (!str_cmp(subfield, "zone")) {
					while (real_mobile(rn) == NOBODY) {
						rn = rand_number(bot, top);
					}
					rn = real_mobile(rn);
				}
				else if (!str_cmp(subfield, "in_zone")) {
					while (!get_char_num(rn) || rn == NOBODY) {
						rn = rand_number(bot, top);
						rn = real_mobile(rn);
					}
				}
			}
			else if (subfield && *subfield && !str_cmp(subfield, "in_game")) {
				while (!get_char_num(rn)) {
					rn = rand_number(0, top_of_mobt);
				}
			}
			else {
				rn = rand_number(0, top_of_mobt);
			}
#ifdef ACTOR_ROOM_IS_UID
			if (!str_cmp(subfield, "in_game") || !str_cmp(subfield, "in_zone"))
				snprintf(str, slen, "%c%ld",UID_CHAR, get_char_num(rn)->id);
			else
				snprintf(str, slen, "%d", mob_index[rn].vnum);
#else
			snprintf(str, slen, "%d", mob_index[rn].vnum);
#endif
		}


__________________
Owner/Coder/Head Admin
Caer Dubrin
Login to reply  Page: « < 1 of 1 > »