/** * Apply pet's new name. * @param sd : player requesting * @param name : new pet name * @return 0:success, 1:failure */ int pet_change_name(struct map_session_data *sd,char *name) { int i; struct pet_data *pd; nullpo_retr(1, sd); pd = sd->pd; if((pd == NULL) || (pd->pet.rename_flag == 1 && !battle_config.pet_rename)) return 1; for(i = 0; i < NAME_LENGTH && name[i]; i++) { if( !(name[i]&0xe0) || name[i]==0x7f) return 1; } return intif_rename_pet(sd, name); }
/** * Begin hatching a pet. * @param sd : player requesting * @param pet : pet requesting */ int pet_birth_process(struct map_session_data *sd, struct s_pet *pet) { nullpo_retr(1, sd); Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->master == sd); if(sd->status.pet_id && pet->incubate == 1) { sd->status.pet_id = 0; return 1; } pet->incubate = 0; pet->account_id = sd->status.account_id; pet->char_id = sd->status.char_id; sd->status.pet_id = pet->pet_id; if(pet_data_init(sd, pet)) { sd->status.pet_id = 0; return 1; } intif_save_petdata(sd->status.account_id,pet); if (save_settings&8) chrif_save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex] if(sd->bl.prev != NULL) { if(map_addblock(&sd->pd->bl)) return 1; clif_spawn(&sd->pd->bl); clif_send_petdata(sd,sd->pd, 0,0); clif_send_petdata(sd,sd->pd, 5,battle_config.pet_hair_style); clif_pet_equip_area(sd->pd); clif_send_petstatus(sd); } Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->master == sd); return 0; }
bool mapif_elemental_load(int ele_id, int char_id, struct s_elemental *ele) { char* data; nullpo_retr(false, ele); memset(ele, 0, sizeof(struct s_elemental)); ele->elemental_id = ele_id; ele->char_id = char_id; if( SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `class`, `mode`, `hp`, `sp`, `max_hp`, `max_sp`, `atk1`, `atk2`, `matk`, `aspd`," "`def`, `mdef`, `flee`, `hit`, `life_time` FROM `%s` WHERE `ele_id` = '%d' AND `char_id` = '%d'", elemental_db, ele_id, char_id) ) { Sql_ShowDebug(inter->sql_handle); return false; } if( SQL_SUCCESS != SQL->NextRow(inter->sql_handle) ) { SQL->FreeResult(inter->sql_handle); return false; } SQL->GetData(inter->sql_handle, 0, &data, NULL); ele->class_ = atoi(data); SQL->GetData(inter->sql_handle, 1, &data, NULL); ele->mode = atoi(data); SQL->GetData(inter->sql_handle, 2, &data, NULL); ele->hp = atoi(data); SQL->GetData(inter->sql_handle, 3, &data, NULL); ele->sp = atoi(data); SQL->GetData(inter->sql_handle, 4, &data, NULL); ele->max_hp = atoi(data); SQL->GetData(inter->sql_handle, 5, &data, NULL); ele->max_sp = atoi(data); SQL->GetData(inter->sql_handle, 6, &data, NULL); ele->atk = atoi(data); SQL->GetData(inter->sql_handle, 7, &data, NULL); ele->atk2 = atoi(data); SQL->GetData(inter->sql_handle, 8, &data, NULL); ele->matk = atoi(data); SQL->GetData(inter->sql_handle, 9, &data, NULL); ele->amotion = atoi(data); SQL->GetData(inter->sql_handle, 10, &data, NULL); ele->def = atoi(data); SQL->GetData(inter->sql_handle, 11, &data, NULL); ele->mdef = atoi(data); SQL->GetData(inter->sql_handle, 12, &data, NULL); ele->flee = atoi(data); SQL->GetData(inter->sql_handle, 13, &data, NULL); ele->hit = atoi(data); SQL->GetData(inter->sql_handle, 14, &data, NULL); ele->life_time = atoi(data); SQL->FreeResult(inter->sql_handle); if( save_log ) ShowInfo("Elemental carregado (%d - %d).\n", ele->elemental_id, ele->char_id); return true; }
int party_invite(struct map_session_data *sd,struct map_session_data *tsd) { struct party_data *p=party_search(sd->status.party_id); int i,flag=0; nullpo_retr(0, sd); if(tsd==NULL || p==NULL) return 0; if(!battle_config.invite_request_check) { if (tsd->guild_invite>0 || tsd->trade_partner) { clif_party_inviteack(sd,tsd->status.name,0); return 0; } } if( tsd->status.party_id>0 || tsd->party_invite>0 ){ clif_party_inviteack(sd,tsd->status.name,0); return 0; } for(i=0;i<MAX_PARTY;i++){ if(p->party.member[i].account_id == 0) //Room for a new member. flag = 1; /* By default Aegis BLOCKS more than one char from the same account on a party. * But eA does support it... so this check is left commented. if(p->party.member[i].account_id==tsd->status.account_id) { clif_party_inviteack(sd,tsd->status.name,4); return 0; } */ } if (!flag) { //Full party. clif_party_inviteack(sd,tsd->status.name,3); return 0; } tsd->party_invite=sd->status.party_id; tsd->party_invite_account=sd->status.account_id; clif_party_invite(sd,tsd); return 1; }
/*========================================== * npcチャットルーム作成 *------------------------------------------ */ int chat_createnpcchat(struct npc_data *nd,int limit,int pub,int trigger,char* title,int titlelen,const char *ev) { struct chat_data *cd; nullpo_retr(1, nd); cd = (struct chat_data *) aCalloc(1,sizeof(struct chat_data)); cd->limit = cd->trigger = limit; if(trigger>0) cd->trigger = trigger; cd->pub = pub; cd->users = 0; memcpy(cd->pass,"",1); if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1; memcpy(cd->title,title,titlelen); cd->title[titlelen]=0; cd->bl.m = nd->bl.m; cd->bl.x = nd->bl.x; cd->bl.y = nd->bl.y; cd->bl.type = BL_CHAT; cd->owner_ = (struct block_list *)nd; cd->owner = &cd->owner_; if (strlen(ev) > 49) { //npc_event is a char[50] [Skotlex] memcpy(cd->npc_event,ev,49); cd->npc_event[49] = '\0'; } else memcpy(cd->npc_event,ev,strlen(ev)); cd->bl.id = map_addobject(&cd->bl); if(cd->bl.id==0){ aFree(cd); return 0; } nd->chat_id=cd->bl.id; clif_dispchat(cd,0); return 0; }
int pet_birth_process(struct map_session_data *sd, struct s_pet *pet) { char pet_output[1024]; // Declaracion de char para Invocacion Pet's [Tab] nullpo_retr(1, sd); Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); if(sd->status.pet_id && pet->incuvate == 1) { sd->status.pet_id = 0; return 1; } pet->incuvate = 0; pet->account_id = sd->status.account_id; pet->char_id = sd->status.char_id; sd->status.pet_id = pet->pet_id; if(pet_data_init(sd, pet)) { sd->status.pet_id = 0; return 1; } intif_save_petdata(sd->status.account_id,pet); if (save_settings&8) chrif_save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex] if(sd->bl.prev != NULL) { map_addblock(&sd->pd->bl); clif_spawn(&sd->pd->bl); clif_send_petdata(sd,sd->pd, 0,0); clif_send_petdata(sd,sd->pd, 5,battle_config.pet_hair_style); clif_pet_equip_area(sd->pd); clif_send_petstatus(sd); } Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); clif_misceffect(&sd->pd->bl, 0); // Efecto 1 de nacimiento [Tab] clif_misceffect(&sd->pd->bl, 344); // Efecto 2 de nacimiento [Tab] sprintf(pet_output,"Get Out %s... NOW!",pet->name); // Cuidado aca con el nombre del pet clif_displaymessage(sd->fd, pet_output); // Frase nacimiento [Tab] return 0; }
// ギルド敵対 int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd) { struct guild *g; int i; nullpo_retr(0, sd); g=guild_search(sd->status.guild_id); if(g==NULL || tsd==NULL) return 0; // Prevent creation opposition with same guilds [LuzZza] if(sd->status.guild_id == tsd->status.guild_id) return 0; if( guild_get_alliance_count(g,1)>=3 ) { clif_guild_oppositionack(sd,1); return 0; } if(agit_flag) { clif_displaymessage(sd->fd,"You cannot make oppositions during Guild Wars!"); return 0; } for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに関係を持っているか確認 if(g->alliance[i].guild_id==tsd->status.guild_id){ if(g->alliance[i].opposition==1){ // すでに敵対 clif_guild_oppositionack(sd,2); return 0; } //Change alliance to opposition. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, sd->status.account_id,tsd->status.account_id,8 ); } } // inter鯖に敵対要請 intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, sd->status.account_id,tsd->status.account_id,1 ); return 0; }
// ギルドへの勧誘 int guild_invite(struct map_session_data *sd,int account_id) { struct map_session_data *tsd; struct guild *g; int i; nullpo_retr(0, sd); tsd= map_id2sd(account_id); g=guild_search(sd->status.guild_id); if(tsd==NULL || g==NULL) return 0; if(!battle_config.invite_request_check) { if (tsd->party_invite>0 || tsd->trade_partner) { // 相手が取引中かどうか clif_guild_inviteack(sd,0); return 0; } } if(tsd->status.guild_id>0 || tsd->guild_invite>0 || map[tsd->bl.m].flag.gvg_castle) { //Can't invite people inside castles. [Skotlex] clif_guild_inviteack(sd,0); return 0; } // 定員確認 for(i=0;i<g->max_member;i++) if(g->member[i].account_id==0) break; if(i==g->max_member){ clif_guild_inviteack(sd,3); return 0; } tsd->guild_invite=sd->status.guild_id; tsd->guild_invite_account=sd->status.account_id; clif_guild_invite(tsd,g); return 0; }
/** * Change a chat room's owner. * @param sd : player requesting * @param nextownername : string of new owner (name should be in chatroom) * @return 0:success, 1:failure */ int chat_changechatowner(struct map_session_data* sd, const char* nextownername) { struct chat_data* cd; struct map_session_data* tmpsd; int i; nullpo_retr(1, sd); cd = (struct chat_data*)map_id2bl(sd->chatID); if( cd == NULL || (struct block_list*) sd != cd->owner ) return 1; ARR_FIND( 1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0 ); if( i == cd->users ) return -1; // name not found // erase temporarily clif_clearchat(cd,0); // set new owner cd->owner = (struct block_list*) cd->usersd[i]; clif_changechatowner(cd,cd->usersd[i]); // swap the old and new owners' positions tmpsd = cd->usersd[i]; cd->usersd[i] = cd->usersd[0]; cd->usersd[0] = tmpsd; // set the new chatroom position map_delblock( &cd->bl ); cd->bl.x = cd->owner->x; cd->bl.y = cd->owner->y; if(map_addblock( &cd->bl )) return 1; // and display again clif_dispchat(cd,0); return 0; }
int party_created(int account_id, int fail, intptr_t party_id, char *name) { struct map_session_data *sd; sd = map_id2sd(account_id); nullpo_retr(0, sd); if (fail == 0) { struct party *p; sd->status.party_id = party_id; if ((p = numdb_search(party_db, party_id)) != NULL) { printf("party: id already exists!\n"); exit(1); } CALLOC(p, struct party, 1); p->party_id = party_id; strncpy(p->name, name, 24); numdb_insert(party_db,party_id, p); clif_party_created(sd, 0); // 0xfa <flag>.B: 0: Party has successfully been organized, 1: That Party Name already exists., 2: The Character is already in a party. } else {
/** * Creates a new homunculus with the given data. * * @remark * The homunculus ID is expected to be 0, and will be filled with the newly * assigned ID. * * @param[in,out] hd The new homunculus' data. * @retval false in case of errors. */ bool mapif_homunculus_create(struct s_homunculus *hd) { char esc_name[NAME_LENGTH*2+1]; nullpo_retr(false, hd); Assert_retr(false, hd->hom_id == 0); SQL->EscapeStringLen(inter->sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH)); if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` " "(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) " "VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')", homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize)) { Sql_ShowDebug(inter->sql_handle); return false; } hd->hom_id = (int)SQL->LastInsertId(inter->sql_handle); return true; }
/*========================================== * ギルド倉庫データのセーブ *------------------------------------------ */ bool gstoragedb_txt_save(struct guild_storage *gs2, int easy) { struct guild_storage *gs1; nullpo_retr(false, gs2); gs1 = (struct guild_storage *)numdb_search(gstorage_db,gs2->guild_id); if(gs1 == NULL) { gs1 = (struct guild_storage *)aCalloc(1, sizeof(struct guild_storage)); gs1->guild_id = gs2->guild_id; gs1->last_fd = -1; numdb_insert(gstorage_db, gs1->guild_id, gs1); } memcpy(gs1, gs2, sizeof(struct guild_storage)); #ifdef TXT_JOURNAL if( storage_journal_enable ) journal_write( &storage_journal, gs1->guild_id, gs1 ); #endif return true; }
// パーティ勧誘への返答 int party_reply_invite(struct map_session_data *sd,int account_id,int flag) { struct map_session_data *tsd= map_id2sd(account_id); nullpo_retr(0, sd); if(flag==1){ // 承諾 //inter鯖へ追加要求 intif_party_addmember( sd->party_invite, sd->status.account_id ); return 0; } else { // 拒否 sd->party_invite=0; sd->party_invite_account=0; if(tsd==NULL) return 0; clif_party_inviteack(tsd,sd->status.name,1); } return 0; }
// 位置やHP通知用 int party_send_xy_timer_sub(void *key,void *data,va_list ap) { struct party *p=(struct party *)data; int i; nullpo_retr(0, p); for(i=0;i<MAX_PARTY;i++){ struct map_session_data *sd; if((sd=p->member[i].sd)!=NULL){ // 座標通知 if(sd->party_x!=sd->bl.x || sd->party_y!=sd->bl.y){ clif_party_xy(sd); sd->party_x=sd->bl.x; sd->party_y=sd->bl.y; } } } return 0; }
// ギルド解散通知用 int guild_broken_sub(DBKey key,void *data,va_list ap) { struct guild *g=(struct guild *)data; int guild_id=va_arg(ap,int); int i,j; struct map_session_data *sd=NULL; nullpo_retr(0, g); for(i=0;i<MAX_GUILDALLIANCE;i++){ // 関係を破棄 if(g->alliance[i].guild_id==guild_id){ for(j=0;j<g->max_member;j++) if( (sd=g->member[j].sd)!=NULL ) clif_guild_delalliance(sd,guild_id,g->alliance[i].opposition); intif_guild_alliance(g->guild_id, guild_id,0,0,g->alliance[i].opposition|8); g->alliance[i].guild_id=0; } } return 0; }
//Taken from party_send_xy_timer_sub. [Skotlex] int guild_send_xy_timer_sub(DBKey key,void *data,va_list ap) { struct guild *g=(struct guild *)data; int i; nullpo_retr(0, g); for(i=0;i<g->max_member;i++){ //struct map_session_data* sd = g->member[i].sd; struct map_session_data* sd = map_charid2sd(g->member[i].char_id); // temporary crashfix if( sd != NULL ) { if(sd->guild_x!=sd->bl.x || sd->guild_y!=sd->bl.y){ clif_guild_xy(sd); sd->guild_x=sd->bl.x; sd->guild_y=sd->bl.y; } } } return 0; }
// ギルド脱退要求 int guild_leave(struct map_session_data *sd,int guild_id, int account_id,int char_id,const char *mes) { struct guild *g; nullpo_retr(0, sd); g = guild_search(sd->status.guild_id); if(g==NULL) return 0; if(sd->status.account_id!=account_id || sd->status.char_id!=char_id || sd->status.guild_id!=guild_id || map[sd->bl.m].flag.gvg_castle) //Can't leave inside guild castles. return 0; intif_guild_leave(sd->status.guild_id, sd->status.account_id, sd->status.char_id,0,mes); return 0; }
/*========================================== * change a chatroom's status (title, etc) *------------------------------------------*/ int chat_changechatstatus(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { struct chat_data* cd; nullpo_retr(1, sd); cd = (struct chat_data*)map_id2bl(sd->chatID); if( cd==NULL || (struct block_list *)sd != cd->owner ) return 1; safestrncpy(cd->title, title, CHATROOM_TITLE_SIZE); safestrncpy(cd->pass, pass, CHATROOM_PASS_SIZE); cd->limit = min(limit, ARRAYLENGTH(cd->usersd)); cd->pub = pub; clif_changechatstatus(cd); clif_dispchat(cd,0); return 0; }
// exp share and added zeny share [Valaris] int party_exp_share(struct party *p,int map,unsigned int base_exp,unsigned int job_exp,int zeny) { struct map_session_data* sd[MAX_PARTY]; int i; short c, bonus =100; // modified [Valaris] nullpo_retr(0, p); for (i = c = 0; i < MAX_PARTY; i++) if ((sd[c] = p->member[i].sd)!=NULL && sd[c]->bl.m == map && !pc_isdead(sd[c])) { if (battle_config.idle_no_share && (pc_issit(sd[c]) || sd[c]->chatID || (sd[c]->idletime < (last_tick - battle_config.idle_no_share)))) continue; c++; } if (c < 1) return 0; if (battle_config.party_even_share_bonus) //Valaris's even share exp bonus equation. bonus += (battle_config.party_even_share_bonus*c*(c-1)/10); //Changed Valaris's bonus switch to an equation [Skotlex] else //Official kRO/iRO sites state that the even share bonus is 10% per additional party member. bonus += (c-1)*10; base_exp/=c; job_exp/=c; if (base_exp/100 > UINT_MAX/bonus) base_exp= UINT_MAX; //Exp overflow else base_exp = base_exp*bonus/100; if (job_exp/100 > UINT_MAX/bonus) job_exp = UINT_MAX; else job_exp = job_exp*bonus/100; for (i = 0; i < c; i++) { pc_gainexp(sd[i], base_exp, job_exp); if (battle_config.zeny_from_mobs) // zeny from mobs [Valaris] pc_getzeny(sd[i],bonus*zeny/(c*100)); } return 0; }
// ギルドデータ一括受信(初期化時) int guild_castlealldataload(int len,struct guild_castle *gc) { int i; int n = (len-4) / sizeof(struct guild_castle); int ev; nullpo_retr(0, gc); //Last owned castle in the list invokes ::OnAgitinit for( i = n-1; i >= 0 && !(gc[i].guild_id); --i ); ev = i; // offset of castle or -1 if( ev < 0 ) { //No castles owned, invoke OnAgitInit as it is. npc_event_doall("OnAgitInit"); npc_event_doall("OnAgitInit2"); } else // load received castles into memory, one by one for( i = 0; i < n; i++, gc++ ) { struct guild_castle *c = guild_castle_search(gc->castle_id); if (!c) { ShowError("guild_castlealldataload Castle id=%d not found.\n", gc->castle_id); continue; } // update mapserver castle data with new info memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((int)&c->guild_id - (int)c)); if( c->guild_id ) { if( i != ev ) guild_request_info(c->guild_id); else { // last owned one guild_npc_request_info(c->guild_id, "::OnAgitInit"); guild_npc_request_info(c->guild_id, "::OnAgitInit2"); } } } return 0; }
/*========================================== * Add an item to the storage from the inventory. *------------------------------------------*/ int storage_storageadd(struct map_session_data* sd, int index, int amount) { nullpo_retr(0, sd); if( sd->status.storage.storage_amount > MAX_STORAGE ) return 0; // storage full if( index < 0 || index >= MAX_INVENTORY ) return 0; if( sd->status.inventory[index].nameid <= 0 ) return 0; // No item on that spot if( amount < 1 || amount > sd->status.inventory[index].amount ) return 0; if( storage_additem(sd,&sd->status.inventory[index],amount) == 0 ) pc_delitem(sd,index,amount,0); return 1; }
/*========================================== * Creates idle timer * Default before instance destroy is 5 minutes *------------------------------------------*/ static int instance_startidletimer(struct instance_data *im, short instance_id) { struct instance_db *db; struct party_data *p; nullpo_retr(1, im); // No current timer if(im->idle_timer != INVALID_TIMER) return 1; // Add the timer im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT / 1000; im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0); // Notify party of added instance timer if((p = party_search(im->party_id)) != NULL && (db = instance_searchtype_db(im->type)) != NULL) clif_instance_status(party_getavailablesd(p), StringBuf_Value(db->name), im->keep_limit, im->idle_limit, 1); return 0; }
/*========================================== * Delete the idle timer *------------------------------------------*/ static int instance_stopidletimer(struct instance_data *im) { struct party_data *p; nullpo_retr(0, im); // No timer if(im->idle_timer == INVALID_TIMER) return 1; // Delete the timer - Party has returned or instance is destroyed im->idle_limit = 0; delete_timer(im->idle_timer, instance_delete_timer); im->idle_timer = INVALID_TIMER; // Notify the party if((p = party_search(im->party_id)) != NULL) clif_instance_changestatus(party_getavailablesd(p), 0, im->idle_limit, 1); return 0; }
/*========================================== * 単純なクエリ発行 *------------------------------------------ */ bool sqldbs_simplequery(struct sqldbs_handle *hd, const char *query) { nullpo_retr(false, hd); sqldbs_free_result(hd); if( mysql_query(&hd->handle, query) ) { printf("DB server Error - %s\n %s\n\n", mysql_error(&hd->handle), query); return false; } hd->result = mysql_store_result(&hd->handle); if( mysql_errno(&hd->handle) != 0 ) { printf("DB server Error - %s\n %s\n\n", mysql_error(&hd->handle), query); return false; } return true; }
/*========================================== * 単純なプリペアドステートメントのクエリ準備 *------------------------------------------ */ bool sqldbs_stmt_simpleprepare(struct sqldbs_stmt *st, const char *query) { nullpo_retr(false, st); // 初期化 st->bind_params = false; st->bind_columns = false; if(st->query) { aFree(st->query); } st->query = (char *)aStrdup(query); if( mysql_stmt_prepare(st->stmt, query, strlen(query)) ) { printf("DB server Error - %s\n %s\n\n", mysql_stmt_error(st->stmt), query); return false; } return true; }
int merc_menu(struct map_session_data *sd,int menunum) { nullpo_retr(0, sd); if (sd->hd == NULL) return 1; switch(menunum) { case 0: break; case 1: merc_hom_food(sd, sd->hd); break; case 2: merc_hom_delete(sd->hd, -1); break; default: ShowError("merc_menu : unknown menu choice : %d\n", menunum) ; break; } return 0; }
/*========================================== * Move an item from cart to storage. *------------------------------------------*/ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amount) { nullpo_retr(0, sd); if( sd->status.storage.storage_amount > MAX_STORAGE ) return 0; // storage full / storage closed if( index < 0 || index >= MAX_CART ) return 0; if( sd->status.cart[index].nameid <= 0 ) return 0; //No item there. if( amount < 1 || amount > sd->status.cart[index].amount ) return 0; if( storage_additem(sd,&sd->status.cart[index],amount) == 0 ) pc_cart_delitem(sd,index,amount,0); return 1; }
/** * Saves an existing homunculus. * * @param hd The homunculus' data. * @retval false in case of errors. */ bool mapif_homunculus_save(const struct s_homunculus *hd) { bool flag = true; char esc_name[NAME_LENGTH*2+1]; nullpo_retr(false, hd); Assert_retr(false, hd->hom_id > 0); SQL->EscapeStringLen(inter->sql_handle, esc_name, hd->name, strnlen(hd->name, NAME_LENGTH)); if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%d',`max_hp`='%d',`sp`='%d',`max_sp`='%d',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'", homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk, hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id)) { Sql_ShowDebug(inter->sql_handle); flag = false; } else { int i; SqlStmt *stmt = SQL->StmtMalloc(inter->sql_handle); if (SQL_ERROR == SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`homun_id`, `id`, `lv`) VALUES (%d, ?, ?)", skill_homunculus_db, hd->hom_id)) { SqlStmt_ShowDebug(stmt); flag = false; } else { for (i = 0; i < MAX_HOMUNSKILL; ++i) { if (hd->hskill[i].id > 0 && hd->hskill[i].lv != 0) { SQL->StmtBindParam(stmt, 0, SQLDT_USHORT, (void*)&hd->hskill[i].id, 0); // FIXME: StmtBindParam should take const void SQL->StmtBindParam(stmt, 1, SQLDT_USHORT, (void*)&hd->hskill[i].lv, 0); // FIXME: StmtBindParam should take const void if (SQL_ERROR == SQL->StmtExecute(stmt)) { SqlStmt_ShowDebug(stmt); flag = false; break; } } } } SQL->StmtFree(stmt); } return flag; }
/*========================================== * チャットルーム作成 *------------------------------------------ */ int chat_createchat(struct map_session_data *sd,int limit,int pub,char* pass,char* title,int titlelen) { struct chat_data *cd; nullpo_retr(0, sd); if (sd->chatID) return 0; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex] cd = (struct chat_data *) aCalloc(1,sizeof(struct chat_data)); cd->limit = limit; cd->pub = pub; cd->users = 1; memcpy(cd->pass,pass,8); cd->pass[7]= '\0'; //Overflow check... [Skotlex] if(titlelen>=sizeof(cd->title)-1) titlelen=sizeof(cd->title)-1; memcpy(cd->title,title,titlelen); cd->title[titlelen]=0; cd->owner = (struct block_list **)(&cd->usersd[0]); cd->usersd[0] = sd; cd->bl.m = sd->bl.m; cd->bl.x = sd->bl.x; cd->bl.y = sd->bl.y; cd->bl.type = BL_CHAT; cd->bl.id = map_addobject(&cd->bl); if(cd->bl.id==0){ clif_createchat(sd,1); aFree(cd); return 0; } pc_setchatid(sd,cd->bl.id); clif_createchat(sd,0); clif_dispchat(cd,0); return 0; }
/// Initializes a chatroom object (common functionality for both pc and npc chatrooms). /// Returns a chatroom object on success, or NULL on failure. static struct chat_data* chat_createchat(struct block_list* bl, const char* title, const char* pass, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl) { struct chat_data* cd; nullpo_retr(NULL, bl); cd = (struct chat_data *) aMalloc(sizeof(struct chat_data)); safestrncpy(cd->title, title, sizeof(cd->title)); safestrncpy(cd->pass, pass, sizeof(cd->pass)); cd->pub = pub; cd->users = 0; cd->limit = min(limit, ARRAYLENGTH(cd->usersd)); cd->trigger = trigger; cd->zeny = zeny; cd->minLvl = minLvl; cd->maxLvl = maxLvl; memset(cd->usersd, 0, sizeof(cd->usersd)); cd->owner = bl; safestrncpy(cd->npc_event, ev, sizeof(cd->npc_event)); cd->bl.id = iMap->get_new_object_id(); cd->bl.m = bl->m; cd->bl.x = bl->x; cd->bl.y = bl->y; cd->bl.type = BL_CHAT; cd->bl.next = cd->bl.prev = NULL; if( cd->bl.id == 0 ) { aFree(cd); cd = NULL; } iMap->addiddb(&cd->bl); if( bl->type != BL_NPC ) cd->kick_list = idb_alloc(DB_OPT_BASE); return cd; }