Added Player Attachable Script Code

This commit is contained in:
Fizban 2008-12-04 06:07:32 +00:00
parent 02f9fe1a9f
commit 6c963b8187
15 changed files with 131 additions and 45 deletions

View file

@ -35,6 +35,8 @@ export (QQ's a zone into a tarball)t
Xlist (mlist, olist, rlist, zlist, slist, tlist, qlist)
(lots of major bugfixes too)
@
[Dec 04 2008] - Fizban
DG Scripts are now attachable to players (cedit toggle defaults this behavior to off).
[Dec 01 2008] - Fizban
Now compiles warning free on GCC 4.3.2
[Oct 09 2008] - Rumble

View file

@ -274,6 +274,7 @@ ACMD(do_gmote);
/** @todo should probably be moved to a more general file handler module */
void clean_llog_entries(void);
/** @todo This should be moved to a more general utility file */
int script_command_interpreter(struct char_data *ch, char *arg);
room_rnum find_target_room(struct char_data *ch, char *rawroomstr);
void perform_immort_vis(struct char_data *ch);
void snoop_check(struct char_data *ch);

View file

@ -297,9 +297,10 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
" is standing here."
};
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS) && IS_NPC(i)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) {
if (IS_NPC(i))
send_to_char(ch, "[%d] ", GET_MOB_VNUM(i));
if SCRIPT(i) {
if (SCRIPT(i) && TRIGGERS(SCRIPT(i))) {
if (!TRIGGERS(SCRIPT(i))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
else
@ -1624,7 +1625,7 @@ static void perform_immort_where(struct char_data *ch, char *arg)
found = 1;
send_to_char(ch, "M%3d. %-25s%s - [%5d] %-25s%s", ++num, GET_NAME(i), QNRM,
GET_ROOM_VNUM(IN_ROOM(i)), world[IN_ROOM(i)].name, QNRM);
if (IS_NPC(i) && SCRIPT(i)) {
if (SCRIPT(i)) {
if (!TRIGGERS(SCRIPT(i))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
else

View file

@ -103,7 +103,8 @@ static void cedit_setup(struct descriptor_data *d)
OLC_CONFIG(d)->play.map_option = CONFIG_MAP;
OLC_CONFIG(d)->play.map_size = CONFIG_MAP_SIZE;
OLC_CONFIG(d)->play.minimap_size = CONFIG_MINIMAP_SIZE;
OLC_CONFIG(d)->play.script_players = CONFIG_SCRIPT_PLAYERS;
/* Crash Saves */
OLC_CONFIG(d)->csd.free_rent = CONFIG_FREE_RENT;
OLC_CONFIG(d)->csd.max_obj_save = CONFIG_MAX_OBJ_SAVE;
@ -199,6 +200,7 @@ static void cedit_save_internally(struct descriptor_data *d)
CONFIG_MAP = OLC_CONFIG(d)->play.map_option;
CONFIG_MAP_SIZE = OLC_CONFIG(d)->play.map_size;
CONFIG_MINIMAP_SIZE = OLC_CONFIG(d)->play.minimap_size;
CONFIG_SCRIPT_PLAYERS = OLC_CONFIG(d)->play.script_players;
/* Crash Saves */
CONFIG_FREE_RENT = OLC_CONFIG(d)->csd.free_rent;
@ -363,6 +365,8 @@ int save_config( IDXTYPE nowhere )
"default_map_size = %d\n\n", CONFIG_MAP_SIZE);
fprintf(fl, "* Default minimap size shown to the right of room descriptions\n"
"default_minimap_size = %d\n\n", CONFIG_MINIMAP_SIZE);
fprintf(fl, "* Do you want scripts to be attachable to players?\n"
"script_players = %d\n\n", CONFIG_SCRIPT_PLAYERS);
strcpy(buf, CONFIG_OK);
@ -595,6 +599,7 @@ static void cedit_disp_game_play_options(struct descriptor_data *d)
"%s4%s) Map/Automap Option : %s%s\r\n"
"%s5%s) Default map size : %s%d\r\n"
"%s6%s) Default minimap size : %s%d\r\n"
"%s7%s) Scripts on PC's : %s%s\r\n"
"%sQ%s) Exit To The Main Menu\r\n"
"Enter your choice : ",
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pk_allowed),
@ -622,6 +627,7 @@ static void cedit_disp_game_play_options(struct descriptor_data *d)
grn, nrm, cyn, m_opt == 0 ? "Off" : (m_opt == 1 ? "On" : (m_opt == 2 ? "Imm-Only" : "Invalid!")),
grn, nrm, cyn, OLC_CONFIG(d)->play.map_size,
grn, nrm, cyn, OLC_CONFIG(d)->play.minimap_size,
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.script_players),
grn, nrm
);
@ -948,6 +954,9 @@ void cedit_parse(struct descriptor_data *d, char *arg)
write_to_output(d, "Enter default mini-map size (1-12) : ");
OLC_MODE(d) = CEDIT_MINIMAP_SIZE;
return;
case '7':
TOGGLE_VAR(OLC_CONFIG(d)->play.script_players);
return;
case 'q':
case 'Q':

View file

@ -38,6 +38,9 @@
/* YES / NO; TRUE / FALSE are all defined in utils.h */
/* Can Scripts be attached to players? */
int script_players = NO;
/* pk_allowed sets the tone of the entire game. If pk_allowed is set to NO,
* then players will not be allowed to kill, summon, charm, or sleep other
* players, as well as a variety of other "asshole player" protections. However,
@ -79,8 +82,7 @@ int dts_are_dumps = YES;
/* Whether you want items that immortals load to appear on the ground or not.
* It is most likely best to set this to 'YES' so that something else doesn't
* grab the item before the immortal does, but that also means people will be
* able to carry around things like boards. That's not necessarily a bad thing,
* but this will be left at a default of 'NO' for historic reasons. */
* able to carry around things like boards. */
int load_into_inventory = YES;
/* "okay" etc. */

View file

@ -16,6 +16,7 @@
#ifndef __CONFIG_C__
/* Global variable declarations, all settable by cedit */
extern int pk_allowed;
extern int script_players;
extern int pt_allowed;
extern int level_can_shout;
extern int holler_move_cost;

View file

@ -3340,6 +3340,7 @@ static void load_default_config( void )
CONFIG_MAP = map_option;
CONFIG_MAP_SIZE = default_map_size;
CONFIG_MINIMAP_SIZE = default_minimap_size;
CONFIG_SCRIPT_PLAYERS = script_players;
/* Rent / crashsave options. */
CONFIG_FREE_RENT = free_rent;
@ -3583,6 +3584,8 @@ void load_config( void )
case 's':
if (!str_cmp(tag, "siteok_everyone"))
CONFIG_SITEOK_ALL = num;
else if (!str_cmp(tag, "script_players"))
CONFIG_SCRIPT_PLAYERS = num;
else if (!str_cmp(tag, "start_messg")) {
strncpy(buf, "Reading start message in load_config()", sizeof(buf));
if (CONFIG_START_MESSG)

View file

@ -43,8 +43,7 @@ static void mob_log(char_data *mob, const char *format, ...)
}
/* Macro to determine if a mob is permitted to use these commands. */
#define MOB_OR_IMPL(ch) \
(IS_NPC(ch) && (!(ch)->desc || GET_LEVEL((ch)->desc->original)>=LVL_IMPL))
#define MOB_OR_IMPL(ch) (GET_LEVEL(ch) > 0)
/* mob commands */
/* prints the argument to all the rooms aroud the mobile */
@ -279,6 +278,7 @@ ACMD(do_mecho)
skip_spaces(&p);
sub_write(p, ch, TRUE, TO_ROOM);
sub_write(p, ch, TRUE, TO_CHAR);
}
ACMD(do_mzoneecho)

View file

@ -969,7 +969,7 @@ ACMD(do_attach)
return;
}
}
if (!IS_NPC(victim)) {
if (!IS_NPC(victim) && !CONFIG_SCRIPT_PLAYERS) {
send_to_char(ch, "Players can't have scripts.\r\n");
return;
}
@ -988,8 +988,12 @@ ACMD(do_attach)
CREATE(SCRIPT(victim), struct script_data, 1);
add_trigger(SCRIPT(victim), trig, loc);
if (IS_NPC(victim))
send_to_char(ch, "Trigger %d (%s) attached to %s [%d].\r\n",
tn, GET_TRIG_NAME(trig), GET_SHORT(victim), GET_MOB_VNUM(victim));
else
send_to_char(ch, "Trigger %d (%s) attached to player named %s.\r\n",
tn, GET_TRIG_NAME(trig), GET_NAME(victim));
}
else if (is_abbrev(arg, "object") || is_abbrev(arg, "otr")) {
@ -1234,18 +1238,21 @@ ACMD(do_detach)
}
if (victim) {
if (!IS_NPC(victim))
if (!IS_NPC(victim) && !CONFIG_SCRIPT_PLAYERS)
{
send_to_char(ch, "Players don't have triggers.\r\n");
return;
}
else if (!SCRIPT(victim))
send_to_char(ch, "That mob doesn't have any triggers.\r\n");
else if (!can_edit_zone(ch, real_zone_by_thing(GET_MOB_VNUM(victim)))) {
if (!SCRIPT(victim))
send_to_char(ch, "That %s doesn't have any triggers.\r\n", IS_NPC(victim) ? "mob" : "player");
else if (!can_edit_zone(ch, real_zone_by_thing(GET_MOB_VNUM(victim))) && IS_NPC(victim)) {
send_to_char(ch, "You can only detach triggers in your own zone\r\n");
return;
}
else if (trigger && !str_cmp(trigger, "all")) {
extract_script(victim, MOB_TRIGGER);
send_to_char(ch, "All triggers removed from %s.\r\n", GET_SHORT(victim));
send_to_char(ch, "All triggers removed from %s.\r\n", IS_NPC(victim) ? GET_SHORT(victim) : GET_NAME(ch));
}
else if (trigger && remove_trigger(SCRIPT(victim), trigger)) {
@ -1806,11 +1813,6 @@ static void process_attach(void *go, struct script_data *sc, trig_data *trig,
}
if (c) {
if (!IS_NPC(c)) {
script_log("Trigger: %s, VNum %d. attach invalid target: '%s'",
GET_TRIG_NAME(trig), GET_TRIG_VNUM(trig), GET_NAME(c));
return;
}
if (!SCRIPT(c))
CREATE(SCRIPT(c), struct script_data, 1);
add_trigger(SCRIPT(c), newtrig, -1);
@ -2652,6 +2654,7 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
else {
switch (type) {
case MOB_TRIGGER:
if (!script_command_interpreter((char_data *) go, cmd))
command_interpreter((char_data *) go, cmd);
break;
case OBJ_TRIGGER:

View file

@ -304,7 +304,7 @@ int command_mtrigger(char_data *actor, char *cmd, char *argument)
ch_next = ch->next_in_room;
if (SCRIPT_CHECK(ch, MTRIG_COMMAND) && !AFF_FLAGGED(ch, AFF_CHARM) &&
(actor!=ch)) {
((actor!=ch) || CONFIG_SCRIPT_PLAYERS)) {
for (t = TRIGGERS(SCRIPT(ch)); t; t = t->next) {
if (!TRIGGER_CHECK(t, MTRIG_COMMAND))
continue;
@ -344,7 +344,7 @@ void speech_mtrigger(char_data *actor, char *str)
ch_next = ch->next_in_room;
if (SCRIPT_CHECK(ch, MTRIG_SPEECH) && AWAKE(ch) &&
!AFF_FLAGGED(ch, AFF_CHARM) && (actor!=ch))
!AFF_FLAGGED(ch, AFF_CHARM) && ((actor!=ch) || CONFIG_SCRIPT_PLAYERS))
for (t = TRIGGERS(SCRIPT(ch)); t; t = t->next) {
if (!TRIGGER_CHECK(t, MTRIG_SPEECH))
continue;

View file

@ -333,30 +333,62 @@ cpp_extern const struct command_info cmd_info[] = {
{ "zcheck" , "zcheck" , POS_DEAD , do_zcheck , LVL_GOD, 0 },
{ "zpurge" , "zpurge" , POS_DEAD , do_zpurge , LVL_BUILDER, 0 },
/* DG trigger commands. minimum_level should be set to -1. */
{ "masound" , "masound" , POS_DEAD , do_masound , -1, 0 },
{ "mkill" , "mkill" , POS_STANDING, do_mkill , -1, 0 },
{ "mjunk" , "mjunk" , POS_SITTING , do_mjunk , -1, 0 },
{ "mdamage" , "mdamage" , POS_DEAD , do_mdamage , -1, 0 },
{ "mdoor" , "mdoor" , POS_DEAD , do_mdoor , -1, 0 },
{ "mecho" , "mecho" , POS_DEAD , do_mecho , -1, 0 },
{ "mrecho" , "mrecho" , POS_DEAD , do_mrecho , -1, 0 },
{ "mechoaround", "mechoaround", POS_DEAD, do_mechoaround, -1, 0 },
{ "msend" , "msend" , POS_DEAD , do_msend , -1, 0 },
{ "mload" , "mload" , POS_DEAD , do_mload , -1, 0 },
{ "mpurge" , "mpurge" , POS_DEAD , do_mpurge , -1, 0 },
{ "mgoto" , "mgoto" , POS_DEAD , do_mgoto , -1, 0 },
{ "mat" , "mat" , POS_DEAD , do_mat , -1, 0 },
{ "mteleport", "mteleport", POS_DEAD , do_mteleport, -1, 0 },
{ "mforce" , "mforce" , POS_DEAD , do_mforce , -1, 0 },
{ "mhunt" , "mhunt" , POS_DEAD , do_mhunt , -1, 0 },
{ "mremember", "mremember", POS_DEAD , do_mremember, -1, 0 },
{ "mforget" , "mforget" , POS_DEAD , do_mforget , -1, 0 },
{ "mtransform", "mtransform", POS_DEAD , do_mtransform,-1, 0 },
{ "mzoneecho", "mzoneecho", POS_DEAD , do_mzoneecho, -1, 0 },
{ "mfollow" , "mfollow" , POS_DEAD , do_mfollow , -1, 0 },
{ "\n", "zzzzzzz", 0, 0, 0, 0 } }; /* this must be last */
/* Thanks to Melzaren for this change to allow DG Scripts to be attachable
*to player's while still disallowing them to manually use the DG-Commands. */
const struct mob_script_command_t mob_script_commands[] = {
{ "\n", "zzzzzzz", 0, 0, 0, 0 } }; /* this must be last */
/* DG trigger commands. minimum_level should be set to -1. */
{ "masound" , do_masound , 0 },
{ "mkill" , do_mkill , 0 },
{ "mjunk" , do_mjunk , 0 },
{ "mdamage" , do_mdamage , 0 },
{ "mdoor" , do_mdoor , 0 },
{ "mecho" , do_mecho , 0 },
{ "mrecho" , do_mrecho , 0 },
{ "mechoaround", do_mechoaround , 0 },
{ "msend" , do_msend , 0 },
{ "mload" , do_mload , 0 },
{ "mpurge" , do_mpurge , 0 },
{ "mgoto" , do_mgoto , 0 },
{ "mat" , do_mat , 0 },
{ "mteleport", do_mteleport, 0 },
{ "mforce" , do_mforce , 0 },
{ "mhunt" , do_mhunt , 0 },
{ "mremember", do_mremember, 0 },
{ "mforget" , do_mforget , 0 },
{ "mtransform", do_mtransform , 0 },
{ "mzoneecho", do_mzoneecho, 0 },
{ "mfollow" , do_mfollow , 0 },
{ "\n" , do_not_here , 0 } };
int script_command_interpreter(struct char_data *ch, char *arg) {
/* DG trigger commands */
int i;
char first_arg[MAX_INPUT_LENGTH];
char *line;
skip_spaces(&arg);
if (!*arg)
return 0;
line = any_one_arg(arg, first_arg);
for (i = 0; *mob_script_commands[i].command_name != '\n'; i++)
if (!str_cmp(first_arg, mob_script_commands[i].command_name))
break; // NB - only allow full matches.
if (*mob_script_commands[i].command_name == '\n')
return 0; // no matching commands.
/* Poiner to the command? */
((*mob_script_commands[i].command_pointer) (ch, line, 0,
mob_script_commands[i].subcmd));
return 1; // We took care of execution. Let caller know.
}
const char *fill[] =
{
@ -443,6 +475,12 @@ void command_interpreter(struct char_data *ch, char *argument)
if (cont) return; /* yes, command trigger took over */
}
/* Allow IMPLs to switch into mobs to test the commands. */
if (IS_NPC(ch) && ch->desc && GET_LEVEL(ch->desc->original) >= LVL_IMPL) {
if (script_command_interpreter(ch, argument))
return;
}
for (length = strlen(arg), cmd = 0; *complete_cmd_info[cmd].command != '\n'; cmd++)
if(complete_cmd_info[cmd].command_pointer != do_action &&
!strncmp(complete_cmd_info[cmd].command, arg, length))

View file

@ -62,6 +62,13 @@ struct command_info {
int subcmd;
};
struct mob_script_command_t {
const char *command_name;
void (*command_pointer)
(struct char_data *ch, char *argument, int cmd, int subcmd);
int subcmd;
};
struct alias_data {
char *alias;
char *replacement;

View file

@ -203,7 +203,9 @@ int load_char(const char *name, struct char_data *ch)
char filename[40];
char buf[128], buf2[128], line[MAX_INPUT_LENGTH + 1], tag[6];
char f1[128], f2[128], f3[128], f4[128];
trig_data *t = NULL;
trig_rnum t_rnum = NOTHING;
if ((id = get_ptable_by_name(name)) < 0)
return (-1);
else {
@ -416,6 +418,14 @@ int load_char(const char *name, struct char_data *ch)
else if (!strcmp(tag, "Thr4")) GET_SAVE(ch, 3) = atoi(line);
else if (!strcmp(tag, "Thr5")) GET_SAVE(ch, 4) = atoi(line);
else if (!strcmp(tag, "Titl")) GET_TITLE(ch) = strdup(line);
else if (!strcmp(tag, "Trig") && CONFIG_SCRIPT_PLAYERS) {
if ((t_rnum = real_trigger(atoi(line))) != NOTHING) {
t = read_trigger(t_rnum);
if (!SCRIPT(ch))
CREATE(SCRIPT(ch), struct script_data, 1);
add_trigger(SCRIPT(ch), t, -1);
}
}
break;
case 'V':
@ -457,6 +467,7 @@ void save_char(struct char_data * ch)
int i, id, save_index = FALSE;
struct affected_type *aff, tmp_aff[MAX_AFFECT];
struct obj_data *char_eq[NUM_WEARS];
trig_data *t;
if (IS_NPC(ch) || GET_PFILEPOS(ch) < 0)
return;
@ -623,6 +634,10 @@ void save_char(struct char_data * ch)
}
if (GET_QUEST(ch) != PFDEF_CURRQUEST) fprintf(fl, "Qcur: %d\n", GET_QUEST(ch));
if (SCRIPT(ch)) {
for (t = TRIGGERS(SCRIPT(ch)); t; t = t->next)
fprintf(fl, "Trig: %d\n",GET_TRIG_VNUM(t));
}
/* Save skills */
if (GET_LEVEL(ch) < LVL_IMMORT) {

View file

@ -1234,6 +1234,7 @@ struct game_data
int map_option; /**< MAP_ON, MAP_OFF or MAP_IMM_ONLY */
int map_size; /**< Default size for map command */
int minimap_size; /**< Default size for mini-map (automap) */
int script_players; /**< Is attaching scripts to players allowed? */
char *OK; /**< When player receives 'Okay.' text. */
char *NOPERSON; /**< 'No one by that name here.' */

View file

@ -866,6 +866,9 @@ void char_from_furniture(struct char_data *ch);
#define CONFIG_MAP_SIZE config_info.play.map_size
#define CONFIG_MINIMAP_SIZE config_info.play.minimap_size
/* DG Script Options */
#define CONFIG_SCRIPT_PLAYERS config_info.play.script_players
/* Crash Saves */
/** Get free rent setting. */
#define CONFIG_FREE_RENT config_info.csd.free_rent