From 7e8c0a5c5fc934555e6802cd12e10677ff7f9be5 Mon Sep 17 00:00:00 2001 From: mcmlxxix <> Date: Thu, 14 Oct 2010 20:18:38 +0000 Subject: [PATCH] added help information for all (most) commands, ghost exits for unlinked rooms, categorized commands for group disabling/enabling, verbose zone editor display (now with colorz!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) --- exec/ircbots/rpgbot/rpg_commands.js | 1063 +++++++++++++++++--------- exec/ircbots/rpgbot/rpg_functions.js | 205 +++-- exec/ircbots/rpgbot/rpgbot.js | 21 + 3 files changed, 864 insertions(+), 425 deletions(-) diff --git a/exec/ircbots/rpgbot/rpg_commands.js b/exec/ircbots/rpgbot/rpg_commands.js index e0f09b6ae4..4c502e09f5 100644 --- a/exec/ircbots/rpgbot/rpg_commands.js +++ b/exec/ircbots/rpgbot/rpg_commands.js @@ -76,11 +76,42 @@ Bot_Commands["LOGIN"].command = function (target,onick,ouh,srv,lvl,cmd) { display_room(srv,player,player.@zone,player.@room); return; } + + + if(!zones[player.@zone]) { + player.@zone=0; + } + var zone=zones[player.@zone]; + + if(!zone.room.(@id == player.@room).length() > 0) { + player.@room = 0; + } + + player.@active=1; player.@channel=target; display_room(srv,player,player.@zone,player.@room); } +Bot_Commands["EDIT"] = new Bot_Command(80,false,false); +Bot_Commands["EDIT"].command = function (target,onick,ouh,srv,lvl,cmd) { + var player=players.player.(@name == onick); + if(player.@active != 1) { + srv.o(target,"You are not logged in."); + return; + } + if(player.@editing != 1) { + player.@editing = 1; + var zone=zones[player.@zone]; + var room=zone.room.(@id == player.@room); + display_room_editor(srv,player,zone,room) + } else { + player.@editing = 0; + srv.o(target,"Editor OFF"); + } + return; +} + Bot_Commands["LOGOUT"] = new Bot_Command(0,false,false); Bot_Commands["LOGOUT"].command = function (target,onick,ouh,srv,lvl,cmd) { var player=players.player.(@name == onick); @@ -96,18 +127,146 @@ Bot_Commands["LOGOUT"].command = function (target,onick,ouh,srv,lvl,cmd) { srv.o(target,"You have been logged out."); } -/* Game commands */ -var RPG_Commands=[]; +Bot_Commands["SAVE"] = new Bot_Command(80,false,false); +Bot_Commands["SAVE"].command = function (target,onick,ouh,srv,lvl,cmd) { + var player=players.player.(@name == onick); + if(player.@active != 1) { + srv.o(target,"You are not logged in."); + return; + } + if(player.@editing != 1) { + srv.o(target,"You must be editing to save."); + return; + } + + var zone=zones[player.@zone]; + mkdir(z_dir + zone.@name.toLowerCase()); + var z_file=new File(z_dir+zone.@name.toLowerCase()+"/map.xml"); + if(!z_file.open("w+")) return; + z_file.write(zone); + srv.o(target,"Zone saved"); + return; +} + +Bot_Commands["HELP"] = new Bot_Command(0,false,false); +Bot_Commands["HELP"].command = function (target,onick,ouh,srv,lvl,cmd) { + cmd.shift(); + var topic=cmd.shift(); + if(!topic) { + var cmd_str=""; + for(var ec in Editor_Commands) { + cmd_str+=", " + ec.toLowerCase(); + } + srv.o(target,"editor commands: " + cmd_str.substr(2),"NOTICE"); + cmd_str=""; + for(var bc in Battle_Commands) { + cmd_str+=", " + bc.toLowerCase(); + } + srv.o(target,"battle commands: " + cmd_str.substr(2),"NOTICE"); + cmd_str=""; + for(var ic in Item_Commands) { + cmd_str+=", " + ic.toLowerCase(); + } + srv.o(target,"item commands: " + cmd_str.substr(2),"NOTICE"); + cmd_str=""; + for(var rc in RPG_Commands) { + cmd_str+=", " + rc.toLowerCase(); + } + srv.o(target,"rpg commands: " + cmd_str.substr(2),"NOTICE"); + srv.o(target,"for detailed command info, type 'rpg help <command>'","NOTICE"); + srv.o(target,"for help creating a characer, type 'rpg help create'","NOTICE"); + srv.o(target,"for help with the editor, type 'rpg help editor'","NOTICE"); + return; + } + + if(Help_Topics[topic.toUpperCase()]) { + for each(var l in Help_Topics[topic.toUpperCase()]) + srv.o(target,l,"NOTICE"); + return; + } + + srv.o(target,"topic not found","NOTICE"); + return; +} -RPG_Commands["NEW"] = function (srv,target,zone,room,cmd,player) { +Bot_Commands["RESTORE"] = new Bot_Command(80,false,false); +Bot_Commands["RESTORE"].command = function (target,onick,ouh,srv,lvl,cmd) { + var player=players.player.(@name == onick); + if(player.@active != 1) { + srv.o(target,"You are not logged in."); + return; + } if(player.@editing != 1) { - srv.o(target,"Editor is OFF. Type 'Editor ON' to enable editing."); + srv.o(target,"You must be editing to restore."); + return; + } + var zone=zones[player.@zone]; + var zone_dir=z_dir+zone.@name.toLowerCase(); + zone=load_zone(zone_dir); + if(!zone) { + srv.o(target,"Error loading zone"); return; } + zones[zone.@id]=zone; + srv.o(target,"Reverted current zone to saved data"); + return; +} + +/* BATTLE COMMANDS */ +var Battle_Commands=[]; + +Battle_Commands["FLEE"] = function (srv,target,zone,room,cmd,player) { + + + var chance=random(100); + if(chance<25) { + srv.o(target,"You couldn't escape!"); + return false; + } + var directions=room.exit; + var random_exit=directions[random(directions.length())]; + + if(random_exit.door) { + var door=zone.door.(@id == random_exit.door); + if(door.open==false) { + srv.o(target,"You couldn't escape!"); + return false; + } + } + + delete (player_attacks[player.@name]); + + srv.o(target,"You flee from battle!"); + if(zones[random_exit.@zone]) player.@zone=<zone>{random_exit.@zone}</zone>; + player.@room=<room>{random_exit.@target}</room>; + display_room(srv,player,player.@zone,player.@room); + return; +} +Battle_Commands["KILL"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); - var editor_cmd=cmd.shift(); + var obj=cmd.shift(); + if(!obj) { + srv.o(target,"Kill whom?"); + return false; + } + var mob_index=find_mob(room,obj); + if(!mob_index) { + srv.o(target,"They're not here!"); + return false; + } + var mob=room.mob[mob_index]; + add_player_attack(player,mob); + add_mob_attack(mob,player); +} + +/* EDITOR COMMANDS */ +var Editor_Commands=[]; + +Editor_Commands["NEW"] = function (srv,target,zone,room,cmd,player) { + cmd.shift(); + var editor_cmd=cmd.shift(); switch(editor_cmd.toUpperCase()) { case "ZONE": var zone_level=cmd.shift(); @@ -125,10 +284,10 @@ RPG_Commands["NEW"] = function (srv,target,zone,room,cmd,player) { <description>{settings.description}</description> </room> </zone>; - srv.o(target,"Zone '" + zone_title + "' created."); + srv.o(target,green + "Zone '" + zone_title + "' created."); player.@room=0; player.@zone=zone_id; - display_room(srv,player,zone_id,0); + display_room_editor(srv,player,zones[zone_id],zones[zone_id].room[0]); break; case "ITEM": srv.o(target,"TODO: Allow dynamic item creation"); @@ -142,59 +301,7 @@ RPG_Commands["NEW"] = function (srv,target,zone,room,cmd,player) { } } -RPG_Commands["EDITOR"] = function (srv,target,zone,room,cmd,player) { - cmd.shift(); - var editor_cmd=cmd.shift(); - - switch(editor_cmd.toUpperCase()) { - case "ON": - if(player.@editing != 1) { - player.@editing = 1; - srv.o(target,"Zone editor ON"); - } - return; - case "OFF": - if(player.@editing == 1) { - player.@editing = 0; - srv.o(target,"Zone editor OFF"); - } - return; - } - - if(player.@editing != 1) { - srv.o(target,"Editor is OFF. Type 'Editor ON' to enable editing."); - return; - } - - switch(editor_cmd.toUpperCase()) { - case "SAVE": - mkdir(z_dir + zone.@name.toLowerCase()); - var z_file=new File(z_dir+zone.@name.toLowerCase()+"/map.xml"); - if(!z_file.open("w+")) return; - z_file.write(zone); - srv.o(target,"Zone saved"); - break; - case "RESTORE": - var zone_dir=z_dir+zone.@name.toLowerCase(); - var zone=load_zone(zone_dir); - if(!zone) { - srv.o(target,"Error loading zone"); - break; - } - zones[zone.@id]=zone; - srv.o(target,"Reverted current zone to saved data"); - break; - } - - return; -} - -RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { - if(player.@editing == 0) { - srv.o(target,"You aren't currently editing."); - return; - } - +Editor_Commands["SET"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); var set=cmd.shift(); if(!set) { @@ -207,11 +314,11 @@ RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { switch(cmd.shift().toUpperCase()) { case "TITLE": settings.title=cmd.join(" "); - srv.o(target,"New room title set to: " + settings.title); + srv.o(target,green + "New room title set to: " + settings.title); break; case "DESCRIPTION": settings.description=cmd.join(" "); - srv.o(target,"New room description set to: " + settings.description); + srv.o(target,green + "New room description set to: " + settings.description); break; default: srv.o(target,"usage: set new <property> <value>"); @@ -222,11 +329,11 @@ RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { switch(cmd.shift().toUpperCase()) { case "TITLE": room.title=cmd.join(" "); - srv.o(target,"Current room title set to: " + room.title); + srv.o(target,green + "Current room title set to: " + room.title); break; case "DESCRIPTION": room.description=cmd.join(" "); - srv.o(target,"Current room description set to: " + room.description); + srv.o(target,green + "Current room description set to: " + room.description); break; default: srv.o(target,"usage: set current <property> <value>"); @@ -236,10 +343,10 @@ RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { case "AUTOLINK": if(settings.autolink) { settings.autolink=false; - srv.o(target,"Auto-link disabled."); + srv.o(target,red + "Auto-link disabled."); } else { settings.autolink=true; - srv.o(target,"Auto-link enabled."); + srv.o(target,green + "Auto-link enabled."); } break; case "LINK": @@ -252,17 +359,8 @@ RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { case "up": case "down": var room_id=cmd.shift(); - if(!room_id) { - target_id=room.exit.(@name == dir).@target; - target_room=zone.room.(@id == target_id); - - /* clear link if no target specified */ - room.exit.(@name == dir).(@target=""); - srv.o(target,"Room exit deleted"); - - /* clear corresponding link in original target room */ - if(settings.autolink) target_room.exit.(@name == reverse_dir(dir)).(@target=""); + srv.o(target,"TODO: auto-link adjacent room if no id is specified"); } else { var target_room=zone.room.(@id == room_id); var exit=room.exit.(@name == dir); @@ -270,12 +368,12 @@ RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { /* set exit target for current room */ if(exit.@target.toString()=="") { room.exit += <exit name={dir} target={room_id}/>; - srv.o(target,"Room exit added"); + srv.o(target,green + "Room exit added"); /* change exit target for current room */ } else { exit.@target=room_id; - srv.o(target,"Room target changed"); + srv.o(target,green + "Room target changed"); } /* change corresponding exit for target room */ @@ -288,97 +386,56 @@ RPG_Commands["SET"] = function (srv,target,zone,room,cmd,player) { } break; deftault: - srv.o(target,"Set what?"); + srv.o(target,"Type 'rpg help set' for help."); break; } } -RPG_Commands["FLEE"] = function (srv,target,zone,room,cmd,player) { - var chance=random(100); - if(chance<25) { - srv.o(target,"You couldn't escape!"); - return false; - } - var directions=room.exit; - var random_exit=directions[random(directions.length())]; - - if(random_exit.door) { - var door=zone.door.(@id == random_exit.door); - if(door.open==false) { - srv.o(target,"You couldn't escape!"); - return false; - } - } - - delete (player_attacks[player.@name]); - - srv.o(target,"You flee from battle!"); - if(zones[random_exit.@zone]) player.@zone=<zone>{random_exit.@zone}</zone>; - player.@room=<room>{random_exit.@target}</room>; - display_room(srv,player,player.@zone,player.@room); - return; -} - -RPG_Commands["KILL"] = function (srv,target,zone,room,cmd,player) { +Editor_Commands["UNSET"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); - var obj=cmd.shift(); - if(!obj) { - srv.o(target,"Kill whom?"); - return false; - } - - var mob_index=find_mob(room,obj); - if(!mob_index) { - srv.o(target,"They're not here!"); - return false; + var set=cmd.shift(); + if(!set) { + srv.o(target,"Unset what?"); + return; } - var mob=room.mob[mob_index]; - add_player_attack(player,mob); - add_mob_attack(mob,player); -} -RPG_Commands["SCORE"] = function (srv,target,zone,room,cmd,player) { - srv.o(target, - "player: " + player.@name + - " level: " + player.level + - " race: " + player.player_race + - " class: " + player.player_class); - srv.o(target, - "str: " + player.strength + - " wis: " + player.wisdom + - " int: " + player.intelligence + - " dex: " + player.dexterity + - " con: " + player.constitution); - srv.o(target, - "experience: " + player.experience + - " movement: " + player.movement + - " hitpoints: " + player.hitpoints + - " mana: " + player.mana + - " gold: " + player.gold); -} + switch(set.toUpperCase()) { + case "LINK": + var dir=cmd.shift().toLowerCase() + switch(dir) { + case "north": + case "south": + case "east": + case "west": + case "up": + case "down": + target_id=room.exit.(@name == dir).@target; + target_room=zone.room.(@id == target_id); -RPG_Commands["STATUS"] = function (srv,target,zone,room,cmd,player) { - srv.o(target,"<HP:" + player.hitpoints + " MA:" + player.mana + " MV:" + player.movement + ">"); + /* clear link if no target specified */ + room.exit.(@name == dir).(@target=undefined); + srv.o(target,red + "Room exit deleted"); + + /* clear corresponding link in original target room */ + if(settings.autolink) target_room.exit.(@name == reverse_dir(dir)).(@target=undefined); + break; + default: + srv.o(target,"usage: unset <direction>"); + break; + } + break; + deftault: + srv.o(target,"Type 'rpg help unset' for help."); + break; + } } -RPG_Commands["MOVE"] = function (srv,target,zone,room,cmd,player) { + +Editor_Commands["MOVE"] = function (srv,target,zone,room,cmd,player) { var exit=room.exit.(@name == cmd[1].toLowerCase()); if(exit.@target.toString()=="") { - if(player.@editing == 1) { - create_new_room(srv,target,zone,room,player,cmd[1].toLowerCase()); - return true; - } else { - srv.o(target,"You cannot go that way."); - return false; - } - } - - if(exit.door) { - var door=zone.door.(@id == exit.door); - if(door.open == false && player.@editing != 1) { - srv.o(target,"The " + door.@name + " is closed."); - return false; - } + create_new_room(srv,target,zone,room,player,cmd[1].toLowerCase()); + return true; } if(zones[exit.@zone]) player.@zone=<zone>{exit.@zone}</zone>; @@ -386,165 +443,131 @@ RPG_Commands["MOVE"] = function (srv,target,zone,room,cmd,player) { zone=zones[player.@zone]; room=zone.room.(@id == player.@room); + + display_room_editor(srv,player,zone,room); +} - srv.o(target,"You " + player.travel + " " + exit.@name + " to " + room.title + ". " + get_exit_string(zone,room,player)); +Editor_Commands["MOBS"] = function (srv,target,zone,room,cmd,player) { + display_mobs_editor(srv,target,zone,room); } -RPG_Commands["UNLOCK"] = function (srv,target,zone,room,cmd,player) { +Editor_Commands["ITEMS"] = function (srv,target,zone,room,cmd,player) { + display_items_editor(srv,target,zone,room); +} + +Editor_Commands["EXITS"] = function (srv,target,zone,room,cmd,player) { + display_exits_editor(srv,target,zone,room); +} + +Editor_Commands["TITLE"] = function (srv,target,zone,room,cmd,player) { + srv.o(target,"[title] " + room.title); +} + +Editor_Commands["DESC"] = function (srv,target,zone,room,cmd,player) { + srv.o(target,"[desc] " + strip_ctrl(room.description)); +} + +Editor_Commands["GOTO"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); - var name=cmd.shift(); - if(!name) { - srv.o(target,"Unlock what?"); + var dest=cmd.shift(); + if(!dest) { + srv.o(target,"Where do you want to go?"); return false; } + var room=cmd.shift(); + if(room) { + player.@zone=<zone>{dest}</zone>; + zone=zones[player.@zone]; + } else { + room=dest; + } + player.@room=<room>{room}</room>; + var room=zone.room.(@id == player.@room); + srv.o(target,"You teleport to " + room.title); + display_room_editor(srv,player,zone,room); + return; +} + +Editor_Commands["LOOK"] = function (srv,target,zone,room,cmd,player) { + cmd.shift(); + var obj=cmd.shift(); - /* first check doors in the room */ - var door=find_door(zone,room,name); - if(door) { - if(door.locked == false) { - srv.o(target,"It is already unlocked."); - return false; - } - - var key=player.inventory.item.(@id == door.key); - if(!key.length() > 0) { - srv.o(target,"You don't have the key."); - return false; - } - - srv.o(target,"You unlock the " + door.@name + "."); - door.locked=false; - return true; - - } else { - srv.o(target,"There is no door there."); - return false; - } - - /* then check containers */ -} - -RPG_Commands["EQUIPMENT"] = function (srv,target,zone,room,cmd,player) { - var list=[]; - var eq=player.equipment..item; - for each(var i in eq) { - list.push("<" + i.parent().@id + "> " + i.title); - } - var str=list.length?list.join(", "):"nothing"; - srv.o(target,"eq: " + str); -} - -RPG_Commands["INVENTORY"] = function (srv,target,zone,room,cmd,player) { - var list=[]; - for each(var i in player.inventory.item) { - list.push(i.title); - } - var str=list.length?list.join(", "):"nothing"; - srv.o(target,"inventory: " + str); -} + /* if no target specified, look at room */ + if(!obj) { + display_room_editor(srv,player,zone,room); + srv.o(player.@channel,red + "[title]" + black + " " + room.title); + srv.o(player.@channel,red + "[desc]" + black + " " + strip_ctrl(room.description)); -RPG_Commands["LOCK"] = function (srv,target,zone,room,cmd,player) { - cmd.shift(); - var name=cmd.shift(); - if(!name) { - srv.o(target,"Lock what?"); - return false; + display_mobs_editor(srv,player.@channel,zone,room); + display_items_editor(srv,player.@channel,zone,room); + display_exits_editor(srv,player.@channel,zone,room); + return; } - /* first check doors in the room */ - var door=find_door(zone,room,name); - if(door) { - if(door.locked == true) { - srv.o(target,"It is already locked."); - return false; - } - - if(door.open == true) { - srv.o(target,"You should close it first."); + /* if the second word is "in", attempt to look inside a container */ + if(obj.toLowerCase()=="in") { + var cont=cmd.shift(); + if(!cont) { + srv.o(target,"Look in what?"); return false; } - var key=player.inventory.item.(@id == door.key); - if(!key.length() > 0) { - srv.o(target,"You don't have the key."); - return false; - } + var container=false; + var container_index=find_object(player.inventory,cont); + if(container_index) container=player.inventory.item[container_index]; - srv.o(target,"You lock the " + door.@name + "."); - door.locked=true; - return true; + /* attampt to match specified container with room items */ + else container_index=find_object(room,cont); + if(!container && container_index) container=room.item[container_index]; - } else { - srv.o(target,"There is no door there."); - return false; - } - - /* then check containers */ -} - -RPG_Commands["OPEN"] = function (srv,target,zone,room,cmd,player) { - cmd.shift(); - var name=cmd.shift(); - if(!name) { - srv.o(target,"Open what?"); + /* if player has this container, check items in container for specified object */ + if(container) { + if(container.type!="container") { + srv.o(target,"That isn't a container!"); + return false; + } + var list=[]; + for each(var i in container.item) { + list.push(i.title); + } + var str=list.length?list.join(", "):"nothing"; + srv.o(target,"contents (" + container.title + "):" + str); + return true; + } + srv.o(target,"You can't find it!"); return false; } - /* first check doors in the room */ - var door=find_door(zone,room,name); - if(door) { - if(door.open == true) { - srv.o(target,"It is already open."); - return false; - } - if(door.locked == true) { - srv.o(target,"It is locked."); - return false; + /* handle looking at items, mobs, doors */ + var mob_index=find_mob(room,obj); + if(mob_index) { + var mob=room.mob[mob_index]; + if(mob.description.length() > 0) srv.o(target,mob.description); + var list=[]; + var eq=mob.equipment..item; + for each(var i in eq) { + list.push("<" + i.parent().@id + "> " + i.title); } - - srv.o(target,"You open the " + door.@name + "."); - door.open=true; + var str=list.length?list.join(", "):"nothing"; + srv.o(target,"eq: " + str); return true; - } else { - srv.o(target,"There is no door there."); - return false; - } - - /* then check containers in the room */ - - /* then check containers in inventory */ -} - -RPG_Commands["CLOSE"] = function (srv,target,zone,room,cmd,player) { - cmd.shift(); - var name=cmd.shift(); - if(!name) { - srv.o(target,"Close what?"); - return false; } - /* first check doors in the room */ - var door=find_door(zone,room,name); - if(door) { - if(door.open == false) { - srv.o(target,"It is already closed."); - return false; - } - - srv.o(target,"You close the " + door.@name + "."); - door.open=false; + var item_index=find_object(room,obj); + if(item_index) { + var item=room.item[item_index]; + srv.o(target,item.description); return true; - } else { - srv.o(target,"There is no door there."); - return false; } - - /* then check containers in the room */ - /* then check containers in inventory */ + srv.o(target,"You don't see that here."); + return false; } -RPG_Commands["DROP"] = function (srv,target,zone,room,cmd,player) { +/* ITEM COMMANDS */ +var Item_Commands=[]; + +Item_Commands["DROP"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); var obj=cmd.shift(); if(!obj) { @@ -575,7 +598,7 @@ RPG_Commands["DROP"] = function (srv,target,zone,room,cmd,player) { return false; } -RPG_Commands["GET"] = function (srv,target,zone,room,cmd,player) { +Item_Commands["GET"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); var obj=cmd.shift(); if(!obj) { @@ -647,7 +670,7 @@ RPG_Commands["GET"] = function (srv,target,zone,room,cmd,player) { return false; } -RPG_Commands["PUT"] = function (srv,target,zone,room,cmd,player) { +Item_Commands["PUT"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); var obj=cmd.shift(); if(!obj) { @@ -703,98 +726,142 @@ RPG_Commands["PUT"] = function (srv,target,zone,room,cmd,player) { return false; } -RPG_Commands["LOOK"] = function (srv,target,zone,room,cmd,player) { +Item_Commands["UNLOCK"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); - var obj=cmd.shift(); - - /* if no target specified, look at room */ - if(!obj) { - display_room(srv,player,player.@zone,player.@room); - return; + var name=cmd.shift(); + if(!name) { + srv.o(target,"Unlock what?"); + return false; } - /* if the second word is "in", attempt to look inside a container */ - if(obj.toLowerCase()=="in") { - var cont=cmd.shift(); - if(!cont) { - srv.o(target,"Look in what?"); + /* first check doors in the room */ + var door=find_door(zone,room,name); + if(door) { + if(door.locked == false) { + srv.o(target,"It is already unlocked."); return false; } - var container=false; - var container_index=find_object(player.inventory,cont); - if(container_index) container=player.inventory.item[container_index]; + var key=player.inventory.item.(@id == door.key); + if(!key.length() > 0) { + srv.o(target,"You don't have the key."); + return false; + } - /* attampt to match specified container with room items */ - else container_index=find_object(room,cont); - if(!container && container_index) container=room.item[container_index]; + srv.o(target,"You unlock the " + door.@name + "."); + door.locked=false; + return true; - /* if player has this container, check items in container for specified object */ - if(container) { - if(container.type!="container") { - srv.o(target,"That isn't a container!"); - return false; - } - var list=[]; - for each(var i in container.item) { - list.push(i.title); - } - var str=list.length?list.join(", "):"nothing"; - srv.o(target,"contents (" + container.title + "):" + str); - return true; - } - srv.o(target,"You can't find it!"); + } else { + srv.o(target,"There is no door there."); return false; } - /* handle looking at items, mobs, doors */ - var mob_index=find_mob(room,obj); - if(mob_index) { - var mob=room.mob[mob_index]; - if(mob.description.length() > 0) srv.o(target,mob.description); - var list=[]; - var eq=mob.equipment..item; - for each(var i in eq) { - list.push("<" + i.parent().@id + "> " + i.title); + /* then check containers */ +} + +Item_Commands["LOCK"] = function (srv,target,zone,room,cmd,player) { + cmd.shift(); + var name=cmd.shift(); + if(!name) { + srv.o(target,"Lock what?"); + return false; + } + + /* first check doors in the room */ + var door=find_door(zone,room,name); + if(door) { + if(door.locked == true) { + srv.o(target,"It is already locked."); + return false; } - var str=list.length?list.join(", "):"nothing"; - srv.o(target,"eq: " + str); + + if(door.open == true) { + srv.o(target,"You should close it first."); + return false; + } + + var key=player.inventory.item.(@id == door.key); + if(!key.length() > 0) { + srv.o(target,"You don't have the key."); + return false; + } + + srv.o(target,"You lock the " + door.@name + "."); + door.locked=true; return true; + + } else { + srv.o(target,"There is no door there."); + return false; } - var item_index=find_object(room,obj); - if(item_index) { - var item=room.item[item_index]; - srv.o(target,item.description); + /* then check containers */ +} + +Item_Commands["OPEN"] = function (srv,target,zone,room,cmd,player) { + cmd.shift(); + var name=cmd.shift(); + if(!name) { + srv.o(target,"Open what?"); + return false; + } + + /* first check doors in the room */ + var door=find_door(zone,room,name); + if(door) { + if(door.open == true) { + srv.o(target,"It is already open."); + return false; + } + if(door.locked == true) { + srv.o(target,"It is locked."); + return false; + } + + srv.o(target,"You open the " + door.@name + "."); + door.open=true; return true; + } else { + srv.o(target,"There is no door there."); + return false; } + + /* then check containers in the room */ - srv.o(target,"You don't see that here."); - return false; + /* then check containers in inventory */ } -RPG_Commands["GOTO"] = function (srv,target,zone,room,cmd,player) { +Item_Commands["CLOSE"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); - var dest=cmd.shift(); - if(!dest) { - srv.o(target,"Where do you want to go?"); + var name=cmd.shift(); + if(!name) { + srv.o(target,"Close what?"); return false; } - var room=cmd.shift(); - if(room) { - player.@zone=<zone>{dest}</zone>; - zone=zones[player.@zone]; + + /* first check doors in the room */ + var door=find_door(zone,room,name); + if(door) { + if(door.open == false) { + srv.o(target,"It is already closed."); + return false; + } + + srv.o(target,"You close the " + door.@name + "."); + door.open=false; + return true; } else { - room=dest; + srv.o(target,"There is no door there."); + return false; } - player.@room=<room>{room}</room>; - var room=zone.room.(@id == player.@room); - srv.o(target,"You teleport to " + room.title); - display_room(srv,player,player.@zone,player.@room); - return; + + /* then check containers in the room */ + + /* then check containers in inventory */ } -RPG_Commands["REMOVE"] = function (srv,target,zone,room,cmd,player) { +Item_Commands["REMOVE"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); var keyword=cmd.join(" "); if(!keyword) { @@ -823,7 +890,7 @@ RPG_Commands["REMOVE"] = function (srv,target,zone,room,cmd,player) { } } -RPG_Commands["WEAR"] = function (srv,target,zone,room,cmd,player) { +Item_Commands["WEAR"] = function (srv,target,zone,room,cmd,player) { cmd.shift(); var keyword=cmd.join(" "); if(!keyword) { @@ -855,5 +922,283 @@ RPG_Commands["WEAR"] = function (srv,target,zone,room,cmd,player) { return true; } } -RPG_Commands["EQUIP"] = RPG_Commands["WEAR"]; -RPG_Commands["WIELD"] = RPG_Commands["WEAR"]; \ No newline at end of file +Item_Commands["EQUIP"] = Item_Commands["WEAR"]; +Item_Commands["WIELD"] = Item_Commands["WEAR"]; + +/* GAMEPLAY COMMANDS */ +var RPG_Commands=[]; + +RPG_Commands["SCORE"] = function (srv,target,zone,room,cmd,player) { + srv.o(target, + "player: " + player.@name + + " level: " + player.level + + " race: " + player.player_race + + " class: " + player.player_class); + srv.o(target, + "str: " + player.strength + + " wis: " + player.wisdom + + " int: " + player.intelligence + + " dex: " + player.dexterity + + " con: " + player.constitution); + srv.o(target, + "experience: " + player.experience + + " movement: " + player.movement + + " hitpoints: " + player.hitpoints + + " mana: " + player.mana + + " gold: " + player.gold); +} + +RPG_Commands["STATUS"] = function (srv,target,zone,room,cmd,player) { + srv.o(target,"<HP:" + player.hitpoints + " MA:" + player.mana + " MV:" + player.movement + ">"); +} + +RPG_Commands["MOVE"] = function (srv,target,zone,room,cmd,player) { + var exit=room.exit.(@name == cmd[1].toLowerCase()); + if(exit.@target.toString()=="") { + srv.o(target,"You cannot go that way."); + return false; + } + + if(exit.door) { + var door=zone.door.(@id == exit.door); + if(door.open == false) { + srv.o(target,"The " + door.@name + " is closed."); + return false; + } + } + + if(zones[exit.@zone]) player.@zone=<zone>{exit.@zone}</zone>; + player.@room=<room>{exit.@target}</room>; + + zone=zones[player.@zone]; + room=zone.room.(@id == player.@room); + + srv.o(target,"You " + player.travel + " " + exit.@name + " to " + room.title + ". " + get_exit_string(zone,room,player)); +} + +RPG_Commands["EQUIPMENT"] = function (srv,target,zone,room,cmd,player) { + var list=[]; + var eq=player.equipment..item; + for each(var i in eq) { + list.push("<" + i.parent().@id + "> " + i.title); + } + var str=list.length?list.join(", "):"nothing"; + srv.o(target,"eq: " + str); +} + +RPG_Commands["INVENTORY"] = function (srv,target,zone,room,cmd,player) { + var list=[]; + for each(var i in player.inventory.item) { + list.push(i.title); + } + var str=list.length?list.join(", "):"nothing"; + srv.o(target,"inventory: " + str); +} + +RPG_Commands["LOOK"] = function (srv,target,zone,room,cmd,player) { + cmd.shift(); + var obj=cmd.shift(); + + /* if no target specified, look at room */ + if(!obj) { + display_room(srv,player,player.@zone,player.@room); + return; + } + + /* if the second word is "in", attempt to look inside a container */ + if(obj.toLowerCase()=="in") { + var cont=cmd.shift(); + if(!cont) { + srv.o(target,"Look in what?"); + return false; + } + + var container=false; + var container_index=find_object(player.inventory,cont); + if(container_index) container=player.inventory.item[container_index]; + + /* attampt to match specified container with room items */ + else container_index=find_object(room,cont); + if(!container && container_index) container=room.item[container_index]; + + /* if player has this container, check items in container for specified object */ + if(container) { + if(container.type!="container") { + srv.o(target,"That isn't a container!"); + return false; + } + var list=[]; + for each(var i in container.item) { + list.push(i.title); + } + var str=list.length?list.join(", "):"nothing"; + srv.o(target,"contents (" + container.title + "):" + str); + return true; + } + srv.o(target,"You can't find it!"); + return false; + } + + /* handle looking at items, mobs, doors */ + var mob_index=find_mob(room,obj); + if(mob_index) { + var mob=room.mob[mob_index]; + if(mob.description.length() > 0) srv.o(target,mob.description); + var list=[]; + var eq=mob.equipment..item; + for each(var i in eq) { + list.push("<" + i.parent().@id + "> " + i.title); + } + var str=list.length?list.join(", "):"nothing"; + srv.o(target,"eq: " + str); + return true; + } + + var item_index=find_object(room,obj); + if(item_index) { + var item=room.item[item_index]; + srv.o(target,item.description); + return true; + } + + srv.o(target,"You don't see that here."); + return false; +} + +/* HELP TOPICS */ +var Help_Topics={ +SET:[ + "change a setting:", + "set [new/current] [title/description] <text>", + "set link [north,south,east,west,up,down] <room id number>", + "set autolink on/off", + "note: autolink will automatically add adjacent", + " room exit links for you, if any. they can still", + " be set/unset manually", + "see topic: 'unset'" +], + +UNSET:[ + "clear an exit link setting:", + "unset link [north,south,east,west,up,down]", + "see topic: 'set'" +], + +NEW:[ + "create a new zone or object:", + "new zone <level> <title>", + "new item <not yet implemented>", + "new mob <not yet implemented>", + "new door <not yet implemented>" +], + +GOTO:[ + "move to a different room:", + "goto <zone id number> <room id number>" +], + +REMOVE:[ + "remove a piece of equipment:", + "remove <item keyword>" +], + +WEAR:[ + "wear a piece of equipment:", + "wear <item keyword>" +], +WIELD:this.WEAR, +EQUIP:this.WEAR, + +GET:[ + "retrieve an item:", + "get <item keyword>", + "get <item keyword> <container>", + "get all", + "get all <container>", + "note: a corpse is a container" +], + +PUT:[ + "place an item in a container:", + "put <item keyword> <container>", + "put all <container>" +], + +DROP:[ + "drop an inventory item in the room:", + "drop <item keyword>" +], + +OPEN:[ + "open a container or door:", + "open <container keyword>", + "open <door keyword>", + "see topics: 'close', 'lock', 'unlock'" +], + +CLOSE:[ + "close a container or door:", + "close <container keyword>", + "close <door keyword>", + "see topics: 'open', 'lock', 'unlock'" +], + +LOCK:[ + "lock a container or door:", + "lock <container keyword>", + "lock <door keyword>", + "you must have the key in your inventory", + "see topics: 'open', 'close', 'unlock'" +], + +UNLOCK:[ + "unlock a container or door:", + "unlock <container keyword>", + "unlock <door keyword>", + "you must have the key in your inventory", + "see topics: 'open', 'close', 'lock'" +], + +KILL:[ + "attack a mob/person:", + "kill <target keyword>" +], +ATTACK:this.KILL, +HIT:this.KILL, +FIGHT:this.KILL, + +FLEE:[ + "run away from battle:", + "see topic: 'kill'" +], + +EDITOR:[ + "The default world is very small. To get comfortable you may want to start by creating a new zone, and seeing how everything works.", + "You must first create a character and login before you can edit. Once you have logged in, type 'rpg edit' to toggle the editor on/off.", + "To create a new zone, turn the editor on and type 'new zone <level> <my new zone name>'.", + "By default, all exits will link automatically if the editor finds a room that is adjacent to you upon creating a new room. You can either turn this feature off, or modify those links later if you choose.", + "see topics: 'set','unset','new','goto'" +], + +CREATE:[ + "To start playing, you must first create a character.", + "To see a list of character races and classes, type 'rpg classes' and 'rpg races'.", + "When you have settled on a combination, type 'rpg create <race> <class>.", + "Once your character is created type 'rpg login' to start playing!" +] + +}; + + + + + + + + + + + + + + diff --git a/exec/ircbots/rpgbot/rpg_functions.js b/exec/ircbots/rpgbot/rpg_functions.js index 5189ed673b..df67844f9b 100644 --- a/exec/ircbots/rpgbot/rpg_functions.js +++ b/exec/ircbots/rpgbot/rpg_functions.js @@ -11,39 +11,29 @@ function Server_command(srv,cmdline,onick,ouh) { } break; case "JOIN": - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - var target=cmd[1]; - //srv.o(target,"Welcome to RPG test!","NOTICE"); - //srv.o(target,"For a list of classes, type " + get_cmd_prefix() + "RPG CLASSES","NOTICE"); - //srv.o(target,"For a list of races, type " + get_cmd_prefix() + "RPG RACES","NOTICE"); - //srv.o(target,"To create a new character, type " + get_cmd_prefix() + "RPG CREATE <race> <class>","NOTICE"); - //srv.o(target,"Type RPG LOGIN to start playing!","NOTICE"); + /* if the user has no RPG player, greet them */ + if(!player.length() > 0) { + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + var target=cmd[1]; + + srv.o(target,"Welcome to RPG test, " + onick + "!","NOTICE"); + srv.o(target,"Type 'help rpg' to get started.","NOTICE"); + } break; case "PRIVMSG": + /* if the user has no RPG player or is not logged in, don't process RPG commands */ + if(player.@active != 1) break; + var target=cmd[1]; - if ((cmd[1][0] == "#") || (cmd[1][0] == "&")) { - /* respond only to private message commands */ - if(player.@active == 1 && player.@channel == target) { - cmd.shift(); - cmd.shift(); - /* handle commands such as north, south, east, west.... */ - try { - handle_command(srv,cmd,player,player.@channel); - } catch(e) { - srv.o(target,e); - } - } - } else if (cmd[1].toUpperCase() == srv.curnick.toUpperCase()) { - if(player.@active ==1 ) { - cmd.shift(); - cmd.shift(); - /* handle commands such as north, south, east, west.... */ - try { - handle_command(srv,cmd,player,onick); - } catch(e) { - srv.o(target,e); - } + if(player.@channel == target) { + cmd.shift(); + cmd.shift(); + /* handle commands such as north, south, east, west.... */ + try { + handle_command(srv,cmd,player,player.@channel); + } catch(e) { + srv.o(target,e); } } break; @@ -99,16 +89,38 @@ function handle_command(srv,cmd,player,target) { break; } + if(player.@editing == 1) { + if(Editor_Commands[cmd[0]]) { + Editor_Commands[cmd[0]](srv,target,zone,room,cmd,player); + } else if(RPG_Commands[cmd[0]] || + Battle_Commands[cmd[0]] || + Item_Commands[cmd[0]]) { + srv.o(target,"You can't do that while editing."); + } + return; + } if(RPG_Commands[cmd[0]]) { RPG_Commands[cmd[0]](srv,target,zone,room,cmd,player); return; + } + if(Battle_Commands[cmd[0]]) { + Battle_Commands[cmd[0]](srv,target,zone,room,cmd,player); + return; + } + if(Item_Commands[cmd[0]]) { + Item_Commands[cmd[0]](srv,target,zone,room,cmd,player); + return; + } + if(Editor_Commands[cmd[0]]) { + srv.o(target,"Type 'rpg edit' to enable editing."); + return; } for(var m in room.mob) { var mob=room.mob[m]; for(var t in mob.trigger) { if(cmd.join().match(mob.trigger[t].@id.toUpperCase())) { - srv.o(target,mob.name + " says, '" + mob.trigger[t].response + "'"); + srv.o(target,mob.@name + " says, '" + mob.trigger[t].response + "'"); } } } @@ -120,38 +132,31 @@ function display_room(srv,player,z,r) { var zone=zones[z]; var room=zone.room.(@id == r); - if(player.@editing == 1) { - srv.o(player.@channel,"Editing '" + zone.@name + "' [Z: " + z + " R: " + r + "]"); - } - show_room_title(srv,player.@channel,zone,room,player); - show_room_description(srv,player.@channel,zone,room,player); - show_room_exits(srv,player.@channel,zone,room,player); - show_room_items(srv,player.@channel,zone,room,player); - show_room_mobs(srv,player.@channel,zone,room,player); + show_room_title(srv,player.@channel,zone,room); + show_room_description(srv,player.@channel,zone,room); + show_room_exits(srv,player.@channel,zone,room); + show_room_items(srv,player.@channel,zone,room); + show_room_mobs(srv,player.@channel,zone,room); show_room_players(srv,player,zone,room); } -function show_room_description(srv,target,zone,room,player) { - if(player.@editing == 1) srv.o(target,"[DESC] " + strip_ctrl(room.description)); - else srv.o(target,strip_ctrl(room.description)); +function show_room_description(srv,target,zone,room) { + srv.o(target,strip_ctrl(room.description)); } -function show_room_title(srv,target,zone,room,player) { - if(player.@editing == 1) srv.o(target,"[TITLE] " + room.title); - else srv.o(target,room.title); +function show_room_title(srv,target,zone,room) { + srv.o(target,room.title); } -function show_room_items(srv,target,zone,room,player) { +function show_room_items(srv,target,zone,room) { for each(var i in room.item) { - if(player.@editing == 1) srv.o(target,"[ITEM: " + i.@id + "] " + i.appearance); - else srv.o(target,i.appearance); + srv.o(target,i.appearance); } } -function show_room_mobs(srv,target,zone,room,player) { +function show_room_mobs(srv,target,zone,room) { for each(var m in room.mob) { - if(player.@editing == 1) srv.o(target,"[MOB: " + m.@id + "] " + m.appearance); - else srv.o(target,m.appearance); + if(room.mob[m].@status != 0) srv.o(target,m.appearance); } } @@ -165,11 +170,11 @@ function show_room_players(srv,player,zone,room) { } } -function show_room_exits(srv,target,zone,room,player) { - srv.o(target,get_exit_string(zone,room,player)); +function show_room_exits(srv,target,zone,room) { + srv.o(target,get_exit_string(zone,room)); } -function get_exit_string(zone,room,player) { +function get_exit_string(zone,room) { var exit_str=""; var exits=room.exit.(@target != ""); for(var e in exits) { @@ -179,8 +184,7 @@ function get_exit_string(zone,room,player) { if(door.locked==true) prefix="@"; else if(door.open==false) prefix="#"; } - exit_str+=", "+prefix+exits[e].@name.substr(0,1); - if(player.@editing == 1) exit_str+="[ID:"+exits[e].@target+"]"; + exit_str+=", "+prefix+exits[e].@name; } return ("exits: " + exit_str.substr(2)); } @@ -255,6 +259,7 @@ function find_object(container,keyword) { function find_mob(room,keyword) { for(var m in room.mob) { var mob=room.mob[m]; + if(mob.@status == 0) continue; if(mob.keywords.match(keyword.toLowerCase())) { return m; } @@ -353,7 +358,7 @@ function kill(srv,object) { var zone=zones[object.@zone]; var room=zone.room.(@id == object.@room); create_corpse(room,object); - delete object; + object.@status=0; } function create_corpse(room,object) { @@ -390,11 +395,11 @@ function load_zone(dir) { for(var r in zone.room) { var room=zone.room[r]; for(var m in room.mob) { - var mob=mobs.mob.(@id == room.mob[m].@id).copy(); - mob.@id=mob_count++; - mob.@room=room.@id; - mob.@zone=zone.@id; - room.mob[m].appendChild(mob.children()); + room.mob[m]=mobs.mob.(@id == room.mob[m].@id).copy(); + room.mob[m].@id=mob_count++; + room.mob[m].@room=room.@id; + room.mob[m].@zone=zone.@id; + room.mob[m].@status=1; } } for (var i in zone..item) { @@ -459,7 +464,75 @@ function load_races() { r_file.close(); } -/* game edit functions */ +/* game editor display functions */ + +function display_room_editor(srv,player,zone,room) { + srv.o(player.@channel,"Editing '" + blue + zone.@name + black + + "' [Z:" + blue + " " + zone.@id + black + + " R:" + blue + " " + room.@id + black + "]"); +} + +function display_exits_editor(srv,target,zone,room) { + var exits=["north","south","east","west","up","down"]; + for each(var e in exits) { + var exit=room.exit.(@name == e); + if(exit.@target != undefined) { + var exit_str=red + "[" + e +"]"; + if(zones[exit.@zone]) exit_str+= black + " z:" + blue + " " + exit.@zone; + exit_str+= black + " r:" + blue + " " + exit.@target; + if(exit.door != undefined) { + var door=zone.door.(@id == exit.door); + exit_str+= black + " door:" + blue + " " + door.@id; + exit_str+= black + " lock:" + blue + " " + door.locked; + exit_str+= black + " open:" + blue + " " + door.open; + } + srv.o(target,exit_str); + } else { + var start=new Coords(0,0,0); + var finish=get_exit_coords(start,e); + + result=find_link(zone,room,start,finish,undefined); + + if(result >= 0) { + var target_room=zone.room.(@id == result); + var exit=target_room.exit.(@name == reverse_dir(e)); + + var exit_str=red + "[" + e +"]"; + exit_str+= black + " r:" + blue + " " + target_room.@id; + + if(exit.door != undefined) { + var door=zone.door.(@id == exit.door); + exit_str+= black + " door:" + blue + " " + door.@id; + exit_str+= black + " lock:" + blue + " " + door.locked; + exit_str+= black + " open:" + blue + " " + door.open; + } + exit_str+= red + " (unlinked)"; + srv.o(target,exit_str); + } + } + } +} + +function display_mobs_editor(srv,target,zone,room) { + for each(var m in room.mob) { + srv.o(target, + red + "[mob]" + + black + " id:" + blue + " " + m.@id + + black + " name:" + blue + " " + m.@name); + } +} + +function display_items_editor(srv,target,zone,room) { + for each(var i in room.item) { + srv.o(target, + red + "[item]" + + black + " id:" + blue + " " + i.@id + + black + " name:" + blue + " " + i.title); + } +} + +/* game editor functions */ + function find_link(zone,room,start_coords,finish_coords,checked) { @@ -598,8 +671,8 @@ function create_new_room(srv,target,zone,room,player,dir) { /* move player to new room */ player.@room=new_id; - srv.o(target,"room " + new_id + " created"); - display_room(srv,player,zone.@id,new_id); + srv.o(target,"Room " + new_id + " created"); + display_room_editor(srv,player,zone,new_room); } function get_dir_coords(exclude) { @@ -611,7 +684,7 @@ function get_dir_coords(exclude) { up:new Coords(0,0,1), down:new Coords(0,0,-1), } - delete dirs[exclude]; + if(exclude) delete dirs[exclude]; return dirs; } diff --git a/exec/ircbots/rpgbot/rpgbot.js b/exec/ircbots/rpgbot/rpgbot.js index d2086793d4..24f2213456 100644 --- a/exec/ircbots/rpgbot/rpgbot.js +++ b/exec/ircbots/rpgbot/rpgbot.js @@ -1,3 +1,19 @@ +/* + $Id$ + Synchronet IRC bot module for ircbot.js + + Role-playing game bot (MUD) with in-game zone editor + using XML data files. + + TODO: + add in-game item creation/editing + add in-game mob creation/editing + add time-based events and zone-cycles + ...more when I think of it + + by Matt Johnson : MCMLXXIX (2010) +*/ + var p_dir=this.dir+"players/"; var z_dir=this.dir+"zones/"; var c_file=new File(this.dir+"classes.xml"); @@ -14,6 +30,11 @@ var player_attacks=[]; var mob_attacks=[]; var global_items=load_items(gi_file); +var black=String.fromCharCode(3)+"1"; +var blue=String.fromCharCode(3)+"2"; +var green=String.fromCharCode(3)+"3"; +var red=String.fromCharCode(3)+"5"; + var activity_timeout=300; // seconds var tick_time=4; // seconds var max_armor=200; -- GitLab