double solve() { int i,j,k,l,m; double x1,y1,x2,y2; /* calculate distances and tangent points for each circle pair */ for(i=0;i<2;i++) for(j=0;j<2;j++) for(k=0;k<n;k++) for(l=0;l<n;l++) dist[i][j][k][l]=-1; memset(theta1,0,sizeof(theta1)); memset(theta2,0,sizeof(theta2)); for(i=0;i<2;i++) for(j=0;j<2;j++) for(k=0;k<n;k++) for(l=0;l<n;l++) if(k!=l) { if(k==1) continue; if((k<2 && i) || (l<2 && j)) continue; twocircletangent(circlex[k],circley[k],circler[k], circlex[l],circley[l],circler[l],i,j,&x1,&y1,&x2,&y2); /* for each other circle: check if it collides */ for(m=0;m<n;m++) if(m!=k && m!=l && linecircleintersect(x1,y1,x2,y2, circlex[m],circley[m],circler[m])) goto fail; // printf("ix (%d %d) %d %d\n",i,j,k,l);printf("from circle (%.1f %.1f %d) to (%.1f %.1f %d): (%f %f) (%f %f)\n",circlex[k],circley[k],circler[k],circlex[l],circley[l],circler[l],x1,y1,x2,y2);printf("dist %.10f\n",dist2d(x1,y1,x2,y2)); dist[i][j][k][l]=dist2d(x1,y1,x2,y2); tx1[i][j][k][l]=x1; ty1[i][j][k][l]=y1; tx2[i][j][k][l]=x2; ty2[i][j][k][l]=y2; theta1[i][j][k][l]=getangle(x1,y1,circlex[k],circley[k]); theta2[i][j][k][l]=getangle(x2,y2,circlex[l],circley[l]); fail:; } // for(i=0;i<2;i++) for(j=0;j<2;j++) for(k=0;k<n;k++) for(l=0;l<n;l++) if(dist[i][j][k][l]>-.5) {printf("%d %d %d %d: %f (%.3f %.3f) (%.3f %.3f) (%.2f %.2f)\n",i,j,k,l,dist[i][j][k][l],tx1[i][j][k][l],ty1[i][j][k][l],tx2[i][j][k][l],ty2[i][j][k][l],theta1[i][j][k][l],theta2[i][j][k][l]);} return dijkstra(); }
int pointisccw(double x1, double y1, double x2, double y2, double px, double py) { double angle = getangle(x1, y1, x2, y2); double angle2 = getangle(x2, y2, px, py); if (normalizeangle(angle2-angle) > 0) { // point is to the "left" side -> counter-clockwise return 1; } // point is to the "right" side -> not counter-clockwise return 0; }
void work() { nac = nzero = 0; for (int i = 0; i < n; ++i) { int x, y; scanf("%d%d", &x, &y); pt[i] = {x, y, 0}; } for (int i = 0; i < n; ++i) { std::memcpy(sorted, pt, n * sizeof(sorted[0])); std::swap(sorted[n - 1], sorted[i]); base = sorted[n - 1]; for (int i = 0; i < n; ++i) sorted[i].angle = getangle(sorted[i] - base); std::sort(sorted, sorted + n - 1, [](const Point& a, const Point& b){ //return cross(a - base, b - base) < 0; //return getangle(a - base) < getangle(b - base); return a.angle < b.angle; }); //std::cout << "BASE " << base.x << ' ' << base.y << std::endl; //for (int j = 0; j < n - 1; ++j) //std::cout << j << ' ' << sorted[j].x << ' ' << sorted[j].y << std::endl; work2(); } long long ttl = (long long) n * (n - 1) * (n - 2) / 2; long long fans = ttl - nac; //std::cout << "RESULT " << nac << ' ' << nzero << ' ' << ttl << std::endl; std::cout << ttl / 3 - fans << std::endl; }
void CPathFind::LookAt(position_t point) { // don't look if i'm at that point if (!AtPoint(&point)){ m_PTarget->loc.p.rotation = getangle(m_PTarget->loc.p, point); } m_PTarget->updatemask |= UPDATE_POS; }
short SoundAngle(int x, int y) { extern short screenpeek; short angle, delta_angle; angle = getangle(x - Player[screenpeek].posx, y - Player[screenpeek].posy); delta_angle = GetDeltaAngle(angle, Player[screenpeek].pang); // convert a delta_angle to a real angle if negative if (delta_angle < 0) delta_angle = NORM_ANGLE((1024 + delta_angle) + 1024); // convert 2048 degree angle to 32 degree angle return delta_angle >> 6; }
void CEnmityContainer::LowerEnmityByPercent(CBattleEntity* PEntity, uint8 percent, CBattleEntity* HateReceiver) { EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if (PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float mod = ((float)(percent) / 100.0f); int32 CEValue = (float)(PEnmity->second->CE * mod); PEnmity->second->CE -= (CEValue < 0 ? 0 : CEValue); int32 VEValue = (float)(PEnmity->second->VE * mod); PEnmity->second->VE -= (VEValue < 0 ? 0 : VEValue); // transfer hate if HateReceiver not nullptr if (HateReceiver != nullptr) { UpdateEnmity(HateReceiver, 0, 0); EnmityList_t::iterator PEnmityReceiver = m_EnmityList.lower_bound(HateReceiver->id); PEnmityReceiver->second->CE = dsp_cap(PEnmityReceiver->second->CE + CEValue,1,10000); PEnmityReceiver->second->VE = dsp_cap(PEnmityReceiver->second->VE + VEValue,0,10000); } } // highest enmity holder after this update CBattleEntity* NewEntity = GetHighestEnmity(); // PEntity is now the target, face the target if (OldEntity != NewEntity && !m_EnmityHolder->isAsleep()) { if ((m_EnmityHolder->objtype == TYPE_MOB && !(((CMobEntity*)m_EnmityHolder)->m_Behaviour & BEHAVIOUR_NO_TURN)) || m_EnmityHolder->objtype != TYPE_MOB) { uint8 angle = getangle(m_EnmityHolder->loc.p, NewEntity->loc.p); m_EnmityHolder->loc.p.rotation = angle; m_EnmityHolder->loc.zone->PushPacket(m_EnmityHolder, CHAR_INRANGE, new CEntityUpdatePacket(m_EnmityHolder, ENTITY_UPDATE, UPDATE_POS)); } } }
void CEnmityContainer::LowerEnmityByPercent(CBattleEntity* PEntity, uint8 percent, CBattleEntity* HateReceiver) { EnmityList_t::iterator PEnmity = m_EnmityList.lower_bound(PEntity->id); // current highest enmity before this update CBattleEntity* OldEntity = GetHighestEnmity(); if( PEnmity != m_EnmityList.end() && !m_EnmityList.key_comp()(PEntity->id, PEnmity->first)) { float mod = ((float)(percent)/100.0f); int32 CEValue = (float)(PEnmity->second->CE * mod); PEnmity->second->CE -= (CEValue < 0 ? 0 : CEValue); int32 VEValue = (float)(PEnmity->second->VE * mod); PEnmity->second->VE -= (VEValue < 0 ? 0 : VEValue); // transfer hate if HateReceiver not null if (HateReceiver != NULL) { UpdateEnmity(HateReceiver,0,0); EnmityList_t::iterator PEnmityReceiver = m_EnmityList.lower_bound(HateReceiver->id); PEnmityReceiver->second->CE += CEValue; PEnmityReceiver->second->VE += VEValue; } } // highest enmity holder after this update CBattleEntity* NewEntity = GetHighestEnmity(); // PEntity is now the target, face the target if (OldEntity != NewEntity && !m_EnmityHolder->isAsleep()) { uint8 angle = getangle(m_EnmityHolder->loc.p, NewEntity->loc.p); m_EnmityHolder->loc.p.rotation = angle; m_EnmityHolder->loc.zone->PushPacket(m_EnmityHolder,CHAR_INRANGE, new CEntityUpdatePacket(m_EnmityHolder, ENTITY_UPDATE)); } }
void CAIMobDummy::ActionRoaming() { if (m_PMob->PEnmityContainer->GetHighestEnmity() != NULL) { m_ActionType = ACTION_ENGAGE; ActionEngage(); } else if (m_PMob->m_OwnerID != 0) { uint16 TargID = m_PMob->m_OwnerID & 0x0FFF; m_PBattleTarget = (CBattleEntity*)m_PMob->loc.zone->GetEntity(TargID, TYPE_PC | TYPE_MOB | TYPE_PET); // TODO: возможно необходимо добавлять цели базовое количество ненависти m_ActionType = ACTION_ENGAGE; ActionEngage(); } else if ((m_Tick - m_LastActionTime) > 45000 && m_PMob->m_Type != MOBTYPE_EVENT) { m_LastActionTime = m_Tick - rand()%30000; position_t RoamingPoint; RoamingPoint.x = m_PMob->m_SpawnPoint.x - 1 + rand()%2; RoamingPoint.y = m_PMob->m_SpawnPoint.y; RoamingPoint.z = m_PMob->m_SpawnPoint.z - 1 + rand()%2; m_PMob->loc.p.rotation = getangle(m_PMob->loc.p, RoamingPoint); battleutils::MoveTo(m_PMob, RoamingPoint, 1); m_PMob->loc.zone->PushPacket(m_PMob,CHAR_INRANGE, new CEntityUpdatePacket(m_PMob,ENTITY_UPDATE)); } if (m_PMob->GetDespawnTimer() > 0 && m_PMob->GetDespawnTimer() < m_Tick) { m_LastActionTime = m_Tick - 12000; m_PMob->PBattleAI->SetCurrentAction(ACTION_DEATH); } }
void CMobController::Move() { if (!PMob->PAI->CanFollowPath()) { return; } float currentDistance = distance(PMob->loc.p, PTarget->loc.p); if (PMob->PAI->PathFind->IsFollowingScriptedPath() && PMob->PAI->CanFollowPath()) { PMob->PAI->PathFind->FollowPath(); return; } // attempt to teleport if (PMob->getMobMod(MOBMOD_TELEPORT_TYPE) == 1) { if (m_Tick >= m_LastSpecialTime + std::chrono::milliseconds(PMob->getBigMobMod(MOBMOD_TELEPORT_CD))) { CMobSkill* teleportBegin = battleutils::GetMobSkill(PMob->getMobMod(MOBMOD_TELEPORT_START)); if (teleportBegin) { m_LastSpecialTime = m_Tick; MobSkill(PMob->targid, teleportBegin->getID()); } } } bool move = PMob->PAI->PathFind->IsFollowingPath(); float attack_range = PMob->m_ModelSize; if (PMob->getMobMod(MOBMOD_ATTACK_SKILL_LIST) > 0) { auto skillList {battleutils::GetMobSkillList(PMob->getMobMod(MOBMOD_ATTACK_SKILL_LIST))}; if (!skillList.empty()) { auto skill {battleutils::GetMobSkill(skillList.front())}; if (skill) { attack_range = skill->getDistance(); } } } if (PMob->getMobMod(MOBMOD_SHARE_POS) > 0) { CMobEntity* posShare = (CMobEntity*)PMob->GetEntity(PMob->getMobMod(MOBMOD_SHARE_POS) + PMob->targid, TYPE_MOB); PMob->loc = posShare->loc; } else if (((distance(PMob->loc.p, PTarget->loc.p) > attack_range - 0.2f) || move) && PMob->PAI->CanFollowPath()) { //#TODO: can this be moved to scripts entirely? if (PMob->getMobMod(MOBMOD_DRAW_IN) > 0) { if (currentDistance >= PMob->m_ModelSize * 2) battleutils::DrawIn(PTarget, PMob, PMob->m_ModelSize - 0.2f); } if (PMob->speed != 0 && PMob->getMobMod(MOBMOD_NO_MOVE) == 0 && m_Tick >= m_LastSpecialTime) { // attempt to teleport to target (if in range) if (PMob->getMobMod(MOBMOD_TELEPORT_TYPE) == 2) { CMobSkill* teleportBegin = battleutils::GetMobSkill(PMob->getMobMod(MOBMOD_TELEPORT_START)); if (teleportBegin && currentDistance <= teleportBegin->getDistance()) { MobSkill(PMob->targid, teleportBegin->getID()); m_LastSpecialTime = m_Tick; return; } } else if (CanMoveForward(currentDistance)) { if (!PMob->PAI->PathFind->IsFollowingPath() || distanceSquared(PMob->PAI->PathFind->GetDestination(), PTarget->loc.p) > 10) { //path to the target if we don't have a path already PMob->PAI->PathFind->PathInRange(PTarget->loc.p, attack_range - 0.2f, PATHFLAG_WALLHACK | PATHFLAG_RUN); } PMob->PAI->PathFind->FollowPath(); if (!PMob->PAI->PathFind->IsFollowingPath()) { //arrived at target - move if there is another mob under me if (PTarget->objtype == TYPE_PC) { for (auto PSpawnedMob : static_cast<CCharEntity*>(PTarget)->SpawnMOBList) { if (PSpawnedMob.second != PMob && !PSpawnedMob.second->PAI->PathFind->IsFollowingPath() && distance(PSpawnedMob.second->loc.p, PMob->loc.p) < 1.f) { auto angle = getangle(PMob->loc.p, PTarget->loc.p) + 64; position_t new_pos {0, PMob->loc.p.x - (cosf(rotationToRadian(angle)) * 1.5f), PTarget->loc.p.y, PMob->loc.p.z + (sinf(rotationToRadian(angle)) * 1.5f), 0}; if (PMob->PAI->PathFind->ValidPosition(new_pos)) { PMob->PAI->PathFind->PathTo(new_pos, PATHFLAG_WALLHACK | PATHFLAG_RUN); } break; } } } } } else { FaceTarget(); } } } else { FaceTarget(); } }
int xyzsound(short num,short i,long x,long y,long z) { long sndist, cx, cy, cz, j,k; short pitche,pitchs,cs; int voice, sndang, ca, pitch; // if(num != 358) return 0; if( num >= NUM_SOUNDS || FXDevice < 0 || ( (soundm[num]&8) && ud.lockout ) || SoundToggle == 0 || Sound[num].num > 3 || FX_VoiceAvailable(soundpr[num]) == 0 || (ps[myconnectindex].timebeforeexit > 0 && ps[myconnectindex].timebeforeexit <= 26*3) || ps[myconnectindex].gm&MODE_MENU) return -1; if( soundm[num]&128 ) { sound(num); return 0; } if( soundm[num]&4 ) { if(VoiceToggle==0 || (ud.multimode > 1 && PN == APLAYER && sprite[i].yvel != screenpeek && ud.coop != 1) ) return -1; for(j=0;j<NUM_SOUNDS;j++) for(k=0;k<Sound[j].num;k++) if( (Sound[j].num > 0) && (soundm[j]&4) ) return -1; } cx = ps[screenpeek].oposx; cy = ps[screenpeek].oposy; cz = ps[screenpeek].oposz; cs = ps[screenpeek].cursectnum; ca = ps[screenpeek].ang+ps[screenpeek].look_ang; sndist = FindDistance3D((cx-x),(cy-y),(cz-z)>>4); if( i >= 0 && (soundm[num]&16) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9 ) sndist = divscale14(sndist,(SHT+1)); pitchs = soundps[num]; pitche = soundpe[num]; j = klabs(pitche-pitchs); if(j) { if( pitchs < pitche ) pitch = pitchs + ( rand()%j ); else pitch = pitche + ( rand()%j ); } else pitch = pitchs; sndist += soundvo[num]; if(sndist < 0) sndist = 0; if( sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,SX,SY,SZ-(24<<8),SECT) ) sndist += sndist>>5; switch(num) { case PIPEBOMB_EXPLODE: case LASERTRIP_EXPLODE: case RPG_EXPLODE: if(sndist > (6144) ) sndist = 6144; if(sector[ps[screenpeek].cursectnum].lotag == 2) pitch -= 1024; break; default: if(sector[ps[screenpeek].cursectnum].lotag == 2 && (soundm[num]&4) == 0) pitch = -768; if( sndist > 31444 && PN != MUSICANDSFX) return -1; break; } if( Sound[num].num > 0 && PN != MUSICANDSFX ) { if( SoundOwner[num][0].i == i ) stopsound(num); else if( Sound[num].num > 1 ) stopsound(num); else if( badguy(&sprite[i]) && sprite[i].extra <= 0 ) stopsound(num); } if( PN == APLAYER && sprite[i].yvel == screenpeek ) { sndang = 0; sndist = 0; } else { sndang = 2048 + ca - getangle(cx-x,cy-y); sndang &= 2047; } if(Sound[num].ptr == 0) { if( loadsound(num) == 0 ) return 0; } else { if (Sound[num].lock < 200) Sound[num].lock = 200; else Sound[num].lock++; } if( soundm[num]&16 ) sndist = 0; if(sndist < ((255-LOUDESTVOLUME)<<6) ) sndist = ((255-LOUDESTVOLUME)<<6); if( soundm[num]&1 ) { if(Sound[num].num > 0) return -1; voice = FX_PlayLoopedAuto( Sound[num].ptr, soundsiz[num], 0, -1, pitch,sndist>>6,sndist>>6,0,soundpr[num],num); } else {
void CAIMobDummy::ActionAttack() { m_PBattleTarget = m_PMob->PEnmityContainer->GetHighestEnmity(); if (m_PBattleTarget == NULL) { m_ActionType = ACTION_DISENGAGE; return; } if (m_PBattleTarget->isDead()) { if (m_PMob->m_OwnerID == m_PBattleTarget->id) { m_PMob->m_OwnerID = 0; } m_PMob->PEnmityContainer->Clear(m_PBattleTarget->id); ActionAttack(); return; } m_PMob->loc.p.rotation = getangle(m_PMob->loc.p, m_PBattleTarget->loc.p); if (m_PMob->PParty != NULL) { for (uint16 i = 0; i < m_PMob->PParty->members.size(); ++i) { CMobEntity* PPartyMember = (CMobEntity*)m_PMob->PParty->members[i]; if (PPartyMember->PBattleAI->GetCurrentAction() == ACTION_ROAMING && distance(m_PMob->loc.p, PPartyMember->loc.p) < 10) { PPartyMember->PEnmityContainer->AddBaseEnmity(m_PBattleTarget); } } } if (distance(m_PMob->loc.p, m_PBattleTarget->loc.p) <= m_PMob->m_ModelSize) { if ((m_Tick - m_LastActionTime) > m_PMob->m_Weapons[SLOT_MAIN]->getDelay()) { if (battleutils::IsParalised(m_PMob)) { m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CMessageBasicPacket(m_PMob,m_PBattleTarget,0,0,29)); } else if (battleutils::IsIntimidated(m_PMob, m_PBattleTarget)) { m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CMessageBasicPacket(m_PMob,m_PBattleTarget,0,0,106)); } else { if (m_PMob->health.tp > 100 && rand()%100 > 55) { m_ActionType = ACTION_MOBABILITY_START; ActionAbilityStart(); return; } apAction_t Action; m_PMob->m_ActionList.clear(); Action.ActionTarget = m_PBattleTarget; Action.reaction = REACTION_EVADE; Action.speceffect = SPECEFFECT_NONE; Action.animation = 0; Action.param = 0; Action.messageID = 15; Action.flag = 0; uint16 damage = 0; if (m_PBattleTarget->StatusEffectContainer->HasStatusEffect(EFFECT_PERFECT_DODGE)) { Action.messageID = 32; } else if ( rand()%90 < battleutils::GetHitRate(m_PMob, m_PBattleTarget) ) { if (battleutils::IsAbsorbByShadow(m_PBattleTarget)) { Action.messageID = 0; m_PBattleTarget->loc.zone->PushPacket(m_PBattleTarget,CHAR_INRANGE_SELF, new CMessageBasicPacket(m_PBattleTarget,m_PBattleTarget,0,1,31)); } else { Action.reaction = REACTION_HIT; Action.speceffect = SPECEFFECT_HIT; Action.messageID = 1; float DamageRatio = battleutils::GetDamageRatio(m_PMob, m_PBattleTarget); if ( rand()%100 < battleutils::GetCritHitRate(m_PMob, m_PBattleTarget) ) { DamageRatio += 1; DamageRatio = (DamageRatio > 3 ? 3 : DamageRatio); Action.speceffect = SPECEFFECT_CRITICAL_HIT; Action.messageID = 67; } damage = (uint16)((m_PMob->m_Weapons[SLOT_MAIN]->getDamage() + battleutils::GetFSTR(m_PMob, m_PBattleTarget)) * DamageRatio); } } else if (m_PBattleTarget->objtype == TYPE_PC) { charutils::TrySkillUP((CCharEntity*)m_PBattleTarget, SKILL_EVA, m_PMob->GetMLevel()); } Action.param = battleutils::TakePhysicalDamage(m_PMob, m_PBattleTarget, damage); m_PMob->m_ActionList.push_back(Action); m_PMob->PEnmityContainer->UpdateEnmityFromAttack(m_PBattleTarget, Action.param); m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CActionPacket(m_PMob)); } m_LastActionTime = m_Tick; } } else { battleutils::MoveTo(m_PMob, m_PBattleTarget->loc.p, 2); } m_PMob->loc.zone->PushPacket(m_PMob,CHAR_INRANGE, new CEntityUpdatePacket(m_PMob, ENTITY_UPDATE)); }
void CMobController::DoCombatTick(time_point tick) { HandleEnmity(); PTarget = static_cast<CBattleEntity*>(PMob->GetEntity(PMob->GetBattleTargetID())); if (TryDeaggro()) { Disengage(); return; } TryLink(); float currentDistance = distance(PMob->loc.p, PTarget->loc.p); if (!(PMob->m_Behaviour & BEHAVIOUR_NO_TURN)) { PMob->PAI->PathFind->LookAt(PTarget->loc.p); } luautils::OnMobFight(PMob, PTarget); // Try to spellcast (this is done first so things like Chainspell spam is prioritised over TP moves etc. if (IsSpecialSkillReady(currentDistance) && TrySpecialSkill()) { return; } else if (IsSpellReady(currentDistance) && TryCastSpell()) { return; } else if (m_Tick >= m_LastMobSkillTime && dsprand::GetRandomNumber(100) < PMob->TPUseChance() && MobSkill()) { return; } if (PMob->PAI->PathFind->IsFollowingScriptedPath() && PMob->PAI->CanFollowPath()) { PMob->PAI->PathFind->FollowPath(); return; } // attempt to teleport if (PMob->getMobMod(MOBMOD_TELEPORT_TYPE) == 1) { if (m_Tick >= m_LastSpecialTime + std::chrono::milliseconds(PMob->getBigMobMod(MOBMOD_TELEPORT_CD))) { CMobSkill* teleportBegin = battleutils::GetMobSkill(PMob->getMobMod(MOBMOD_TELEPORT_START)); if (teleportBegin) { m_LastSpecialTime = m_Tick; MobSkill(PMob->targid, teleportBegin->getID()); } } } bool move = PMob->PAI->PathFind->IsFollowingPath(); float attack_range = PMob->m_ModelSize; if (PMob->getMobMod(MOBMOD_ATTACK_SKILL_LIST) > 0) { auto skillList {battleutils::GetMobSkillList(PMob->getMobMod(MOBMOD_ATTACK_SKILL_LIST))}; if (!skillList.empty()) { auto skill {battleutils::GetMobSkill(skillList.front())}; if (skill) { attack_range = skill->getDistance(); } } } if (PMob->getMobMod(MOBMOD_SHARE_POS) > 0) { CMobEntity* posShare = (CMobEntity*)PMob->GetEntity(PMob->getMobMod(MOBMOD_SHARE_POS) + PMob->targid, TYPE_MOB); PMob->loc = posShare->loc; } else if (((distance(PMob->loc.p, PTarget->loc.p) > attack_range - 0.2f) || move) && PMob->PAI->CanFollowPath()) { //#TODO: can this be moved to scripts entirely? if (PMob->getMobMod(MOBMOD_DRAW_IN) > 0) { if (currentDistance >= PMob->m_ModelSize * 2) battleutils::DrawIn(PTarget, PMob, PMob->m_ModelSize - 0.2f); } if (PMob->speed != 0 && m_Tick >= m_LastSpecialTime) { // attempt to teleport to target (if in range) if (PMob->getMobMod(MOBMOD_TELEPORT_TYPE) == 2) { CMobSkill* teleportBegin = battleutils::GetMobSkill(PMob->getMobMod(MOBMOD_TELEPORT_START)); if (teleportBegin && currentDistance <= teleportBegin->getDistance()) { MobSkill(PMob->targid, teleportBegin->getID()); m_LastSpecialTime = m_Tick; return; } } else if (CanMoveForward(currentDistance)) { if (!PMob->PAI->PathFind->IsFollowingPath()) { //path to the target if we don't have a path already PMob->PAI->PathFind->PathInRange(PTarget->loc.p, attack_range - 0.2f, PATHFLAG_WALLHACK | PATHFLAG_RUN); } PMob->PAI->PathFind->FollowPath(); if (!PMob->PAI->PathFind->IsFollowingPath()) { //arrived at target - move if there is another mob under me if (PTarget->objtype == TYPE_PC) { for (auto PSpawnedMob : static_cast<CCharEntity*>(PTarget)->SpawnMOBList) { if (PSpawnedMob.second != PMob && !PSpawnedMob.second->PAI->PathFind->IsFollowingPath() && distance(PSpawnedMob.second->loc.p, PMob->loc.p) < 1.f) { auto angle = getangle(PMob->loc.p, PTarget->loc.p) + 64; position_t new_pos {0, PMob->loc.p.x - (cosf(rotationToRadian(angle)) * 1.5f), PTarget->loc.p.y, PMob->loc.p.z + (sinf(rotationToRadian(angle)) * 1.5f), 0}; if (PMob->PAI->PathFind->ValidPosition(new_pos)) { PMob->PAI->PathFind->PathTo(new_pos, PATHFLAG_WALLHACK | PATHFLAG_RUN); } break; } } } } } } } }
void move_p1_to_p2(double& x1, double& y1, const double& x2, const double& y2, const double& speed) { x1 += speed*cos(getangle(x1, y1, x2, y2)); y1 += speed*sin(getangle(x1, y1, x2, y2));//yは画面の上のほうが小さいのでマイナス }
int WallBreakPosition(short hitwall, short *sectnum, long *x, long *y, long *z, short *ang) { short w,nw; WALLp wp; long nx,ny; short wall_ang; long ret=0; w = hitwall; wp = &wall[w]; nw = wall[w].point2; wall_ang = NORM_ANGLE(getangle(wall[nw].x - wall[w].x, wall[nw].y - wall[w].y)+512); *sectnum = SectorOfWall(w); ASSERT(*sectnum >= 0); // midpoint of wall *x = DIV2(wall[w].x + wall[w].x); *y = DIV2(wall[w].y + wall[w].y); //getzsofsector(*sectnum, *x, *y, cz, fz); if (wp->nextwall < 0) { // white wall *z = DIV2(sector[*sectnum].floorz + sector[*sectnum].ceilingz); } else { short next_sectnum = wp->nextsector; // red wall ASSERT(wp->nextsector >= 0); // floor and ceiling meet if (sector[next_sectnum].floorz == sector[next_sectnum].ceilingz) *z = DIV2(sector[*sectnum].floorz + sector[*sectnum].ceilingz); else // floor is above other sector if (sector[next_sectnum].floorz < sector[*sectnum].floorz) *z = DIV2(sector[next_sectnum].floorz + sector[*sectnum].floorz); else // ceiling is below other sector if (sector[next_sectnum].ceilingz > sector[*sectnum].ceilingz) *z = DIV2(sector[next_sectnum].ceilingz + sector[*sectnum].ceilingz); } *ang = wall_ang; nx = MOVEx(128, wall_ang); ny = MOVEy(128, wall_ang); *x += nx; *y += ny; updatesectorz(*x,*y,*z,sectnum); if (*sectnum < 0) { *x = MAXLONG; // don't spawn shrap, just change wall return(FALSE); } return(TRUE); }
static inline int32_t S_GetAngle(int32_t camang, const vec3_t *cam, const vec3_t *pos) { return (2048 + camang - getangle(cam->x-pos->x, cam->y-pos->y))&2047; }