/// opens accounts file, loads it, and starts a periodic saving timer static bool account_db_txt_init(AccountDB* self) { AccountDB_TXT* db = (AccountDB_TXT*)self; DBMap* accounts; FILE* fp; char line[2048]; unsigned int version = 0; // create accounts database db->accounts = idb_alloc(DB_OPT_RELEASE_DATA); accounts = db->accounts; // open data file fp = fopen(db->account_db, "r"); if( fp == NULL ) { // no account file -> no account -> no login, including char-server (ERROR) ShowError(CL_RED"account_db_txt_init: Accounts file [%s] not found."CL_RESET"\n", db->account_db); return false; } // load data file while( fgets(line, sizeof(line), fp) != NULL ) { int account_id, n; unsigned int v; struct mmo_account acc; struct mmo_account* tmp; struct DBIterator* iter; int (*compare)(const char* str1, const char* str2) = ( db->case_sensitive ) ? strcmp : stricmp; if( line[0] == '/' && line[1] == '/' ) continue; n = 0; if( sscanf(line, "%d%n", &v, &n) == 1 && (line[n] == '\n' || line[n] == '\r') ) {// format version definition version = v; continue; } n = 0; if( sscanf(line, "%d\t%%newid%%%n", &account_id, &n) == 1 && (line[n] == '\n' || line[n] == '\r') ) {// auto-increment if( account_id > db->next_account_id ) db->next_account_id = account_id; continue; } if( !mmo_auth_fromstr(&acc, line, version) ) { ShowError("account_db_txt_init: skipping invalid data: %s", line); continue; } // apply constraints & checks here if( acc.sex != 'S' && (acc.account_id < START_ACCOUNT_NUM || acc.account_id > END_ACCOUNT_NUM) ) ShowWarning("account_db_txt_init: account %d:'%s' has ID outside of the defined range for accounts (min:%d max:%d)!\n", acc.account_id, acc.userid, START_ACCOUNT_NUM, END_ACCOUNT_NUM); iter = accounts->iterator(accounts); for( tmp = (struct mmo_account*)iter->first(iter,NULL); iter->exists(iter); tmp = (struct mmo_account*)iter->next(iter,NULL) ) if( compare(acc.userid, tmp->userid) == 0 ) break; iter->destroy(iter); if( tmp != NULL ) {// entry with identical username ShowWarning("account_db_txt_init: account %d:'%s' has same username as account %d. The account will be inaccessible!\n", acc.account_id, acc.userid, tmp->account_id); } if( idb_get(accounts, acc.account_id) != NULL ) {// account id already occupied ShowError("account_db_txt_init: ID collision for account id %d! Discarding data for account '%s'...\n", acc.account_id, acc.userid); continue; } // record entry in db tmp = (struct mmo_account*)aMalloc(sizeof(struct mmo_account)); memcpy(tmp, &acc, sizeof(struct mmo_account)); idb_put(accounts, acc.account_id, tmp); if( db->next_account_id < acc.account_id) db->next_account_id = acc.account_id + 1; } // close data file fclose(fp); // initialize data saving timer add_timer_func_list(mmo_auth_sync_timer, "mmo_auth_sync_timer"); db->save_timer = add_timer_interval(gettick() + AUTH_SAVING_INTERVAL, mmo_auth_sync_timer, 0, (intptr)db, AUTH_SAVING_INTERVAL); return true; }
void CStatusEffectContainer::SaveStatusEffects(bool logout) { DSP_DEBUG_BREAK_IF(m_POwner->objtype != TYPE_PC); Sql_Query(SqlHandle,"DELETE FROM char_effects WHERE charid = %u", m_POwner->id); for (uint16 i = 0; i < m_StatusEffectList.size(); ++i) { CStatusEffect* PStatusEffect = m_StatusEffectList.at(i); if (logout && PStatusEffect->GetFlag() & EFFECTFLAG_LOGOUT) continue; uint32 realduration = (PStatusEffect->GetDuration() + PStatusEffect->GetStartTime() - gettick()) / 1000; if (realduration > 0) { const int8* Query = "INSERT INTO char_effects (charid, effectid, icon, power, tick, duration, subid, subpower, tier) VALUES(%u,%u,%u,%u,%u,%u,%u,%u,%u);"; // save power of utsusemi and blink if (PStatusEffect->GetStatusID() == EFFECT_COPY_IMAGE) { PStatusEffect->SetPower(m_POwner->getMod(MOD_UTSUSEMI)); } else if (PStatusEffect->GetStatusID() == EFFECT_BLINK) { PStatusEffect->SetPower(m_POwner->getMod(MOD_BLINK)); } else if (PStatusEffect->GetStatusID() == EFFECT_STONESKIN) { PStatusEffect->SetPower(m_POwner->getMod(MOD_STONESKIN)); } uint32 tick = PStatusEffect->GetTickTime() == 0 ? 0 : PStatusEffect->GetTickTime() / 1000; uint32 duration = PStatusEffect->GetDuration() == 0 ? 0 : realduration; Sql_Query(SqlHandle, Query, m_POwner->id, PStatusEffect->GetStatusID(), PStatusEffect->GetIcon(), PStatusEffect->GetPower(), tick, duration, PStatusEffect->GetSubID(), PStatusEffect->GetSubPower(), PStatusEffect->GetTier()); } } }
void CInstance::init(){ //reload from sql instanceutils::spawnMonstersForBcnm(this); m_StartTime = gettick(); m_AllDeadTime = 0; }
/** * Attempt to send mail * @param sd Sender * @param dest_name Destination name * @param title Mail title * @param body_msg Mail message * @param body_len Message's length */ void mail_send(struct map_session_data *sd, const char *dest_name, const char *title, const char *body_msg, int body_len) { struct mail_message msg; nullpo_retv(sd); if( sd->state.trading ) return; if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 ) { clif_displaymessage(sd->fd,msg_txt(sd,675)); //"Cannot send mails too fast!!." clif_Mail_send(sd, WRITE_MAIL_FAILED); // fail return; } if( battle_config.mail_daily_count ){ mail_refresh_remaining_amount(sd); // After calling mail_refresh_remaining_amount the status should always be there if( sd->sc.data[SC_DAILYSENDMAILCNT] == NULL || sd->sc.data[SC_DAILYSENDMAILCNT]->val2 >= battle_config.mail_daily_count ){ clif_Mail_send(sd, WRITE_MAIL_FAILED_CNT); return; }else{ sc_start2( &sd->bl, &sd->bl, SC_DAILYSENDMAILCNT, 100, date_get_dayofyear(), sd->sc.data[SC_DAILYSENDMAILCNT]->val2 + 1, -1 ); } } if( body_len > MAIL_BODY_LENGTH ) body_len = MAIL_BODY_LENGTH; if( !mail_setattachment(sd, &msg) ) { // Invalid Append condition int i; clif_Mail_send(sd, WRITE_MAIL_FAILED); // fail for( i = 0; i < MAIL_MAX_ITEM; i++ ){ mail_removeitem(sd,0,sd->mail.item[i].index + 2, sd->mail.item[i].amount); } mail_removezeny(sd,false); return; } msg.id = 0; // id will be assigned by charserver msg.send_id = sd->status.char_id; msg.dest_id = 0; // will attempt to resolve name safestrncpy(msg.send_name, sd->status.name, NAME_LENGTH); safestrncpy(msg.dest_name, (char*)dest_name, NAME_LENGTH); safestrncpy(msg.title, (char*)title, MAIL_TITLE_LENGTH); msg.type = MAIL_INBOX_NORMAL; if (msg.title[0] == '\0') { return; // Message has no length and somehow client verification was skipped. } if (body_len) safestrncpy(msg.body, (char*)body_msg, body_len + 1); else memset(msg.body, 0x00, MAIL_BODY_LENGTH); msg.timestamp = time(NULL); if( !intif_Mail_send(sd->status.account_id, &msg) ) mail_deliveryfail(sd, &msg); sd->cansendmail_tick = gettick() + battle_config.mail_delay; // Flood Protection }
// Wisp/page request to send int mapif_parse_WisRequest(int fd) { struct WisData* wd; char name[NAME_LENGTH]; char esc_name[NAME_LENGTH*2+1];// escaped name char* data; size_t len; if ( fd <= 0 ) {return 0;} // check if we have a valid fd if (RFIFOW(fd,2)-52 >= sizeof(wd->msg)) { ShowWarning("inter: Wis message size too long.\n"); return 0; } else if (RFIFOW(fd,2)-52 <= 0) { // normaly, impossible, but who knows... ShowError("inter: Wis message doesn't exist.\n"); return 0; } safestrncpy(name, (char*)RFIFOP(fd,28), NAME_LENGTH); //Received name may be too large and not contain \0! [Skotlex] Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name` FROM `%s` WHERE `name`='%s'", schema_config.char_db, esc_name) ) Sql_ShowDebug(sql_handle); // search if character exists before to ask all map-servers if( SQL_SUCCESS != Sql_NextRow(sql_handle) ) { unsigned char buf[27]; WBUFW(buf, 0) = 0x3802; memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH); WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target chmapif_send(fd, buf, 27); } else {// Character exists. So, ask all map-servers // to be sure of the correct name, rewrite it Sql_GetData(sql_handle, 0, &data, &len); memset(name, 0, NAME_LENGTH); memcpy(name, data, min(len, NAME_LENGTH)); // if source is destination, don't ask other servers. if( strncmp((const char*)RFIFOP(fd,4), name, NAME_LENGTH) == 0 ) { uint8 buf[27]; WBUFW(buf, 0) = 0x3802; memcpy(WBUFP(buf, 2), RFIFOP(fd, 4), NAME_LENGTH); WBUFB(buf,26) = 1; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target chmapif_send(fd, buf, 27); } else { static int wisid = 0; CREATE(wd, struct WisData, 1); // Whether the failure of previous wisp/page transmission (timeout) check_ttl_wisdata(); wd->id = ++wisid; wd->fd = fd; wd->len= RFIFOW(fd,2)-52; memcpy(wd->src, RFIFOP(fd, 4), NAME_LENGTH); memcpy(wd->dst, RFIFOP(fd,28), NAME_LENGTH); memcpy(wd->msg, RFIFOP(fd,52), wd->len); wd->tick = gettick(); idb_put(wis_db, wd->id, wd); mapif_wis_message(wd); } } Sql_FreeResult(sql_handle); return 0; }
int32 do_init(int32 argc, int8** argv) { ShowStatus("do_init: begin server initialization...\n"); MAP_CONF_FILENAME = "./conf/map_darkstar.conf"; srand((uint32)time(NULL)); WELL512::seed((uint32)time(NULL)); map_config_default(); map_config_read(MAP_CONF_FILENAME); ShowMessage("\t\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); ShowStatus("do_init: map_config is reading"); ShowMessage("\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); luautils::init(); CmdHandler.init(luautils::LuaHandle); PacketParserInitialize(); SqlHandle = Sql_Malloc(); ShowStatus("do_init: sqlhandle is allocating"); if( Sql_Connect(SqlHandle,map_config.mysql_login, map_config.mysql_password, map_config.mysql_host, map_config.mysql_port, map_config.mysql_database) == SQL_ERROR ) { exit(EXIT_FAILURE); } Sql_Keepalive(SqlHandle); // отчищаем таблицу сессий при старте сервера (временное решение, т.к. в кластере это не будет работать) Sql_Query(SqlHandle, "TRUNCATE TABLE accounts_sessions"); ShowMessage("\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); ShowStatus("do_init: zlib is reading"); zlib_init(); ShowMessage("\t\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); ShowStatus("do_init: loading items"); itemutils::Initialize(); ShowMessage("\t\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); // нужно будет написать один метод для инициализации всех данных в battleutils // и один метод для освобождения этих данных ShowStatus("do_init: loading spells"); spell::LoadSpellList(); mobSpellList::LoadMobSpellList(); ShowMessage("\t\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); charutils::ResetAllTwoHours(); guildutils::Initialize(); charutils::LoadExpTable(); linkshell::LoadLinkshellList(); traits::LoadTraitsList(); effects::LoadEffectsParameters(); battleutils::LoadSkillTable(); meritNameSpace::LoadMeritsList(); nameSpaceUnlockableWeapons::LoadUnlockableWeaponList(); ability::LoadAbilitiesList(); battleutils::LoadWeaponSkillsList(); battleutils::LoadMobSkillsList(); battleutils::LoadEnmityTable(); battleutils::LoadSkillChainDamageModifiers(); petutils::LoadPetList(); conquest::LoadConquestSystem(); mobutils::LoadCustomMods(); ShowStatus("do_init: loading zones"); zoneutils::LoadZoneList(); ShowMessage("\t\t\t - " CL_GREEN"[OK]" CL_RESET"\n"); luautils::OnServerStart(); fishingutils::LoadFishingMessages(); ShowStatus("do_init: server is binding with port %u",map_config.usMapPort); map_fd = makeBind_udp(map_config.uiMapIp,map_config.usMapPort); ShowMessage("\t - " CL_GREEN"[OK]" CL_RESET"\n"); CVanaTime::getInstance()->setCustomOffset(map_config.vanadiel_time_offset); CTaskMgr::getInstance()->AddTask("time_server", gettick(), NULL, CTaskMgr::TASK_INTERVAL, time_server, 2400); CTaskMgr::getInstance()->AddTask("map_cleanup", gettick(), NULL, CTaskMgr::TASK_INTERVAL, map_cleanup, 5000); CTaskMgr::getInstance()->AddTask("garbage_collect", gettick(), NULL, CTaskMgr::TASK_INTERVAL, map_garbage_collect, 15 * 60 * 1000); CREATE(g_PBuff, int8, map_config.buffer_size + 20); CREATE(PTempBuff, int8, map_config.buffer_size + 20); aFree((void*)map_config.mysql_login); aFree((void*)map_config.mysql_password); ShowStatus("The map-server is " CL_GREEN"ready" CL_RESET" to work...\n"); ShowMessage("=======================================================================\n"); return 0; }
void merc_hom_init_timers(struct homun_data * hd) { if (hd->hungry_timer == INVALID_TIMER) hd->hungry_timer = add_timer(gettick()+hd->homunculusDB->hungryDelay,merc_hom_hungry,hd->master->bl.id,0); hd->regen.state.block = 0; //Restore HP/SP block. }
void elemental_summon_init(struct elemental_data *ed) { if( ed->summon_timer == INVALID_TIMER ) ed->summon_timer = add_timer(gettick() + ed->elemental.life_time, elemental_summon_end, ed->master->bl.id, 0); ed->regen.state.block = 0; }
/** * Auth successful, inform client and create a temp auth_node. * @param sd: player session */ static void logclif_auth_ok(struct login_session_data* sd) { int fd = sd->fd; uint32 ip = session[fd]->client_addr; uint8 server_num, n; uint32 subnet_char_ip; struct auth_node* node; int i; if( runflag != LOGINSERVER_ST_RUNNING ){ // players can only login while running logclif_sent_auth_result(fd,1); // server closed return; } if( login_config.group_id_to_connect >= 0 && sd->group_id != login_config.group_id_to_connect ) { ShowStatus("Connection refused: the required group id for connection is %d (account: %s, group: %d).\n", login_config.group_id_to_connect, sd->userid, sd->group_id); logclif_sent_auth_result(fd,1); // server closed return; } else if( login_config.min_group_id_to_connect >= 0 && login_config.group_id_to_connect == -1 && sd->group_id < login_config.min_group_id_to_connect ) { ShowStatus("Connection refused: the minium group id required for connection is %d (account: %s, group: %d).\n", login_config.min_group_id_to_connect, sd->userid, sd->group_id); logclif_sent_auth_result(fd,1); // server closed return; } server_num = 0; for( i = 0; i < ARRAYLENGTH(ch_server); ++i ) if( session_isActive(ch_server[i].fd) ) server_num++; if( server_num == 0 ) {// if no char-server, don't send void list of servers, just disconnect the player with proper message ShowStatus("Connection refused: there is no char-server online (account: %s).\n", sd->userid); logclif_sent_auth_result(fd,1); // server closed return; } { struct online_login_data* data = (struct online_login_data*)idb_get(online_db, sd->account_id); if( data ) {// account is already marked as online! if( data->char_server > -1 ) {// Request char servers to kick this account out. [Skotlex] uint8 buf[6]; ShowNotice("User '%s' is already online - Rejected.\n", sd->userid); WBUFW(buf,0) = 0x2734; WBUFL(buf,2) = sd->account_id; logchrif_sendallwos(-1, buf, 6); if( data->waiting_disconnect == INVALID_TIMER ) data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, login_waiting_disconnect_timer, sd->account_id, 0); logclif_sent_auth_result(fd,8); // 08 = Server still recognizes your last login return; } else if( data->char_server == -1 ) {// client has authed but did not access char-server yet // wipe previous session idb_remove(auth_db, sd->account_id); login_remove_online_user(sd->account_id); data = NULL; } } } login_log(ip, sd->userid, 100, "login ok"); ShowStatus("Connection of the account '%s' accepted.\n", sd->userid); WFIFOHEAD(fd,47+32*server_num); WFIFOW(fd,0) = 0x69; WFIFOW(fd,2) = 47+32*server_num; WFIFOL(fd,4) = sd->login_id1; WFIFOL(fd,8) = sd->account_id; WFIFOL(fd,12) = sd->login_id2; WFIFOL(fd,16) = 0; // in old version, that was for ip (not more used) //memcpy(WFIFOP(fd,20), sd->lastlogin, 24); // in old version, that was for name (not more used) memset(WFIFOP(fd,20), 0, 24); WFIFOW(fd,44) = 0; // unknown WFIFOB(fd,46) = sex_str2num(sd->sex); for( i = 0, n = 0; i < ARRAYLENGTH(ch_server); ++i ) { if( !session_isValid(ch_server[i].fd) ) continue; subnet_char_ip = lan_subnetcheck(ip); // Advanced subnet check [LuzZza] WFIFOL(fd,47+n*32) = htonl((subnet_char_ip) ? subnet_char_ip : ch_server[i].ip); WFIFOW(fd,47+n*32+4) = ntows(htons(ch_server[i].port)); // [!] LE byte order here [!] memcpy(WFIFOP(fd,47+n*32+6), ch_server[i].name, 20); WFIFOW(fd,47+n*32+26) = ch_server[i].users; WFIFOW(fd,47+n*32+28) = ch_server[i].type; WFIFOW(fd,47+n*32+30) = ch_server[i].new_; n++; } WFIFOSET(fd,47+32*server_num); // create temporary auth entry CREATE(node, struct auth_node, 1); node->account_id = sd->account_id; node->login_id1 = sd->login_id1; node->login_id2 = sd->login_id2; node->sex = sd->sex; node->ip = ip; node->version = sd->version; node->clienttype = sd->clienttype; idb_put(auth_db, sd->account_id, node); { struct online_login_data* data; // mark client as 'online' data = login_add_online_user(-1, sd->account_id); // schedule deletion of this node data->waiting_disconnect = add_timer(gettick()+AUTH_TIMEOUT, login_waiting_disconnect_timer, sd->account_id, 0); } }
void CBattlefield::init() { //reload from sql battlefieldutils::spawnMonstersForBcnm(this); m_StartTime = gettick(); m_AllDeadTime = 0; }
int32 do_init(int32 argc, int8** argv) { ShowStatus("do_init: begin server initialization...\n"); MAP_CONF_FILENAME = "./conf/map_darkstar.conf"; srand((uint32)time(NULL)); map_config_default(); map_config_read(MAP_CONF_FILENAME); ShowMessage("\t\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); ShowStatus("do_init: map_config is reading"); ShowMessage("\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); luautils::init(); CmdHandler.init("conf/commands.conf",luautils::LuaHandle); PacketParderInitialize(); SqlHandle = Sql_Malloc(); ShowStatus("do_init: sqlhandle is allocating"); if( Sql_Connect(SqlHandle,map_config.mysql_login, map_config.mysql_password, map_config.mysql_host, map_config.mysql_port, map_config.mysql_database) == SQL_ERROR ) { exit(EXIT_FAILURE); } Sql_Keepalive(SqlHandle); ShowMessage("\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); ShowStatus("do_init: zlib is reading"); zlib_init(); ShowMessage("\t\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); ShowStatus("do_init: loading items"); itemutils::LoadItemList(); ShowMessage("\t\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); // нужно будет написать один метод для инициализации всех данных в battleutils // и один метод для освобождения этих данных ShowStatus("do_init: loading spells"); battleutils::LoadSpellList(); ShowMessage("\t\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); guildutils::Initialize(); charutils::LoadExpTable(); battleutils::LoadSkillTable(); battleutils::LoadAbilitiesList(); battleutils::LoadWeaponSkillsList(); battleutils::LoadTraitsList(); battleutils::LoadMobSkillsList(); battleutils::LoadEnmityTable(); petutils::LoadPetList(); ShowStatus("do_init: loading zones"); zoneutils::LoadZoneList(); ShowMessage("\t\t\t - "CL_GREEN"[OK]"CL_RESET"\n"); luautils::OnServerStart(); ShowStatus("do_init: server is binding with port %u",map_config.usMapPort); map_fd = makeBind_udp(map_config.uiMapIp,map_config.usMapPort); ShowMessage("\t - "CL_GREEN"[OK]"CL_RESET"\n"); CVanaTime::getInstance()->setCustomOffset(map_config.vanadiel_time_offset); CTaskMgr::getInstance()->AddTask("time_server", gettick()+1000, NULL, CTaskMgr::TASK_INTERVAL, time_server, 2400); CTaskMgr::getInstance()->AddTask("map_cleanup", gettick()+5000, NULL, CTaskMgr::TASK_INTERVAL, map_cleanup, map_config.max_time_lastupdate); CREATE(g_PBuff, int8, map_config.buffer_size + 20); CREATE(PTempBuff, int8, map_config.buffer_size + 20); ShowStatus("The map-server is "CL_GREEN"ready"CL_RESET" to work...\n"); ShowMessage("=======================================================================\n"); return 0; }
void CParty::SetSyncTarget(CBattleEntity* PEntity, uint16 message) { if (map_config.level_sync_enable) { if (PEntity && PEntity->objtype == TYPE_PC) { CCharEntity* PChar = (CCharEntity*)PEntity; //enable level sync if (PChar->GetMLevel() < 10 ) { ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 10, 541)); return; } else if (PChar->getZone() != GetLeader()->getZone()) { ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 542)); return; } else { for (uint32 i = 0; i < members.size(); ++i) { if(members.at(i)->StatusEffectContainer->HasStatusEffect(EFFECT_LEVEL_RESTRICTION)) { ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 543)); return; } } m_PSyncTarget = PChar; for (uint32 i = 0; i < members.size(); ++i) { if(members.at(i)->objtype != TYPE_PC) continue; CCharEntity* member = (CCharEntity*)members.at(i); if (member->status != STATUS_DISAPPEAR && member->getZone() == PChar->getZone() ) { member->pushPacket(new CMessageStandardPacket(PChar->GetMLevel(), 0, 0, 0, message)); member->StatusEffectContainer->AddStatusEffect(new CStatusEffect( EFFECT_LEVEL_SYNC, EFFECT_LEVEL_SYNC, PChar->GetMLevel(), 0, 0), true); member->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DISPELABLE); member->loc.zone->PushPacket(member, CHAR_INRANGE, new CCharSyncPacket(member)); } } } } else { if (m_PSyncTarget != NULL) { //disable level sync for (uint32 i = 0; i < members.size(); ++i) { if(members.at(i)->objtype != TYPE_PC) continue; CCharEntity* member = (CCharEntity*)members.at(i); if (member->status != STATUS_DISAPPEAR && member->getZone() == m_PSyncTarget->getZone() ) { CStatusEffect* sync = member->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC); if (sync && sync->GetDuration() == 0) { member->pushPacket(new CMessageBasicPacket(member, member, 10, 30, message)); sync->SetStartTime(gettick()); sync->SetDuration(30000); } } } } } } }
void CParty::RemoveMember(CBattleEntity* PEntity) { DSP_DEBUG_BREAK_IF(PEntity == NULL); DSP_DEBUG_BREAK_IF(PEntity->PParty != this); if (m_PLeader == PEntity) { RemovePartyLeader(PEntity); } else { for (uint32 i = 0; i < members.size(); ++i) { if (PEntity == members.at(i)) { members.erase(members.begin()+i); if (m_PartyType == PARTY_PCS) { CCharEntity* PChar = (CCharEntity*)PEntity; if (m_PQuaterMaster == PChar) { SetQuaterMaster(NULL); } if (m_PSyncTarget == PChar) { SetSyncTarget(NULL, 553); CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC); if (sync && sync->GetDuration() == 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553)); sync->SetStartTime(gettick()); sync->SetDuration(30000); } DisableSync(); } if (m_PSyncTarget != NULL && m_PSyncTarget != PChar) { if (PChar->status != STATUS_DISAPPEAR && PChar->getZone() == m_PSyncTarget->getZone() ) { CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC); if (sync && sync->GetDuration() == 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553)); sync->SetStartTime(gettick()); sync->SetDuration(30000); } } } PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size()); PChar->pushPacket(new CPartyDefinePacket(NULL)); PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, PChar->getZone())); PChar->pushPacket(new CCharUpdatePacket(PChar)); PChar->PParty = NULL; ReloadParty(); if (PChar->PTreasurePool != NULL && PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE) { PChar->PTreasurePool->DelMember(PChar); PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO); PChar->PTreasurePool->AddMember(PChar); PChar->PTreasurePool->UpdatePool(PChar); } Sql_Query(SqlHandle,"UPDATE accounts_sessions SET partyid = 0 WHERE charid = %u", PChar->id); } break; } } } }
void do_init_chcnslif(void){ if( charserv_config.console ){ //start listening add_timer_func_list(cnslif_console_timer, "cnslif_console_timer"); add_timer_interval(gettick()+1000, cnslif_console_timer, 0, 0, 1000); //start in 1s each 1sec } }
void CMobEntity::SetDespawnTimer(uint32 duration) { m_DespawnTimer = (duration > 0 ? (duration * 1000) + gettick() : duration); }
void do_init_battleground(void) { bg_team_db = idb_alloc(DB_OPT_RELEASE_DATA); add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer"); add_timer_interval(gettick() + battle_config.bg_update_interval, bg_send_xy_timer, 0, 0, battle_config.bg_update_interval); }
/** * Initialize the module. * Launched at login-serv start, create db or other long scope variable here. */ void do_init_logincnslif(void){ if( login_config.console ) { add_timer_func_list(parse_console_timer, "parse_console_timer"); add_timer_interval(gettick()+1000, parse_console_timer, 0, 0, 1000); //start in 1s each 1sec } }
static u_int saost_tc_get_timecount(struct timecounter *tc) { return (u_int)gettick(); }
int elemental_data_received(struct s_elemental *ele, bool flag) { struct map_session_data *sd; struct elemental_data *ed; struct s_elemental_db *db; int i = elemental_search_index(ele->class_); if( (sd = map_charid2sd(ele->char_id)) == NULL ) return 0; if( !flag || i < 0 ) { // Not created - loaded - DB info sd->status.ele_id = 0; return 0; } db = &elemental_db[i]; if( !sd->ed ) { // Initialize it after first summon. sd->ed = ed = (struct elemental_data*)aCalloc(1,sizeof(struct elemental_data)); ed->bl.type = BL_ELEM; ed->bl.id = npc_get_new_npc_id(); ed->master = sd; ed->db = db; memcpy(&ed->elemental, ele, sizeof(struct s_elemental)); status_set_viewdata(&ed->bl, ed->elemental.class_); ed->vd->head_mid = 10; // Why? status_change_init(&ed->bl); unit_dataset(&ed->bl); ed->ud.dir = sd->ud.dir; ed->bl.m = sd->bl.m; ed->bl.x = sd->bl.x; ed->bl.y = sd->bl.y; unit_calc_pos(&ed->bl, sd->bl.x, sd->bl.y, sd->ud.dir); ed->bl.x = ed->ud.to_x; ed->bl.y = ed->ud.to_y; map_addiddb(&ed->bl); status_calc_elemental(ed,1); ed->last_thinktime = gettick(); ed->summon_timer = INVALID_TIMER; ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode. elemental_summon_init(ed); } else { memcpy(&sd->ed->elemental, ele, sizeof(struct s_elemental)); ed = sd->ed; } sd->status.ele_id = ele->elemental_id; ed->battle_status.mode = ele->mode = EL_MODE_PASSIVE; // Initial mode. if( ed->bl.prev == NULL && sd->bl.prev != NULL ) { map_addblock(&ed->bl); clif_spawn(&ed->bl); clif_elemental_info(sd); clif_elemental_updatestatus(sd,SP_HP); clif_hpmeter_single(sd->fd,ed->bl.id,ed->battle_status.hp,ed->battle_status.matk_max); clif_elemental_updatestatus(sd,SP_SP); } return 1; }
static void saost_tc_init(void) { static struct timecounter saost_tc = { .tc_get_timecount = saost_tc_get_timecount, .tc_counter_mask = ~0, .tc_name = "saost_count", #if !(defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)) .tc_frequency = TIMER_FREQUENCY, #endif .tc_quality = 100, }; #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250) saost_tc.tc_frequency = TIMER_FREQUENCY, #endif tc_init(&saost_tc); } static uint32_t gettick(void) { struct saost_softc *sc = saost_sc; uint32_t counter; u_int saved_ints; saved_ints = disable_interrupts(I32_bit); counter = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SAOST_CR); restore_interrupts(saved_ints); return counter; } void delay(u_int usecs) { uint32_t xtick, otick, delta; int csec, usec; csec = usecs / 10000; usec = usecs % 10000; usecs = (TIMER_FREQUENCY / 100) * csec + (TIMER_FREQUENCY / 100) * usec / 10000; if (saost_sc == NULL) { volatile int k = 0; int j; /* clock isn't initialized yet */ for (; usecs > 0; usecs--) for (j = 100; j > 0; j--, k--) continue; return; } otick = gettick(); while (1) { xtick = gettick(); delta = xtick - otick; if (delta > usecs) break; usecs -= delta; otick = xtick; } }
void CCharEntity::SetPlayTime(uint32 playTime) { m_PlayTime = playTime; m_SaveTime = gettick() / 1000; }
void CZone::IncreaseZoneCounter(CCharEntity* PChar) { DSP_DEBUG_BREAK_IF(PChar == NULL); DSP_DEBUG_BREAK_IF(PChar->loc.zone != NULL); DSP_DEBUG_BREAK_IF(PChar->PTreasurePool != NULL); // ищем свободный targid для входящего в зону персонажа PChar->targid = 0x400; for (EntityList_t::const_iterator it = m_charList.begin() ; it != m_charList.end() ; ++it) { if (PChar->targid != it->first) { break; } PChar->targid++; } if (PChar->targid >= 0x700) { ShowError(CL_RED"CZone::InsertChar : targid is high (03hX)\n" CL_RESET, PChar->targid); return; } PChar->loc.zone = this; PChar->loc.zoning = false; PChar->loc.destination = 0; PChar->m_InsideRegionID = 0; PChar->m_PVPFlag = CanUseMisc(MISC_PVP); m_charList[PChar->targid] = PChar; ShowDebug(CL_CYAN"CZone:: %s IncreaseZoneCounter <%u> %s \n" CL_RESET, GetName(), m_charList.size(),PChar->GetName()); if (!ZoneTimer && !m_charList.empty()) { ZoneTimer = CTaskMgr::getInstance()->AddTask( m_zoneName, gettick(), this, CTaskMgr::TASK_INTERVAL, m_regionList.empty() ? zone_server : zone_server_region, 500); } //remove status effects that wear on zone PChar->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_ON_ZONE); if (PChar->animation == ANIMATION_CHOCOBO && !CanUseMisc(MISC_CHOCOBO)) { PChar->animation = ANIMATION_NONE; PChar->StatusEffectContainer->DelStatusEffectSilent(EFFECT_CHOCOBO); } if (PChar->m_Costum != 0) { PChar->m_Costum = 0; PChar->StatusEffectContainer->DelStatusEffect(EFFECT_COSTUME); } if (PChar->PParty != NULL) { if (m_TreasurePool != NULL) { PChar->PTreasurePool = m_TreasurePool; PChar->PTreasurePool->AddMember(PChar); } else { PChar->PParty->ReloadTreasurePool(PChar); } if (PChar->PParty->GetSyncTarget() != NULL) { if (PChar->getZone() == PChar->PParty->GetSyncTarget()->getZone() ) { if (PChar->PParty->GetSyncTarget()->StatusEffectContainer->HasStatusEffect(EFFECT_LEVEL_SYNC) && PChar->PParty->GetSyncTarget()->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC)->GetDuration() == 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, PChar->PParty->GetSyncTarget()->GetMLevel(), 540)); PChar->StatusEffectContainer->AddStatusEffect(new CStatusEffect( EFFECT_LEVEL_SYNC, EFFECT_LEVEL_SYNC, PChar->PParty->GetSyncTarget()->GetMLevel(), 0, 0), true); PChar->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DEATH); } } } } else { PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO); PChar->PTreasurePool->AddMember(PChar); } PChar->PLatentEffectContainer->CheckLatentsZone(); }
void DespawnPet(CBattleEntity* PMaster) { DSP_DEBUG_BREAK_IF(PMaster->PPet == NULL); CBattleEntity* PPet = PMaster->PPet; // mob was not reset properly on death/uncharm // reset manually if (PPet->isCharmed && PMaster->objtype == TYPE_MOB) { PPet->isCharmed = false; PMaster->charmTime = 0; delete PPet->PBattleAI; PPet->PBattleAI = new CAIMobDummy((CMobEntity*)PMaster); PPet->PBattleAI->SetLastActionTime(gettick()); PPet->PBattleAI->SetCurrentAction(ACTION_FALL); ShowDebug("An ex charmed mob was not reset properly, Manually resetting it.\n"); return; } switch (PPet->objtype) { case TYPE_PET: { PPet->PBattleAI->SetCurrentAction(ACTION_FALL); if( ((CPetEntity*)PPet)->getPetType() == PETTYPE_AVATAR ) PMaster->setModifier(MOD_AVATAR_PERPETUATION, 0); if (PMaster->PParty != NULL) { for (uint8 i = 0; i < PMaster->PParty->members.size(); ++i) { CCharEntity* PMember = (CCharEntity*)PMaster->PParty->members.at(i); PMember->PLatentEffectContainer->CheckLatentsPartyAvatar(); } } CCharEntity* PChar = (CCharEntity*)PMaster; PChar->PLatentEffectContainer->CheckLatentsPartyAvatar(); } break; case TYPE_MOB: { if(PMaster->objtype == TYPE_PC) { CMobEntity* PMob = (CMobEntity*)PMaster->PPet; CCharEntity* PChar = (CCharEntity*)PMaster; // mobs charm wears off whist fighting another mob. Both mobs now attack player since mobs are no longer enemies if(PMob->PBattleAI != NULL && PMob->PBattleAI->GetBattleTarget() != NULL && PMob->PBattleAI->GetBattleTarget()->objtype == TYPE_MOB){ ((CMobEntity*)PMob->PBattleAI->GetBattleTarget())->PEnmityContainer->Clear(); ((CMobEntity*)PMob->PBattleAI->GetBattleTarget())->PEnmityContainer->UpdateEnmity(PChar, 0, 0); } //clear the ex-charmed mobs enmity PMob->PEnmityContainer->Clear(); // charm time is up, mob attacks player now if (PMob->GetHPP() != 0 && PMob->PMaster->GetHPP() != 0 && distance(PMob->loc.p, PMob->PMaster->loc.p) < 30) { PMob->PEnmityContainer->UpdateEnmity(PChar, 0, 0); } else { PMob->m_OwnerID.clean(); } // dirty exp if not full PMob->m_giveExp = PMob->GetHPP() == 100; //master using leave command if (PMaster->PBattleAI->GetCurrentAction() == ACTION_JOBABILITY_FINISH && PMaster->PBattleAI->GetCurrentJobAbility()->getID() == 55 || PChar->loc.zoning) { PMob->PEnmityContainer->Clear(); PMob->m_OwnerID.clean(); } PMob->isCharmed = false; PMob->charmTime = 0; PMob->PMaster = NULL; delete PMob->PBattleAI; PMob->PBattleAI = new CAIMobDummy(PMob); PMob->PBattleAI->SetLastActionTime(gettick()); if (PMob->GetHPP() == 0) PMob->PBattleAI->SetCurrentAction(ACTION_FALL); else PMob->PBattleAI->SetCurrentAction(ACTION_DISENGAGE); PChar->PPet = NULL; PChar->pushPacket(new CCharUpdatePacket(PChar)); PMob->loc.zone->PushPacket(PMob, CHAR_INRANGE, new CEntityUpdatePacket(PMob, ENTITY_UPDATE)); } } break; case TYPE_PC: { // освобождаем персонажа из под контроля } break; } }
CStatusEffectPacket::CStatusEffectPacket(CCharEntity* PChar) { this->type = 0x63; this->size = 0x64; int i = 0; std::fill(reinterpret_cast<uint16*>(data+0x08), reinterpret_cast<uint16*>(data+0x08+32), 0x00FF); ref<uint8>(0x04) = 0x09; ref<uint8>(0x06) = 0xC4; PChar->StatusEffectContainer->ForEachEffect([this, &i](CStatusEffect* PEffect) { ref<uint16>(0x08 + (i * 0x02)) = PEffect->GetIcon(); ref<uint32>(0x48 + (i * 0x04)) = PEffect->GetDuration() == 0 ? 0x7FFFFFFF : (((PEffect->GetDuration() - (gettick() - PEffect->GetStartTime())) / 1000) + CVanaTime::getInstance()->getVanaTime()) * 60; ++i; }); }
/** * Initializing autotraders from table */ void do_init_buyingstore_autotrade( void ) { if(battle_config.feature_autotrade) { if (Sql_Query(mmysql_handle, "SELECT `id`, `account_id`, `char_id`, `sex`, `title`, `limit`, `body_direction`, `head_direction`, `sit` " "FROM `%s` " "WHERE `autotrade` = 1 AND `limit` > 0 AND (SELECT COUNT(`buyingstore_id`) FROM `%s` WHERE `buyingstore_id` = `id`) > 0 " "ORDER BY `id`;", buyingstores_table, buyingstore_items_table ) != SQL_SUCCESS ) { Sql_ShowDebug(mmysql_handle); return; } if( Sql_NumRows(mmysql_handle) > 0 ) { uint16 items = 0; DBIterator *iter = NULL; struct s_autotrader *at = NULL; // Init each autotrader data while (SQL_SUCCESS == Sql_NextRow(mmysql_handle)) { size_t len; char* data; at = NULL; CREATE(at, struct s_autotrader, 1); Sql_GetData(mmysql_handle, 0, &data, NULL); at->id = atoi(data); Sql_GetData(mmysql_handle, 1, &data, NULL); at->account_id = atoi(data); Sql_GetData(mmysql_handle, 2, &data, NULL); at->char_id = atoi(data); Sql_GetData(mmysql_handle, 3, &data, NULL); at->sex = (data[0] == 'F') ? 0 : 1; Sql_GetData(mmysql_handle, 4, &data, &len); safestrncpy(at->title, data, zmin(len + 1, MESSAGE_SIZE)); Sql_GetData(mmysql_handle, 5, &data, NULL); at->limit = atoi(data); Sql_GetData(mmysql_handle, 6, &data, NULL); at->dir = atoi(data); Sql_GetData(mmysql_handle, 7, &data, NULL); at->head_dir = atoi(data); Sql_GetData(mmysql_handle, 8, &data, NULL); at->sit = atoi(data); at->count = 0; if (battle_config.feature_autotrade_direction >= 0) at->dir = battle_config.feature_autotrade_direction; if (battle_config.feature_autotrade_head_direction >= 0) at->head_dir = battle_config.feature_autotrade_head_direction; if (battle_config.feature_autotrade_sit >= 0) at->sit = battle_config.feature_autotrade_sit; // initialize player CREATE(at->sd, struct map_session_data, 1); pc_setnewpc(at->sd, at->account_id, at->char_id, 0, gettick(), at->sex, 0); at->sd->state.autotrade = 1|4; at->sd->state.monster_ignore = (battle_config.autotrade_monsterignore); chrif_authreq(at->sd, true); uidb_put(buyingstore_autotrader_db, at->char_id, at); } Sql_FreeResult(mmysql_handle); // Init items for each autotraders iter = db_iterator(buyingstore_autotrader_db); for (at = (struct s_autotrader *)dbi_first(iter); dbi_exists(iter); at = (struct s_autotrader *)dbi_next(iter)) { uint16 j = 0; if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT `item_id`, `amount`, `price` " "FROM `%s` " "WHERE `buyingstore_id` = %d " "ORDER BY `index` ASC;", buyingstore_items_table, at->id ) ) { Sql_ShowDebug(mmysql_handle); continue; } if (!(at->count = (uint16)Sql_NumRows(mmysql_handle))) { map_quit(at->sd); buyingstore_autotrader_remove(at, true); continue; } //Init the list CREATE(at->entries, struct s_autotrade_entry *,at->count); //Add the item into list j = 0; while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && j < at->count) { char *data; CREATE(at->entries[j], struct s_autotrade_entry, 1); Sql_GetData(mmysql_handle, 0, &data, NULL); at->entries[j]->item_id = atoi(data); Sql_GetData(mmysql_handle, 1, &data, NULL); at->entries[j]->amount = atoi(data); Sql_GetData(mmysql_handle, 2, &data, NULL); at->entries[j]->price = atoi(data); j++; } items += j; Sql_FreeResult(mmysql_handle); } dbi_destroy(iter); ShowStatus("Done loading '"CL_WHITE"%d"CL_RESET"' buyingstore autotraders with '"CL_WHITE"%d"CL_RESET"' items.\n", db_size(buyingstore_autotrader_db), items); } }
/*========================================== * (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; }
bool CStatusEffectContainer::AddStatusEffect(CStatusEffect* PStatusEffect, bool silent) { if(PStatusEffect == nullptr){ ShowWarning("status_effect_container::AddStatusEffect Status effect given was nullptr!\n"); return false; } uint16 statusId = PStatusEffect->GetStatusID(); if(statusId >= MAX_EFFECTID){ ShowWarning("status_effect_container::AddStatusEffect statusId given is OVER limit %d\n", statusId); return false; } if(CanGainStatusEffect((EFFECT)statusId, PStatusEffect->GetPower())) { // check for minimum duration if(PStatusEffect->GetDuration() < effects::EffectsParams[statusId].MinDuration){ PStatusEffect->SetDuration(effects::EffectsParams[statusId].MinDuration); } // remove clean up other effects OverwriteStatusEffect(PStatusEffect); PStatusEffect->SetOwner(m_POwner); SetEffectParams(PStatusEffect); // remove effects with same type DelStatusEffectsByType(PStatusEffect->GetType()); PStatusEffect->SetStartTime(gettick()); m_StatusEffectList.push_back(PStatusEffect); luautils::OnEffectGain(m_POwner, PStatusEffect); m_POwner->addModifiers(&PStatusEffect->modList); if (PStatusEffect->GetStatusID() >= EFFECT_FIRE_MANEUVER && PStatusEffect->GetStatusID() <= EFFECT_DARK_MANEUVER && m_POwner->objtype == TYPE_PC) { puppetutils::CheckAttachmentsForManeuver((CCharEntity*)m_POwner, PStatusEffect->GetStatusID(), true); } if( m_POwner->health.maxhp != 0) //make sure we're not in the middle of logging in { m_POwner->UpdateHealth(); } if (m_POwner->objtype == TYPE_PC) { CCharEntity* PChar = (CCharEntity*)m_POwner; if (PStatusEffect->GetIcon() != 0) { UpdateStatusIcons(); } if( m_POwner->health.maxhp != 0) //make sure we're not in the middle of logging in { //check for latents PChar->PLatentEffectContainer->CheckLatentsFoodEffect(); PChar->PLatentEffectContainer->CheckLatentsStatusEffect(); PChar->PLatentEffectContainer->CheckLatentsRollSong(PStatusEffect->GetFlag() & (EFFECTFLAG_SONG | EFFECTFLAG_ROLL)); PChar->UpdateHealth(); PChar->pushPacket(new CCharHealthPacket(PChar)); } PChar->pushPacket(new CCharSyncPacket(PChar)); } m_POwner->updatemask |= UPDATE_HP; return true; } return false; }
void harmony_action_request_global(int task, int id, intptr data) { switch (task) { case HARMTASK_LOGIN_ACTION: chrif_harmony_request((uint8*)data, id); break; case HARMTASK_GET_FD: { TBL_PC *sd = BL_CAST(BL_PC, map_id2bl(id)); *(int32*)data = (sd ? sd->fd : 0); } break; case HARMTASK_SET_LOG_METHOD: log_method = id; break; case HARMTASK_INIT_GROUPS: if (chrif_isconnected()) harmony_register_groups(); else { // Register groups as soon as the char server is available again if (tid_group_register != INVALID_TIMER) delete_timer(tid_group_register, harmony_group_register_timer); tid_group_register = add_timer_interval(gettick()+1000, harmony_group_register_timer, 0, 0, 500); } break; case HARMTASK_RESOLVE_GROUP: #if HARMSW == HARMSW_RATHENA_GROUP *(int32*)data = pc_group_id2level(id); #else *(int32*)data = id; #endif break; case HARMTASK_PACKET: clif_send((const uint8*)data, id, NULL, ALL_CLIENT); break; case HARMTASK_GET_ADMINS: { #if HARMSW == HARMSW_RATHENA_GROUP // Iterate groups and register each group individually current_groupscan_minlevel = id; pc_group_iterate(harmony_iterate_groups_adminlevel); #else // int account_id; int level = id; if (SQL_SUCCESS != SqlStmt_BindParam(admin_stmt, 0, SQLDT_INT, (void*)&level, sizeof(level)) || SQL_SUCCESS != SqlStmt_Execute(admin_stmt)) { ShowError("Fetching GM accounts failed.\n"); Sql_ShowDebug(mmysql_handle); break; } SqlStmt_BindColumn(admin_stmt, 0, SQLDT_INT, &account_id, 0, NULL, NULL); while (SQL_SUCCESS == SqlStmt_NextRow(admin_stmt)) { harm_funcs->zone_register_admin(account_id, false); } #endif break; } case HARMTASK_IS_CHAR_CONNECTED: *(int*)data = chrif_isconnected(); break; default: ShowError("Harmony requested unknown action! (Global; ID=%d)\n", task); ShowError("This indicates that you are running an incompatible version.\n"); break; } }
int pet_data_init(struct map_session_data *sd, struct s_pet *pet) { struct pet_data *pd; int i=0,interval=0; nullpo_retr(1, sd); Assert((sd->status.pet_id == 0 || sd->pd == 0) || sd->pd->msd == sd); if(sd->status.account_id != pet->account_id || sd->status.char_id != pet->char_id) { sd->status.pet_id = 0; return 1; } if (sd->status.pet_id != pet->pet_id) { if (sd->status.pet_id) { //Wrong pet?? Set incuvate to no and send it back for saving. pet->incuvate = 1; intif_save_petdata(sd->status.account_id,pet); sd->status.pet_id = 0; return 1; } //The pet_id value was lost? odd... restore it. sd->status.pet_id = pet->pet_id; } i = search_petDB_index(pet->class_,PET_CLASS); if(i < 0) { sd->status.pet_id = 0; return 1; } sd->pd = pd = (struct pet_data *)aCalloc(1,sizeof(struct pet_data)); pd->bl.type = BL_PET; pd->bl.id = npc_get_new_npc_id(); pd->msd = sd; pd->petDB = &pet_db[i]; pd->db = mob_db(pet->class_); memcpy(&pd->pet, pet, sizeof(struct s_pet)); status_set_viewdata(&pd->bl, pet->class_); unit_dataset(&pd->bl); pd->ud.dir = sd->ud.dir; pd->bl.m = sd->bl.m; pd->bl.x = sd->bl.x; pd->bl.y = sd->bl.y; unit_calc_pos(&pd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); pd->bl.x = pd->ud.to_x; pd->bl.y = pd->ud.to_y; map_addiddb(&pd->bl); status_calc_pet(pd,1); pd->last_thinktime = gettick(); pd->state.skillbonus = 0; if( battle_config.pet_status_support ) run_script(pet_db[i].pet_script,0,sd->bl.id,0); if( pd->petDB && pd->petDB->equip_script ) status_calc_pc(sd,0); if( battle_config.pet_hungry_delay_rate != 100 ) interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100; else interval = pd->petDB->hungry_delay; if( interval <= 0 ) interval = 1; pd->pet_hungry_timer = add_timer(gettick() + interval, pet_hungry, sd->bl.id, 0); return 0; }
void CZone::UpdateWeather() { uint32 CurrentVanaDate = CVanaTime::getInstance()->getDate(); // Current Vanadiel timestamp in minutes uint32 StartFogVanaDate = (CurrentVanaDate - (CurrentVanaDate % VTIME_DAY)) + (VTIME_HOUR * 2); // Vanadiel timestamp of 2 AM in minutes uint32 EndFogVanaDate = StartFogVanaDate + (VTIME_HOUR * 5); // Vanadiel timestamp of 7 AM in minutes uint32 WeatherNextUpdate = 0; uint32 WeatherDay = 0; uint8 WeatherOffset = 0; uint8 WeatherChance = 0; // Random time between 3 minutes and 30 minutes for the next weather change WeatherNextUpdate = (dsprand::GetRandomNumber(180,1620)); // Find the timestamp since the start of vanadiel WeatherDay = CVanaTime::getInstance()->getVanaTime(); // Calculate what day we are on since the start of vanadiel time // 1 Vana'diel Day = 57 minutes 36 seconds or 3456 seconds WeatherDay = WeatherDay / 3456; // The weather starts over again every 2160 days WeatherDay = WeatherDay % WEATHER_CYCLE; // Get a random number to determine which weather effect we will use WeatherChance = dsprand::GetRandomNumber(100); zoneWeather_t&& weatherType = zoneWeather_t(0, 0, 0); for (auto& weather : m_WeatherVector) { if (weather.first > WeatherDay) { break; } weatherType = weather.second; } uint8 Weather = 0; // 15% chance for rare weather, 35% chance for common weather, 50% chance for normal weather // * Percentages were generated from a 6 hour sample and rounded down to closest multiple of 5* if (WeatherChance <= 15) //15% chance to have the weather_rare { Weather = weatherType.rare; } else if (WeatherChance <= 50) // 35% chance to have weather_common { Weather = weatherType.common; } else { Weather = weatherType.normal; } // Fog in the morning between the hours of 2 and 7 if there is not a specific elemental weather to override it if ((CurrentVanaDate >= StartFogVanaDate) && (CurrentVanaDate < EndFogVanaDate) && (Weather < WEATHER_HOT_SPELL) && (GetType() > ZONETYPE_CITY)) { Weather = WEATHER_FOG; //Force the weather to change by 7 am // 2.4 vanadiel minutes = 1 earth second WeatherNextUpdate = (uint32)((EndFogVanaDate - CurrentVanaDate) * 2.4); } SetWeather((WEATHER)Weather); luautils::OnZoneWeatherChange(GetID(), Weather); //ShowDebug(CL_YELLOW"Zone::zone_update_weather: Weather of %s updated to %u\n" CL_RESET, PZone->GetName(), Weather); CTaskMgr::getInstance()->AddTask(new CTaskMgr::CTask("zone_update_weather", gettick() + (WeatherNextUpdate * 1000), this, CTaskMgr::TASK_ONCE, zone_update_weather)); }