Welcome to the Builder Academy

Question assistance with rune weapon

More
18 May 2023 08:00 #10337 by Nero
I am trying to add a new skill for a subclass called rune ward where it can imbue a weapon with specified elemental attacks. It works but I am trying to figure out how to get it to only last for 2 or 3 ticks before it wears off of the weapon and reverts back to the weapons original attack type.
The issue seems to be that 1) The timer does not seems to be setting or wearing off after 2 ticks and 2) I am not sure if its properly going to set the attack type back to the weapons default so I am sure more is needed.
Code:
[code]ACMD(do_rune) { struct obj_data *weapon = NULL; char weapon_name[MAX_STRING_LENGTH]; char rune_type[MAX_INPUT_LENGTH]; int found = FALSE, element = APPLY_NONE; two_arguments(argument, weapon_name, rune_type); // ... (existing code) // Check if the player provided a valid rune type if (!*rune_type) { send_to_char(ch, "What type of rune do you want to add?\r\n"); return; } // Find the weapon in the player's inventory weapon = get_obj_in_list_vis(ch, weapon_name, ch->carrying); if (!weapon) { send_to_char(ch, "You don't have %s in your inventory!\r\n", weapon_name); return; } // Check if the object is a weapon if (GET_OBJ_TYPE(weapon) != ITEM_WEAPON) { send_to_char(ch, "It doesn't look like %s would make a good weapon...\r\n", weapon_name); return; } // Check if the weapon already has a rune if (GET_OBJ_RUNED(weapon) == 1) { send_to_char(ch, "This weapon is already imbued with runes!\r\n"); return; } // Check if element is valid if (is_abbrev(rune_type, "fire")) { element = 15; } else if (is_abbrev(rune_type, "cold")) { element = TYPE_COLD; } else if (is_abbrev(rune_type, "electric")) { element = TYPE_ELEC; } else if (is_abbrev(rune_type, "acid")) { element = TYPE_ACID; } else if (is_abbrev(rune_type, "poison")) { element = TYPE_POIS; } else { send_to_char(ch, "Invalid element!\r\n"); return; } // Apply the rune to the weapon GET_OBJ_RUNED(weapon) += 1; GET_OBJ_VAL(weapon, 3) = element; // Mark the weapon as customized and magical SET_BIT_AR(GET_OBJ_EXTRA(weapon), ITEM_UNIQUE_SAVE); SET_BIT_AR(GET_OBJ_EXTRA(weapon), ITEM_MAGIC); // Set the weapon's timer GET_OBJ_TIMER(weapon) = 2; // Set the timer to 2 game ticks // Display messages to the player act("$n enchants $p with magical runes!", TRUE, ch, weapon, 0, TO_ROOM); act("You enchant $p with magical runes!", FALSE, ch, weapon, 0, TO_CHAR); }
[/code]

Limits.C
Code:
    /* Handle camp timer */       if (GET_OBJ_TYPE(j) == ITEM_CAMP) {       if (GET_OBJ_TIMER(j) > 0)         GET_OBJ_TIMER(j)--;       if (!GET_OBJ_TIMER(j)) {         /* Remove the camp object from the room */         struct room_data *room = &world[j->in_room];         if (room && j->in_room != NOWHERE) {           act("The last embers of the campfire have faded away, leaving only a pile of charred wood and ashes.", FALSE, world[IN_ROOM(j)].people, j, 0, TO_ROOM);           act("The last embers of the campfire have faded away, leaving only a pile of charred wood and ashes.", FALSE, world[IN_ROOM(j)].people, j, 0, TO_CHAR);           extract_obj(j);         }       }     /* Rune Ward */       if (GET_OBJ_TYPE(j) == ITEM_WEAPON) {         if (GET_OBJ_TIMER(j) > 0)           GET_OBJ_TIMER(j)--;         if (!GET_OBJ_TIMER(j)) {           GET_OBJ_RUNED(j) = 0;  // Fix: Use the assignment operator (=) instead of equality operator (==)           // Reset the weapon's attack type to its original value           GET_OBJ_VAL(j, 3) = GET_OBJ_VAL(j, 0);           // Display a message to the player           act("The magical runes on $p fade away.", FALSE, NULL, j, NULL, TO_ROOM);           act("The magical runes on $p fade away.", FALSE, NULL, j, NULL, TO_CHAR);         }       }     }     /* If the timer is set, count it down and at 0, try the trigger */     /* note to .rej hand-patchers: make this last in your point-update() */     else if (GET_OBJ_TIMER(j) > 0) {       GET_OBJ_TIMER(j)--;       if (!GET_OBJ_TIMER(j))         timer_otrigger(j);     }   }

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

More
18 May 2023 12:10 #10338 by thomas
Replied by thomas on topic assistance with rune weapon
You have a mismatched brace in limits.c; there's one missing from the `if (GET_OBJ_TYPE(j) == ITEM_CAMP) {` statement, so you're basically checking if the object type is both and thus never hitting the second block.

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

More
19 May 2023 01:28 #10339 by Nero
Replied by Nero on topic assistance with rune weapon
Thanks for pointing that out
that seems to be firing it off now so we are in the ball park
although this isn't working:
          act("The magical runes on $p fade away.", TRUE, NULL, j, NULL, TO_ROOM);
          act("The magical runes on $p fade away.", TRUE, NULL, j, NULL, TO_CHAR);

getting an error in cygwin no valid target to act!
but it is resetting the object to where I can rune it again
but it screws up the attack type not sure if there is a way to get it to revert back to it's original attack type after the rune wears off

 

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

More
19 May 2023 02:55 - 19 May 2023 03:04 #10340 by Nero
Replied by Nero on topic assistance with rune weapon
So it looks like the issue with it is that the object needs to be in the room on the ground for the act to fire off. I had to change it to:

    /* Rune Ward */
    if (GET_OBJ_TYPE(j) == ITEM_WEAPON) {
      if (GET_OBJ_TIMER(j) > 0)
        GET_OBJ_TIMER(j)--;

      if (!GET_OBJ_TIMER(j)) {
        if (GET_OBJ_RUNED(j) == 1) {
          // Reset the weapon's attack type to its original value

          // Display the message if it hasn't been displayed yet
          if (j->carried_by) {
            act("The magical runes on $p fade away.", FALSE, j->carried_by, j, 0, TO_CHAR);
          }
          if (j->worn_by) {
            act("The magical runes on $p fade away.", FALSE, j->worn_by, j, 0, TO_CHAR);
          }
          // Display the message to the room if the item is on the ground
          act("The magical runes on $p fade away.", FALSE, NULL, j, NULL, TO_ROOM);
          // Set the flag to indicate that the message has been displayed
          GET_OBJ_RUNED(j) = 0;
        }
      } else {
        // Set the flag to indicate that the weapon is currently runed
        GET_OBJ_RUNED(j) = 1;
      }
    }

but now I have to figure out how to get the item to be reverted back to the original attack type after the runes wear off.
Last edit: 19 May 2023 03:04 by Nero.

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

More
19 May 2023 04:38 #10341 by Nero
Replied by Nero on topic assistance with rune weapon
Working (I think pending further testing but so far seems good) I had to add an integer to the object struct to store the original attack type
final code:
Code:
ACMD(do_rune) {   struct obj_data *weapon = NULL;     struct obj_data *obj, *next_obj;   struct affected_type af;     char weapon_name[MAX_STRING_LENGTH];   char rune_type[MAX_INPUT_LENGTH];   char buf[MAX_INPUT_LENGTH];   int found = FALSE, i, element = APPLY_NONE;   two_arguments(argument, weapon_name, rune_type);   if (!can_see_room(ch, IN_ROOM(ch))) {           send_to_char(ch, "It's too dark for you to see!\r\n");           return;   }   /* No rune while fighting */   if (IS_FIGHTING(ch)) {           send_to_char(ch, "You are too busy fighting to do that right now!\r\n");           return;   }   if (!*weapon_name || !*rune_type) {     send_to_char(ch, "Usage: rune <weapon> <element>\r\n");     return;   }     if (!*weapon_name) {         send_to_char(ch, "What do you wish to imbue?\r\n");         return;     }   // Check if the player provided a valid rune type   if (!*rune_type) {     send_to_char(ch, "What type of rune do you want to add?\r\n");     return;   }     for (obj = ch->carrying; obj; obj = next_obj) {         next_obj = obj->next_content;         if (obj == NULL)             return;         else if (!(weapon = get_obj_in_list_vis(ch->carrying, ch, weapon_name)))             continue;         else             found = TRUE;     }          if (found == FALSE) {         sprintf(buf, "You don't have %s in your inventory!\r\n", weapon_name);         send_to_char(ch, buf);         return;     }     if (found && (GET_OBJ_TYPE(weapon) != ITEM_WEAPON)) {         sprintf(buf, "It doesn't look like %s would make a good weapon...\r\n", weapon_name);         send_to_char(ch, buf);         return;     }   if (GET_OBJ_RUNED(weapon) == 1) {         send_to_char(ch, "This weapon is already imbued with runes!\r\n");         return;     }     /* Check if element is valid */   if (is_abbrev(rune_type, "fire")) {     element = 15;   } else if (is_abbrev(rune_type, "cold")) {     element = TYPE_COLD;   } else if (is_abbrev(rune_type, "electric")) {     element = TYPE_ELEC;   } else if (is_abbrev(rune_type, "acid")) {     element = TYPE_ACID;   } else if (is_abbrev(rune_type, "poison")) {     element = TYPE_POIS;   } else {     send_to_char(ch, "Invalid element!\r\n");     return;   }     // Store the original attack type     weapon->original_attack_type = GET_OBJ_VAL(weapon, 3);     GET_OBJ_RUNED(weapon) += 1; //Prevents from doing multiple runes while one is already active     GET_OBJ_VAL(weapon, 3) = element;     SET_BIT_AR(GET_OBJ_EXTRA(weapon), ITEM_MAGIC);     GET_OBJ_TIMER(weapon) = 2;     act("$n enchants $p with magical runes!", TRUE, ch, weapon, 0, TO_ROOM);     act("You enchant $p with magical runes!", FALSE, ch, weapon, 0, TO_CHAR); }

Code:
    /* Rune Ward */     if (GET_OBJ_TYPE(j) == ITEM_WEAPON) {       if (GET_OBJ_TIMER(j) > 0)         GET_OBJ_TIMER(j)--;       if (!GET_OBJ_TIMER(j)) {         if (GET_OBJ_RUNED(j) == 1) {           // Reset the weapon's attack type to its original value           // Display the message if it hasn't been displayed yet           if (j->carried_by) {             act("The magical runes on $p fade away.", FALSE, j->carried_by, j, 0, TO_CHAR);           }           if (j->worn_by) {             act("The magical runes on $p fade away.", FALSE, j->worn_by, j, 0, TO_CHAR);           }           // Display the message to the room if the item is on the ground           act("The magical runes on $p fade away.", FALSE, NULL, j, NULL, TO_ROOM);           // Set the flag to indicate that the message has been displayed           GET_OBJ_RUNED(j) = 0;           GET_OBJ_VAL(j, 3) = j->original_attack_type;         }       } else {         // Set the flag to indicate that the weapon is currently runed         GET_OBJ_RUNED(j) = 1;       }     }

Code:
struct obj_data {    obj_vnum item_number;       /* Where in data-base */    room_rnum in_room;           /* In what room -1 when conta/carr */    struct obj_flag_data       obj_flags;  /* Object information */    struct obj_affected_type   affected[MAX_OBJ_AFFECT];  /* affects */    struct obj_bonus_prof_type bonus_profs[MAX_OBJ_PROF_BONUSES];  /* bonus spell/skill profs */    char    *name;                  /* Title of object :get etc. */    char    *description;              /* When in room */    char    *short_description;     /* when worn/carry/in cont. */    char    *action_description;    /* What to write when used */    struct extra_descr_data *ex_description; /* extra descriptions */    struct char_data *carried_by; /* Carried by :NULL in room/conta */    struct char_data *worn_by;       /* Worn by?             */    sh_int worn_on;                 /* Worn where?         */    struct obj_data *in_obj;       /* In what object NULL when none */    struct obj_data *contains;     /* Contains objects */    long id;                       /* used by DG triggers */    time_t generation;             /* creation time for dupe check */    unsigned long long unique_id;  /* random bits for dupe check */    struct trig_proto_list *proto_script; /* list of default triggers */    struct script_data *script;    /* script info for the object */    struct obj_data *next_content; /* For 'contains' lists */    struct obj_data *next;         /* For the object list */    struct char_data *sitting_here;/* who is sitting on furniture*/    int original_attack_type; // Rune Ward };
The following user(s) said Thank You: lacrc

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

Time to create page: 0.194 seconds