void SECTREE::DecreasePC() { LPSECTREE_LIST::iterator it_tree = m_neighbor_list.begin(); while (it_tree != m_neighbor_list.end()) { LPSECTREE tree = *it_tree++; if (--tree->m_iPCCount <= 0) { if (tree->m_iPCCount < 0) { sys_err("tree pc count lower than zero (value %d coord %d %d)", tree->m_iPCCount, tree->m_id.coord.x, tree->m_id.coord.y); tree->m_iPCCount = 0; } ENTITY_SET::iterator it_entity = tree->m_set_entity.begin(); while (it_entity != tree->m_set_entity.end()) { LPENTITY pkEnt = *(it_entity++); if (pkEnt->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) pkEnt; ch->StopStateMachine(); } } } } }
void operator () (LPENTITY ent) { if (ent == m_except) return; if (ent->GetDesc()) ent->GetDesc()->Packet(m_data, m_bytes); }
void CEntity::ViewCleanup() { ENTITY_MAP::iterator it = m_map_view.begin(); while (it != m_map_view.end()) { LPENTITY entity = it->first; ++it; entity->ViewRemove(this, false); } m_map_view.clear(); }
void CEntity::ViewRemove(LPENTITY entity, bool recursive) { ENTITY_MAP::iterator it = m_map_view.find(entity); if (it == m_map_view.end()) return; m_map_view.erase(it); if (!entity->m_bIsObserver) entity->EncodeRemovePacket(this); if (recursive) entity->ViewRemove(this, false); }
void CObject::EncodeInsertPacket(LPENTITY entity) { LPDESC d; if (!(d = entity->GetDesc())) return; sys_log(0, "ObjectInsertPacket vid %u vnum %u rot %f %f %f", m_dwVID, m_data.dwVnum, m_data.xRot, m_data.yRot, m_data.zRot); TPacketGCCharacterAdd pack; memset(&pack, 0, sizeof(TPacketGCCharacterAdd)); pack.header = HEADER_GC_CHARACTER_ADD; pack.dwVID = m_dwVID; pack.bType = CHAR_TYPE_BUILDING; pack.angle = m_data.zRot; pack.x = GetX(); pack.y = GetY(); pack.z = GetZ(); pack.wRaceNum = m_data.dwVnum; // 빌딩 회전 정보(벽일때는 문 위치)를 변환 pack.dwAffectFlag[0] = unsigned(m_data.xRot); pack.dwAffectFlag[1] = unsigned(m_data.yRot); if (GetLand()) { // pack.dwGuild = GetLand()->GetOwner(); } d->Packet(&pack, sizeof(pack)); }
void SECTREE::RemoveEntity(LPENTITY pkEnt) { ENTITY_SET::iterator it = m_set_entity.find(pkEnt); if (it == m_set_entity.end()) { return; } m_set_entity.erase(it); pkEnt->SetSectree(NULL); if (pkEnt->IsType(ENTITY_CHARACTER)) { if (((LPCHARACTER) pkEnt)->IsPC()) DecreasePC(); } }
void SECTREE::Destroy() { if (!m_set_entity.empty()) { sys_err("Sectree: entity set not empty!!"); ENTITY_SET::iterator it = m_set_entity.begin(); for ( ; it != m_set_entity.end(); ++it) { LPENTITY ent = *it; if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; sys_err("Sectree: destroying character: %s is_pc %d", ch->GetName(), ch->IsPC() ? 1 : 0); if (ch->GetDesc()) DESC_MANAGER::instance().DestroyDesc(ch->GetDesc()); else M2_DESTROY_CHARACTER(ch); } else if (ent->IsType(ENTITY_ITEM)) { LPITEM item = (LPITEM) ent; sys_err("Sectree: destroying Item: %s", item->GetName()); M2_DESTROY_ITEM(item); } else sys_err("Sectree: unknown type: %d", ent->GetType()); } } m_set_entity.clear(); if (!isClone && m_pkAttribute) { M2_DELETE(m_pkAttribute); m_pkAttribute = NULL; } }
void operator() (LPENTITY ent) { if (true == ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = static_cast<LPCHARACTER>(ent); if (false == ch->IsPC()) { ch->Dead(); } } }
void FWarpEmpire::operator() (LPENTITY ent) { if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; if (ch->IsPC() && ch->GetEmpire() == m_bEmpire) { ch->WarpSet(m_x, m_y, m_lMapIndexTo); } } }
void FSendPacket::operator() (LPENTITY ent) { if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; if (ch->GetDesc()) { ch->GetDesc()->Packet(buf.read_peek(), buf.size()); } } }
void CEntity::ViewInsert(LPENTITY entity, bool recursive) { if (this == entity) return; ENTITY_MAP::iterator it = m_map_view.find(entity); if (m_map_view.end() != it) { it->second = m_iViewAge; return; } m_map_view.insert(ENTITY_MAP::value_type(entity, m_iViewAge)); if (!entity->m_bIsObserver) entity->EncodeInsertPacket(this); if (recursive) entity->ViewInsert(this, false); }
bool SECTREE::InsertEntity(LPENTITY pkEnt) { LPSECTREE pkCurTree; if ((pkCurTree = pkEnt->GetSectree()) == this) return false; if (m_set_entity.find(pkEnt) != m_set_entity.end()) { sys_err("entity %p already exist in this sectree!", get_pointer(pkEnt)); return false; } if (pkCurTree) pkCurTree->m_set_entity.erase(pkEnt); pkEnt->SetSectree(this); //pkEnt->UpdateSectree(); m_set_entity.insert(pkEnt); if (pkEnt->IsType(ENTITY_CHARACTER)) { LPCHARACTER pkChr = (LPCHARACTER) pkEnt; if (pkChr->IsPC()) { IncreasePC(); if (pkCurTree) pkCurTree->DecreasePC(); } else if (m_iPCCount > 0 && !pkChr->IsWarp() && !pkChr->IsGoto()) // PC가 아니고 이 곳에 PC가 있다면 Idle event를 시작 시킨다. { pkChr->StartStateMachine(); } } return true; }
void CEntity::ViewReencode() { if (m_bIsObserver) return; EncodeRemovePacket(this); EncodeInsertPacket(this); ENTITY_MAP::iterator it = m_map_view.begin(); while (it != m_map_view.end()) { LPENTITY entity = (it++)->first; EncodeRemovePacket(entity); if (!m_bIsObserver) EncodeInsertPacket(entity); if (!entity->m_bIsObserver) entity->EncodeInsertPacket(this); } }
void CItem::EncodeRemovePacket(LPENTITY ent) { LPDESC d; if (!(d = ent->GetDesc())) return; struct packet_item_ground_del pack; pack.bHeader = HEADER_GC_ITEM_GROUND_DEL; pack.dwVID = m_dwVID; d->Packet(&pack, sizeof(pack)); sys_log(2, "Item::EncodeRemovePacket %s to %s", GetName(), ((LPCHARACTER) ent)->GetName()); }
void CObject::EncodeRemovePacket(LPENTITY entity) { LPDESC d; if (!(d = entity->GetDesc())) return; sys_log(0, "ObjectRemovePacket vid %u", m_dwVID); TPacketGCCharacterDelete pack; pack.header = HEADER_GC_CHARACTER_DEL; pack.id = m_dwVID; d->Packet(&pack, sizeof(TPacketGCCharacterDelete)); }
void operator () (LPENTITY ent) { if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; if (ch->IsMonster()) { return; } if (sx <= ch->GetX() && ch->GetX() <= ex && sy <= ch->GetY() && ch->GetY() <= ey) { bIn = true; } } }
void operator()(LPENTITY ent) { if (NULL != ent && true == ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER pChar = static_cast<LPCHARACTER>(ent); if (true == pChar->IsPC()) { if (NULL != pChar->GetGuild()) { if (dwGuildID == pChar->GetGuild()->GetID()) { pChar->WarpSet(x, y, mapIndex); } } } } }
void operator () (LPENTITY ent) { // 오브젝트가 아닌 것은 거리를 계산하여 거리가 멀면 추가하지 않는다. if (!ent->IsType(ENTITY_OBJECT)) if (DISTANCE_APPROX(ent->GetX() - m_me->GetX(), ent->GetY() - m_me->GetY()) > dwViewRange) return; // 나를 대상에 추가 m_me->ViewInsert(ent); // 둘다 캐릭터면 if (ent->IsType(ENTITY_CHARACTER) && m_me->IsType(ENTITY_CHARACTER)) { LPCHARACTER chMe = (LPCHARACTER) m_me; LPCHARACTER chEnt = (LPCHARACTER) ent; // 대상이 NPC면 StateMachine을 킨다. if (chMe->IsPC() && !chEnt->IsPC() && !chEnt->IsWarp() && !chEnt->IsGoto()) chEnt->StartStateMachine(); } }
void CItem::EncodeInsertPacket(LPENTITY ent) { LPDESC d; if (!(d = ent->GetDesc())) return; const PIXEL_POSITION & c_pos = GetXYZ(); struct packet_item_ground_add pack; pack.bHeader = HEADER_GC_ITEM_GROUND_ADD; pack.x = c_pos.x; pack.y = c_pos.y; pack.z = c_pos.z; pack.dwVnum = GetVnum(); pack.dwVID = m_dwVID; //pack.count = m_dwCount; d->Packet(&pack, sizeof(pack)); if (m_pkOwnershipEvent != NULL) { item_event_info * info = dynamic_cast<item_event_info *>(m_pkOwnershipEvent->info); if ( info == NULL ) { sys_err( "CItem::EncodeInsertPacket> <Factor> Null pointer" ); return; } TPacketGCItemOwnership p; p.bHeader = HEADER_GC_ITEM_OWNERSHIP; p.dwVID = m_dwVID; strlcpy(p.szName, info->szOwnerName, sizeof(p.szName)); d->Packet(&p, sizeof(TPacketGCItemOwnership)); } }
void CEntity::UpdateSectree() { if (!GetSectree()) { if (IsType(ENTITY_CHARACTER)) { LPCHARACTER tch = (LPCHARACTER) this; sys_err("null sectree name: %s %d %d", tch->GetName(), GetX(), GetY()); } return; } ++m_iViewAge; CFuncViewInsert f(this); // 나를 섹트리에 있는 사람들에게 추가 GetSectree()->ForEachAround(f); ENTITY_MAP::iterator it, this_it; // // m_map_view에서 필요 없는 녀석들 지우기 // if (m_bObserverModeChange) { if (m_bIsObserver) { it = m_map_view.begin(); while (it != m_map_view.end()) { this_it = it++; if (this_it->second < m_iViewAge) { LPENTITY ent = this_it->first; // 나로 부터 상대방을 지운다. ent->EncodeRemovePacket(this); m_map_view.erase(this_it); // 상대로 부터 나를 지운다. ent->ViewRemove(this, false); } else { LPENTITY ent = this_it->first; // 나로 부터 상대방을 지운다. //ent->EncodeRemovePacket(this); //m_map_view.erase(this_it); // 상대로 부터 나를 지운다. //ent->ViewRemove(this, false); EncodeRemovePacket(ent); } } } else { it = m_map_view.begin(); while (it != m_map_view.end()) { this_it = it++; if (this_it->second < m_iViewAge) { LPENTITY ent = this_it->first; // 나로 부터 상대방을 지운다. ent->EncodeRemovePacket(this); m_map_view.erase(this_it); // 상대로 부터 나를 지운다. ent->ViewRemove(this, false); } else { LPENTITY ent = this_it->first; ent->EncodeInsertPacket(this); EncodeInsertPacket(ent); ent->ViewInsert(this, true); } } } m_bObserverModeChange = false; } else { if (!m_bIsObserver) { it = m_map_view.begin(); while (it != m_map_view.end()) { this_it = it++; if (this_it->second < m_iViewAge) { LPENTITY ent = this_it->first; // 나로 부터 상대방을 지운다. ent->EncodeRemovePacket(this); m_map_view.erase(this_it); // 상대로 부터 나를 지운다. ent->ViewRemove(this, false); } } } } }
bool operator () (LPENTITY ent) { if (!ent->IsType(ENTITY_CHARACTER)) return false; LPCHARACTER pkChr = (LPCHARACTER) ent; if (pkChr->IsBuilding() && (pkChr->IsAffectFlag(AFF_BUILDING_CONSTRUCTION_SMALL) || pkChr->IsAffectFlag(AFF_BUILDING_CONSTRUCTION_LARGE) || pkChr->IsAffectFlag(AFF_BUILDING_UPGRADE))) { m_pkChrBuilding = pkChr; } if (pkChr->IsNPC()) { if ( !pkChr->IsMonster() || !m_pkChr->IsAttackMob() || m_pkChr->IsAggressive() ) return false; } if (pkChr->IsDead()) return false; if (pkChr->IsAffectFlag(AFF_EUNHYUNG) || pkChr->IsAffectFlag(AFF_INVISIBILITY) || pkChr->IsAffectFlag(AFF_REVIVE_INVISIBLE)) return false; if (pkChr->IsAffectFlag(AFF_TERROR) && m_pkChr->IsImmune(IMMUNE_TERROR) == false ) // 공포 처리 { if ( pkChr->GetLevel() >= m_pkChr->GetLevel() ) return false; } if ( m_pkChr->IsNoAttackShinsu() ) { if ( pkChr->GetEmpire() == 1 ) return false; } if ( m_pkChr->IsNoAttackChunjo() ) { if ( pkChr->GetEmpire() == 2 ) return false; } if ( m_pkChr->IsNoAttackJinno() ) { if ( pkChr->GetEmpire() == 3 ) return false; } int iDistance = DISTANCE_APPROX(m_lx - pkChr->GetX(), m_ly - pkChr->GetY()); if (iDistance < m_iMinDistance && iDistance <= m_iMaxDistance) { m_pkChrVictim = pkChr; m_iMinDistance = iDistance; } return true; }