#if defined(macintosh) #include <types.h> #else #include <sys/types.h> #endif #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include "merc.h" #include "recycle.h" void do_fuse (CHAR_DATA *ch, char *argument) { DESCRIPTOR_DATA *d, *desc1, *desc2; CHAR_DATA *ch2, *fuse; OBJ_DATA *obj, *obj_next; char arg[MAX_INPUT_LENGTH]; char *msg = "***********************************************\n\r" "*%s has fused with %s, with %s\n\r" "*taking control. %s will remain\n\r" "*conscious of everything happening,\n\r" "*but can take no action while the\n\r" "*fuse lasts.\n\r" "***********************************************\n\r"; char slave_name[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH]; int i, j; if (IS_NPC(ch)) { sendch ("Players only.\n\r", ch); return; } if (get_skill(ch, gsn_fusion) < 1) { sendch ("You do not know how to fuse.\n\r", ch); return; } one_argument (argument, arg); if (argument[0] == '\0') { sendch ("fuse <target> to fuse with someone.\n\r" "fuse accept to accept a request to fusion.\n\r" "fuse decline to decline the request.\n\r" "fuse cancel to cancel an outgoing request.\n\r", ch); return; } else if (!str_cmp(argument, "accept")) { if (ch->pcdata->fusion_request) { sendch ("You must first cancel your request to fuse with someone.\n\r", ch); return; } ch2 = ch; ch = NULL; // Find character who issued request for (d = descriptor_list; d; d = d->next) { if (d->character && d->character->pcdata && d->character->pcdata->fusion_request == ch2) { ch = d->character; break; } } if (ch == NULL) { sendch ("No one wants to fuse with you!\n\r", ch2); return; } if (IS_FUSED(ch2)) { sendch ("You're already fused!\n\r", ch2); return; } if (IS_FUSED(ch)) { act ("$e is already fused!", ch2, NULL, ch, TO_CHAR); return; } act ("{r$n fuses with $N!{x", ch, NULL, ch2, TO_NOTVICT); desc1 = ch->desc; desc2 = ch2->desc; fuse = new_char (); fuse->pcdata = new_pcdata (); fuse->name = str_dup (ch->name); // Locate a vowel in the name, around the 5th letter for (i = UMIN(strlen(ch->name)-1, 5); i > 1; --i) if (LOWER(ch->name[i]) == 'a' || LOWER(ch->name[i]) == 'e' || LOWER(ch->name[i]) == 'i' || LOWER(ch->name[i]) == 'o' || LOWER(ch->name[i]) == 'u' || LOWER(ch->name[i]) == 'y') break; // Now add the first 3 of the second name after the vowel ++i; for (j = 0; ch2->name[j] != '\0' && j < 3; ++j) fuse->name[i+j] = LOWER(ch2->name[j]); fuse->name[i+j] = '\0'; fuse->id = get_pc_id (); // Add the two chars together // (All ripped from load_char_obj) fuse->race = ch->race; fuse->act = ch->act; fuse->comm = ch->comm; if (ch->prompt) fuse->prompt = str_dup (ch->prompt); fuse->pcdata->confirm_delete = FALSE; fuse->pcdata->board = &boards[DEFAULT_BOARD]; fuse->pcdata->pwd = str_dup (""); if (ch->pcdata->bamfin) fuse->pcdata->bamfin = str_dup (ch->pcdata->bamfin); if (ch->pcdata->bamfout) fuse->pcdata->bamfout = str_dup (ch->pcdata->bamfout); fuse->pcdata->title = str_dup (" the {YFused{x."); for (i = 0; i < MAX_STATS; i++) fuse->perm_stat[i] = ch->perm_stat[i] + ch2->perm_stat[i]; fuse->pcdata->condition[COND_THIRST] = ch->pcdata->condition[COND_THIRST] + ch2->pcdata->condition[COND_THIRST]; fuse->pcdata->condition[COND_FULL] = ch->pcdata->condition[COND_FULL] + ch2->pcdata->condition[COND_FULL]; fuse->pcdata->condition[COND_HUNGER] = ch->pcdata->condition[COND_HUNGER] + ch2->pcdata->condition[COND_HUNGER]; fuse->pcdata->security = ch->pcdata->security; fuse->size = ch->size; fuse->affected_by = ch->affected_by; fuse->alignment = URANGE(-1000,ch->alignment + ch2->alignment,1000); for (i = 0; i < 4; i++) fuse->armor[i] = ch->armor[i] + ch2->armor[i]; for (i = 0; i < MAX_ALIAS; ++i) { if (fuse->pcdata->alias[i] == NULL) break; fuse->pcdata->alias[i] = str_dup (fuse->pcdata->alias[i]); fuse->pcdata->alias_sub[i] = str_dup (fuse->pcdata->alias_sub[i]); } for (i = 0; i < MAX_STATS; i++) { fuse->mod_stat[i] = ch->mod_stat[i] + ch2->mod_stat[i]; fuse->perm_stat[i] = ch->perm_stat[i] + ch2->perm_stat[i]; } for (i = 0; i < MAX_BOARD; i++) fuse->pcdata->last_note[i] = ch->pcdata->last_note[i]; fuse->clan = ch->clan; fuse->comm = ch->comm; fuse->damroll = ch->damroll + ch2->damroll; fuse->hitroll = ch->hitroll + ch2->hitroll; fuse->max_hit = ch->max_hit + ch2->max_hit; fuse->hit = fuse->max_hit; fuse->max_ki = ch->max_ki + ch2->max_ki; fuse->ki = fuse->max_ki; fuse->pcdata->perm_hit = ch->pcdata->perm_hit + ch2->pcdata->perm_hit; fuse->pcdata->perm_ki = ch->pcdata->perm_ki + ch2->pcdata->perm_ki; fuse->invis_level = ch->invis_level; fuse->incog_level = ch->incog_level; fuse->level = ch->level; fuse->played = ch->played + ch2->played; fuse->pl = UMIN(ch->pl + ch2->pl, MAX_PL); fuse->cur_pl = 25; fuse->perm_trans = ch->perm_trans; fuse->race = ch->race; fuse->saving_throw = ch->saving_throw + ch2->saving_throw; fuse->lines = ch->lines; fuse->sex = ch->sex; for (i=0; i<MAX_SKILL; ++i) fuse->pcdata->learned[i] = UMIN(ch->pcdata->learned[i] + ch2->pcdata->learned[i], 10); fuse->pcdata->true_sex = ch->pcdata->true_sex; fuse->train = ch->train + ch2->train; fuse->trans = ch->trans; fuse->trans_count = ch->trans_count; fuse->wimpy = ch->wimpy; fuse->wiznet = ch->wiznet; fuse->zenni = ch->zenni + ch2->zenni; default_colour(fuse); fuse->fuse_control = str_dup (ch->name); fuse->fuse_slave = str_dup (ch2->name); fuse->fuse_count = 5; // Take all the equipment from the controller for (obj = ch->carrying; obj; obj = obj_next) { obj_next = obj->next_content; obj_from_char (obj); obj_to_char (obj, fuse); } char_to_room(fuse, ch->in_room); strcpy (slave_name, ch2->name); strcat (slave_name, "Slave"); fuse->next = char_list; char_list = fuse; reset_char (fuse); // Remove the characters save_char_obj (ch); save_char_obj (ch2); if (ch->pcdata->in_progress) free_note (ch->pcdata->in_progress); if (ch2->pcdata->in_progress) free_note (ch2->pcdata->in_progress); extract_char (ch, TRUE); extract_char (ch2, TRUE); // Set the descriptors, create some place-holder character for the slave fuse->desc = desc1; fuse->desc->character = fuse; fuse->slave = new_char (); fuse->slave->desc = desc2; fuse->slave->desc->connected = CON_FUSE_SLAVE; fuse->slave->desc->character = fuse->slave; fuse->slave->pcdata = new_pcdata (); fuse->slave->name = str_dup (slave_name); sprintf (buf, msg, fuse->fuse_control, fuse->fuse_slave, fuse->fuse_control, fuse->fuse_slave); sendch (buf, fuse); return; } else if (!str_cmp(argument, "decline")) { ch2 = NULL; // Find character who issued request for (d = descriptor_list; d; d = d->next) { if (d->character && d->character->pcdata && d->character->pcdata->fusion_request == ch) { ch2 = d->character; break; } } if (ch2 == NULL) { sendch ("No one wants to fuse with you!\n\r", ch); return; } sendch ("Your request to fuse has been declined.\n\r", ch2); sendch ("You decline the request to fuse.\n\r", ch); ch2->pcdata->fusion_request = NULL; return; } else if (!str_cmp(argument, "cancel")) { if (ch->pcdata->fusion_request == NULL) { sendch ("You haven't asked anyone to fuse.\n\r", ch); return; } sendch ("The request to fuse has been cancelled.\n\r", ch->pcdata->fusion_request); sendch ("You have cancelled the request to fuse.\n\r", ch); ch->pcdata->fusion_request = NULL; return; } else if ((ch2 = get_char_room(ch, NULL, arg)) == NULL || IS_NPC(ch2)) { sendch ("Character not found.\n\r", ch); return; } if (IS_FUSED(ch2)) { sendch ("You're already fused!\n\r", ch2); return; } if (IS_FUSED(ch)) { act ("$e is already fused!", ch2, NULL, ch, TO_CHAR); return; } if (ch->pl/2 > ch2->pl || ch2->pl/2 > ch->pl) { sendch ("You cannot fuse because you and your target are of radically different powerlevel.\n\r", ch); return; } // not sure why its kaioken, changed it to fusion.. ?? if (get_skill(ch2, gsn_fusion) < 1) { sendch ("You cannot fuse because your target does not know how to.\n\r", ch); return; } if (ch->pcdata->fusion_request) sendch ("The request to fuse has been cancelled.\n\r", ch->pcdata->fusion_request); ch->pcdata->fusion_request = ch2; sendch ("You have sent out a request to fuse.\n\r", ch); sprintf (buf, "You have been asked by %s to fuse.\n\r", ch->name); sendch (buf, ch2); return; } void do_unfuse (CHAR_DATA *ch, char *argument) { if (IS_NPC(ch)) { sendch ("Players only.\n\r", ch); return; } if (!IS_FUSED(ch)) { sendch ("You're not fused!\n\r", ch); return; } unfuse (ch); return; } void unfuse (CHAR_DATA *ch) { DESCRIPTOR_DATA *desc1, *desc2 = NULL, d; // d is a temporary descriptor CHAR_DATA *ch1, *ch2; OBJ_DATA *obj, *obj_next; ROOM_INDEX_DATA *in_room; char fuse_control[40], fuse_slave[40]; /* * Try to change each character's stats * to reflect anything gained during a * fusion. Doesn't work. If the * player's skills are both 10, fused * has only only 10 as well. So, it * appears the stats have gone from * 10+10 down only 10 - thus, after fuse * both players lose 5 in each skill long long int c_pl; int c_zenni, c_train; int c_hit, c_ki; int c_skill[MAX_SKILL]; int c_align; int i; */ if (IS_NPC(ch) || !IS_FUSED(ch)) return; sendch ("{rThe fuse is broken!{x\n\r", ch); desc1 = ch->desc; if (ch->slave) desc2 = ch->slave->desc; if (desc2) desc2->connected = CON_PLAYING; strcpy (fuse_control, ch->fuse_control); strcpy (fuse_slave, ch->fuse_slave); in_room = ch->in_room; /* c_pl = get_perm_pl(ch); c_zenni = ch->zenni; c_train = ch->train; c_hit = ch->max_hit; c_ki = ch->max_ki; c_align = ch->alignment; for (i=0; i<MAX_SKILL; ++i) c_skill[i] = ch->pcdata->learned[i]; */ if (desc1) { load_char_obj (desc1, fuse_control); ch1 = desc1->character; } else { load_char_obj (&d, fuse_control); ch1 = d.character; ch1->desc = NULL; } if (desc2) { load_char_obj (desc2, fuse_slave); ch2 = desc2->character; } else { load_char_obj (&d, fuse_slave); ch2 = d.character; ch2->desc = NULL; } char_to_room(ch1, in_room); char_to_room(ch2, in_room); ch1->next = ch2; ch2->next = char_list; char_list = ch1; // Take all the equipment from the previous controlling character for (obj = ch1->carrying; obj; obj = obj_next) { obj_next = obj->next_content; obj_from_char (obj); extract_obj (obj); } // Give all equipment to the new character for (obj = ch->carrying; obj; obj = obj_next) { obj_next = obj->next_content; obj_from_char (obj); obj_to_char (obj, ch1); } if (ch->pcdata->in_progress) free_note (ch->pcdata->in_progress); extract_char (ch, TRUE); // extracting the fused character will set the descriptors to NULL -- set them back ch1->desc = desc1; if (desc1) desc1->character = ch1; /* c_pl -= get_perm_pl(ch1) + get_perm_pl(ch2); c_zenni -= ch1->zenni + ch2->zenni; c_train -= ch1->train + ch2->train; c_hit -= ch1->max_hit + ch2->max_hit; c_ki -= ch1->max_ki + ch2->max_ki; c_align -= ch1->alignment + ch2->alignment; for (i=0; i<MAX_SKILL; ++i) c_skill[i] -= ch1->pcdata->learned[i] + ch2->pcdata->learned[i]; ch1->pl += c_pl / 2; ch1->cur_pl = UMIN(ch1->cur_pl, ch1->pl); ch1->zenni += c_zenni / 2; ch1->train += c_train / 2; ch1->max_hit += c_hit / 2; ch1->max_ki += c_ki / 2; ch1->alignment = URANGE(-1000, ch1->alignment + c_align / 2, 1000); ch2->pl += c_pl / 2; ch2->cur_pl = UMIN(ch2->cur_pl, ch2->pl); ch2->zenni += c_zenni / 2; ch2->train += c_train / 2; ch2->max_hit += c_hit / 2; ch2->max_ki += c_ki / 2; ch2->alignment = URANGE(-1000, ch2->alignment + c_align / 2, 1000); for (i=0; i<MAX_SKILL; ++i) { ch1->pcdata->learned[i] += c_skill[i] / 2; ch2->pcdata->learned[i] += c_skill[i] / 2; } */ reset_char (ch1); reset_char (ch2); act ("{r$n seperates from the fusion with $N!{x", ch1, NULL, ch2, TO_NOTVICT); act ("{rYou break from the fusion with $N.{x", ch1, NULL, ch2, TO_CHAR); act ("{rYou break from the fusion with $N.{x", ch2, NULL, ch1, TO_CHAR); }