/// 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) { 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; memset(cd->usersd, 0, sizeof(cd->usersd)); cd->owner = bl; safestrncpy(cd->npc_event, ev, sizeof(cd->npc_event)); 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; cd->bl.id = map_addobject(&cd->bl); if( cd->bl.id == 0 ) { aFree(cd); cd = NULL; } return cd; }
dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t> env) { dumb_ptr<invocation> retval; retval.new_(); dumb_ptr<block_list> caster; retval->env = env; retval->caster = env->VAR(VAR_CASTER).v.v_int; retval->spell = env->VAR(VAR_SPELL).v.v_spell; retval->stack_size = 0; retval->current_effect = effect_set->effect; retval->trigger_effect = effect_set->at_trigger; retval->end_effect = effect_set->at_end; caster = map_id2bl(retval->caster); // must still exist retval->bl_id = map_addobject(retval); retval->bl_type = BL::SPELL; retval->bl_m = caster->bl_m; retval->bl_x = caster->bl_x; retval->bl_y = caster->bl_y; map_addblock(retval); set_env_invocation(VAR_INVOCATION, retval); return retval; }
/*========================================== * npcチャットルーム作成 *------------------------------------------ */ int chat_createnpcchat( struct npc_data *nd,int limit,int pub,int trigger,const char* title,int titlelen,const char *ev, int zeny,int lowlv,int highlv,unsigned int job,int upper) { int change_flag = 0; struct chat_data *cd; nullpo_retr(1, nd); // 既にチャットを持っているなら状態変更するだけ if( nd->chat_id && (cd = map_id2cd(nd->chat_id)) ) { change_flag = 1; memset(cd->npc_event, 0, sizeof(cd->npc_event)); } else { cd = (struct chat_data *)aCalloc(1,sizeof(struct chat_data)); cd->pass[0] = 0; cd->users = 0; cd->bl.type = BL_CHAT; cd->owner_ = &nd->bl; cd->owner = &cd->owner_; cd->bl.id = map_addobject(&cd->bl); if(cd->bl.id == 0) { aFree(cd); return 0; } nd->chat_id = cd->bl.id; } cd->limit = (unsigned char)limit; cd->trigger = (trigger > 0)? trigger: limit; cd->pub = pub; if(titlelen >= (int)(sizeof(cd->title) - 1)) { titlelen = (int)(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->zeny = zeny; cd->lowlv = lowlv; cd->highlv = highlv; cd->job = job; cd->upper = upper; memcpy(cd->npc_event,ev,sizeof(cd->npc_event)); cd->npc_event[sizeof(cd->npc_event)-1] = '\0'; if(change_flag) clif_changechatstatus(cd); clif_dispchat(cd,-1); return 0; }
/*========================================== * チャットルーム作成 *------------------------------------------ */ void chat_createchat(struct map_session_data *sd, unsigned short limit, unsigned char pub, const char* pass, const char* title, int titlelen) { struct chat_data *cd; nullpo_retv(sd); if(sd->state.joinchat && chat_leavechat(sd,0)) return; cd = (struct chat_data *)aCalloc(1,sizeof(struct chat_data)); cd->limit = (unsigned char)limit; cd->pub = pub; cd->users = 1; memcpy(cd->pass,pass,8); 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->zeny = 0; cd->lowlv = 0; cd->highlv = MAX_LEVEL; cd->job = 0xFFFFFFFF; cd->upper = 0; cd->bl.id = map_addobject(&cd->bl); if(cd->bl.id == 0) { clif_createchat(sd,1); aFree(cd); return; } sd->chatID = cd->bl.id; sd->state.joinchat = 1; clif_createchat(sd,0); clif_dispchat(cd,-1); return; }
/*========================================== * 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 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; }
/*========================================== * チャットルーム作成 *------------------------------------------ */ int chat_createchat(struct map_session_data *sd,int limit,int pub,char* pass,char* title,int titlelen) { struct chat_data *cd; cd = malloc(sizeof(*cd)); if(cd==NULL){ printf("out of memory : chat_createchat\n"); exit(1); } memset(cd,0,sizeof(*cd)); cd->limit = limit; cd->pub = pub; cd->users = 1; memcpy(cd->pass,pass,8); 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); free(cd); return 0; } pc_setchatid(sd,cd->bl.id); clif_createchat(sd,0); clif_dispchat(cd,0); return 0; }
/*========================================== * npcチャットルーム作成 *------------------------------------------ */ int chat_createcnpchat(struct npc_data *nd,int limit,char* title,int titlelen,const char *ev) { struct chat_data *cd; cd = malloc(sizeof(*cd)); if(cd==NULL){ printf("out of memory : chat_createchat\n"); exit(1); } memset(cd,0,sizeof(*cd)); cd->limit = limit; cd->pub = 1; cd->users = 0; memcpy(cd->pass,"",8); 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_; memcpy(cd->npc_event,ev,sizeof(cd->npc_event)); cd->bl.id = map_addobject(&cd->bl); if(cd->bl.id==0){ free(cd); return 0; } nd->chat_id=cd->bl.id; clif_dispchat(cd,0); return 0; }
dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base) { dumb_ptr<invocation> retval; retval.new_(); // block_list in general is not copyable // since this is the only call site, it is expanded here //*retval = *base; retval->next_invocation = NULL; retval->flags = INVOCATION_FLAG::ZERO; dumb_ptr<env_t> env = retval->env = clone_env(base->env); retval->spell = base->spell; retval->caster = base->caster; retval->subject = 0; // retval->timer = 0; retval->stack_size = 0; // retval->stack = undef; retval->script_pos = 0; // huh? retval->current_effect = base->trigger_effect; retval->trigger_effect = base->trigger_effect; retval->end_effect = NULL; // retval->status_change_refs = NULL; retval->bl_id = 0; retval->bl_prev = NULL; retval->bl_next = NULL; retval->bl_m = base->bl_m; retval->bl_x = base->bl_x; retval->bl_y = base->bl_y; retval->bl_type = base->bl_type; retval->bl_id = map_addobject(retval); set_env_invocation(VAR_INVOCATION, retval); return retval; }
/*========================================== * (m,x,y)を中心に3x3以内に床アイテム設置 * * item_dataはamount以外をcopyする *------------------------------------------ */ int map_addflooritem(struct item *item_data,int amount,int m,int x,int y,struct map_session_data *first_sd, struct map_session_data *second_sd,struct map_session_data *third_sd,int type) { int xy,r; unsigned int tick; struct flooritem_data *fitem; if((xy=map_searchrandfreecell(m,x,y,1))<0) return 0; r=rand(); fitem = malloc(sizeof(*fitem)); if(fitem==NULL){ printf("out of memory : map_addflooritem\n"); exit(1); } fitem->bl.type=BL_ITEM; fitem->bl.prev = fitem->bl.next = NULL; fitem->bl.m=m; fitem->bl.x=xy&0xffff; fitem->bl.y=(xy>>16)&0xffff; fitem->first_get_id = 0; fitem->first_get_tick = 0; fitem->second_get_id = 0; fitem->second_get_tick = 0; fitem->third_get_id = 0; fitem->third_get_tick = 0; fitem->bl.id = map_addobject(&fitem->bl); if(fitem->bl.id==0){ free(fitem); return 0; } tick = gettick(); if(first_sd) { fitem->first_get_id = first_sd->bl.id; if(type) fitem->first_get_tick = tick + battle_config.mvp_item_first_get_time; else fitem->first_get_tick = tick + battle_config.item_first_get_time; } if(second_sd) { fitem->second_get_id = second_sd->bl.id; if(type) fitem->second_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time; else fitem->second_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time; } if(third_sd) { fitem->third_get_id = third_sd->bl.id; if(type) fitem->third_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time + battle_config.mvp_item_third_get_time; else fitem->third_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time + battle_config.item_third_get_time; } memcpy(&fitem->item_data,item_data,sizeof(*item_data)); fitem->item_data.amount=amount; fitem->subx=(r&3)*3+3; fitem->suby=((r>>2)&3)*3+3; fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0); map_addblock(&fitem->bl); clif_dropflooritem(fitem); return fitem->bl.id; }