viewing paste Unknown #12142 | Text

Posted on the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
/*==========================================
 * Standard call when a player connection is closed.
 *------------------------------------------*/
int map_quit(struct map_session_data *sd) {
    int i;
 
    if(!sd->state.active) { //Removing a player that is not active.
        struct auth_node *node = chrif->search(sd->status.account_id);
        if (node && node->char_id == sd->status.char_id &&
            node->state != ST_LOGOUT)
            //Except when logging out, clear the auth-connect data immediately.
            chrif->auth_delete(node->account_id, node->char_id, node->state);
        //Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed.
        return 0;
    }
    
    if( sd->expiration_tid != INVALID_TIMER )
        timer->delete(sd->expiration_tid,pc->expiration_timer);
 
    if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
        npc->timerevent_quit(sd);
 
    if (sd->npc_id)
        npc->event_dequeue(sd);
 
    if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
        bg->team_leave(sd,1);
 
    if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing )
        pc->autotrade_update(sd,PAUC_REMOVE);
 
    skill->cooldown_save(sd);
    pc->itemcd_do(sd,false);
 
    for( i = 0; i < sd->queues_count; i++ ) {
        struct hQueue *queue;
        if( (queue = script->queue(sd->queues[i])) && queue->onLogOut[0] != '\0' ) {
            npc->event(sd, queue->onLogOut, 0);
        }
    }
    /* two times, the npc event above may assign a new one or delete others */
    for( i = 0; i < sd->queues_count; i++ ) {
        if( sd->queues[i] != -1 )
            script->queue_remove(sd->queues[i],sd->status.account_id);
    }
 
    npc->script_event(sd, NPCE_LOGOUT);
 
    //BEGIN Added by Matias [Harmony]
    harmony_logout(sd);
    //END Added
 
    //Unit_free handles clearing the player related data,
    //map->quit handles extra specific data which is related to quitting normally
    //(changing map-servers invokes unit_free but bypasses map->quit)
    if( sd->sc.count ) {
        //Status that are not saved...
        for(i=0; i < SC_MAX; i++){
            if ( status->get_sc_type(i)&SC_NO_SAVE ) {
                if ( !sd->sc.data[i] )
                    continue;
                switch( i ){
                    case SC_ENDURE:
                    case SC_GDSKILL_REGENERATION:
                        if( !sd->sc.data[i]->val4 )
                            break;
                    default:
                        status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
                }
            }
        }
    }
 
    for( i = 0; i < EQI_MAX; i++ ) {
        if( sd->equip_index[ i ] >= 0 )
            if( !pc->isequip( sd , sd->equip_index[ i ] ) )
                pc->unequipitem( sd , sd->equip_index[ i ] , 2 );
    }
 
    // Return loot to owner
    if( sd->pd ) pet->lootitem_drop(sd->pd, sd);
 
    if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
 
    if( sd->ed ) {
        elemental->clean_effect(sd->ed);
        unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK);
    }
 
    if( hChSys.local && map->list[sd->bl.m].channel && idb_exists(map->list[sd->bl.m].channel->users, sd->status.char_id) ) {
        clif->chsys_left(map->list[sd->bl.m].channel,sd);
    }
 
    clif->chsys_quit(sd);
 
    unit->remove_map_pc(sd,CLR_RESPAWN);
 
    if( map->list[sd->bl.m].instance_id >= 0 ) { // Avoid map conflicts and warnings on next login
        int16 m;
        struct point *pt;
        if( map->list[sd->bl.m].save.map )
            pt = &map->list[sd->bl.m].save;
        else
            pt = &sd->status.save_point;
 
        if( (m=map->mapindex2mapid(pt->map)) >= 0 ) {
            sd->bl.m = m;
            sd->bl.x = pt->x;
            sd->bl.y = pt->y;
            sd->mapindex = pt->map;
        }
    }
 
    if( sd->state.vending ) {
        idb_remove(vending->db, sd->status.char_id);
    }
    
    party->booking_delete(sd); // Party Booking [Spiria]
    pc->makesavestatus(sd);
    pc->clean_skilltree(sd);
    chrif->save(sd,1);
    unit->free_pc(sd);
    return 0;
}
Viewed 884 times, submitted by Xgear.