root/trunk/src/game/ObjectPosSelector.cpp @ 2

Revision 2, 5.3 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#include "ObjectPosSelector.h"
20
21ObjectPosSelector::ObjectPosSelector(float x,float y,float size,float dist)
22: m_center_x(x),m_center_y(y),m_size(size),m_dist(dist)
23{
24    m_anglestep = acos(m_dist/(m_dist+2*m_size));
25
26    m_nextUsedPos[USED_POS_PLUS]  = m_UsedPosLists[USED_POS_PLUS].end();
27    m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].end();
28
29    m_smallStepAngle[USED_POS_PLUS]  = 0;
30    m_smallStepAngle[USED_POS_MINUS] = 0;
31
32    m_smallStepOk[USED_POS_PLUS]  = false;
33    m_smallStepOk[USED_POS_MINUS] = false;
34
35    m_smallStepNextUsedPos[USED_POS_PLUS]  = NULL;
36    m_smallStepNextUsedPos[USED_POS_MINUS] = NULL;
37}
38
39ObjectPosSelector::UsedPosList::value_type const* ObjectPosSelector::nextUsedPos(UsedPosType uptype)
40{
41    UsedPosList::const_iterator itr = m_nextUsedPos[uptype];
42    if(itr!=m_UsedPosLists[uptype].end())
43        ++itr;
44
45    if(itr==m_UsedPosLists[uptype].end())
46    {
47        if(!m_UsedPosLists[~uptype].empty())
48            return &*m_UsedPosLists[~uptype].rbegin();
49        else
50            return NULL;
51    }
52    else
53        return &*itr;
54}
55
56void ObjectPosSelector::AddUsedPos(float size,float angle,float dist)
57{
58    if(angle>=0)
59        m_UsedPosLists[USED_POS_PLUS].insert(UsedPosList::value_type(angle,UsedPos(1.0,size,dist)));
60    else
61        m_UsedPosLists[USED_POS_MINUS].insert(UsedPosList::value_type(-angle,UsedPos(-1.0,size,dist)));
62}
63
64void ObjectPosSelector::InitializeAngle()
65{
66    m_nextUsedPos[USED_POS_PLUS]  = m_UsedPosLists[USED_POS_PLUS].begin();
67    m_nextUsedPos[USED_POS_MINUS] = m_UsedPosLists[USED_POS_MINUS].begin();
68
69    m_smallStepAngle[USED_POS_PLUS]  = 0;
70    m_smallStepAngle[USED_POS_MINUS] = 0;
71
72    m_smallStepOk[USED_POS_PLUS]  = true;
73    m_smallStepOk[USED_POS_MINUS] = true;
74}
75
76bool ObjectPosSelector::FirstAngle(float& angle)
77{
78    if(m_UsedPosLists[USED_POS_PLUS].empty() && !m_UsedPosLists[USED_POS_MINUS].empty() )
79        return NextAngleFor(*m_UsedPosLists[USED_POS_MINUS].begin(),1.0,USED_POS_PLUS,angle);
80    else if(m_UsedPosLists[USED_POS_MINUS].empty() && !m_UsedPosLists[USED_POS_PLUS].empty() )
81        return NextAngleFor(*m_UsedPosLists[USED_POS_PLUS].begin(),-1.0,USED_POS_MINUS,angle);
82
83    return false;
84}
85
86bool ObjectPosSelector::NextAngle(float& angle)
87{
88    while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() ||
89        m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() ||
90        m_smallStepOk[USED_POS_PLUS] || m_smallStepOk[USED_POS_MINUS] )
91    {
92        // calculate next possible angle
93        if(NextPosibleAngle(angle))
94            return true;
95    }
96
97    return false;
98}
99
100bool ObjectPosSelector::NextUsedAngle(float& angle)
101{
102    while(m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() ||
103        m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end() )
104    {
105        // calculate next possible angle
106        if(!NextPosibleAngle(angle))
107            return true;
108    }
109
110    return false;
111}
112
113bool ObjectPosSelector::NextPosibleAngle( float& angle )
114{
115    // ++ direction less updated
116    if( m_nextUsedPos[USED_POS_PLUS]!=m_UsedPosLists[USED_POS_PLUS].end() &&
117        (m_nextUsedPos[USED_POS_MINUS]==m_UsedPosLists[USED_POS_MINUS].end() || m_nextUsedPos[USED_POS_PLUS]->first <= m_nextUsedPos[USED_POS_MINUS]->first) )
118    {
119        bool ok;
120        if(m_smallStepOk[USED_POS_PLUS])
121            ok = NextSmallStepAngle(1.0,USED_POS_PLUS,angle);
122        else
123            ok = NextAngleFor(*m_nextUsedPos[USED_POS_PLUS],1.0,USED_POS_PLUS,angle);
124
125        if(!ok)
126            ++m_nextUsedPos[USED_POS_PLUS];                 // increase. only at fail (original or checked)
127        return ok;
128    }
129    // -- direction less updated
130    else if( m_nextUsedPos[USED_POS_MINUS]!=m_UsedPosLists[USED_POS_MINUS].end())
131    {
132        bool ok;
133        if(m_smallStepOk[USED_POS_MINUS])
134            ok = NextSmallStepAngle(-1.0,USED_POS_MINUS,angle);
135        else
136            ok =  NextAngleFor(*m_nextUsedPos[USED_POS_MINUS],-1.0,USED_POS_MINUS,angle);
137
138        if(!ok)
139            ++m_nextUsedPos[USED_POS_MINUS];
140        return ok;
141    }
142    else                                                    // both list empty
143    {
144        if( m_smallStepOk[USED_POS_PLUS] && (!m_smallStepOk[USED_POS_MINUS] || m_smallStepAngle[USED_POS_PLUS] <= m_smallStepAngle[USED_POS_MINUS]) )
145        {
146            return NextSmallStepAngle(1.0,USED_POS_PLUS,angle);
147        }
148        // -- direction less updated
149        else if( m_smallStepOk[USED_POS_MINUS] )
150        {
151            return NextSmallStepAngle(-1.0,USED_POS_MINUS,angle);
152        }
153    }
154
155    // no angles
156    return false;
157}
Note: See TracBrowser for help on using the browser.