/* Accept an applicant into the clan */ void do_caccept( struct char_data *ch, struct clan_type *cptr, struct char_data *vict ) { int i=0; if (vict != NULL && (GET_CLAN(vict) < CLAN_MEMBER)) { GET_CLAN(vict) = GET_CLAN(ch); GET_CLAN_RANK(vict) = CLAN_MEMBER; /* send some sort of mail to player notifying him/her of acceptance */ sprintf(buf, "%s,\r\n\r\n" " Congratulations! You have been accepted into the ranks of\r\n" "%s. The leader of our clan is %s. Good luck.\r\n", GET_NAME(vict), cptr->name, cptr->leadersname); store_mail(GET_IDNUM(vict), GET_IDNUM(ch), -1, buf); /* now that the mail has been sent, let's continue. */ GET_HOME(vict) = GET_HOME(ch); save_char(vict, NOWHERE); /* now remove the player from the petition list */ remove_applicant(cptr, vict); for (i = 0; i < 100; i++) { if (cptr->members[i] == NULL) { cptr->members[i] = strdup(GET_NAME(vict)); break; } if (strcmp(cptr->members[i], GET_NAME(vict)) == 0) break; } save_clans(); } return; }
/* Dismiss a member from the clan/Resign from the clan */ void do_dismiss( struct char_data *ch, struct clan_type *cptr, struct char_data *vict ) { if (vict != ch){ if (vict != NULL && GET_CLAN(vict) == GET_CLAN(ch)) { if (GET_CLAN_RANK(vict) >= GET_CLAN_RANK(ch)) { send_to_char("You may not dismiss those of equal or greater clan status than yourself!\r\n", ch); return; } /* send some sort of mail to player notifying him/her of dismissal */ sprintf(buf, "%s,\r\n\r\n" " You have been dismissed from the clan of %s.\r\n" "If you are unsure of the reason why, please feel\r\n" "free to contact the leader, %s.\r\n", GET_NAME(vict), cptr->name, cptr->leadersname); store_mail(GET_IDNUM(vict), GET_IDNUM(ch), -1, buf); remove_member(cptr, vict); } } else if (GET_CLAN_RANK(vict) == CLAN_LEADER) { GET_CLAN_RANK(vict) = CLAN_MEMBER; send_to_char("You have resigned as leader.\r\n", ch); cptr->leadersname = strdup("NoOne"); save_clans(); return; } GET_CLAN(vict) = CLAN_NONE; GET_CLAN_RANK(vict) = CLAN_NONE; GET_HOME(vict) = 1; remove_member(cptr, vict); save_char(vict, NOWHERE); save_clans(); return; }
void account_delete_char(struct account *account, struct creature *ch) { void remove_bounties(int); int idx, count; PGresult *res; clear_clan_owner(GET_IDNUM(ch)); remove_char_clan(GET_CLAN(ch), GET_IDNUM(ch)); // TODO: Remove character from any access groups sql_exec("delete from sgroup_members where player=%ld", GET_IDNUM(ch)); // Remove character from any quests they might have joined if (GET_QUEST(ch)) { struct quest *quest = quest_by_vnum(GET_QUEST(ch)); if (quest) { remove_quest_player(quest, GET_IDNUM(ch)); save_quests(); } } // Remove character from trusted lists - we have to take the accounts // in memory into consideration when we do this, so we have to go // through each account res = sql_query("select account from trusted where player=%ld", GET_IDNUM(ch)); count = PQntuples(res); for (idx = 0; idx < count; idx++) { struct account *acct = account_by_idnum(atoi(PQgetvalue(res, idx, 0))); if (acct) account_distrust(acct, GET_IDNUM(ch)); } // Remove from the bounty list remove_bounties(GET_IDNUM(ch)); sql_exec("delete from bounty_hunters where idnum=%ld or victim=%ld", GET_IDNUM(ch), GET_IDNUM(ch)); // Disassociate author from board messages sql_exec("update board_messages set author=null where author=%ld", GET_IDNUM(ch)); // Remove character from account account->chars = g_list_remove(account->chars, GINT_TO_POINTER(GET_IDNUM(ch))); sql_exec("delete from players where idnum=%ld", GET_IDNUM(ch)); // Remove character from game if (ch->in_room) { send_to_char(ch, "A cold wind blows through your soul, and you disappear!\r\n"); creature_purge(ch, false); } }
/* Reject an applicant from a clan/Withdraw an application */ void do_creject( struct char_data *ch, struct clan_type *cptr, struct char_data *vict) { int i=0; long leader; if (vict != ch) { if (vict != NULL) { /* send some sort of mail to player notifying him/her of rejection */ sprintf(buf, "%s,\r\n\r\n" " You have been rejected from the clan of %s.\r\n" "If you are unsure of the reason why, please feel\r\n" "free to contact the leader, %s.\r\n", GET_NAME(vict), cptr->name, cptr->leadersname); store_mail(GET_IDNUM(vict), GET_IDNUM(ch), -1, buf); /* mail's been sent, let's move on */ } } else { for (i=0; i<20; i++) { if (!str_cmp(cptr->applicants[i], GET_NAME(ch))) { send_to_char("You aren't applying to the clan...\r\n", ch); break; } } /* send some sort of mail to leader notifying him/her of withdrawal */ leader = get_id_by_name(cptr->leadersname); sprintf(buf, "%s,\r\n\r\n" " I have withdrawn my application from the clan.\r\n" "\r\n%s\r\n", cptr->leadersname, GET_NAME(ch)); store_mail(leader, GET_IDNUM(ch), -1, buf); /* now that the mail has been sent, let's continue. */ } GET_CLAN(vict) = CLAN_NONE; GET_CLAN_RANK(vict) = 0; save_char(vict, NOWHERE); /* now remove the player from the petition list */ remove_applicant(cptr, vict); save_clans(); return; }
void mobile_activity(void) { register struct char_data *ch, *next_ch, *vict; struct char_data *min_vict = NULL; struct obj_data *obj, *next_obj, *best_obj, *cont; int door, found, max, where; int casual, max_abil=0, curr_abil, gold; memory_rec *names; room_rnum target_room; extern int no_specials; ACMD(do_get); for (ch = character_list; ch; ch = next_ch) { next_ch = ch->next; if (!IS_MOB(ch)) continue; //lance ripristina il master! if (IS_NPC(ch) && MOB_FLAGGED(ch, MOB_SAVE)) chkmaster(ch); // Examine call for special procedure if (MOB_FLAGGED(ch, MOB_SPEC) && !no_specials) { if (mob_index[GET_MOB_RNUM(ch)].func == NULL) { sprintf(buf, "SYSERR: %s (#%d): Attempting to call non-existing mob func", GET_NAME(ch), GET_MOB_VNUM(ch)); log(buf); REMOVE_BIT(MOB_FLAGS(ch), MOB_SPEC); } else { //(mob_index[GET_MOB_RNUM(ch)].func) (ch, ch, 0, ""); if ((mob_index[GET_MOB_RNUM(ch)].func) (ch, ch, 0, "")) continue; /* go to next char*/ } } // If the mob has no specproc, do the default actions if (FIGHTING(ch) || !AWAKE(ch)) continue; // Nuovo Scavenger (picking up objects) by Rusty if (MOB_FLAGGED(ch, MOB_SCAVENGER)) if (world[ch->in_room].contents && (number(0, 10) > 5)) { max = -1000; best_obj = NULL; for (obj = world[ch->in_room].contents; obj; obj = obj->next_content) if (CAN_GET_OBJ(ch, obj) && objlevel(obj) > max) { best_obj = obj; max = objlevel(obj); } if (best_obj != NULL) { obj_from_room(best_obj); obj_to_char(best_obj, ch); act("$n prende $p.", FALSE, ch, best_obj, 0, TO_ROOM); // Orione, tolta la procedura che fa indossare l'eq raccolto ai mob scavenger // Scavenger Plus:Mob wear the best object /* where=find_eq_pos(ch, best_obj, 0); if (CAN_WEAR(best_obj, ITEM_WEAR_WIELD)) where=WEAR_WIELD; if ( (where>0) && GET_EQ(ch,where)) { // se ce l'ha gia! if ((objlevel((ch)->equipment[where]))< objlevel(best_obj)) { obj_to_char((obj=unequip_char(ch, where)), ch); act("$n smette di usare $p.", FALSE, ch, obj, 0, TO_ROOM); } else { where = NUM_WEARS; // cioe' oggetto non indossabile } if (GET_LEVEL(ch)>=objlevel(best_obj)) { if (where>=0 && where <NUM_WEARS) { obj_from_char(best_obj); equip_char(ch,best_obj,where); wear_message(ch,best_obj,where); } } } */ } } //End ifif // Mob BodyGuard !? if (MOB_FLAGGED(ch, MOB_BGUARD) && (ch->master)) { if ( (FIGHTING(ch->master) && (npc_rescue(ch, ch->master) == FALSE)) || (ch->master && WHOKILLED(ch->master)) ) { act("$N Si schiera Prontamente al tuo fianco!", FALSE,ch->master, 0, ch, TO_CHAR); act("$n Si schiera prontamente al fianco di $N", FALSE, ch, 0, ch->master, TO_ROOM); if (WHOKILLED(ch->master)) hit(ch, WHOKILLED(ch->master), TYPE_UNDEFINED);/*in ogni caso assiste*/ else hit(ch, FIGHTING(ch->master), TYPE_UNDEFINED);/*in ogni caso assiste*/ } if (FIGHTING(ch)) { npc_rescue(ch, ch->master); if (WHOKILLED(ch->master)) hit(ch, WHOKILLED(ch->master), TYPE_UNDEFINED); /*in ogni caso assiste*/ continue; } } //MOB_THIEF if ( MOB_FLAGGED(ch, MOB_CRIMINAL) && (GET_POS(ch) == POS_RESTING) && IS_AFFECTED(ch, AFF_HIDE) && GET_HIT(ch) >= 2*GET_MAX_HIT(ch)/3) { appear(ch); GET_POS(ch)=POS_STANDING; } if ( MOB_FLAGGED(ch, MOB_CRIMINAL) && ( GET_POS(ch) == POS_STANDING) && ( (casual = number(0, 11)) < 6 ) ) { // 50% Rubare // cerca le vittime 1) Devono aver almeno 1 coin // 2) Deve aver una buona prob di farcela for (found=FALSE, min_vict = NULL, vict = world[ch->in_room].people; vict; vict = vict->next_in_room) { if (CAN_SEE(ch, vict) && (vict != ch)) { if ((min_vict == NULL) || (max_abil < 100)) { //se ha il 100% tanto vale fermarsi //Calcolo dell abilita:presa esattamente da D n'D curr_abil = MIN(90, (10*(GET_LEVEL(ch)) - 5*GET_LEVEL(vict))); curr_abil -= dex_app[GET_DEX(vict)].reaction; if (GET_POS(vict) < POS_STANDING) curr_abil += 200; // Se la vittima e' addormentata-stunned - incap o morta ovviamente // deruberai questa sicuramente if ( (curr_abil >= 40) && (GET_GOLD(vict) != 0) && (curr_abil > max_abil) ) { min_vict = vict; max_abil = curr_abil; found=TRUE; } } } } // Se ha trovato la vittima if (found == TRUE) { if ((casual = number(1, 100)) > max_abil) { if (!IS_NPC(min_vict)) act(" $n cerca di prendere dei soldi dal tuo Borsello", FALSE, ch, 0, min_vict, TO_CHAR); else { act("Oops...", FALSE, ch, 0, min_vict, TO_ROOM); act("$n cerca di rubare soldi a $N..Ma viene Scoperto! ", FALSE, ch, 0, min_vict, TO_ROOM); } //Beccato ... fa 2 tentativi di fuga if (((door = number(1, 7)) < NUM_OF_DIRS) && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch,door,1,CAN_SHOW_ROOM); if ((door -= 1) < NUM_OF_DIRS && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch,door,1,CAN_SHOW_ROOM); if ((door += 2) < NUM_OF_DIRS && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch,door,1,CAN_SHOW_ROOM); if (IS_NPC(min_vict)) { act("$n Urla: $N e' uno sporco LADRO!!!!", FALSE, min_vict, 0, ch, TO_ROOM); hit(min_vict, ch, TYPE_UNDEFINED); } } // Il Bastardo ce la fa! else { if (GET_POS(min_vict) < 5) { GET_GOLD(ch) += GET_GOLD(min_vict); GET_GOLD(min_vict) = 0; //la ripulisce completamente } else { gold = number((GET_GOLD(min_vict) / 10), (GET_GOLD(min_vict) / 2)); //gold = MIN(5000, gold); if (gold > 0) { GET_GOLD(ch) += gold; GET_GOLD(min_vict) -= gold; if (GET_GOLD(min_vict) < 0) GET_GOLD(min_vict) = 0; } } // Dopo il furto si allontana if (((door = number(1, 6)) < NUM_OF_DIRS) && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch,door,1,CAN_SHOW_ROOM); if ((door -=1) < NUM_OF_DIRS && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch,door,1,CAN_SHOW_ROOM); if ((door +=2) < NUM_OF_DIRS && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch,door,1,CAN_SHOW_ROOM); } } else { // Nessuna vittima appetibile:se ne va! if (((door = number(0, 6)) < NUM_OF_DIRS) && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) ) perform_move(ch, door, 1, CAN_SHOW_ROOM); } } // Mob Sciacalli indossano EQ if (MOB_FLAGGED(ch, MOB_NECRO) && !FIGHTING(ch) && AWAKE(ch)) if (world[ch->in_room].contents) { max = -1000; best_obj=NULL; for (cont = world[ch->in_room].contents;cont;cont = cont->next_content) if (GET_OBJ_TYPE(cont) == ITEM_CONTAINER) { for (obj = cont->contains; obj; obj = next_obj) { next_obj = obj->next_content; if (obj != NULL) { if (CAN_SEE_OBJ(ch, obj) && ( (max = objlevel(obj)) <= GET_LEVEL(ch)) ) { perform_get_from_container(ch, obj, cont, FIND_OBJ_INV); if (obj != NULL) { where = find_eq_pos(ch, obj, 0); if (CAN_WEAR(obj, ITEM_WEAR_HOLD)) where = WEAR_HOLD; if (GET_OBJ_TYPE(obj)==ITEM_LIGHT) where = WEAR_LIGHT; if (CAN_WEAR(obj, ITEM_WEAR_WIELD)) where = WEAR_WIELD; if (where < 0) { sprintf(buf,"SYSERR:pos < 0 ,in cont %s obj %d %s In room %d", cont->name, GET_OBJ_RNUM(obj), obj->name, IN_ROOM(ch)); log(buf); where = NUM_WEARS; } if (GET_EQ(ch, where) && where < NUM_WEARS) { if ((objlevel((ch)->equipment[where])) < objlevel(obj)) { obj_to_char((best_obj = unequip_char(ch, where)), ch); act("$n smette di usare $p.",FALSE, ch, best_obj, 0, TO_ROOM); } else where = NUM_WEARS; } if (where >= 0 && where < NUM_WEARS) { wear_message(ch, obj, where); obj_from_char(obj); equip_char(ch, obj, where); } } } } } } //End forif } //End ifif // Mob Movement if (HUNTING(ch)) hunt_victim(ch); else { if (MOB_FLAGGED(ch , MOB_SEARCHER)) {} else { if (ch->in_room != NOWHERE) { if (!IS_IN_WILD(ch)) { if ( !MOB_FLAGGED(ch, MOB_SENTINEL) && (GET_POS(ch) == POS_STANDING) && ( (door = number(0, 8)) < NUM_OF_DIRS) && CAN_GO(ch, door) && !ROOM_FLAGGED(EXIT(ch, door)->to_room, ROOM_NOMOB | ROOM_DEATH) && ( !MOB_FLAGGED(ch, MOB_STAY_ZONE) || (world[EXIT(ch, door)->to_room].zone == world[ch->in_room].zone))) { perform_move(ch, door, 1, CAN_SHOW_ROOM); } } else { // E' in wilderness if (MOB_FLAGGED(ch, MOB_WILDHUNT)) door = wild_mobhunter(ch); else door = number(0, 8); if (door >= 0 && door < NUM_OF_DIRS) target_room = wild_target_room(ch, door); else target_room = -1; if ( !MOB_FLAGGED(ch, MOB_SENTINEL) && (GET_POS(ch) == POS_STANDING) && (target_room != -1) && ( !MOB_FLAGGED(ch, MOB_STAY_ZONE) || (world[target_room].wild_rnum == world[ch->in_room].wild_rnum))) { perform_move(ch, door, 1, CAN_SHOW_ROOM); } } } } } // Aggressive Mobs if (MOB_FLAGGED(ch, MOB_AGGRESSIVE | MOB_AGGR_TO_ALIGN)) { found = FALSE; for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room) { if (IS_NPC(vict) || !CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE)) continue; if (number(0, 3) < 2) continue; // Simple simulate Random a Joke from Phantom ;P if (GET_ABIL (vict, ABIL_TRATTATIVA) >= EXPERT_LIV) continue; // I pg con trattativa ad esperto fanno pace con gli aggressivi (by Spini) if (controllo_volo(ch, vict)) continue; if (affected_by_spell (vict, SPELLSKILL, DISEASE_PESTE)) continue; if (MOB_FLAGGED(ch, MOB_AGGR_NO_PROP) && (MASTER_ID(ch)==GET_IDNUM(vict))) continue; if (MOB_FLAGGED(ch, MOB_AGGR_NO_CLAN) && (CLAN_ID(ch)==GET_CLAN(vict))) continue; if (MOB_FLAGGED(ch, MOB_AGGR_NO_AL_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == ALLIANCE)) continue; if (MOB_FLAGGED(ch, MOB_AGGR_NO_EN_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == WAR)) continue; if (MOB_FLAGGED(ch, MOB_AGGR_NO_PC_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == PEACE)) continue; if (MOB_FLAGGED(ch, MOB_AGGR_VAS_CLAN) && (GET_CLAN_DIPLO(GET_CLAN(ch),GET_CLAN(vict)) == VASSALLO)) continue; if ( !MOB_FLAGGED(ch, MOB_AGGR_TO_ALIGN) || (MOB_FLAGGED(ch, MOB_AGGR_EVIL) && IS_EVIL(vict)) || (MOB_FLAGGED(ch, MOB_AGGR_NEUTRAL) && IS_NEUTRAL(vict)) || (MOB_FLAGGED(ch, MOB_AGGR_GOOD) && IS_GOOD(vict)) ) { if (GET_MOB_SPEC(ch)== thief) npc_backstab(ch,vict); else hit(ch, vict, TYPE_UNDEFINED); found = TRUE; } } } // Mob Memory if (MOB_FLAGGED(ch, MOB_MEMORY) && MEMORY(ch)) { found = FALSE; for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room) { if (!CAN_SEE(ch, vict) || PRF_FLAGGED(vict, PRF_NOHASSLE)) continue; for (names = MEMORY(ch); names && !found; names = names->next) if (names->id == GET_IDNUM(vict)) { found = TRUE; act("$n esclama, 'Hey!! Tu sei il tipo che mi ha attaccato!!!'", FALSE, ch, 0, 0, TO_ROOM); hit(ch, vict, TYPE_UNDEFINED); } //End forif } } // Helper Mobs Paladino del bene if ( MOB_FLAGGED(ch, MOB_HELPER) && !MOB_FLAGGED(ch, MOB_CRIMINALHELPER) ) { found = FALSE; for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room) if ( ch != vict && IS_NPC(vict) && FIGHTING(vict) && !IS_NPC(FIGHTING(vict)) && ch != FIGHTING(vict) ) { if ( MOB_FLAGGED(vict, MOB_CRIMINAL) || ( (ch->master) && (FIGHTING(vict) == ch->master) ) ) { hit(ch, vict, TYPE_UNDEFINED); found = TRUE; } else { act("$n arriva in aiuto di $N!", FALSE, ch, 0, vict, TO_ROOM); hit(ch, FIGHTING(vict), TYPE_UNDEFINED); found = TRUE; } } //End forif } // Helper Mobs Servo del male if ( MOB_FLAGGED(ch, MOB_CRIMINALHELPER) && !MOB_FLAGGED(ch, MOB_HELPER) ) { found = FALSE; for (vict = world[ch->in_room].people; vict && !found; vict = vict->next_in_room) if ( ch != vict && IS_NPC(vict) && FIGHTING(vict) && !IS_NPC(FIGHTING(vict)) && ch != FIGHTING(vict) ) { if ( MOB_FLAGGED(vict, MOB_CRIMINAL) || ( (ch->master) && (vict == ch->master) ) ) { act("$n arriva in aiuto di $N!", FALSE, ch, 0, vict, TO_ROOM); hit(ch, FIGHTING(vict), TYPE_UNDEFINED); found = TRUE; } } //End forif } // Add new mobile actions here } // end for() }
void auction_update(void) { long clanid, tax; if (auction.ticks == AUC_NONE) /* No auction */ return; /* Seller left! */ if (!get_ch_by_id_desc(auction.seller) && !get_ch_by_id(auction.seller)) { if (auction.obj) extract_obj(auction.obj); auction_reset(); return; } /* If there is an auction but it's not sold yet */ if (auction.ticks >= AUC_BID && auction.ticks <= AUC_SOLD) { struct char_data *bidder = get_ch_by_id(auction.bidder); struct char_data *seller = get_ch_by_id(auction.seller); /* If there is a bidder and it's not sold yet */ if (bidder && (auction.ticks < AUC_SOLD)) { /* Non colored message */ sprintf(buf, "%s all'asta %s%s%s a %s per %ld coin%s.", auction.obj->short_description, auction.ticks == AUC_BID ? "uno" : "", auction.ticks == AUC_ONCE ? "due" : "", auction.ticks == AUC_TWICE ? "ultima chiamata" : "", GET_NAME(bidder), auction.bid, auction.bid != 1 ? "" : " "); /* Colored message */ sprintf(buf2, "\x1B[1;37m%s\x1B[35m all'asta \x1B[1;37m%s%s%s\x1B[35m a \x1B[1;37m%s\x1B[35m per \x1B[1;37m%ld\x1B[35m coin%s.", auction.obj->short_description, auction.ticks == AUC_BID ? "uno" : "", auction.ticks == AUC_ONCE ? "due" : "", auction.ticks == AUC_TWICE ? "ultima chiamata" : "", GET_NAME(bidder), auction.bid, auction.bid != 1 ? "" : " "); /* send the output */ auction_output(buf2, buf); /* Increment timer */ auction.ticks++; return; } /* If there is no bidder and we ARE in the sold state */ if (!bidder && (auction.ticks == AUC_SOLD)) { /* Colored message */ sprintf(buf2, "\x1B[1;37m%s\x1B[35m VENDUTO\x1B[35m a \x1B[1;37mnessuno\x1B[35m per \x1B[1;37m%ld\x1B[35m coin%s.", auction.obj->short_description, auction.bid, auction.bid != 1 ? " " : " "); /* No color message */ sprintf(buf, "%s e' VENDUTO a nessuno per %ld coin%s.", auction.obj->short_description, auction.bid, auction.bid != 1 ? "s" : " "); /* Send the output away */ auction_output(buf2, buf); /* Give the poor fellow his unsold goods back */ if (seller) if ((IS_CARRYING_W(seller) + GET_OBJ_WEIGHT(auction.obj)) <= CAN_CARRY_W(seller)) { act("Nessuno ha comprato $p.", FALSE, seller, auction.obj, 0, TO_CHAR); obj_to_char(auction.obj, seller); } else { /* Cosi' si evitano le aste per diminuire il peso */ act("Nessuno ha comprato $p, ma hai troppo peso e lo devi lasciare per terra.", FALSE, seller, auction.obj, 0, TO_CHAR); obj_to_room(auction.obj, IN_ROOM(seller)); } /* He's not around to get it back, destroy the object */ else extract_obj(auction.obj); /* Reset the auction for next time */ auction_reset(); return; } /* If there is no bidder and we are not in the sold state */ if (!bidder && (auction.ticks < AUC_SOLD)) { /* Colored output message */ sprintf(buf2, "\x1B[1;37m%s\x1B[35m all'asta \x1B[1;37m%s%s%s\x1B[35m a \x1B[1;37mnessuno\x1B[35m per \x1B[1;37m%ld\x1B[35m coin%s.", auction.obj->short_description, auction.ticks == AUC_BID ? "uno" : "", auction.ticks == AUC_ONCE ? "due" : "", auction.ticks == AUC_TWICE ? "ultima chiamata" : "", auction.bid, auction.bid != 1 ? "s" : ""); /* No color output message */ sprintf(buf, "%s all'asta %s%s%s a nessuno per %ld coin%s.", auction.obj->short_description, auction.ticks == AUC_BID ? "uno" : "", auction.ticks == AUC_ONCE ? "due" : "", auction.ticks == AUC_TWICE ? "ultima chiamata" : "", auction.bid, auction.bid != 1 ? "s" : ""); /* Send output away */ auction_output(buf2, buf); /* Increment timer */ auction.ticks++; return; } /* Sold */ if (bidder && (auction.ticks >= AUC_SOLD)) { /* Colored output */ sprintf(buf2, "\x1B[1;37m%s\x1B[35m VENDUTO\x1B[35m a \x1B[1;37m%s\x1B[35m per \x1B[1;37m%ld\x1B[35m coin%s.", auction.obj->short_description ? auction.obj->short_description : "qualcosa", bidder->player.name ? bidder->player.name : "qualcuno", auction.bid, auction.bid != 1 ? " " : ""); /* Non color output */ sprintf(buf, "%s VENDUTO a %s per %ld coin%s.", auction.obj->short_description ? auction.obj->short_description : "something", bidder->player.name ? bidder->player.name : "someone", auction.bid, auction.bid != 1 ? "s" : ""); /* Send the output */ auction_output(buf2, buf); /* If the seller is still around we give him the money */ if (seller) { act("Congrats! Hai venduto $p!", FALSE, seller, auction.obj, 0, TO_CHAR); if ((clanid = find_clan_by_id(GET_CLAN(seller)))>=0) { tax = auction.bid * PERC_TAS_AUC/100; GET_GOLD(seller) += MAX(0,auction.bid - (auction.bid*PERC_TAS_AUC/100)); clan[clanid].economy.treasure += MAX(0,(auction.bid*PERC_TAS_AUC/100)); clan[clanid].economy.current_entrate += MAX(0,(auction.bid*PERC_TAS_AUC/100)); sprintf(buf,"Paghi %ld di tasse al tuo regno per la vendita.", tax); act(buf, FALSE, seller, auction.obj, 0, TO_CHAR); } else GET_GOLD(seller) += auction.bid; } /* If the bidder is here he gets the object */ if (bidder) { obj_to_char(auction.obj, bidder); act("Congrats! Ora hai $p!", FALSE, bidder, auction.obj, 0, TO_CHAR); } /* Restore the status of the auction */ auction_reset(); return; } } return; }
struct creature * load_player_from_file(const char *path) { struct creature *ch = NULL; char *txt; if (access(path, W_OK)) { errlog("Unable to open xml player file '%s': %s", path, strerror(errno)); return NULL; } xmlDocPtr doc = xmlParseFile(path); if (!doc) { errlog("XML parse error while loading %s", path); return NULL; } xmlNodePtr root = xmlDocGetRootElement(doc); if (!root) { xmlFreeDoc(doc); errlog("XML file %s is empty", path); return NULL; } /* to save memory, only PC's -- not MOB's -- have player_specials */ ch = make_creature(true); ch->player.name = (char *)xmlGetProp(root, (xmlChar *) "name"); ch->char_specials.saved.idnum = xmlGetIntProp(root, "idnum", 0); set_title(ch, ""); ch->player.short_descr = NULL; ch->player.long_descr = NULL; if (ch->points.max_mana < 100) ch->points.max_mana = 100; ch->char_specials.carry_weight = 0; ch->char_specials.carry_items = 0; ch->char_specials.worn_weight = 0; ch->points.armor = 100; ch->points.hitroll = 0; ch->points.damroll = 0; ch->player_specials->saved.speed = 0; // Read in the subnodes for (xmlNodePtr node = root->xmlChildrenNode; node; node = node->next) { if (xmlMatches(node->name, "points")) { ch->points.mana = xmlGetIntProp(node, "mana", 100); ch->points.max_mana = xmlGetIntProp(node, "maxmana", 100); ch->points.hit = xmlGetIntProp(node, "hit", 100); ch->points.max_hit = xmlGetIntProp(node, "maxhit", 100); ch->points.move = xmlGetIntProp(node, "move", 100); ch->points.max_move = xmlGetIntProp(node, "maxmove", 100); } else if (xmlMatches(node->name, "money")) { ch->points.gold = xmlGetIntProp(node, "gold", 0); ch->points.cash = xmlGetIntProp(node, "cash", 0); ch->points.exp = xmlGetIntProp(node, "xp", 0); } else if (xmlMatches(node->name, "stats")) { ch->player.level = xmlGetIntProp(node, "level", 0); ch->player.height = xmlGetIntProp(node, "height", 0); ch->player.weight = xmlGetIntProp(node, "weight", 0); GET_ALIGNMENT(ch) = xmlGetIntProp(node, "align", 0); /*** Temp fix for negative weights ***/ if (ch->player.weight < 0) { calculate_height_weight(ch); } GET_SEX(ch) = 0; char *sex = (char *)xmlGetProp(node, (xmlChar *) "sex"); if (sex != NULL) GET_SEX(ch) = search_block(sex, genders, false); free(sex); GET_RACE(ch) = 0; char *race_name = (char *)xmlGetProp(node, (xmlChar *) "race"); if (race_name != NULL) { struct race *race = race_by_name(race_name, true); if (race != NULL) { GET_RACE(ch) = race->idnum; } } free(race_name); } else if (xmlMatches(node->name, "class")) { GET_OLD_CLASS(ch) = GET_REMORT_CLASS(ch) = GET_CLASS(ch) = -1; char *trade = (char *)xmlGetProp(node, (xmlChar *) "name"); if (trade != NULL) { GET_CLASS(ch) = search_block(trade, class_names, false); free(trade); } trade = (char *)xmlGetProp(node, (xmlChar *) "remort"); if (trade != NULL) { GET_REMORT_CLASS(ch) = search_block(trade, class_names, false); free(trade); } if (IS_CYBORG(ch)) { char *subclass = (char *)xmlGetProp(node, (xmlChar *) "subclass"); if (subclass != NULL) { GET_OLD_CLASS(ch) = search_block(subclass, borg_subchar_class_names, false); free(subclass); } } if (GET_CLASS(ch) == CLASS_MAGE) { ch->player_specials->saved.mana_shield_low = xmlGetLongProp(node, "manash_low", 0); ch->player_specials->saved.mana_shield_pct = xmlGetLongProp(node, "manash_pct", 0); } GET_REMORT_GEN(ch) = xmlGetIntProp(node, "gen", 0); GET_TOT_DAM(ch) = xmlGetIntProp(node, "total_dam", 0); GET_BROKE(ch) = xmlGetIntProp(node, "broken", 0); } else if (xmlMatches(node->name, "time")) { ch->player.time.birth = xmlGetLongProp(node, "birth", 0); ch->player.time.death = xmlGetLongProp(node, "death", 0); ch->player.time.played = xmlGetLongProp(node, "played", 0); ch->player.time.logon = xmlGetLongProp(node, "last", 0); } else if (xmlMatches(node->name, "carnage")) { GET_PKILLS(ch) = xmlGetIntProp(node, "pkills", 0); GET_ARENAKILLS(ch) = xmlGetIntProp(node, "akills", 0); GET_MOBKILLS(ch) = xmlGetIntProp(node, "mkills", 0); GET_PC_DEATHS(ch) = xmlGetIntProp(node, "deaths", 0); RAW_REPUTATION_OF(ch) = xmlGetIntProp(node, "reputation", 0); GET_SEVERITY(ch) = xmlGetIntProp(node, "severity", 0); } else if (xmlMatches(node->name, "attr")) { ch->aff_abils.str = ch->real_abils.str = xmlGetIntProp(node, "str", 0); ch->aff_abils.str = ch->real_abils.str += xmlGetIntProp(node, "stradd", 0) / 10; ch->aff_abils.intel = ch->real_abils.intel = xmlGetIntProp(node, "int", 0); ch->aff_abils.wis = ch->real_abils.wis = xmlGetIntProp(node, "wis", 0); ch->aff_abils.dex = ch->real_abils.dex = xmlGetIntProp(node, "dex", 0); ch->aff_abils.con = ch->real_abils.con = xmlGetIntProp(node, "con", 0); ch->aff_abils.cha = ch->real_abils.cha = xmlGetIntProp(node, "cha", 0); } else if (xmlMatches(node->name, "condition")) { GET_COND(ch, THIRST) = xmlGetIntProp(node, "thirst", 0); GET_COND(ch, FULL) = xmlGetIntProp(node, "hunger", 0); GET_COND(ch, DRUNK) = xmlGetIntProp(node, "drunk", 0); } else if (xmlMatches(node->name, "player")) { GET_WIMP_LEV(ch) = xmlGetIntProp(node, "wimpy", 0); GET_LIFE_POINTS(ch) = xmlGetIntProp(node, "lp", 0); GET_CLAN(ch) = xmlGetIntProp(node, "clan", 0); } else if (xmlMatches(node->name, "home")) { GET_HOME(ch) = xmlGetIntProp(node, "town", 0); GET_HOMEROOM(ch) = xmlGetIntProp(node, "homeroom", 0); GET_LOADROOM(ch) = xmlGetIntProp(node, "loadroom", 0); } else if (xmlMatches(node->name, "quest")) { GET_QUEST(ch) = xmlGetIntProp(node, "current", 0); GET_IMMORT_QP(ch) = xmlGetIntProp(node, "points", 0); GET_QUEST_ALLOWANCE(ch) = xmlGetIntProp(node, "allowance", 0); } else if (xmlMatches(node->name, "bits")) { char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1"); ch->char_specials.saved.act = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag2"); ch->player_specials->saved.plr2_bits = hex2dec(flag); free(flag); } else if (xmlMatches(node->name, "frozen")) { ch->player_specials->thaw_time = xmlGetIntProp(node, "thaw_time", 0); ch->player_specials->freezer_id = xmlGetIntProp(node, "freezer_id", 0); } else if (xmlMatches(node->name, "prefs")) { char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1"); ch->player_specials->saved.pref = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag2"); ch->player_specials->saved.pref2 = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "tongue"); if (flag) GET_TONGUE(ch) = find_tongue_idx_by_name(flag); free(flag); } else if (xmlMatches(node->name, "weaponspec")) { int vnum = xmlGetIntProp(node, "vnum", -1); int level = xmlGetIntProp(node, "level", 0); if (vnum > 0 && level > 0) { for (int i = 0; i < MAX_WEAPON_SPEC; i++) { if (GET_WEAP_SPEC(ch, i).level <= 0) { GET_WEAP_SPEC(ch, i).vnum = vnum; GET_WEAP_SPEC(ch, i).level = level; break; } } } } else if (xmlMatches(node->name, "title")) { char *txt; txt = (char *)xmlNodeGetContent(node); set_title(ch, txt); free(txt); } else if (xmlMatches(node->name, "affect")) { struct affected_type af; init_affect(&af); af.type = xmlGetIntProp(node, "type", 0); af.duration = xmlGetIntProp(node, "duration", 0); af.modifier = xmlGetIntProp(node, "modifier", 0); af.location = xmlGetIntProp(node, "location", 0); af.level = xmlGetIntProp(node, "level", 0); af.aff_index = xmlGetIntProp(node, "index", 0); af.owner = xmlGetIntProp(node, "owner", 0); af.next = NULL; char *instant = (char *)xmlGetProp(node, (xmlChar *) "instant"); if (instant != NULL && strcmp(instant, "yes") == 0) { af.is_instant = 1; } free(instant); char *bits = (char *)xmlGetProp(node, (xmlChar *) "affbits"); af.bitvector = hex2dec(bits); free(bits); affect_to_char(ch, &af); } else if (xmlMatches(node->name, "affects")) { // PCs shouldn't have ANY perm affects if (IS_NPC(ch)) { char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1"); AFF_FLAGS(ch) = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag2"); AFF2_FLAGS(ch) = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag3"); AFF3_FLAGS(ch) = hex2dec(flag); free(flag); } else { AFF_FLAGS(ch) = 0; AFF2_FLAGS(ch) = 0; AFF3_FLAGS(ch) = 0; } } else if (xmlMatches(node->name, "skill")) { char *spellName = (char *)xmlGetProp(node, (xmlChar *) "name"); int index = str_to_spell(spellName); if (index >= 0) { SET_SKILL(ch, index, xmlGetIntProp(node, "level", 0)); } free(spellName); } else if (xmlMatches(node->name, "tongue")) { char *tongue = (char *)xmlGetProp(node, (xmlChar *) "name"); int index = find_tongue_idx_by_name(tongue); if (index >= 0) SET_TONGUE(ch, index, MIN(100, xmlGetIntProp(node, "level", 0))); free(tongue); } else if (xmlMatches(node->name, "alias")) { struct alias_data *alias; CREATE(alias, struct alias_data, 1); alias->type = xmlGetIntProp(node, "type", 0); alias->alias = (char *)xmlGetProp(node, (xmlChar *) "alias"); alias->replacement = (char *)xmlGetProp(node, (xmlChar *) "replace"); if (alias->alias == NULL || alias->replacement == NULL) { free(alias); } else { add_alias(ch, alias); } } else if (xmlMatches(node->name, "description")) { txt = (char *)xmlNodeGetContent(node); ch->player.description = strdup(tmp_gsub(txt, "\n", "\r\n")); free(txt); } else if (xmlMatches(node->name, "poofin")) { POOFIN(ch) = (char *)xmlNodeGetContent(node); } else if (xmlMatches(node->name, "poofout")) { POOFOUT(ch) = (char *)xmlNodeGetContent(node); } else if (xmlMatches(node->name, "immort")) { txt = (char *)xmlGetProp(node, (xmlChar *) "badge"); strncpy(BADGE(ch), txt, 7); BADGE(ch)[7] = '\0'; free(txt); GET_QLOG_LEVEL(ch) = xmlGetIntProp(node, "qlog", 0); GET_INVIS_LVL(ch) = xmlGetIntProp(node, "invis", 0); } else if (xmlMatches(node->name, "rent")) { char *txt; ch->player_specials->rentcode = xmlGetIntProp(node, "code", 0); ch->player_specials->rent_per_day = xmlGetIntProp(node, "perdiem", 0); ch->player_specials->rent_currency = xmlGetIntProp(node, "currency", 0); txt = (char *)xmlGetProp(node, (xmlChar *) "state"); if (txt) ch->player_specials->desc_mode = (enum cxn_state)search_block(txt, desc_modes, false); free(txt); } else if (xmlMatches(node->name, "recentkill")) { struct kill_record *kill; CREATE(kill, struct kill_record, 1); kill->vnum = xmlGetIntProp(node, "vnum", 0); kill->times = xmlGetIntProp(node, "times", 0); GET_RECENT_KILLS(ch) = g_list_prepend(GET_RECENT_KILLS(ch), kill); } else if (xmlMatches(node->name, "grievance")) {
void save_player_to_file(struct creature *ch, const char *path) { void expire_old_grievances(struct creature *); // Save vital statistics FILE *ouf; char *tmp_path; struct alias_data *cur_alias; int idx; int hit = GET_HIT(ch), mana = GET_MANA(ch), move = GET_MOVE(ch); tmp_path = tmp_sprintf("%s.tmp", path); ouf = fopen(tmp_path, "w"); if (!ouf) { fprintf(stderr, "Unable to open XML player file for save.[%s] (%s)\n", path, strerror(errno)); return; } struct aff_stash *aff_stash = stash_creature_affects(ch); expire_old_grievances(ch); fprintf(ouf, "<creature name=\"%s\" idnum=\"%ld\">\n", GET_NAME(ch), ch->char_specials.saved.idnum); fprintf(ouf, "<points hit=\"%d\" mana=\"%d\" move=\"%d\" maxhit=\"%d\" maxmana=\"%d\" maxmove=\"%d\"/>\n", ch->points.hit, ch->points.mana, ch->points.move, ch->points.max_hit, ch->points.max_mana, ch->points.max_move); fprintf(ouf, "<money gold=\"%" PRId64 "\" cash=\"%" PRId64 "\" xp=\"%d\"/>\n", ch->points.gold, ch->points.cash, ch->points.exp); fprintf(ouf, "<stats level=\"%d\" sex=\"%s\" race=\"%s\" height=\"%d\" weight=\"%f\" align=\"%d\"/>\n", GET_LEVEL(ch), genders[(int)GET_SEX(ch)], race_name_by_idnum(GET_RACE(ch)), GET_HEIGHT(ch), GET_WEIGHT(ch), GET_ALIGNMENT(ch)); fprintf(ouf, "<class name=\"%s\"", class_names[GET_CLASS(ch)]); if (GET_REMORT_CLASS(ch) != CLASS_UNDEFINED) fprintf(ouf, " remort=\"%s\"", class_names[GET_REMORT_CLASS(ch)]); if (GET_REMORT_GEN(ch) > 0) fprintf(ouf, " gen=\"%d\"", GET_REMORT_GEN(ch)); if (IS_CYBORG(ch)) { if (GET_OLD_CLASS(ch) != -1) fprintf(ouf, " subclass=\"%s\"", borg_subchar_class_names[GET_OLD_CLASS(ch)]); if (GET_TOT_DAM(ch)) fprintf(ouf, " total_dam=\"%d\"", GET_TOT_DAM(ch)); if (GET_BROKE(ch)) fprintf(ouf, " broken=\"%d\"", GET_BROKE(ch)); } if (GET_CLASS(ch) == CLASS_MAGE && GET_SKILL(ch, SPELL_MANA_SHIELD) > 0) { fprintf(ouf, " manash_low=\"%ld\" manash_pct=\"%ld\"", ch->player_specials->saved.mana_shield_low, ch->player_specials->saved.mana_shield_pct); } fprintf(ouf, "/>\n"); fprintf(ouf, "<time birth=\"%ld\" death=\"%ld\" played=\"%ld\" last=\"%ld\"/>\n", ch->player.time.birth, ch->player.time.death, ch->player.time.played, ch->player.time.logon); fprintf(ouf, "<carnage pkills=\"%d\" akills=\"%d\" mkills=\"%d\" deaths=\"%d\" reputation=\"%d\"", GET_PKILLS(ch), GET_ARENAKILLS(ch), GET_MOBKILLS(ch), GET_PC_DEATHS(ch), ch->player_specials->saved.reputation); fprintf(ouf, "/>\n"); fprintf(ouf, "<attr str=\"%d\" int=\"%d\" wis=\"%d\" dex=\"%d\" con=\"%d\" cha=\"%d\"/>\n", ch->real_abils.str, ch->real_abils.intel, ch->real_abils.wis, ch->real_abils.dex, ch->real_abils.con, ch->real_abils.cha); fprintf(ouf, "<condition hunger=\"%d\" thirst=\"%d\" drunk=\"%d\"/>\n", GET_COND(ch, FULL), GET_COND(ch, THIRST), GET_COND(ch, DRUNK)); fprintf(ouf, "<player wimpy=\"%d\" lp=\"%d\" clan=\"%d\"/>\n", GET_WIMP_LEV(ch), GET_LIFE_POINTS(ch), GET_CLAN(ch)); if (ch->desc) ch->player_specials->desc_mode = ch->desc->input_mode; if (ch->player_specials->rentcode == RENT_CREATING || ch->player_specials->rentcode == RENT_REMORTING) { fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" " "currency=\"%d\" state=\"%s\"/>\n", ch->player_specials->rentcode, ch->player_specials->rent_per_day, ch->player_specials->rent_currency, desc_modes[(int)ch->player_specials->desc_mode]); } else { fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" currency=\"%d\"/>\n", ch->player_specials->rentcode, ch->player_specials->rent_per_day, ch->player_specials->rent_currency); } fprintf(ouf, "<home town=\"%d\" homeroom=\"%d\" loadroom=\"%d\"/>\n", GET_HOME(ch), GET_HOMEROOM(ch), GET_LOADROOM(ch)); fprintf(ouf, "<quest"); if (GET_QUEST(ch)) fprintf(ouf, " current=\"%d\"", GET_QUEST(ch)); if (GET_LEVEL(ch) >= LVL_IMMORT) fprintf(ouf, " allowance=\"%d\"", GET_QUEST_ALLOWANCE(ch)); if (GET_IMMORT_QP(ch) != 0) fprintf(ouf, " points=\"%d\"", GET_IMMORT_QP(ch)); fprintf(ouf, "/>\n"); fprintf(ouf, "<bits flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\"/>\n", ch->char_specials.saved.act, ch->player_specials->saved.plr2_bits); if (PLR_FLAGGED(ch, PLR_FROZEN)) { fprintf(ouf, "<frozen thaw_time=\"%d\" freezer_id=\"%d\"/>\n", ch->player_specials->thaw_time, ch->player_specials->freezer_id); } fprintf(ouf, "<prefs flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" tongue=\"%s\"/>\n", ch->player_specials->saved.pref, ch->player_specials->saved.pref2, tongue_name(GET_TONGUE(ch))); fprintf(ouf, "<affects flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" flag3=\"%" PRIx32 "\"/>\n", ch->char_specials.saved.affected_by, ch->char_specials.saved.affected2_by, ch->char_specials.saved.affected3_by); for (idx = 0; idx < MAX_WEAPON_SPEC; idx++) { if (GET_WEAP_SPEC(ch, idx).level > 0) fprintf(ouf, "<weaponspec vnum=\"%d\" level=\"%d\"/>\n", GET_WEAP_SPEC(ch, idx).vnum, GET_WEAP_SPEC(ch, idx).level); } if (GET_TITLE(ch) && *GET_TITLE(ch)) { fprintf(ouf, "<title>%s</title>\n", xmlEncodeTmp(GET_TITLE(ch))); } if (GET_LEVEL(ch) >= 50) { fprintf(ouf, "<immort badge=\"%s\" qlog=\"%d\" invis=\"%d\"/>\n", xmlEncodeSpecialTmp(BADGE(ch)), GET_QLOG_LEVEL(ch), GET_INVIS_LVL(ch)); if (POOFIN(ch) && *POOFIN(ch)) fprintf(ouf, "<poofin>%s</poofin>\n", xmlEncodeTmp(POOFIN(ch))); if (POOFOUT(ch) && *POOFOUT(ch)) fprintf(ouf, "<poofout>%s</poofout>\n", xmlEncodeTmp(POOFOUT(ch))); } if (ch->player.description && *ch->player.description) { fprintf(ouf, "<description>%s</description>\n", xmlEncodeTmp(tmp_gsub(tmp_gsub(ch->player.description, "\r\n", "\n"), "\r", ""))); } for (cur_alias = ch->player_specials->aliases; cur_alias; cur_alias = cur_alias->next) fprintf(ouf, "<alias type=\"%d\" alias=\"%s\" replace=\"%s\"/>\n", cur_alias->type, xmlEncodeSpecialTmp(cur_alias->alias), xmlEncodeSpecialTmp(cur_alias->replacement)); for (struct affected_type *cur_aff = aff_stash->saved_affs; cur_aff; cur_aff = cur_aff->next) fprintf(ouf, "<affect type=\"%d\" duration=\"%d\" modifier=\"%d\" location=\"%d\" level=\"%d\" instant=\"%s\" affbits=\"%lx\" index=\"%d\" owner=\"%ld\"/>\n", cur_aff->type, cur_aff->duration, cur_aff->modifier, cur_aff->location, cur_aff->level, (cur_aff->is_instant) ? "yes" : "no", cur_aff->bitvector, cur_aff->aff_index, cur_aff->owner); if (!IS_IMMORT(ch)) { for (idx = 0; idx < MAX_SKILLS; idx++) if (ch->player_specials->saved.skills[idx] > 0) fprintf(ouf, "<skill name=\"%s\" level=\"%d\"/>\n", spell_to_str(idx), GET_SKILL(ch, idx)); write_tongue_xml(ch, ouf); for (GList * it = GET_RECENT_KILLS(ch); it; it = it->next) { struct kill_record *kill = it->data; fprintf(ouf, "<recentkill vnum=\"%d\" times=\"%d\"/>\n", kill->vnum, kill->times); } for (GList * it = GET_GRIEVANCES(ch); it; it = it->next) { struct grievance *grievance = it->data; fprintf(ouf, "<grievance time=\"%lu\" player=\"%d\" reputation=\"%d\" kind=\"%s\"/>\n", (long unsigned)grievance->time, grievance->player_id, grievance->rep, grievance_kind_descs[grievance->grievance]); } } if (IS_PC(ch) && ch->player_specials->tags) { GHashTableIter iter; char *key; g_hash_table_iter_init(&iter, ch->player_specials->tags); while (g_hash_table_iter_next(&iter, (gpointer *)&key, NULL)) { fprintf(ouf, "<tag tag=\"%s\"/>\n", key); } } fprintf(ouf, "</creature>\n"); fclose(ouf); // on success, move temp file on top of the old file rename(tmp_path, path); restore_creature_affects(ch, aff_stash); free(aff_stash); GET_HIT(ch) = MIN(GET_MAX_HIT(ch), hit); GET_MANA(ch) = MIN(GET_MAX_MANA(ch), mana); GET_MOVE(ch) = MIN(GET_MAX_MOVE(ch), move); }