# include <arts/kmedia2.h>
# include <arts/kplayobject.h>
# include <arts/kplayobjectfactory.h>
# include <kapplication.h>
# include <kconfig.h>
# include <kcursor.h>
# include <kdebug.h>
# include <knuminput.h>
# include <kfiledialog.h>
# include <kglobal.h>
# include <klineedit.h>
# include <kmessagebox.h>
# include <kpixmapeffect.h>
# include <kprinter.h>
# include <kstandarddirs.h>
# include <tqbrush.h>
# include <tqcanvas.h>
# include <tqcheckbox.h>
# include <tqcolor.h>
# include <tqcursor.h>
# include <tqevent.h>
# include <tqfont.h>
# include <tqfontmetrics.h>
# include <tqimage.h>
# include <tqlabel.h>
# include <tqlayout.h>
# include <tqmap.h>
# include <tqpainter.h>
# include <tqpaintdevicemetrics.h>
# include <tqpen.h>
# include <tqpixmap.h>
# include <tqpixmapcache.h>
# include <tqpoint.h>
# include <tqpointarray.h>
# include <tqrect.h>
# include <tqsimplerichtext.h>
# include <tqsize.h>
# include <tqslider.h>
# include <tqspinbox.h>
# include <tqstring.h>
# include <tqstringlist.h>
# include <tqtimer.h>
# include <tqtooltip.h>
# include <tqvaluelist.h>
# include <tqwhatsthis.h>
# include <math.h>
# include <stdlib.h>
# include <unistd.h>
# include "kcomboboxdialog.h"
# include "kvolumecontrol.h"
# include "vector.h"
# include "game.h"
inline TQString makeGroup ( int id , int hole , TQString name , int x , int y )
{
return TQString ( " %1-%2@%3,%4|%5 " ) . arg ( hole ) . arg ( name ) . arg ( x ) . arg ( y ) . arg ( id ) ;
}
inline TQString makeStateGroup ( int id , const TQString & name )
{
return TQString ( " %1|%2 " ) . arg ( name ) . arg ( id ) ;
}
/////////////////////////
RectPoint : : RectPoint ( TQColor color , RectItem * rect , TQCanvas * canvas )
: TQCanvasEllipse ( canvas )
{
setZ ( 9999 ) ;
setSize ( 10 , 10 ) ;
this - > rect = rect ;
setBrush ( TQBrush ( color ) ) ;
setSizeFactor ( 1.0 ) ;
dontmove = false ;
}
void RectPoint : : moveBy ( double dx , double dy )
{
TQCanvasEllipse : : moveBy ( dx , dy ) ;
if ( dontmove )
{
dontmove = false ;
return ;
}
TQCanvasItem * qitem = dynamic_cast < TQCanvasItem * > ( rect ) ;
if ( ! qitem )
return ;
double nw = m_sizeFactor * fabs ( x ( ) - qitem - > x ( ) ) ;
double nh = m_sizeFactor * fabs ( y ( ) - qitem - > y ( ) ) ;
if ( nw < = 0 | | nh < = 0 )
return ;
rect - > newSize ( nw , nh ) ;
}
Config * RectPoint : : config ( TQWidget * parent )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( rect ) ;
if ( citem )
return citem - > config ( parent ) ;
else
return CanvasItem : : config ( parent ) ;
}
/////////////////////////
Arrow : : Arrow ( TQCanvas * canvas )
: TQCanvasLine ( canvas )
{
line1 = new TQCanvasLine ( canvas ) ;
line2 = new TQCanvasLine ( canvas ) ;
m_angle = 0 ;
m_length = 20 ;
m_reversed = false ;
setPen ( black ) ;
updateSelf ( ) ;
setVisible ( false ) ;
}
void Arrow : : setPen ( TQPen p )
{
TQCanvasLine : : setPen ( p ) ;
line1 - > setPen ( p ) ;
line2 - > setPen ( p ) ;
}
void Arrow : : setZ ( double newz )
{
TQCanvasLine : : setZ ( newz ) ;
line1 - > setZ ( newz ) ;
line2 - > setZ ( newz ) ;
}
void Arrow : : setVisible ( bool yes )
{
TQCanvasLine : : setVisible ( yes ) ;
line1 - > setVisible ( yes ) ;
line2 - > setVisible ( yes ) ;
}
void Arrow : : moveBy ( double dx , double dy )
{
TQCanvasLine : : moveBy ( dx , dy ) ;
line1 - > moveBy ( dx , dy ) ;
line2 - > moveBy ( dx , dy ) ;
}
void Arrow : : aboutToDie ( )
{
delete line1 ;
delete line2 ;
}
void Arrow : : updateSelf ( )
{
TQPoint start = startPoint ( ) ;
TQPoint end ( m_length * cos ( m_angle ) , m_length * sin ( m_angle ) ) ;
if ( m_reversed )
{
TQPoint tmp ( start ) ;
start = end ;
end = tmp ;
}
setPoints ( start . x ( ) , start . y ( ) , end . x ( ) , end . y ( ) ) ;
const double lineLen = m_length / 2 ;
const double angle1 = m_angle - M_PI / 2 - 1 ;
line1 - > move ( end . x ( ) + x ( ) , end . y ( ) + y ( ) ) ;
start = end ;
end = TQPoint ( lineLen * cos ( angle1 ) , lineLen * sin ( angle1 ) ) ;
line1 - > setPoints ( 0 , 0 , end . x ( ) , end . y ( ) ) ;
const double angle2 = m_angle + M_PI / 2 + 1 ;
line2 - > move ( start . x ( ) + x ( ) , start . y ( ) + y ( ) ) ;
end = TQPoint ( lineLen * cos ( angle2 ) , lineLen * sin ( angle2 ) ) ;
line2 - > setPoints ( 0 , 0 , end . x ( ) , end . y ( ) ) ;
}
/////////////////////////
BridgeConfig : : BridgeConfig ( Bridge * bridge , TQWidget * parent )
: Config ( parent )
{
this - > bridge = bridge ;
m_vlayout = new TQVBoxLayout ( this , marginHint ( ) , spacingHint ( ) ) ;
TQGridLayout * layout = new TQGridLayout ( m_vlayout , 2 , 3 , spacingHint ( ) ) ;
layout - > addWidget ( new TQLabel ( i18n ( " Walls on: " ) , this ) , 0 , 0 ) ;
top = new TQCheckBox ( i18n ( " &Top " ) , this ) ;
layout - > addWidget ( top , 0 , 1 ) ;
connect ( top , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( topWallChanged ( bool ) ) ) ;
top - > setChecked ( bridge - > topWallVisible ( ) ) ;
bot = new TQCheckBox ( i18n ( " &Bottom " ) , this ) ;
layout - > addWidget ( bot , 1 , 1 ) ;
connect ( bot , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( botWallChanged ( bool ) ) ) ;
bot - > setChecked ( bridge - > botWallVisible ( ) ) ;
left = new TQCheckBox ( i18n ( " &Left " ) , this ) ;
layout - > addWidget ( left , 1 , 0 ) ;
connect ( left , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( leftWallChanged ( bool ) ) ) ;
left - > setChecked ( bridge - > leftWallVisible ( ) ) ;
right = new TQCheckBox ( i18n ( " &Right " ) , this ) ;
layout - > addWidget ( right , 1 , 2 ) ;
connect ( right , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( rightWallChanged ( bool ) ) ) ;
right - > setChecked ( bridge - > rightWallVisible ( ) ) ;
}
void BridgeConfig : : topWallChanged ( bool yes )
{
bridge - > setTopWallVisible ( yes ) ;
changed ( ) ;
}
void BridgeConfig : : botWallChanged ( bool yes )
{
bridge - > setBotWallVisible ( yes ) ;
changed ( ) ;
}
void BridgeConfig : : leftWallChanged ( bool yes )
{
bridge - > setLeftWallVisible ( yes ) ;
changed ( ) ;
}
void BridgeConfig : : rightWallChanged ( bool yes )
{
bridge - > setRightWallVisible ( yes ) ;
changed ( ) ;
}
/////////////////////////
Bridge : : Bridge ( TQRect rect , TQCanvas * canvas )
: TQCanvasRectangle ( rect , canvas )
{
TQColor color ( " #92772D " ) ;
setBrush ( TQBrush ( color ) ) ;
setPen ( Qt : : NoPen ) ;
setZ ( 998 ) ;
topWall = new Wall ( canvas ) ;
topWall - > setAlwaysShow ( true ) ;
botWall = new Wall ( canvas ) ;
botWall - > setAlwaysShow ( true ) ;
leftWall = new Wall ( canvas ) ;
leftWall - > setAlwaysShow ( true ) ;
rightWall = new Wall ( canvas ) ;
rightWall - > setAlwaysShow ( true ) ;
setWallZ ( z ( ) + 0.01 ) ;
setWallColor ( color ) ;
topWall - > setVisible ( false ) ;
botWall - > setVisible ( false ) ;
leftWall - > setVisible ( false ) ;
rightWall - > setVisible ( false ) ;
point = new RectPoint ( color , this , canvas ) ;
editModeChanged ( false ) ;
newSize ( width ( ) , height ( ) ) ;
}
bool Bridge : : collision ( Ball * ball , long int /*id*/ )
{
ball - > setFrictionMultiplier ( .63 ) ;
return false ;
}
void Bridge : : setWallZ ( double newz )
{
topWall - > setZ ( newz ) ;
botWall - > setZ ( newz ) ;
leftWall - > setZ ( newz ) ;
rightWall - > setZ ( newz ) ;
}
void Bridge : : setGame ( KolfGame * game )
{
CanvasItem : : setGame ( game ) ;
topWall - > setGame ( game ) ;
botWall - > setGame ( game ) ;
leftWall - > setGame ( game ) ;
rightWall - > setGame ( game ) ;
}
void Bridge : : setWallColor ( TQColor color )
{
topWall - > setPen ( TQPen ( color . dark ( ) , 3 ) ) ;
botWall - > setPen ( topWall - > pen ( ) ) ;
leftWall - > setPen ( topWall - > pen ( ) ) ;
rightWall - > setPen ( topWall - > pen ( ) ) ;
}
void Bridge : : aboutToDie ( )
{
delete point ;
topWall - > aboutToDie ( ) ;
delete topWall ;
botWall - > aboutToDie ( ) ;
delete botWall ;
leftWall - > aboutToDie ( ) ;
delete leftWall ;
rightWall - > aboutToDie ( ) ;
delete rightWall ;
}
void Bridge : : editModeChanged ( bool changed )
{
point - > setVisible ( changed ) ;
moveBy ( 0 , 0 ) ;
}
void Bridge : : moveBy ( double dx , double dy )
{
TQCanvasRectangle : : moveBy ( dx , dy ) ;
point - > dontMove ( ) ;
point - > move ( x ( ) + width ( ) , y ( ) + height ( ) ) ;
topWall - > move ( x ( ) , y ( ) ) ;
botWall - > move ( x ( ) , y ( ) - 1 ) ;
leftWall - > move ( x ( ) , y ( ) ) ;
rightWall - > move ( x ( ) , y ( ) ) ;
TQCanvasItemList list = collisions ( true ) ;
for ( TQCanvasItemList : : Iterator it = list . begin ( ) ; it ! = list . end ( ) ; + + it )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( * it ) ;
if ( citem )
citem - > updateZ ( ) ;
}
}
void Bridge : : load ( KConfig * cfg )
{
doLoad ( cfg ) ;
}
void Bridge : : doLoad ( KConfig * cfg )
{
newSize ( cfg - > readNumEntry ( " width " , width ( ) ) , cfg - > readNumEntry ( " height " , height ( ) ) ) ;
setTopWallVisible ( cfg - > readBoolEntry ( " topWallVisible " , topWallVisible ( ) ) ) ;
setBotWallVisible ( cfg - > readBoolEntry ( " botWallVisible " , botWallVisible ( ) ) ) ;
setLeftWallVisible ( cfg - > readBoolEntry ( " leftWallVisible " , leftWallVisible ( ) ) ) ;
setRightWallVisible ( cfg - > readBoolEntry ( " rightWallVisible " , rightWallVisible ( ) ) ) ;
}
void Bridge : : save ( KConfig * cfg )
{
doSave ( cfg ) ;
}
void Bridge : : doSave ( KConfig * cfg )
{
cfg - > writeEntry ( " width " , width ( ) ) ;
cfg - > writeEntry ( " height " , height ( ) ) ;
cfg - > writeEntry ( " topWallVisible " , topWallVisible ( ) ) ;
cfg - > writeEntry ( " botWallVisible " , botWallVisible ( ) ) ;
cfg - > writeEntry ( " leftWallVisible " , leftWallVisible ( ) ) ;
cfg - > writeEntry ( " rightWallVisible " , rightWallVisible ( ) ) ;
}
TQPtrList < TQCanvasItem > Bridge : : moveableItems ( ) const
{
TQPtrList < TQCanvasItem > ret ;
ret . append ( point ) ;
return ret ;
}
void Bridge : : newSize ( int width , int height )
{
setSize ( width , height ) ;
}
void Bridge : : setSize ( int width , int height )
{
TQCanvasRectangle : : setSize ( width , height ) ;
topWall - > setPoints ( 0 , 0 , width , 0 ) ;
botWall - > setPoints ( 0 , height , width , height ) ;
leftWall - > setPoints ( 0 , 0 , 0 , height ) ;
rightWall - > setPoints ( width , 0 , width , height ) ;
moveBy ( 0 , 0 ) ;
}
/////////////////////////
WindmillConfig : : WindmillConfig ( Windmill * windmill , TQWidget * parent )
: BridgeConfig ( windmill , parent )
{
this - > windmill = windmill ;
m_vlayout - > addStretch ( ) ;
TQCheckBox * check = new TQCheckBox ( i18n ( " Windmill on bottom " ) , this ) ;
check - > setChecked ( windmill - > bottom ( ) ) ;
connect ( check , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( endChanged ( bool ) ) ) ;
m_vlayout - > addWidget ( check ) ;
TQHBoxLayout * hlayout = new TQHBoxLayout ( m_vlayout , spacingHint ( ) ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Slow " ) , this ) ) ;
TQSlider * slider = new TQSlider ( 1 , 10 , 1 , windmill - > curSpeed ( ) , Qt : : Horizontal , this ) ;
hlayout - > addWidget ( slider ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Fast " ) , this ) ) ;
connect ( slider , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( speedChanged ( int ) ) ) ;
endChanged ( check - > isChecked ( ) ) ;
}
void WindmillConfig : : speedChanged ( int news )
{
windmill - > setSpeed ( news ) ;
changed ( ) ;
}
void WindmillConfig : : endChanged ( bool bottom )
{
windmill - > setBottom ( bottom ) ;
changed ( ) ;
bot - > setEnabled ( ! bottom ) ;
if ( startedUp )
{
bot - > setChecked ( ! bottom ) ;
botWallChanged ( bot - > isChecked ( ) ) ;
}
top - > setEnabled ( bottom ) ;
if ( startedUp )
{
top - > setChecked ( bottom ) ;
topWallChanged ( top - > isChecked ( ) ) ;
}
}
/////////////////////////
Windmill : : Windmill ( TQRect rect , TQCanvas * canvas )
: Bridge ( rect , canvas ) , speedfactor ( 16 ) , m_bottom ( true )
{
guard = new WindmillGuard ( canvas ) ;
guard - > setPen ( TQPen ( black , 5 ) ) ;
guard - > setVisible ( true ) ;
guard - > setAlwaysShow ( true ) ;
setSpeed ( 5 ) ;
guard - > setZ ( wallZ ( ) + .1 ) ;
left = new Wall ( canvas ) ;
left - > setPen ( wallPen ( ) ) ;
left - > setAlwaysShow ( true ) ;
right = new Wall ( canvas ) ;
right - > setPen ( wallPen ( ) ) ;
right - > setAlwaysShow ( true ) ;
left - > setZ ( wallZ ( ) ) ;
right - > setZ ( wallZ ( ) ) ;
left - > setVisible ( true ) ;
right - > setVisible ( true ) ;
setTopWallVisible ( false ) ;
setBotWallVisible ( false ) ;
setLeftWallVisible ( true ) ;
setRightWallVisible ( true ) ;
newSize ( width ( ) , height ( ) ) ;
moveBy ( 0 , 0 ) ;
}
void Windmill : : aboutToDie ( )
{
Bridge : : aboutToDie ( ) ;
guard - > aboutToDie ( ) ;
delete guard ;
left - > aboutToDie ( ) ;
delete left ;
right - > aboutToDie ( ) ;
delete right ;
}
void Windmill : : setSpeed ( int news )
{
if ( news < 0 )
return ;
speed = news ;
guard - > setXVelocity ( ( ( double ) news / ( double ) 3 ) * ( guard - > xVelocity ( ) > 0 ? 1 : - 1 ) ) ;
}
void Windmill : : setGame ( KolfGame * game )
{
Bridge : : setGame ( game ) ;
guard - > setGame ( game ) ;
left - > setGame ( game ) ;
right - > setGame ( game ) ;
}
void Windmill : : save ( KConfig * cfg )
{
cfg - > writeEntry ( " speed " , speed ) ;
cfg - > writeEntry ( " bottom " , m_bottom ) ;
doSave ( cfg ) ;
}
void Windmill : : load ( KConfig * cfg )
{
setSpeed ( cfg - > readNumEntry ( " speed " , - 1 ) ) ;
doLoad ( cfg ) ;
left - > editModeChanged ( false ) ;
right - > editModeChanged ( false ) ;
guard - > editModeChanged ( false ) ;
setBottom ( cfg - > readBoolEntry ( " bottom " , true ) ) ;
}
void Windmill : : moveBy ( double dx , double dy )
{
Bridge : : moveBy ( dx , dy ) ;
left - > move ( x ( ) , y ( ) ) ;
right - > move ( x ( ) , y ( ) ) ;
guard - > moveBy ( dx , dy ) ;
guard - > setBetween ( x ( ) , x ( ) + width ( ) ) ;
update ( ) ;
}
void Windmill : : setSize ( int width , int height )
{
newSize ( width , height ) ;
}
void Windmill : : setBottom ( bool yes )
{
m_bottom = yes ;
newSize ( width ( ) , height ( ) ) ;
}
void Windmill : : newSize ( int width , int height )
{
Bridge : : newSize ( width , height ) ;
const int indent = width / 4 ;
double indentY = m_bottom ? height : 0 ;
left - > setPoints ( 0 , indentY , indent , indentY ) ;
right - > setPoints ( width - indent , indentY , width , indentY ) ;
guard - > setBetween ( x ( ) , x ( ) + width ) ;
double guardY = m_bottom ? height + 4 : - 4 ;
guard - > setPoints ( 0 , guardY , ( double ) indent / ( double ) 1.07 - 2 , guardY ) ;
}
/////////////////////////
void WindmillGuard : : advance ( int phase )
{
Wall : : advance ( phase ) ;
if ( phase = = 1 )
{
if ( x ( ) + startPoint ( ) . x ( ) < = min )
setXVelocity ( fabs ( xVelocity ( ) ) ) ;
else if ( x ( ) + endPoint ( ) . x ( ) > = max )
setXVelocity ( - fabs ( xVelocity ( ) ) ) ;
}
}
/////////////////////////
Sign : : Sign ( TQCanvas * canvas )
: Bridge ( TQRect ( 0 , 0 , 110 , 40 ) , canvas )
{
setZ ( 998.8 ) ;
m_text = m_untranslatedText = i18n ( " New Text " ) ;
setBrush ( TQBrush ( white ) ) ;
setWallColor ( black ) ;
setWallZ ( z ( ) + .01 ) ;
setTopWallVisible ( true ) ;
setBotWallVisible ( true ) ;
setLeftWallVisible ( true ) ;
setRightWallVisible ( true ) ;
}
void Sign : : load ( KConfig * cfg )
{
m_text = cfg - > readEntry ( " Comment " , m_text ) ;
m_untranslatedText = cfg - > readEntryUntranslated ( " Comment " , m_untranslatedText ) ;
doLoad ( cfg ) ;
}
void Sign : : save ( KConfig * cfg )
{
cfg - > writeEntry ( " Comment " , m_untranslatedText ) ;
doSave ( cfg ) ;
}
void Sign : : setText ( const TQString & text )
{
m_text = text ;
m_untranslatedText = text ;
update ( ) ;
}
void Sign : : draw ( TQPainter & painter )
{
Bridge : : draw ( painter ) ;
painter . setPen ( TQPen ( black , 1 ) ) ;
TQSimpleRichText txt ( m_text , kapp - > font ( ) ) ;
const int indent = wallPen ( ) . width ( ) + 3 ;
txt . setWidth ( width ( ) - 2 * indent ) ;
TQColorGroup colorGroup ;
colorGroup . setColor ( TQColorGroup : : Foreground , black ) ;
colorGroup . setColor ( TQColorGroup : : Text , black ) ;
colorGroup . setColor ( TQColorGroup : : Background , black ) ;
colorGroup . setColor ( TQColorGroup : : Base , black ) ;
txt . draw ( & painter , x ( ) + indent , y ( ) , TQRect ( x ( ) + indent , y ( ) , width ( ) - indent , height ( ) - indent ) , colorGroup ) ;
}
/////////////////////////
SignConfig : : SignConfig ( Sign * sign , TQWidget * parent )
: BridgeConfig ( sign , parent )
{
this - > sign = sign ;
m_vlayout - > addStretch ( ) ;
m_vlayout - > addWidget ( new TQLabel ( i18n ( " Sign HTML: " ) , this ) ) ;
KLineEdit * name = new KLineEdit ( sign - > text ( ) , this ) ;
m_vlayout - > addWidget ( name ) ;
connect ( name , TQT_SIGNAL ( textChanged ( const TQString & ) ) , this , TQT_SLOT ( textChanged ( const TQString & ) ) ) ;
}
void SignConfig : : textChanged ( const TQString & text )
{
sign - > setText ( text ) ;
changed ( ) ;
}
/////////////////////////
EllipseConfig : : EllipseConfig ( Ellipse * ellipse , TQWidget * parent )
: Config ( parent ) , slow1 ( 0 ) , fast1 ( 0 ) , slow2 ( 0 ) , fast2 ( 0 ) , slider1 ( 0 ) , slider2 ( 0 )
{
this - > ellipse = ellipse ;
m_vlayout = new TQVBoxLayout ( this , marginHint ( ) , spacingHint ( ) ) ;
TQCheckBox * check = new TQCheckBox ( i18n ( " Enable show/hide " ) , this ) ;
m_vlayout - > addWidget ( check ) ;
connect ( check , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( check1Changed ( bool ) ) ) ;
check - > setChecked ( ellipse - > changeEnabled ( ) ) ;
TQHBoxLayout * hlayout = new TQHBoxLayout ( m_vlayout , spacingHint ( ) ) ;
slow1 = new TQLabel ( i18n ( " Slow " ) , this ) ;
hlayout - > addWidget ( slow1 ) ;
slider1 = new TQSlider ( 1 , 100 , 5 , 100 - ellipse - > changeEvery ( ) , Qt : : Horizontal , this ) ;
hlayout - > addWidget ( slider1 ) ;
fast1 = new TQLabel ( i18n ( " Fast " ) , this ) ;
hlayout - > addWidget ( fast1 ) ;
connect ( slider1 , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( value1Changed ( int ) ) ) ;
check1Changed ( ellipse - > changeEnabled ( ) ) ;
// TODO add slider2 and friends and make it possible for ellipses to grow and contract
m_vlayout - > addStretch ( ) ;
}
void EllipseConfig : : value1Changed ( int news )
{
ellipse - > setChangeEvery ( 100 - news ) ;
changed ( ) ;
}
void EllipseConfig : : value2Changed ( int /*news*/ )
{
changed ( ) ;
}
void EllipseConfig : : check1Changed ( bool on )
{
ellipse - > setChangeEnabled ( on ) ;
if ( slider1 )
slider1 - > setEnabled ( on ) ;
if ( slow1 )
slow1 - > setEnabled ( on ) ;
if ( fast1 )
fast1 - > setEnabled ( on ) ;
changed ( ) ;
}
void EllipseConfig : : check2Changed ( bool on )
{
//ellipse->setChangeEnabled(on);
if ( slider2 )
slider2 - > setEnabled ( on ) ;
if ( slow2 )
slow2 - > setEnabled ( on ) ;
if ( fast2 )
fast2 - > setEnabled ( on ) ;
changed ( ) ;
}
/////////////////////////
Ellipse : : Ellipse ( TQCanvas * canvas )
: TQCanvasEllipse ( canvas )
{
savingDone ( ) ;
setChangeEnabled ( false ) ;
setChangeEvery ( 50 ) ;
count = 0 ;
setVisible ( true ) ;
point = new RectPoint ( black , this , canvas ) ;
point - > setSizeFactor ( 2.0 ) ;
}
void Ellipse : : aboutToDie ( )
{
delete point ;
}
void Ellipse : : setChangeEnabled ( bool changeEnabled )
{
m_changeEnabled = changeEnabled ;
setAnimated ( m_changeEnabled ) ;
if ( ! m_changeEnabled )
setVisible ( true ) ;
}
TQPtrList < TQCanvasItem > Ellipse : : moveableItems ( ) const
{
TQPtrList < TQCanvasItem > ret ;
ret . append ( point ) ;
return ret ;
}
void Ellipse : : newSize ( int width , int height )
{
TQCanvasEllipse : : setSize ( width , height ) ;
}
void Ellipse : : moveBy ( double dx , double dy )
{
TQCanvasEllipse : : moveBy ( dx , dy ) ;
point - > dontMove ( ) ;
point - > move ( x ( ) + width ( ) / 2 , y ( ) + height ( ) / 2 ) ;
}
void Ellipse : : editModeChanged ( bool changed )
{
point - > setVisible ( changed ) ;
moveBy ( 0 , 0 ) ;
}
void Ellipse : : advance ( int phase )
{
TQCanvasEllipse : : advance ( phase ) ;
if ( phase = = 1 & & m_changeEnabled & & ! dontHide )
{
if ( count > ( m_changeEvery + 10 ) * 1.8 )
count = 0 ;
if ( count = = 0 )
setVisible ( ! isVisible ( ) ) ;
count + + ;
}
}
void Ellipse : : load ( KConfig * cfg )
{
setChangeEnabled ( cfg - > readBoolEntry ( " changeEnabled " , changeEnabled ( ) ) ) ;
setChangeEvery ( cfg - > readNumEntry ( " changeEvery " , changeEvery ( ) ) ) ;
double newWidth = width ( ) , newHeight = height ( ) ;
newWidth = cfg - > readNumEntry ( " width " , newWidth ) ;
newHeight = cfg - > readNumEntry ( " height " , newHeight ) ;
newSize ( newWidth , newHeight ) ;
}
void Ellipse : : save ( KConfig * cfg )
{
cfg - > writeEntry ( " changeEvery " , changeEvery ( ) ) ;
cfg - > writeEntry ( " changeEnabled " , changeEnabled ( ) ) ;
cfg - > writeEntry ( " width " , width ( ) ) ;
cfg - > writeEntry ( " height " , height ( ) ) ;
}
Config * Ellipse : : config ( TQWidget * parent )
{
return new EllipseConfig ( this , parent ) ;
}
void Ellipse : : aboutToSave ( )
{
setVisible ( true ) ;
dontHide = true ;
}
void Ellipse : : savingDone ( )
{
dontHide = false ;
}
/////////////////////////
Puddle : : Puddle ( TQCanvas * canvas )
: Ellipse ( canvas )
{
setSize ( 45 , 30 ) ;
TQBrush brush ;
TQPixmap pic ;
if ( ! TQPixmapCache : : find ( " puddle " , pic ) )
{
pic . load ( locate ( " appdata " , " pics/puddle.png " ) ) ;
TQPixmapCache : : insert ( " puddle " , pic ) ;
}
brush . setPixmap ( pic ) ;
setBrush ( brush ) ;
KPixmap pointPic ( pic ) ;
KPixmapEffect : : intensity ( pointPic , .45 ) ;
brush . setPixmap ( pointPic ) ;
point - > setBrush ( brush ) ;
setZ ( - 25 ) ;
}
bool Puddle : : collision ( Ball * ball , long int /*id*/ )
{
if ( ball - > isVisible ( ) )
{
TQCanvasRectangle i ( TQRect ( ball - > x ( ) , ball - > y ( ) , 1 , 1 ) , canvas ( ) ) ;
i . setVisible ( true ) ;
// is center of ball in?
if ( i . collidesWith ( this ) /* && ball->curVector().magnitude() < 4*/ )
{
playSound ( " puddle " ) ;
ball - > setAddStroke ( ball - > addStroke ( ) + 1 ) ;
ball - > setPlaceOnGround ( true ) ;
ball - > setVisible ( false ) ;
ball - > setState ( Stopped ) ;
ball - > setVelocity ( 0 , 0 ) ;
if ( game & & game - > curBall ( ) = = ball )
game - > stoppedBall ( ) ;
}
else
return true ;
}
return false ;
}
/////////////////////////
Sand : : Sand ( TQCanvas * canvas )
: Ellipse ( canvas )
{
setSize ( 45 , 40 ) ;
TQBrush brush ;
TQPixmap pic ;
if ( ! TQPixmapCache : : find ( " sand " , pic ) )
{
pic . load ( locate ( " appdata " , " pics/sand.png " ) ) ;
TQPixmapCache : : insert ( " sand " , pic ) ;
}
brush . setPixmap ( pic ) ;
setBrush ( brush ) ;
KPixmap pointPic ( pic ) ;
KPixmapEffect : : intensity ( pointPic , .45 ) ;
brush . setPixmap ( pointPic ) ;
point - > setBrush ( brush ) ;
setZ ( - 26 ) ;
}
bool Sand : : collision ( Ball * ball , long int /*id*/ )
{
TQCanvasRectangle i ( TQRect ( ball - > x ( ) , ball - > y ( ) , 1 , 1 ) , canvas ( ) ) ;
i . setVisible ( true ) ;
// is center of ball in?
if ( i . collidesWith ( this ) /* && ball->curVector().magnitude() < 4*/ )
{
if ( ball - > curVector ( ) . magnitude ( ) > 0 )
ball - > setFrictionMultiplier ( 7 ) ;
else
{
ball - > setVelocity ( 0 , 0 ) ;
ball - > setState ( Stopped ) ;
}
}
return true ;
}
/////////////////////////
Putter : : Putter ( TQCanvas * canvas )
: TQCanvasLine ( canvas )
{
m_showGuideLine = true ;
oneDegree = M_PI / 180 ;
len = 9 ;
angle = 0 ;
guideLine = new TQCanvasLine ( canvas ) ;
guideLine - > setPen ( TQPen ( white , 1 , TQPen : : DotLine ) ) ;
guideLine - > setZ ( 998.8 ) ;
setPen ( TQPen ( black , 4 ) ) ;
putterWidth = 11 ;
maxAngle = 2 * M_PI ;
hideInfo ( ) ;
// this also sets Z
resetAngles ( ) ;
}
void Putter : : showInfo ( )
{
guideLine - > setVisible ( isVisible ( ) ) ;
}
void Putter : : hideInfo ( )
{
guideLine - > setVisible ( m_showGuideLine ? isVisible ( ) : false ) ;
}
void Putter : : moveBy ( double dx , double dy )
{
TQCanvasLine : : moveBy ( dx , dy ) ;
guideLine - > move ( x ( ) , y ( ) ) ;
}
void Putter : : setShowGuideLine ( bool yes )
{
m_showGuideLine = yes ;
setVisible ( isVisible ( ) ) ;
}
void Putter : : setVisible ( bool yes )
{
TQCanvasLine : : setVisible ( yes ) ;
guideLine - > setVisible ( m_showGuideLine ? yes : false ) ;
}
void Putter : : setOrigin ( int _x , int _y )
{
setVisible ( true ) ;
move ( _x , _y ) ;
len = 9 ;
finishMe ( ) ;
}
void Putter : : setAngle ( Ball * ball )
{
angle = angleMap . contains ( ball ) ? angleMap [ ball ] : 0 ;
finishMe ( ) ;
}
void Putter : : go ( Direction d , Amount amount )
{
double addition = ( amount = = Amount_More ? 6 * oneDegree : amount = = Amount_Less ? .5 * oneDegree : 2 * oneDegree ) ;
switch ( d )
{
case Forwards :
len - = 1 ;
guideLine - > setVisible ( false ) ;
break ;
case Backwards :
len + = 1 ;
guideLine - > setVisible ( false ) ;
break ;
case D_Left :
angle + = addition ;
if ( angle > maxAngle )
angle - = maxAngle ;
break ;
case D_Right :
angle - = addition ;
if ( angle < 0 )
angle = maxAngle - fabs ( angle ) ;
break ;
}
finishMe ( ) ;
}
void Putter : : finishMe ( )
{
midPoint . setX ( cos ( angle ) * len ) ;
midPoint . setY ( - sin ( angle ) * len ) ;
TQPoint start ;
TQPoint end ;
if ( midPoint . y ( ) | | ! midPoint . x ( ) )
{
start . setX ( midPoint . x ( ) - putterWidth * sin ( angle ) ) ;
start . setY ( midPoint . y ( ) - putterWidth * cos ( angle ) ) ;
end . setX ( midPoint . x ( ) + putterWidth * sin ( angle ) ) ;
end . setY ( midPoint . y ( ) + putterWidth * cos ( angle ) ) ;
}
else
{
start . setX ( midPoint . x ( ) ) ;
start . setY ( midPoint . y ( ) + putterWidth ) ;
end . setY ( midPoint . y ( ) - putterWidth ) ;
end . setX ( midPoint . x ( ) ) ;
}
guideLine - > setPoints ( midPoint . x ( ) , midPoint . y ( ) , - cos ( angle ) * len * 4 , sin ( angle ) * len * 4 ) ;
setPoints ( start . x ( ) , start . y ( ) , end . x ( ) , end . y ( ) ) ;
}
/////////////////////////
Bumper : : Bumper ( TQCanvas * canvas )
: TQCanvasEllipse ( 20 , 20 , canvas )
{
setZ ( - 25 ) ;
firstColor = TQColor ( " #E74804 " ) ;
secondColor = firstColor . light ( ) ;
count = 0 ;
setBrush ( firstColor ) ;
setAnimated ( false ) ;
inside = new Inside ( this , canvas ) ;
inside - > setBrush ( firstColor . light ( 109 ) ) ;
inside - > setSize ( width ( ) / 2.6 , height ( ) / 2.6 ) ;
inside - > show ( ) ;
}
void Bumper : : aboutToDie ( )
{
delete inside ;
}
void Bumper : : moveBy ( double dx , double dy )
{
TQCanvasEllipse : : moveBy ( dx , dy ) ;
//const double insideLen = (double)(width() - inside->width()) / 2.0;
inside - > move ( x ( ) , y ( ) ) ;
}
void Bumper : : editModeChanged ( bool changed )
{
inside - > setVisible ( ! changed ) ;
}
void Bumper : : advance ( int phase )
{
TQCanvasEllipse : : advance ( phase ) ;
if ( phase = = 1 )
{
count + + ;
if ( count > 2 )
{
count = 0 ;
setBrush ( firstColor ) ;
update ( ) ;
setAnimated ( false ) ;
}
}
}
bool Bumper : : collision ( Ball * ball , long int /*id*/ )
{
setBrush ( secondColor ) ;
double speed = 1.8 + ball - > curVector ( ) . magnitude ( ) * .9 ;
if ( speed > 8 )
speed = 8 ;
const TQPoint start ( x ( ) , y ( ) ) ;
const TQPoint end ( ball - > x ( ) , ball - > y ( ) ) ;
Vector betweenVector ( start , end ) ;
betweenVector . setMagnitude ( speed ) ;
// add some randomness so we don't go indefinetely
betweenVector . setDirection ( betweenVector . direction ( ) + deg2rad ( ( kapp - > random ( ) % 3 ) - 1 ) ) ;
ball - > setVector ( betweenVector ) ;
// for some reason, x is always switched...
ball - > setXVelocity ( - ball - > xVelocity ( ) ) ;
ball - > setState ( Rolling ) ;
setAnimated ( true ) ;
return true ;
}
/////////////////////////
Hole : : Hole ( TQColor color , TQCanvas * canvas )
: TQCanvasEllipse ( 15 , 15 , canvas )
{
setZ ( 998.1 ) ;
setPen ( black ) ;
setBrush ( color ) ;
}
bool Hole : : collision ( Ball * ball , long int /*id*/ )
{
bool wasCenter = false ;
switch ( result ( TQPoint ( ball - > x ( ) , ball - > y ( ) ) , ball - > curVector ( ) . magnitude ( ) , & wasCenter ) )
{
case Result_Holed :
place ( ball , wasCenter ) ;
return false ;
default :
break ;
}
return true ;
}
HoleResult Hole : : result ( TQPoint p , double s , bool * /*wasCenter*/ )
{
const double longestRadius = width ( ) > height ( ) ? width ( ) : height ( ) ;
if ( s > longestRadius / 5.0 )
return Result_Miss ;
TQCanvasRectangle i ( TQRect ( p , TQSize ( 1 , 1 ) ) , canvas ( ) ) ;
i . setVisible ( true ) ;
// is center of ball in cup?
if ( i . collidesWith ( this ) )
{
return Result_Holed ;
}
else
return Result_Miss ;
}
/////////////////////////
Cup : : Cup ( TQCanvas * canvas )
: Hole ( TQColor ( " #808080 " ) , canvas )
{
if ( ! TQPixmapCache : : find ( " cup " , pixmap ) )
{
pixmap . load ( locate ( " appdata " , " pics/cup.png " ) ) ;
TQPixmapCache : : insert ( " cup " , pixmap ) ;
}
}
void Cup : : draw ( TQPainter & p )
{
p . drawPixmap ( TQPoint ( x ( ) - width ( ) / 2 , y ( ) - height ( ) / 2 ) , pixmap ) ;
}
bool Cup : : place ( Ball * ball , bool /*wasCenter*/ )
{
ball - > setState ( Holed ) ;
playSound ( " holed " ) ;
// the picture's center is a little different
ball - > move ( x ( ) - 1 , y ( ) ) ;
ball - > setVelocity ( 0 , 0 ) ;
if ( game & & game - > curBall ( ) = = ball )
game - > stoppedBall ( ) ;
return true ;
}
void Cup : : save ( KConfig * cfg )
{
cfg - > writeEntry ( " dummykey " , true ) ;
}
/////////////////////////
BlackHole : : BlackHole ( TQCanvas * canvas )
: Hole ( black , canvas ) , exitDeg ( 0 )
{
infoLine = 0 ;
m_minSpeed = 3.0 ;
m_maxSpeed = 5.0 ;
runs = 0 ;
const TQColor myColor ( ( TQRgb ) ( kapp - > random ( ) % 0x01000000 ) ) ;
outside = new TQCanvasEllipse ( canvas ) ;
outside - > setZ ( z ( ) - .001 ) ;
outside - > setBrush ( TQBrush ( myColor ) ) ;
setBrush ( black ) ;
exitItem = new BlackHoleExit ( this , canvas ) ;
exitItem - > setPen ( TQPen ( myColor , 6 ) ) ;
exitItem - > setX ( 300 ) ;
exitItem - > setY ( 100 ) ;
setSize ( width ( ) , width ( ) / .8 ) ;
const float factor = 1.3 ;
outside - > setSize ( width ( ) * factor , height ( ) * factor ) ;
outside - > setVisible ( true ) ;
moveBy ( 0 , 0 ) ;
finishMe ( ) ;
}
void BlackHole : : showInfo ( )
{
delete infoLine ;
infoLine = new TQCanvasLine ( canvas ( ) ) ;
infoLine - > setVisible ( true ) ;
infoLine - > setPen ( TQPen ( exitItem - > pen ( ) . color ( ) , 2 ) ) ;
infoLine - > setZ ( 10000 ) ;
infoLine - > setPoints ( x ( ) , y ( ) , exitItem - > x ( ) , exitItem - > y ( ) ) ;
exitItem - > showInfo ( ) ;
}
void BlackHole : : hideInfo ( )
{
delete infoLine ;
infoLine = 0 ;
exitItem - > hideInfo ( ) ;
}
void BlackHole : : aboutToDie ( )
{
Hole : : aboutToDie ( ) ;
delete outside ;
exitItem - > aboutToDie ( ) ;
delete exitItem ;
}
void BlackHole : : updateInfo ( )
{
if ( infoLine )
{
infoLine - > setVisible ( true ) ;
infoLine - > setPoints ( x ( ) , y ( ) , exitItem - > x ( ) , exitItem - > y ( ) ) ;
exitItem - > showInfo ( ) ;
}
}
void BlackHole : : moveBy ( double dx , double dy )
{
TQCanvasEllipse : : moveBy ( dx , dy ) ;
outside - > move ( x ( ) , y ( ) ) ;
updateInfo ( ) ;
}
void BlackHole : : setExitDeg ( int newdeg )
{
exitDeg = newdeg ;
if ( game & & game - > isEditing ( ) & & game - > curSelectedItem ( ) = = exitItem )
game - > updateHighlighter ( ) ;
exitItem - > updateArrowAngle ( ) ;
finishMe ( ) ;
}
TQPtrList < TQCanvasItem > BlackHole : : moveableItems ( ) const
{
TQPtrList < TQCanvasItem > ret ;
ret . append ( exitItem ) ;
return ret ;
}
BlackHoleTimer : : BlackHoleTimer ( Ball * ball , double speed , int msec )
: m_speed ( speed ) , m_ball ( ball )
{
TQTimer : : singleShot ( msec , this , TQT_SLOT ( mySlot ( ) ) ) ;
TQTimer : : singleShot ( msec / 2 , this , TQT_SLOT ( myMidSlot ( ) ) ) ;
}
void BlackHoleTimer : : mySlot ( )
{
emit eject ( m_ball , m_speed ) ;
delete this ;
}
void BlackHoleTimer : : myMidSlot ( )
{
emit halfway ( ) ;
}
bool BlackHole : : place ( Ball * ball , bool /*wasCenter*/ )
{
// most number is 10
if ( runs > 10 & & game & & game - > isInPlay ( ) )
return false ;
playSound ( " blackholeputin " ) ;
const double diff = ( m_maxSpeed - m_minSpeed ) ;
const double speed = m_minSpeed + ball - > curVector ( ) . magnitude ( ) * ( diff / 3.75 ) ;
ball - > setVelocity ( 0 , 0 ) ;
ball - > setState ( Stopped ) ;
ball - > setVisible ( false ) ;
ball - > setForceStillGoing ( true ) ;
double magnitude = Vector ( TQPoint ( x ( ) , y ( ) ) , TQPoint ( exitItem - > x ( ) , exitItem - > y ( ) ) ) . magnitude ( ) ;
BlackHoleTimer * timer = new BlackHoleTimer ( ball , speed , magnitude * 2.5 - speed * 35 + 500 ) ;
connect ( timer , TQT_SIGNAL ( eject ( Ball * , double ) ) , this , TQT_SLOT ( eject ( Ball * , double ) ) ) ;
connect ( timer , TQT_SIGNAL ( halfway ( ) ) , this , TQT_SLOT ( halfway ( ) ) ) ;
playSound ( " blackhole " ) ;
return false ;
}
void BlackHole : : eject ( Ball * ball , double speed )
{
ball - > move ( exitItem - > x ( ) , exitItem - > y ( ) ) ;
Vector v ;
v . setMagnitude ( 10 ) ;
v . setDirection ( deg2rad ( exitDeg ) ) ;
ball - > setVector ( v ) ;
// advance ball 10
ball - > doAdvance ( ) ;
v . setMagnitude ( speed ) ;
ball - > setVector ( v ) ;
ball - > setForceStillGoing ( false ) ;
ball - > setVisible ( true ) ;
ball - > setState ( Rolling ) ;
runs + + ;
playSound ( " blackholeeject " ) ;
}
void BlackHole : : halfway ( )
{
playSound ( " blackhole " ) ;
}
void BlackHole : : load ( KConfig * cfg )
{
TQPoint exit = cfg - > readPointEntry ( " exit " , & exit ) ;
exitItem - > setX ( exit . x ( ) ) ;
exitItem - > setY ( exit . y ( ) ) ;
exitDeg = cfg - > readNumEntry ( " exitDeg " , exitDeg ) ;
m_minSpeed = cfg - > readDoubleNumEntry ( " minspeed " , m_minSpeed ) ;
m_maxSpeed = cfg - > readDoubleNumEntry ( " maxspeed " , m_maxSpeed ) ;
exitItem - > updateArrowAngle ( ) ;
exitItem - > updateArrowLength ( ) ;
finishMe ( ) ;
}
void BlackHole : : finishMe ( )
{
double radians = deg2rad ( exitDeg ) ;
TQPoint midPoint ( 0 , 0 ) ;
TQPoint start ;
TQPoint end ;
const int width = 15 ;
if ( midPoint . y ( ) | | ! midPoint . x ( ) )
{
start . setX ( midPoint . x ( ) - width * sin ( radians ) ) ;
start . setY ( midPoint . y ( ) - width * cos ( radians ) ) ;
end . setX ( midPoint . x ( ) + width * sin ( radians ) ) ;
end . setY ( midPoint . y ( ) + width * cos ( radians ) ) ;
}
else
{
start . setX ( midPoint . x ( ) ) ;
start . setY ( midPoint . y ( ) + width ) ;
end . setY ( midPoint . y ( ) - width ) ;
end . setX ( midPoint . x ( ) ) ;
}
exitItem - > setPoints ( start . x ( ) , start . y ( ) , end . x ( ) , end . y ( ) ) ;
exitItem - > setVisible ( true ) ;
}
void BlackHole : : save ( KConfig * cfg )
{
cfg - > writeEntry ( " exit " , TQPoint ( exitItem - > x ( ) , exitItem - > y ( ) ) ) ;
cfg - > writeEntry ( " exitDeg " , exitDeg ) ;
cfg - > writeEntry ( " minspeed " , m_minSpeed ) ;
cfg - > writeEntry ( " maxspeed " , m_maxSpeed ) ;
}
/////////////////////////
BlackHoleExit : : BlackHoleExit ( BlackHole * blackHole , TQCanvas * canvas )
: TQCanvasLine ( canvas )
{
this - > blackHole = blackHole ;
arrow = new Arrow ( canvas ) ;
setZ ( blackHole - > z ( ) ) ;
arrow - > setZ ( z ( ) - .00001 ) ;
updateArrowLength ( ) ;
arrow - > setVisible ( false ) ;
}
void BlackHoleExit : : aboutToDie ( )
{
arrow - > aboutToDie ( ) ;
delete arrow ;
}
void BlackHoleExit : : moveBy ( double dx , double dy )
{
TQCanvasLine : : moveBy ( dx , dy ) ;
arrow - > move ( x ( ) , y ( ) ) ;
blackHole - > updateInfo ( ) ;
}
void BlackHoleExit : : setPen ( TQPen p )
{
TQCanvasLine : : setPen ( p ) ;
arrow - > setPen ( TQPen ( p . color ( ) , 1 ) ) ;
}
void BlackHoleExit : : updateArrowAngle ( )
{
// arrows work in a different angle system
arrow - > setAngle ( - deg2rad ( blackHole - > curExitDeg ( ) ) ) ;
arrow - > updateSelf ( ) ;
}
void BlackHoleExit : : updateArrowLength ( )
{
arrow - > setLength ( 10.0 + 5.0 * ( double ) ( blackHole - > minSpeed ( ) + blackHole - > maxSpeed ( ) ) / 2.0 ) ;
arrow - > updateSelf ( ) ;
}
void BlackHoleExit : : editModeChanged ( bool editing )
{
if ( editing )
showInfo ( ) ;
else
hideInfo ( ) ;
}
void BlackHoleExit : : showInfo ( )
{
arrow - > setVisible ( true ) ;
}
void BlackHoleExit : : hideInfo ( )
{
arrow - > setVisible ( false ) ;
}
Config * BlackHoleExit : : config ( TQWidget * parent )
{
return blackHole - > config ( parent ) ;
}
/////////////////////////
BlackHoleConfig : : BlackHoleConfig ( BlackHole * blackHole , TQWidget * parent )
: Config ( parent )
{
this - > blackHole = blackHole ;
TQVBoxLayout * layout = new TQVBoxLayout ( this , marginHint ( ) , spacingHint ( ) ) ;
layout - > addWidget ( new TQLabel ( i18n ( " Exiting ball angle: " ) , this ) ) ;
TQSpinBox * deg = new TQSpinBox ( 0 , 359 , 10 , this ) ;
deg - > setSuffix ( TQString ( " " ) + i18n ( " degrees " ) ) ;
deg - > setValue ( blackHole - > curExitDeg ( ) ) ;
deg - > setWrapping ( true ) ;
layout - > addWidget ( deg ) ;
connect ( deg , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( degChanged ( int ) ) ) ;
layout - > addStretch ( ) ;
TQHBoxLayout * hlayout = new TQHBoxLayout ( layout , spacingHint ( ) ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Minimum exit speed: " ) , this ) ) ;
KDoubleNumInput * min = new KDoubleNumInput ( this ) ;
min - > setRange ( 0 , 8 , 1 , true ) ;
hlayout - > addWidget ( min ) ;
connect ( min , TQT_SIGNAL ( valueChanged ( double ) ) , this , TQT_SLOT ( minChanged ( double ) ) ) ;
min - > setValue ( blackHole - > minSpeed ( ) ) ;
hlayout = new TQHBoxLayout ( layout , spacingHint ( ) ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Maximum: " ) , this ) ) ;
KDoubleNumInput * max = new KDoubleNumInput ( this ) ;
max - > setRange ( 1 , 10 , 1 , true ) ;
hlayout - > addWidget ( max ) ;
connect ( max , TQT_SIGNAL ( valueChanged ( double ) ) , this , TQT_SLOT ( maxChanged ( double ) ) ) ;
max - > setValue ( blackHole - > maxSpeed ( ) ) ;
}
void BlackHoleConfig : : degChanged ( int newdeg )
{
blackHole - > setExitDeg ( newdeg ) ;
changed ( ) ;
}
void BlackHoleConfig : : minChanged ( double news )
{
blackHole - > setMinSpeed ( news ) ;
changed ( ) ;
}
void BlackHoleConfig : : maxChanged ( double news )
{
blackHole - > setMaxSpeed ( news ) ;
changed ( ) ;
}
/////////////////////////
WallPoint : : WallPoint ( bool start , Wall * wall , TQCanvas * canvas )
: TQCanvasEllipse ( canvas )
{
this - > wall = wall ;
this - > start = start ;
alwaysShow = false ;
editing = false ;
visible = true ;
lastId = INT_MAX - 10 ;
dontmove = false ;
move ( 0 , 0 ) ;
TQPoint p ;
if ( start )
p = wall - > startPoint ( ) ;
else
p = wall - > endPoint ( ) ;
setX ( p . x ( ) ) ;
setY ( p . y ( ) ) ;
}
void WallPoint : : clean ( )
{
int oldWidth = width ( ) ;
setSize ( 7 , 7 ) ;
update ( ) ;
TQCanvasItem * onPoint = 0 ;
TQCanvasItemList l = collisions ( true ) ;
for ( TQCanvasItemList : : Iterator it = l . begin ( ) ; it ! = l . end ( ) ; + + it )
if ( ( * it ) - > rtti ( ) = = rtti ( ) )
onPoint = ( * it ) ;
if ( onPoint )
move ( onPoint - > x ( ) , onPoint - > y ( ) ) ;
setSize ( oldWidth , oldWidth ) ;
}
void WallPoint : : moveBy ( double dx , double dy )
{
TQCanvasEllipse : : moveBy ( dx , dy ) ;
if ( ! editing )
updateVisible ( ) ;
if ( dontmove )
{
dontmove = false ;
return ;
}
if ( ! wall )
return ;
if ( start )
{
wall - > setPoints ( x ( ) , y ( ) , wall - > endPoint ( ) . x ( ) + wall - > x ( ) , wall - > endPoint ( ) . y ( ) + wall - > y ( ) ) ;
}
else
{
wall - > setPoints ( wall - > startPoint ( ) . x ( ) + wall - > x ( ) , wall - > startPoint ( ) . y ( ) + wall - > y ( ) , x ( ) , y ( ) ) ;
}
wall - > move ( 0 , 0 ) ;
}
void WallPoint : : updateVisible ( )
{
if ( ! wall - > isVisible ( ) )
{
visible = false ;
return ;
}
if ( alwaysShow )
visible = true ;
else
{
visible = true ;
TQCanvasItemList l = collisions ( true ) ;
for ( TQCanvasItemList : : Iterator it = l . begin ( ) ; it ! = l . end ( ) ; + + it )
if ( ( * it ) - > rtti ( ) = = rtti ( ) )
visible = false ;
}
}
void WallPoint : : editModeChanged ( bool changed )
{
editing = changed ;
setVisible ( true ) ;
if ( ! editing )
updateVisible ( ) ;
}
bool WallPoint : : collision ( Ball * ball , long int id )
{
if ( ball - > curVector ( ) . magnitude ( ) < = 0 )
return false ;
long int tempLastId = lastId ;
lastId = id ;
TQCanvasItemList l = collisions ( true ) ;
for ( TQCanvasItemList : : Iterator it = l . begin ( ) ; it ! = l . end ( ) ; + + it )
{
if ( ( * it ) - > rtti ( ) = = rtti ( ) )
{
WallPoint * point = ( WallPoint * ) ( * it ) ;
point - > lastId = id ;
}
}
//kdDebug(12007) << "WallPoint::collision id: " << id << ", tempLastId: " << tempLastId << endl;
Vector ballVector ( ball - > curVector ( ) ) ;
//kdDebug(12007) << "Wall::collision ball speed: " << ball->curVector().magnitude() << endl;
int allowableDifference = 1 ;
if ( ballVector . magnitude ( ) < .30 )
allowableDifference = 8 ;
else if ( ballVector . magnitude ( ) < .50 )
allowableDifference = 6 ;
else if ( ballVector . magnitude ( ) < .65 )
allowableDifference = 4 ;
else if ( ballVector . magnitude ( ) < .95 )
allowableDifference = 2 ;
if ( abs ( id - tempLastId ) < = allowableDifference )
{
//kdDebug(12007) << "WallPoint::collision - SKIP\n";
}
else
{
bool weirdBounce = visible ;
TQPoint relStart ( start ? wall - > startPoint ( ) : wall - > endPoint ( ) ) ;
TQPoint relEnd ( start ? wall - > endPoint ( ) : wall - > startPoint ( ) ) ;
Vector wallVector ( relStart , relEnd ) ;
wallVector . setDirection ( - wallVector . direction ( ) ) ;
// find the angle between vectors, between 0 and PI
{
double difference = fabs ( wallVector . direction ( ) - ballVector . direction ( ) ) ;
while ( difference > 2 * M_PI )
difference - = 2 * M_PI ;
if ( difference < M_PI / 2 | | difference > 3 * M_PI / 2 )
weirdBounce = false ;
}
playSound ( " wall " , ball - > curVector ( ) . magnitude ( ) / 10.0 ) ;
ballVector / = wall - > dampening ;
const double ballAngle = ballVector . direction ( ) ;
double wallAngle = wallVector . direction ( ) ;
// opposite bounce, because we're the endpoint
if ( weirdBounce )
wallAngle + = M_PI / 2 ;
const double collisionAngle = ballAngle - wallAngle ;
const double leavingAngle = wallAngle - collisionAngle ;
ballVector . setDirection ( leavingAngle ) ;
ball - > setVector ( ballVector ) ;
wall - > lastId = id ;
//kdDebug(12007) << "WallPoint::collision - NOT skip, weirdBounce is " << weirdBounce << endl;
} // end if that skips
wall - > lastId = id ;
return false ;
}
/////////////////////////
Wall : : Wall ( TQCanvas * canvas )
: TQCanvasLine ( canvas )
{
editing = false ;
lastId = INT_MAX - 10 ;
dampening = 1.2 ;
startItem = 0 ;
endItem = 0 ;
moveBy ( 0 , 0 ) ;
setZ ( 50 ) ;
startItem = new WallPoint ( true , this , canvas ) ;
endItem = new WallPoint ( false , this , canvas ) ;
startItem - > setVisible ( true ) ;
endItem - > setVisible ( true ) ;
setPen ( TQPen ( darkRed , 3 ) ) ;
setPoints ( - 15 , 10 , 15 , - 5 ) ;
moveBy ( 0 , 0 ) ;
editModeChanged ( false ) ;
}
void Wall : : selectedItem ( TQCanvasItem * item )
{
if ( item - > rtti ( ) = = Rtti_WallPoint )
{
WallPoint * wallPoint = dynamic_cast < WallPoint * > ( item ) ;
if ( wallPoint ) {
setPoints ( startPoint ( ) . x ( ) , startPoint ( ) . y ( ) , wallPoint - > x ( ) - x ( ) , wallPoint - > y ( ) - y ( ) ) ;
}
}
}
void Wall : : clean ( )
{
startItem - > clean ( ) ;
endItem - > clean ( ) ;
}
void Wall : : setAlwaysShow ( bool yes )
{
startItem - > setAlwaysShow ( yes ) ;
endItem - > setAlwaysShow ( yes ) ;
}
void Wall : : setVisible ( bool yes )
{
TQCanvasLine : : setVisible ( yes ) ;
startItem - > setVisible ( yes ) ;
endItem - > setVisible ( yes ) ;
startItem - > updateVisible ( ) ;
endItem - > updateVisible ( ) ;
}
void Wall : : setZ ( double newz )
{
TQCanvasLine : : setZ ( newz ) ;
if ( startItem )
startItem - > setZ ( newz + .002 ) ;
if ( endItem )
endItem - > setZ ( newz + .001 ) ;
}
void Wall : : setPen ( TQPen p )
{
TQCanvasLine : : setPen ( p ) ;
if ( startItem )
startItem - > setBrush ( TQBrush ( p . color ( ) ) ) ;
if ( endItem )
endItem - > setBrush ( TQBrush ( p . color ( ) ) ) ;
}
void Wall : : aboutToDie ( )
{
delete startItem ;
delete endItem ;
}
void Wall : : setGame ( KolfGame * game )
{
CanvasItem : : setGame ( game ) ;
startItem - > setGame ( game ) ;
endItem - > setGame ( game ) ;
}
TQPtrList < TQCanvasItem > Wall : : moveableItems ( ) const
{
TQPtrList < TQCanvasItem > ret ;
ret . append ( startItem ) ;
ret . append ( endItem ) ;
return ret ;
}
void Wall : : moveBy ( double dx , double dy )
{
TQCanvasLine : : moveBy ( dx , dy ) ;
if ( ! startItem | | ! endItem )
return ;
startItem - > dontMove ( ) ;
endItem - > dontMove ( ) ;
startItem - > move ( startPoint ( ) . x ( ) + x ( ) , startPoint ( ) . y ( ) + y ( ) ) ;
endItem - > move ( endPoint ( ) . x ( ) + x ( ) , endPoint ( ) . y ( ) + y ( ) ) ;
}
void Wall : : setVelocity ( double vx , double vy )
{
TQCanvasLine : : setVelocity ( vx , vy ) ;
/*
startItem - > setVelocity ( vx , vy ) ;
endItem - > setVelocity ( vx , vy ) ;
*/
}
TQPointArray Wall : : areaPoints ( ) const
{
// editing we want full width for easy moving
if ( editing )
return TQCanvasLine : : areaPoints ( ) ;
// lessen width, for TQCanvasLine::areaPoints() likes
// to make lines _very_ fat :(
// from qcanvas.cpp, only the stuff for a line width of 1 taken
// it's all squished because I don't want my
// line counts to count code I didn't write!
TQPointArray p ( 4 ) ; const int xi = int ( x ( ) ) ; const int yi = int ( y ( ) ) ; const TQPoint start = startPoint ( ) ; const TQPoint end = endPoint ( ) ; const int x1 = start . x ( ) ; const int x2 = end . x ( ) ; const int y1 = start . y ( ) ; const int y2 = end . y ( ) ; const int dx = TQABS ( x1 - x2 ) ; const int dy = TQABS ( y1 - y2 ) ; if ( dx > dy ) { p [ 0 ] = TQPoint ( x1 + xi , y1 + yi - 1 ) ; p [ 1 ] = TQPoint ( x2 + xi , y2 + yi - 1 ) ; p [ 2 ] = TQPoint ( x2 + xi , y2 + yi + 1 ) ; p [ 3 ] = TQPoint ( x1 + xi , y1 + yi + 1 ) ; } else { p [ 0 ] = TQPoint ( x1 + xi - 1 , y1 + yi ) ; p [ 1 ] = TQPoint ( x2 + xi - 1 , y2 + yi ) ; p [ 2 ] = TQPoint ( x2 + xi + 1 , y2 + yi ) ; p [ 3 ] = TQPoint ( x1 + xi + 1 , y1 + yi ) ; } return p ;
}
void Wall : : editModeChanged ( bool changed )
{
// make big for debugging?
const bool debugPoints = false ;
editing = changed ;
startItem - > setZ ( z ( ) + .002 ) ;
endItem - > setZ ( z ( ) + .001 ) ;
startItem - > editModeChanged ( editing ) ;
endItem - > editModeChanged ( editing ) ;
int neww = 0 ;
if ( changed | | debugPoints )
neww = 10 ;
else
neww = pen ( ) . width ( ) ;
startItem - > setSize ( neww , neww ) ;
endItem - > setSize ( neww , neww ) ;
moveBy ( 0 , 0 ) ;
}
bool Wall : : collision ( Ball * ball , long int id )
{
if ( ball - > curVector ( ) . magnitude ( ) < = 0 )
return false ;
long int tempLastId = lastId ;
lastId = id ;
startItem - > lastId = id ;
endItem - > lastId = id ;
//kdDebug(12007) << "Wall::collision id: " << id << ", tempLastId: " << tempLastId << endl;
Vector ballVector ( ball - > curVector ( ) ) ;
//kdDebug(12007) << "Wall::collision ball speed: " << ball->curVector().magnitude() << endl;
int allowableDifference = 1 ;
if ( ballVector . magnitude ( ) < .30 )
allowableDifference = 8 ;
else if ( ballVector . magnitude ( ) < .50 )
allowableDifference = 6 ;
else if ( ballVector . magnitude ( ) < .75 )
allowableDifference = 4 ;
else if ( ballVector . magnitude ( ) < .95 )
allowableDifference = 2 ;
//kdDebug(12007) << "Wall::collision allowableDifference is " << allowableDifference << endl;
if ( abs ( id - tempLastId ) < = allowableDifference )
{
//kdDebug(12007) << "Wall::collision - SKIP\n";
return false ;
}
playSound ( " wall " , ball - > curVector ( ) . magnitude ( ) / 10.0 ) ;
ballVector / = dampening ;
const double ballAngle = ballVector . direction ( ) ;
const double wallAngle = - Vector ( startPoint ( ) , endPoint ( ) ) . direction ( ) ;
const double collisionAngle = ballAngle - wallAngle ;
const double leavingAngle = wallAngle - collisionAngle ;
ballVector . setDirection ( leavingAngle ) ;
ball - > setVector ( ballVector ) ;
//kdDebug(12007) << "Wall::collision - NOT skip\n";
return false ;
}
void Wall : : load ( KConfig * cfg )
{
TQPoint start ( startPoint ( ) ) ;
start = cfg - > readPointEntry ( " startPoint " , & start ) ;
TQPoint end ( endPoint ( ) ) ;
end = cfg - > readPointEntry ( " endPoint " , & end ) ;
setPoints ( start . x ( ) , start . y ( ) , end . x ( ) , end . y ( ) ) ;
moveBy ( 0 , 0 ) ;
startItem - > move ( start . x ( ) , start . y ( ) ) ;
endItem - > move ( end . x ( ) , end . y ( ) ) ;
}
void Wall : : save ( KConfig * cfg )
{
cfg - > writeEntry ( " startPoint " , TQPoint ( startItem - > x ( ) , startItem - > y ( ) ) ) ;
cfg - > writeEntry ( " endPoint " , TQPoint ( endItem - > x ( ) , endItem - > y ( ) ) ) ;
}
/////////////////////////
HoleConfig : : HoleConfig ( HoleInfo * holeInfo , TQWidget * parent )
: Config ( parent )
{
this - > holeInfo = holeInfo ;
TQVBoxLayout * layout = new TQVBoxLayout ( this , marginHint ( ) , spacingHint ( ) ) ;
TQHBoxLayout * hlayout = new TQHBoxLayout ( layout , spacingHint ( ) ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Course name: " ) , this ) ) ;
KLineEdit * nameEdit = new KLineEdit ( holeInfo - > untranslatedName ( ) , this ) ;
hlayout - > addWidget ( nameEdit ) ;
connect ( nameEdit , TQT_SIGNAL ( textChanged ( const TQString & ) ) , this , TQT_SLOT ( nameChanged ( const TQString & ) ) ) ;
hlayout = new TQHBoxLayout ( layout , spacingHint ( ) ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Course author: " ) , this ) ) ;
KLineEdit * authorEdit = new KLineEdit ( holeInfo - > author ( ) , this ) ;
hlayout - > addWidget ( authorEdit ) ;
connect ( authorEdit , TQT_SIGNAL ( textChanged ( const TQString & ) ) , this , TQT_SLOT ( authorChanged ( const TQString & ) ) ) ;
layout - > addStretch ( ) ;
hlayout = new TQHBoxLayout ( layout , spacingHint ( ) ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Par: " ) , this ) ) ;
TQSpinBox * par = new TQSpinBox ( 1 , 15 , 1 , this ) ;
par - > setValue ( holeInfo - > par ( ) ) ;
hlayout - > addWidget ( par ) ;
connect ( par , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( parChanged ( int ) ) ) ;
hlayout - > addStretch ( ) ;
hlayout - > addWidget ( new TQLabel ( i18n ( " Maximum: " ) , this ) ) ;
TQSpinBox * maxstrokes = new TQSpinBox ( holeInfo - > lowestMaxStrokes ( ) , 30 , 1 , this ) ;
TQWhatsThis : : add ( maxstrokes , i18n ( " Maximum number of strokes player can take on this hole. " ) ) ;
TQToolTip : : add ( maxstrokes , i18n ( " Maximum number of strokes " ) ) ;
maxstrokes - > setSpecialValueText ( i18n ( " Unlimited " ) ) ;
maxstrokes - > setValue ( holeInfo - > maxStrokes ( ) ) ;
hlayout - > addWidget ( maxstrokes ) ;
connect ( maxstrokes , TQT_SIGNAL ( valueChanged ( int ) ) , this , TQT_SLOT ( maxStrokesChanged ( int ) ) ) ;
TQCheckBox * check = new TQCheckBox ( i18n ( " Show border walls " ) , this ) ;
check - > setChecked ( holeInfo - > borderWalls ( ) ) ;
layout - > addWidget ( check ) ;
connect ( check , TQT_SIGNAL ( toggled ( bool ) ) , this , TQT_SLOT ( borderWallsChanged ( bool ) ) ) ;
}
void HoleConfig : : authorChanged ( const TQString & newauthor )
{
holeInfo - > setAuthor ( newauthor ) ;
changed ( ) ;
}
void HoleConfig : : nameChanged ( const TQString & newname )
{
holeInfo - > setName ( newname ) ;
holeInfo - > setUntranslatedName ( newname ) ;
changed ( ) ;
}
void HoleConfig : : parChanged ( int newpar )
{
holeInfo - > setPar ( newpar ) ;
changed ( ) ;
}
void HoleConfig : : maxStrokesChanged ( int newms )
{
holeInfo - > setMaxStrokes ( newms ) ;
changed ( ) ;
}
void HoleConfig : : borderWallsChanged ( bool yes )
{
holeInfo - > borderWallsChanged ( yes ) ;
changed ( ) ;
}
/////////////////////////
StrokeCircle : : StrokeCircle ( TQCanvas * canvas )
: TQCanvasItem ( canvas )
{
dvalue = 0 ;
dmax = 360 ;
iwidth = 100 ;
iheight = 100 ;
ithickness = 8 ;
setZ ( 10000 ) ;
}
void StrokeCircle : : setValue ( double v )
{
dvalue = v ;
if ( dvalue > dmax )
dvalue = dmax ;
update ( ) ;
}
double StrokeCircle : : value ( )
{
return dvalue ;
}
bool StrokeCircle : : collidesWith ( const TQCanvasItem * ) const { return false ; }
bool StrokeCircle : : collidesWith ( const TQCanvasSprite * , const TQCanvasPolygonalItem * , const TQCanvasRectangle * , const TQCanvasEllipse * , const TQCanvasText * ) const { return false ; }
TQRect StrokeCircle : : boundingRect ( ) const { return TQRect ( x ( ) , y ( ) , iwidth , iheight ) ; }
void StrokeCircle : : setMaxValue ( double m )
{
dmax = m ;
if ( dvalue > dmax )
dvalue = dmax ;
update ( ) ;
}
void StrokeCircle : : setSize ( int w , int h )
{
if ( w > 0 )
iwidth = w ;
if ( h > 0 )
iheight = h ;
update ( ) ;
}
void StrokeCircle : : setThickness ( int t )
{
if ( t > 0 )
ithickness = t ;
update ( ) ;
}
int StrokeCircle : : thickness ( ) const
{
return ithickness ;
}
int StrokeCircle : : width ( ) const
{
return iwidth ;
}
int StrokeCircle : : height ( ) const
{
return iheight ;
}
void StrokeCircle : : draw ( TQPainter & p )
{
int al = ( int ) ( ( dvalue * 360 * 16 ) / dmax ) ;
int length , deg ;
if ( al < 0 )
{
deg = 270 * 16 ;
length = - al ;
}
else if ( al < = ( 270 * 16 ) )
{
deg = 270 * 16 - al ;
length = al ;
}
else
{
deg = ( 360 * 16 ) - ( al - ( 270 * 16 ) ) ;
length = al ;
}
p . setBrush ( TQBrush ( black , TQt : : NoBrush ) ) ;
p . setPen ( TQPen ( white , ithickness / 2 ) ) ;
p . drawEllipse ( x ( ) + ithickness / 2 , y ( ) + ithickness / 2 , iwidth - ithickness , iheight - ithickness ) ;
p . setPen ( TQPen ( TQColor ( ( int ) ( 0xff * dvalue ) / dmax , 0 , 0xff - ( int ) ( 0xff * dvalue ) / dmax ) , ithickness ) ) ;
p . drawArc ( x ( ) + ithickness / 2 , y ( ) + ithickness / 2 , iwidth - ithickness , iheight - ithickness , deg , length ) ;
p . setPen ( TQPen ( white , 1 ) ) ;
p . drawEllipse ( x ( ) , y ( ) , iwidth , iheight ) ;
p . drawEllipse ( x ( ) + ithickness , y ( ) + ithickness , iwidth - ithickness * 2 , iheight - ithickness * 2 ) ;
p . setPen ( TQPen ( white , 3 ) ) ;
p . drawLine ( x ( ) + iwidth / 2 , y ( ) + iheight - ithickness * 1.5 , x ( ) + iwidth / 2 , y ( ) + iheight ) ;
p . drawLine ( x ( ) + iwidth / 4 - iwidth / 20 , y ( ) + iheight - iheight / 4 + iheight / 20 , x ( ) + iwidth / 4 + iwidth / 20 , y ( ) + iheight - iheight / 4 - iheight / 20 ) ;
p . drawLine ( x ( ) + iwidth - iwidth / 4 + iwidth / 20 , y ( ) + iheight - iheight / 4 + iheight / 20 , x ( ) + iwidth - iwidth / 4 - iwidth / 20 , y ( ) + iheight - iheight / 4 - iheight / 20 ) ;
}
/////////////////////////////////////////
KolfGame : : KolfGame ( ObjectList * obj , PlayerList * players , TQString filename , TQWidget * parent , const char * name )
: TQCanvasView ( parent , name )
{
// for mouse control
setMouseTracking ( true ) ;
viewport ( ) - > setMouseTracking ( true ) ;
setFrameShape ( NoFrame ) ;
regAdv = false ;
curHole = 0 ; // will get ++'d
cfg = 0 ;
setFilename ( filename ) ;
this - > players = players ;
this - > obj = obj ;
curPlayer = players - > end ( ) ;
curPlayer - - ; // will get ++'d to end and sent back
// to beginning
paused = false ;
modified = false ;
inPlay = false ;
putting = false ;
stroking = false ;
editing = false ;
strict = false ;
lastDelId = - 1 ;
m_showInfo = false ;
ballStateList . canUndo = false ;
fastAdvancedExist = false ;
soundDir = locate ( " appdata " , " sounds/ " ) ;
dontAddStroke = false ;
addingNewHole = false ;
scoreboardHoles = 0 ;
infoShown = false ;
m_useMouse = true ;
m_useAdvancedPutting = false ;
m_useAdvancedPutting = true ;
m_sound = true ;
m_ignoreEvents = false ;
soundedOnce = false ;
oldPlayObjects . setAutoDelete ( true ) ;
highestHole = 0 ;
recalcHighestHole = false ;
holeInfo . setGame ( this ) ;
holeInfo . setAuthor ( i18n ( " Course Author " ) ) ;
holeInfo . setName ( i18n ( " Course Name " ) ) ;
holeInfo . setUntranslatedName ( i18n ( " Course Name " ) ) ;
holeInfo . setMaxStrokes ( 10 ) ;
holeInfo . borderWallsChanged ( true ) ;
// width and height are the width and height of the canvas
// in easy storage
width = 400 ;
height = 400 ;
grass = TQColor ( " #35760D " ) ;
margin = 10 ;
setFocusPolicy ( TQ_StrongFocus ) ;
setFixedSize ( width + 2 * margin , height + 2 * margin ) ;
setMargins ( margin , margin , margin , margin ) ;
course = new TQCanvas ( TQT_TQOBJECT ( this ) ) ;
course - > setBackgroundColor ( white ) ;
course - > resize ( width , height ) ;
TQPixmap pic ;
if ( ! TQPixmapCache : : find ( " grass " , pic ) )
{
pic . load ( locate ( " appdata " , " pics/grass.png " ) ) ;
TQPixmapCache : : insert ( " grass " , pic ) ;
}
course - > setBackgroundPixmap ( pic ) ;
setCanvas ( course ) ;
move ( 0 , 0 ) ;
adjustSize ( ) ;
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > setCanvas ( course ) ;
// highlighter shows current item
highlighter = new TQCanvasRectangle ( course ) ;
highlighter - > setPen ( TQPen ( yellow , 1 ) ) ;
highlighter - > setBrush ( TQBrush ( NoBrush ) ) ;
highlighter - > setVisible ( false ) ;
highlighter - > setZ ( 10000 ) ;
// shows some info about hole
infoText = new TQCanvasText ( course ) ;
infoText - > setText ( " " ) ;
infoText - > setColor ( white ) ;
TQFont font = kapp - > font ( ) ;
font . setPixelSize ( 12 ) ;
infoText - > move ( 15 , width / 2 ) ;
infoText - > setZ ( 10001 ) ;
infoText - > setFont ( font ) ;
infoText - > setVisible ( false ) ;
// create the advanced putting indicator
strokeCircle = new StrokeCircle ( course ) ;
strokeCircle - > move ( width - 90 , height - 90 ) ;
strokeCircle - > setSize ( 80 , 80 ) ;
strokeCircle - > setThickness ( 8 ) ;
strokeCircle - > setVisible ( false ) ;
strokeCircle - > setValue ( 0 ) ;
strokeCircle - > setMaxValue ( 360 ) ;
// whiteBall marks the spot of the whole whilst editing
whiteBall = new Ball ( course ) ;
whiteBall - > setGame ( this ) ;
whiteBall - > setColor ( white ) ;
whiteBall - > setVisible ( false ) ;
whiteBall - > setDoDetect ( false ) ;
int highestLog = 0 ;
// if players have scores from loaded game, move to last hole
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
if ( ( int ) ( * it ) . scores ( ) . count ( ) > highestLog )
highestLog = ( * it ) . scores ( ) . count ( ) ;
( * it ) . ball ( ) - > setGame ( this ) ;
( * it ) . ball ( ) - > setAnimated ( true ) ;
}
// here only for saved games
if ( highestLog )
curHole = highestLog ;
putter = new Putter ( course ) ;
// border walls:
// horiz
addBorderWall ( TQPoint ( margin , margin ) , TQPoint ( width - margin , margin ) ) ;
addBorderWall ( TQPoint ( margin , height - margin - 1 ) , TQPoint ( width - margin , height - margin - 1 ) ) ;
// vert
addBorderWall ( TQPoint ( margin , margin ) , TQPoint ( margin , height - margin ) ) ;
addBorderWall ( TQPoint ( width - margin - 1 , margin ) , TQPoint ( width - margin - 1 , height - margin ) ) ;
timer = new TQTimer ( this ) ;
connect ( timer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( timeout ( ) ) ) ;
timerMsec = 300 ;
fastTimer = new TQTimer ( this ) ;
connect ( fastTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( fastTimeout ( ) ) ) ;
fastTimerMsec = 11 ;
autoSaveTimer = new TQTimer ( this ) ;
connect ( autoSaveTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( autoSaveTimeout ( ) ) ) ;
autoSaveMsec = 5 * 1000 * 60 ; // 5 min autosave
// setUseAdvancedPutting() sets maxStrength!
setUseAdvancedPutting ( false ) ;
putting = false ;
putterTimer = new TQTimer ( this ) ;
connect ( putterTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( putterTimeout ( ) ) ) ;
putterTimerMsec = 20 ;
}
void KolfGame : : startFirstHole ( int hole )
{
if ( curHole > 0 ) // if there was saved game, sync scoreboard
// with number of holes
{
for ( ; scoreboardHoles < curHole ; + + scoreboardHoles )
{
cfg - > setGroup ( TQString ( " %1-hole@-50,-50|0 " ) . arg ( scoreboardHoles + 1 ) ) ;
emit newHole ( cfg - > readNumEntry ( " par " , 3 ) ) ;
}
// lets load all of the scores from saved game if there are any
for ( int hole = 1 ; hole < = curHole ; + + hole )
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
emit scoreChanged ( ( * it ) . id ( ) , hole , ( * it ) . score ( hole ) ) ;
}
curHole = hole - 1 ;
// this increments curHole, etc
recalcHighestHole = true ;
startNextHole ( ) ;
paused = true ;
unPause ( ) ;
}
void KolfGame : : setFilename ( const TQString & filename )
{
this - > filename = filename ;
delete cfg ;
cfg = new KConfig ( filename , false , false ) ;
}
KolfGame : : ~ KolfGame ( )
{
oldPlayObjects . clear ( ) ;
delete cfg ;
}
void KolfGame : : setModified ( bool mod )
{
modified = mod ;
emit modifiedChanged ( mod ) ;
}
void KolfGame : : pause ( )
{
if ( paused )
{
// play along with people who call pause() again, instead of unPause()
unPause ( ) ;
return ;
}
paused = true ;
timer - > stop ( ) ;
fastTimer - > stop ( ) ;
putterTimer - > stop ( ) ;
}
void KolfGame : : unPause ( )
{
if ( ! paused )
return ;
paused = false ;
timer - > start ( timerMsec ) ;
fastTimer - > start ( fastTimerMsec ) ;
if ( putting | | stroking )
putterTimer - > start ( putterTimerMsec ) ;
}
void KolfGame : : addBorderWall ( TQPoint start , TQPoint end )
{
Wall * wall = new Wall ( course ) ;
wall - > setPoints ( start . x ( ) , start . y ( ) , end . x ( ) , end . y ( ) ) ;
wall - > setVisible ( true ) ;
wall - > setGame ( this ) ;
wall - > setZ ( 998.7 ) ;
borderWalls . append ( wall ) ;
}
void KolfGame : : updateHighlighter ( )
{
if ( ! selectedItem )
return ;
TQRect rect = selectedItem - > boundingRect ( ) ;
highlighter - > move ( rect . x ( ) + 1 , rect . y ( ) + 1 ) ;
highlighter - > setSize ( rect . width ( ) , rect . height ( ) ) ;
}
void KolfGame : : handleMouseDoubleClickEvent ( TQMouseEvent * e )
{
// allow two fast single clicks
handleMousePressEvent ( e ) ;
}
void KolfGame : : handleMousePressEvent ( TQMouseEvent * e )
{
if ( m_ignoreEvents )
return ;
if ( editing )
{
if ( inPlay )
return ;
storedMousePos = e - > pos ( ) ;
TQCanvasItemList list = course - > collisions ( e - > pos ( ) ) ;
if ( list . first ( ) = = highlighter )
list . pop_front ( ) ;
moving = false ;
highlighter - > setVisible ( false ) ;
selectedItem = 0 ;
movingItem = 0 ;
if ( list . count ( ) < 1 )
{
emit newSelectedItem ( & holeInfo ) ;
return ;
}
// only items we keep track of
if ( ( ! ( items . containsRef ( list . first ( ) ) | | list . first ( ) = = whiteBall | | extraMoveable . containsRef ( list . first ( ) ) ) ) )
{
emit newSelectedItem ( & holeInfo ) ;
return ;
}
CanvasItem * citem = dynamic_cast < CanvasItem * > ( list . first ( ) ) ;
if ( ! citem | | ! citem - > moveable ( ) )
{
emit newSelectedItem ( & holeInfo ) ;
return ;
}
switch ( e - > button ( ) )
{
// select AND move now :)
case Qt : : LeftButton :
{
selectedItem = list . first ( ) ;
movingItem = selectedItem ;
moving = true ;
if ( citem - > cornerResize ( ) )
setCursor ( KCursor : : sizeFDiagCursor ( ) ) ;
else
setCursor ( KCursor : : sizeAllCursor ( ) ) ;
emit newSelectedItem ( citem ) ;
highlighter - > setVisible ( true ) ;
TQRect rect = selectedItem - > boundingRect ( ) ;
highlighter - > move ( rect . x ( ) + 1 , rect . y ( ) + 1 ) ;
highlighter - > setSize ( rect . width ( ) , rect . height ( ) ) ;
}
break ;
default :
break ;
}
}
else
{
if ( m_useMouse )
{
if ( ! inPlay & & e - > button ( ) = = Qt : : LeftButton )
puttPress ( ) ;
else if ( e - > button ( ) = = Qt : : RightButton )
toggleShowInfo ( ) ;
}
}
setFocus ( ) ;
}
TQPoint KolfGame : : viewportToViewport ( const TQPoint & p )
{
// for some reason viewportToContents doesn't work right
return p - TQPoint ( margin , margin ) ;
}
// the following four functions are needed to handle both
// border presses and regular in-course presses
void KolfGame : : mouseReleaseEvent ( TQMouseEvent * e )
{
TQMouseEvent fixedEvent ( TQEvent : : MouseButtonRelease , viewportToViewport ( viewportToContents ( e - > pos ( ) ) ) , e - > button ( ) , e - > state ( ) ) ;
handleMouseReleaseEvent ( & fixedEvent ) ;
}
void KolfGame : : mousePressEvent ( TQMouseEvent * e )
{
TQMouseEvent fixedEvent ( TQEvent : : MouseButtonPress , viewportToViewport ( viewportToContents ( e - > pos ( ) ) ) , e - > button ( ) , e - > state ( ) ) ;
handleMousePressEvent ( & fixedEvent ) ;
}
void KolfGame : : mouseDoubleClickEvent ( TQMouseEvent * e )
{
TQMouseEvent fixedEvent ( TQEvent : : MouseButtonDblClick , viewportToViewport ( viewportToContents ( e - > pos ( ) ) ) , e - > button ( ) , e - > state ( ) ) ;
handleMouseDoubleClickEvent ( & fixedEvent ) ;
}
void KolfGame : : mouseMoveEvent ( TQMouseEvent * e )
{
TQMouseEvent fixedEvent ( TQEvent : : MouseMove , viewportToViewport ( viewportToContents ( e - > pos ( ) ) ) , e - > button ( ) , e - > state ( ) ) ;
handleMouseMoveEvent ( & fixedEvent ) ;
}
void KolfGame : : handleMouseMoveEvent ( TQMouseEvent * e )
{
if ( inPlay | | ! putter | | m_ignoreEvents )
return ;
TQPoint mouse = e - > pos ( ) ;
// mouse moving of putter
if ( ! editing )
{
updateMouse ( ) ;
return ;
}
if ( ! moving )
{
// lets change the cursor to a hand
// if we're hovering over something
TQCanvasItemList list = course - > collisions ( e - > pos ( ) ) ;
if ( list . count ( ) > 0 )
setCursor ( KCursor : : handCursor ( ) ) ;
else
setCursor ( KCursor : : arrowCursor ( ) ) ;
return ;
}
int moveX = storedMousePos . x ( ) - mouse . x ( ) ;
int moveY = storedMousePos . y ( ) - mouse . y ( ) ;
// moving counts as modifying
if ( moveX | | moveY )
setModified ( true ) ;
highlighter - > moveBy ( - ( double ) moveX , - ( double ) moveY ) ;
movingItem - > moveBy ( - ( double ) moveX , - ( double ) moveY ) ;
TQRect brect = movingItem - > boundingRect ( ) ;
emit newStatusText ( TQString ( " %1x%2 " ) . arg ( brect . x ( ) ) . arg ( brect . y ( ) ) ) ;
storedMousePos = mouse ;
}
void KolfGame : : updateMouse ( )
{
// don't move putter if in advanced putting sequence
if ( ! m_useMouse | | ( ( stroking | | putting ) & & m_useAdvancedPutting ) )
return ;
const TQPoint cursor = viewportToViewport ( viewportToContents ( mapFromGlobal ( TQCursor : : pos ( ) ) ) ) ;
const TQPoint ball ( ( * curPlayer ) . ball ( ) - > x ( ) , ( * curPlayer ) . ball ( ) - > y ( ) ) ;
putter - > setAngle ( - Vector ( cursor , ball ) . direction ( ) ) ;
}
void KolfGame : : handleMouseReleaseEvent ( TQMouseEvent * e )
{
setCursor ( KCursor : : arrowCursor ( ) ) ;
if ( editing )
{
emit newStatusText ( TQString ( ) ) ;
moving = false ;
}
if ( m_ignoreEvents )
return ;
if ( ! editing & & m_useMouse )
{
if ( ! inPlay & & e - > button ( ) = = Qt : : LeftButton )
puttRelease ( ) ;
else if ( e - > button ( ) = = Qt : : RightButton )
toggleShowInfo ( ) ;
}
setFocus ( ) ;
}
void KolfGame : : keyPressEvent ( TQKeyEvent * e )
{
if ( inPlay | | editing | | m_ignoreEvents )
return ;
switch ( e - > key ( ) )
{
case Key_Up :
if ( ! e - > isAutoRepeat ( ) )
toggleShowInfo ( ) ;
break ;
case Key_Escape :
putting = false ;
stroking = false ;
finishStroking = false ;
strokeCircle - > setVisible ( false ) ;
putterTimer - > stop ( ) ;
putter - > setOrigin ( ( * curPlayer ) . ball ( ) - > x ( ) , ( * curPlayer ) . ball ( ) - > y ( ) ) ;
break ;
case Key_Left :
case Key_Right :
// don't move putter if in advanced putting sequence
if ( ( ! stroking & & ! putting ) | | ! m_useAdvancedPutting )
putter - > go ( e - > key ( ) = = Key_Left ? D_Left : D_Right , e - > state ( ) & ShiftButton ? Amount_More : e - > state ( ) & ControlButton ? Amount_Less : Amount_Normal ) ;
break ;
case Key_Space : case Key_Down :
puttPress ( ) ;
break ;
default :
break ;
}
}
void KolfGame : : toggleShowInfo ( )
{
setShowInfo ( ! m_showInfo ) ;
}
void KolfGame : : updateShowInfo ( )
{
setShowInfo ( m_showInfo ) ;
}
void KolfGame : : setShowInfo ( bool yes )
{
m_showInfo = yes ;
if ( m_showInfo )
{
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
citem - > showInfo ( ) ;
}
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > showInfo ( ) ;
showInfo ( ) ;
}
else
{
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
citem - > hideInfo ( ) ;
}
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > hideInfo ( ) ;
hideInfo ( ) ;
}
}
void KolfGame : : puttPress ( )
{
// Advanced putting: 1st click start putting sequence, 2nd determine strength, 3rd determine precision
if ( ! putting & & ! stroking & & ! inPlay )
{
puttCount = 0 ;
puttReverse = false ;
putting = true ;
stroking = false ;
strength = 0 ;
if ( m_useAdvancedPutting )
{
strokeCircle - > setValue ( 0 ) ;
int pw = putter - > endPoint ( ) . x ( ) - putter - > startPoint ( ) . x ( ) ;
if ( pw < 0 ) pw = - pw ;
int px = ( int ) putter - > x ( ) + pw / 2 ;
int py = ( int ) putter - > y ( ) ;
if ( px > width / 2 & & py < height / 2 )
strokeCircle - > move ( px - pw / 2 - 10 - strokeCircle - > width ( ) , py + 10 ) ;
else if ( px > width / 2 )
strokeCircle - > move ( px - pw / 2 - 10 - strokeCircle - > width ( ) , py - 10 - strokeCircle - > height ( ) ) ;
else if ( py < height / 2 )
strokeCircle - > move ( px + pw / 2 + 10 , py + 10 ) ;
else
strokeCircle - > move ( px + pw / 2 + 10 , py - 10 - strokeCircle - > height ( ) ) ;
strokeCircle - > setVisible ( true ) ;
}
putterTimer - > start ( putterTimerMsec ) ;
}
else if ( m_useAdvancedPutting & & putting & & ! editing )
{
putting = false ;
stroking = true ;
puttReverse = false ;
finishStroking = false ;
}
else if ( m_useAdvancedPutting & & stroking )
{
finishStroking = true ;
putterTimeout ( ) ;
}
}
void KolfGame : : keyReleaseEvent ( TQKeyEvent * e )
{
if ( e - > isAutoRepeat ( ) | | m_ignoreEvents )
return ;
if ( e - > key ( ) = = Key_Space | | e - > key ( ) = = Key_Down )
puttRelease ( ) ;
else if ( ( e - > key ( ) = = Key_Backspace | | e - > key ( ) = = Key_Delete ) & & ! ( e - > state ( ) & ControlButton ) )
{
if ( editing & & ! moving & & selectedItem )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( selectedItem ) ;
if ( ! citem )
return ;
citem = citem - > itemToDelete ( ) ;
if ( ! citem )
return ;
TQCanvasItem * item = dynamic_cast < TQCanvasItem * > ( citem ) ;
if ( citem & & citem - > deleteable ( ) )
{
lastDelId = citem - > curId ( ) ;
highlighter - > setVisible ( false ) ;
items . removeRef ( item ) ;
citem - > hideInfo ( ) ;
citem - > aboutToDelete ( ) ;
citem - > aboutToDie ( ) ;
delete citem ;
selectedItem = 0 ;
emit newSelectedItem ( & holeInfo ) ;
setModified ( true ) ;
}
}
}
else if ( e - > key ( ) = = Key_I | | e - > key ( ) = = Key_Up )
toggleShowInfo ( ) ;
}
void KolfGame : : puttRelease ( )
{
if ( ! m_useAdvancedPutting & & putting & & ! editing )
{
putting = false ;
stroking = true ;
}
}
void KolfGame : : stoppedBall ( )
{
if ( ! inPlay )
{
inPlay = true ;
dontAddStroke = true ;
}
}
void KolfGame : : timeout ( )
{
Ball * curBall = ( * curPlayer ) . ball ( ) ;
// test if the ball is gone
// in this case we want to stop the ball and
// later undo the shot
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
if ( ! course - > rect ( ) . contains ( TQPoint ( ( * it ) . ball ( ) - > x ( ) , ( * it ) . ball ( ) - > y ( ) ) ) )
{
( * it ) . ball ( ) - > setState ( Stopped ) ;
// don't do it if he's past maxStrokes
if ( ( * it ) . score ( curHole ) < holeInfo . maxStrokes ( ) - 1 | | ! holeInfo . hasMaxStrokes ( ) )
{
loadStateList ( ) ;
}
shotDone ( ) ;
return ;
}
}
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
if ( ( * it ) . ball ( ) - > forceStillGoing ( ) | | ( ( * it ) . ball ( ) - > curState ( ) = = Rolling & & ( * it ) . ball ( ) - > curVector ( ) . magnitude ( ) > 0 & & ( * it ) . ball ( ) - > isVisible ( ) ) )
return ;
int curState = curBall - > curState ( ) ;
if ( curState = = Stopped & & inPlay )
{
inPlay = false ;
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( shotDone ( ) ) ) ;
}
if ( curState = = Holed & & inPlay )
{
emit inPlayEnd ( ) ;
emit playerHoled ( & ( * curPlayer ) ) ;
int curScore = ( * curPlayer ) . score ( curHole ) ;
if ( ! dontAddStroke )
curScore + + ;
if ( curScore = = 1 )
{
playSound ( " holeinone " ) ;
}
else if ( curScore < = holeInfo . par ( ) )
{
// I don't have a sound!!
// *sob*
// playSound("woohoo");
}
( * curPlayer ) . ball ( ) - > setZ ( ( * curPlayer ) . ball ( ) - > z ( ) + .1 - ( .1 ) / ( curScore ) ) ;
if ( allPlayersDone ( ) )
{
inPlay = false ;
if ( curHole > 0 & & ! dontAddStroke )
{
( * curPlayer ) . addStrokeToHole ( curHole ) ;
emit scoreChanged ( ( * curPlayer ) . id ( ) , curHole , ( * curPlayer ) . score ( curHole ) ) ;
}
TQTimer : : singleShot ( 600 , this , TQT_SLOT ( holeDone ( ) ) ) ;
}
else
{
inPlay = false ;
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( shotDone ( ) ) ) ;
}
}
}
void KolfGame : : fastTimeout ( )
{
// do regular advance every other time
if ( regAdv )
course - > advance ( ) ;
regAdv = ! regAdv ;
if ( ! editing )
{
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > doAdvance ( ) ;
if ( fastAdvancedExist )
{
CanvasItem * citem = 0 ;
for ( citem = fastAdvancers . first ( ) ; citem ; citem = fastAdvancers . next ( ) )
citem - > doAdvance ( ) ;
}
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > fastAdvanceDone ( ) ;
if ( fastAdvancedExist )
{
CanvasItem * citem = 0 ;
for ( citem = fastAdvancers . first ( ) ; citem ; citem = fastAdvancers . next ( ) )
citem - > fastAdvanceDone ( ) ;
}
}
}
void KolfGame : : ballMoved ( )
{
if ( putter - > isVisible ( ) )
{
putter - > move ( ( * curPlayer ) . ball ( ) - > x ( ) , ( * curPlayer ) . ball ( ) - > y ( ) ) ;
updateMouse ( ) ;
}
}
void KolfGame : : putterTimeout ( )
{
if ( inPlay | | editing )
return ;
if ( m_useAdvancedPutting )
{
if ( putting )
{
const float base = 2.0 ;
if ( puttReverse & & strength < = 0 )
{
// aborted
putting = false ;
strokeCircle - > setVisible ( false ) ;
}
else if ( strength > maxStrength | | puttReverse )
{
// decreasing strength as we've reached the top
puttReverse = true ;
strength - = pow ( base , strength / maxStrength ) - 1.8 ;
if ( ( int ) strength < puttCount * 2 )
{
puttCount - - ;
if ( puttCount > = 0 )
putter - > go ( Forwards ) ;
}
}
else
{
// make the increase at high strength faster
strength + = pow ( base , strength / maxStrength ) - .3 ;
if ( ( int ) strength > puttCount * 2 )
{
putter - > go ( Backwards ) ;
puttCount + + ;
}
}
// make the visible steps at high strength smaller
strokeCircle - > setValue ( pow ( strength / maxStrength , 0.8 ) * 360 ) ;
}
else if ( stroking )
{
double al = strokeCircle - > value ( ) ;
if ( al > = 45 )
al - = 0.2 + strength / 50 + al / 100 ;
else
al - = 0.2 + strength / 50 ;
if ( puttReverse )
{
// show the stroke
puttCount - - ;
if ( puttCount > = 0 )
putter - > go ( Forwards ) ;
else
{
strokeCircle - > setVisible ( false ) ;
finishStroking = false ;
putterTimer - > stop ( ) ;
putting = false ;
stroking = false ;
shotStart ( ) ;
}
}
else if ( al < - 45 | | finishStroking )
{
strokeCircle - > setValue ( al ) ;
int deg ;
// if > 45 or < -45 then bad stroke
if ( al > 45 )
{
deg = putter - > curDeg ( ) - 45 + rand ( ) % 90 ;
strength - = rand ( ) % ( int ) strength ;
}
else if ( ! finishStroking )
{
deg = putter - > curDeg ( ) - 45 + rand ( ) % 90 ;
strength - = rand ( ) % ( int ) strength ;
}
else
deg = putter - > curDeg ( ) + ( int ) ( strokeCircle - > value ( ) / 3 ) ;
if ( deg < 0 )
deg + = 360 ;
else if ( deg > 360 )
deg - = 360 ;
putter - > setDeg ( deg ) ;
puttReverse = true ;
}
else
{
strokeCircle - > setValue ( al ) ;
putterTimer - > changeInterval ( putterTimerMsec / 10 ) ;
}
}
}
else
{
if ( putting )
{
putter - > go ( Backwards ) ;
puttCount + + ;
strength + = 1.5 ;
if ( strength > maxStrength )
{
putting = false ;
stroking = true ;
}
}
else if ( stroking )
{
if ( putter - > curLen ( ) < ( * curPlayer ) . ball ( ) - > height ( ) + 2 )
{
stroking = false ;
putterTimer - > stop ( ) ;
putting = false ;
stroking = false ;
shotStart ( ) ;
}
putter - > go ( Forwards ) ;
putterTimer - > changeInterval ( putterTimerMsec / 10 ) ;
}
}
}
void KolfGame : : autoSaveTimeout ( )
{
// this should be a config option
// until it is i'll disable it
if ( editing )
{
//save();
}
}
void KolfGame : : recreateStateList ( )
{
stateDB . clear ( ) ;
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
{
stateDB . setName ( makeStateGroup ( citem - > curId ( ) , citem - > name ( ) ) ) ;
citem - > saveState ( & stateDB ) ;
}
}
ballStateList . clear ( ) ;
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
ballStateList . append ( ( * it ) . stateInfo ( curHole ) ) ;
ballStateList . canUndo = true ;
}
void KolfGame : : undoShot ( )
{
if ( ballStateList . canUndo )
loadStateList ( ) ;
}
void KolfGame : : loadStateList ( )
{
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
{
stateDB . setName ( makeStateGroup ( citem - > curId ( ) , citem - > name ( ) ) ) ;
citem - > loadState ( & stateDB ) ;
}
}
for ( BallStateList : : Iterator it = ballStateList . begin ( ) ; it ! = ballStateList . end ( ) ; + + it )
{
BallStateInfo info = ( * it ) ;
Player & player = ( * players - > at ( info . id - 1 ) ) ;
player . ball ( ) - > move ( info . spot . x ( ) , info . spot . y ( ) ) ;
player . ball ( ) - > setBeginningOfHole ( info . beginningOfHole ) ;
if ( ( * curPlayer ) . id ( ) = = info . id )
ballMoved ( ) ;
else
player . ball ( ) - > setVisible ( ! info . beginningOfHole ) ;
player . setScoreForHole ( info . score , curHole ) ;
player . ball ( ) - > setState ( info . state ) ;
emit scoreChanged ( info . id , curHole , info . score ) ;
}
}
void KolfGame : : shotDone ( )
{
inPlay = false ;
emit inPlayEnd ( ) ;
setFocus ( ) ;
Ball * ball = ( * curPlayer ) . ball ( ) ;
double oldx = ball - > x ( ) , oldy = ball - > y ( ) ;
if ( ! dontAddStroke & & ( * curPlayer ) . numHoles ( ) )
( * curPlayer ) . addStrokeToHole ( curHole ) ;
dontAddStroke = false ;
// do hack stuff, shouldn't be done here
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
if ( ( * it ) . ball ( ) - > addStroke ( ) )
{
for ( int i = 1 ; i < = ( * it ) . ball ( ) - > addStroke ( ) ; + + i )
( * it ) . addStrokeToHole ( curHole ) ;
// emit that we have a new stroke count
emit scoreChanged ( ( * it ) . id ( ) , curHole , ( * it ) . score ( curHole ) ) ;
}
( * it ) . ball ( ) - > setAddStroke ( 0 ) ;
}
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
Ball * ball = ( * it ) . ball ( ) ;
if ( ball - > curState ( ) = = Holed )
continue ;
Vector v ;
if ( ball - > placeOnGround ( v ) )
{
ball - > setPlaceOnGround ( false ) ;
TQStringList options ;
const TQString placeOutside = i18n ( " Drop Outside of Hazard " ) ;
const TQString rehit = i18n ( " Rehit From Last Location " ) ;
options < < placeOutside < < rehit ;
const TQString choice = KComboBoxDialog : : getItem ( i18n ( " What would you like to do for your next shot? " ) , i18n ( " %1 is in a Hazard " ) . arg ( ( * it ) . name ( ) ) , options , placeOutside , " hazardOptions " ) ;
if ( choice = = placeOutside )
{
( * it ) . ball ( ) - > setDoDetect ( false ) ;
double x = ball - > x ( ) , y = ball - > y ( ) ;
while ( 1 )
{
TQCanvasItemList list = ball - > collisions ( true ) ;
bool keepMoving = false ;
while ( ! list . isEmpty ( ) )
{
TQCanvasItem * item = list . first ( ) ;
if ( item - > rtti ( ) = = Rtti_DontPlaceOn )
keepMoving = true ;
list . pop_front ( ) ;
}
if ( ! keepMoving )
break ;
const float movePixel = 3.0 ;
x - = cos ( v . direction ( ) ) * movePixel ;
y + = sin ( v . direction ( ) ) * movePixel ;
ball - > move ( x , y ) ;
}
// move another two pixels away
x - = cos ( v . direction ( ) ) * 2 ;
y + = sin ( v . direction ( ) ) * 2 ;
}
else if ( choice = = rehit )
{
for ( BallStateList : : Iterator it = ballStateList . begin ( ) ; it ! = ballStateList . end ( ) ; + + it )
{
if ( ( * it ) . id = = ( * curPlayer ) . id ( ) )
{
if ( ( * it ) . beginningOfHole )
ball - > move ( whiteBall - > x ( ) , whiteBall - > y ( ) ) ;
else
ball - > move ( ( * it ) . spot . x ( ) , ( * it ) . spot . y ( ) ) ;
break ;
}
}
}
ball - > setVisible ( true ) ;
ball - > setState ( Stopped ) ;
( * it ) . ball ( ) - > setDoDetect ( true ) ;
ball - > collisionDetect ( oldx , oldy ) ;
}
}
// emit again
emit scoreChanged ( ( * curPlayer ) . id ( ) , curHole , ( * curPlayer ) . score ( curHole ) ) ;
ball - > setVelocity ( 0 , 0 ) ;
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
Ball * ball = ( * it ) . ball ( ) ;
int curStrokes = ( * it ) . score ( curHole ) ;
if ( curStrokes > = holeInfo . maxStrokes ( ) & & holeInfo . hasMaxStrokes ( ) )
{
ball - > setState ( Holed ) ;
ball - > setVisible ( false ) ;
// move to center in case he/she hit out
ball - > move ( width / 2 , height / 2 ) ;
playerWhoMaxed = ( * it ) . name ( ) ;
if ( allPlayersDone ( ) )
{
startNextHole ( ) ;
TQTimer : : singleShot ( 100 , this , TQT_SLOT ( emitMax ( ) ) ) ;
return ;
}
TQTimer : : singleShot ( 100 , this , TQT_SLOT ( emitMax ( ) ) ) ;
}
}
// change player to next player
// skip player if he's Holed
do
{
curPlayer + + ;
if ( curPlayer = = players - > end ( ) )
curPlayer = players - > begin ( ) ;
}
while ( ( * curPlayer ) . ball ( ) - > curState ( ) = = Holed ) ;
emit newPlayersTurn ( & ( * curPlayer ) ) ;
( * curPlayer ) . ball ( ) - > setVisible ( true ) ;
putter - > setAngle ( ( * curPlayer ) . ball ( ) ) ;
putter - > setOrigin ( ( * curPlayer ) . ball ( ) - > x ( ) , ( * curPlayer ) . ball ( ) - > y ( ) ) ;
updateMouse ( ) ;
inPlay = false ;
( * curPlayer ) . ball ( ) - > collisionDetect ( oldx , oldy ) ;
}
void KolfGame : : emitMax ( )
{
emit maxStrokesReached ( playerWhoMaxed ) ;
}
void KolfGame : : startBall ( const Vector & vector )
{
playSound ( " hit " ) ;
emit inPlayStart ( ) ;
putter - > setVisible ( false ) ;
( * curPlayer ) . ball ( ) - > setState ( Rolling ) ;
( * curPlayer ) . ball ( ) - > setVector ( vector ) ;
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
citem - > shotStarted ( ) ;
}
inPlay = true ;
}
void KolfGame : : shotStart ( )
{
// ensure we never hit the ball back into the hole which
// can cause hole skippage
if ( ( * curPlayer ) . ball ( ) - > curState ( ) = = Holed )
return ;
// save state
recreateStateList ( ) ;
putter - > saveAngle ( ( * curPlayer ) . ball ( ) ) ;
strength / = 8 ;
if ( ! strength )
strength = 1 ;
startBall ( Vector ( strength , putter - > curAngle ( ) + M_PI ) ) ;
addHoleInfo ( ballStateList ) ;
}
void KolfGame : : addHoleInfo ( BallStateList & list )
{
list . player = ( * curPlayer ) . id ( ) ;
list . vector = ( * curPlayer ) . ball ( ) - > curVector ( ) ;
list . hole = curHole ;
}
void KolfGame : : sayWhosGoing ( )
{
if ( players - > count ( ) > = 2 )
{
KMessageBox : : information ( this , i18n ( " %1 will start off. " ) . arg ( ( * curPlayer ) . name ( ) ) , i18n ( " New Hole " ) , " newHole " ) ;
}
}
void KolfGame : : holeDone ( )
{
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > setVisible ( false ) ;
startNextHole ( ) ;
sayWhosGoing ( ) ;
}
// this function is WAY too smart for it's own good
// ie, bad design :-(
void KolfGame : : startNextHole ( )
{
setFocus ( ) ;
bool reset = true ;
if ( askSave ( true ) )
{
if ( allPlayersDone ( ) )
{
// we'll reload this hole, but not reset
curHole - - ;
reset = false ;
}
else
return ;
}
else
setModified ( false ) ;
pause ( ) ;
dontAddStroke = false ;
inPlay = false ;
timer - > stop ( ) ;
putter - > resetAngles ( ) ;
int oldCurHole = curHole ;
curHole + + ;
emit currentHole ( curHole ) ;
if ( reset )
{
whiteBall - > move ( width / 2 , height / 2 ) ;
holeInfo . borderWallsChanged ( true ) ;
}
int leastScore = INT_MAX ;
// to get the first player to go first on every hole,
// don't do the score stuff below
curPlayer = players - > begin ( ) ;
double oldx = ( * curPlayer ) . ball ( ) - > x ( ) , oldy = ( * curPlayer ) . ball ( ) - > y ( ) ;
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
if ( curHole > 1 )
{
bool ahead = false ;
if ( ( * it ) . lastScore ( ) ! = 0 )
{
if ( ( * it ) . lastScore ( ) < leastScore )
ahead = true ;
else if ( ( * it ) . lastScore ( ) = = leastScore )
{
for ( int i = curHole - 1 ; i > 0 ; - - i )
{
const int thisScore = ( * it ) . score ( i ) ;
const int thatScore = ( * curPlayer ) . score ( i ) ;
if ( thisScore < thatScore )
{
ahead = true ;
break ;
}
else if ( thisScore > thatScore )
break ;
}
}
}
if ( ahead )
{
curPlayer = it ;
leastScore = ( * it ) . lastScore ( ) ;
}
}
if ( reset )
( * it ) . ball ( ) - > move ( width / 2 , height / 2 ) ;
else
( * it ) . ball ( ) - > move ( whiteBall - > x ( ) , whiteBall - > y ( ) ) ;
( * it ) . ball ( ) - > setState ( Stopped ) ;
// this gets set to false when the ball starts
// to move by the Mr. Ball himself.
( * it ) . ball ( ) - > setBeginningOfHole ( true ) ;
if ( ( int ) ( * it ) . scores ( ) . count ( ) < curHole )
( * it ) . addHole ( ) ;
( * it ) . ball ( ) - > setVelocity ( 0 , 0 ) ;
( * it ) . ball ( ) - > setVisible ( false ) ;
}
emit newPlayersTurn ( & ( * curPlayer ) ) ;
if ( reset )
openFile ( ) ;
inPlay = false ;
timer - > start ( timerMsec ) ;
// if (false) { we're done with the round! }
if ( oldCurHole ! = curHole )
{
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > setPlaceOnGround ( false ) ;
// here we have to make sure the scoreboard shows
// all of the holes up until now;
for ( ; scoreboardHoles < curHole ; + + scoreboardHoles )
{
cfg - > setGroup ( TQString ( " %1-hole@-50,-50|0 " ) . arg ( scoreboardHoles + 1 ) ) ;
emit newHole ( cfg - > readNumEntry ( " par " , 3 ) ) ;
}
resetHoleScores ( ) ;
updateShowInfo ( ) ;
// this is from shotDone()
( * curPlayer ) . ball ( ) - > setVisible ( true ) ;
putter - > setOrigin ( ( * curPlayer ) . ball ( ) - > x ( ) , ( * curPlayer ) . ball ( ) - > y ( ) ) ;
updateMouse ( ) ;
ballStateList . canUndo = false ;
( * curPlayer ) . ball ( ) - > collisionDetect ( oldx , oldy ) ;
}
unPause ( ) ;
}
void KolfGame : : showInfo ( )
{
TQString text = i18n ( " Hole %1: par %2, maximum %3 strokes " ) . arg ( curHole ) . arg ( holeInfo . par ( ) ) . arg ( holeInfo . maxStrokes ( ) ) ;
infoText - > move ( ( width - TQFontMetrics ( infoText - > font ( ) ) . width ( text ) ) / 2 , infoText - > y ( ) ) ;
infoText - > setText ( text ) ;
// I hate this text! Let's not show it
//infoText->setVisible(true);
emit newStatusText ( text ) ;
}
void KolfGame : : showInfoDlg ( bool addDontShowAgain )
{
KMessageBox : : information ( parentWidget ( ) ,
i18n ( " Course name: %1 " ) . arg ( holeInfo . name ( ) ) + TQString ( " \n " )
+ i18n ( " Created by %1 " ) . arg ( holeInfo . author ( ) ) + TQString ( " \n " )
+ i18n ( " %1 holes " ) . arg ( highestHole ) ,
i18n ( " Course Information " ) ,
addDontShowAgain ? holeInfo . name ( ) + TQString ( " " ) + holeInfo . author ( ) : TQString ( ) ) ;
}
void KolfGame : : hideInfo ( )
{
infoText - > setText ( " " ) ;
infoText - > setVisible ( false ) ;
emit newStatusText ( TQString ( ) ) ;
}
void KolfGame : : openFile ( )
{
Object * curObj = 0 ;
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
{
// sometimes info is still showing
citem - > hideInfo ( ) ;
citem - > aboutToDie ( ) ;
}
}
items . setAutoDelete ( true ) ;
items . clear ( ) ;
items . setAutoDelete ( false ) ;
extraMoveable . setAutoDelete ( false ) ;
extraMoveable . clear ( ) ;
fastAdvancers . setAutoDelete ( false ) ;
fastAdvancers . clear ( ) ;
selectedItem = 0 ;
// will tell basic course info
// we do this here for the hell of it.
// there is no fake id, by the way,
// because it's old and when i added ids i forgot to change it.
cfg - > setGroup ( " 0-course@-50,-50 " ) ;
holeInfo . setAuthor ( cfg - > readEntry ( " author " , holeInfo . author ( ) ) ) ;
holeInfo . setName ( cfg - > readEntry ( " Name " , holeInfo . name ( ) ) ) ;
holeInfo . setUntranslatedName ( cfg - > readEntryUntranslated ( " Name " , holeInfo . untranslatedName ( ) ) ) ;
emit titleChanged ( holeInfo . name ( ) ) ;
cfg - > setGroup ( TQString ( " %1-hole@-50,-50|0 " ) . arg ( curHole ) ) ;
curPar = cfg - > readNumEntry ( " par " , 3 ) ;
holeInfo . setPar ( curPar ) ;
holeInfo . borderWallsChanged ( cfg - > readBoolEntry ( " borderWalls " , holeInfo . borderWalls ( ) ) ) ;
holeInfo . setMaxStrokes ( cfg - > readNumEntry ( " maxstrokes " , 10 ) ) ;
bool hasFinalLoad = cfg - > readBoolEntry ( " hasFinalLoad " , true ) ;
TQStringList missingPlugins ;
TQStringList groups = cfg - > groupList ( ) ;
int numItems = 0 ;
int _highestHole = 0 ;
for ( TQStringList : : Iterator it = groups . begin ( ) ; it ! = groups . end ( ) ; + + it )
{
// [<holeNum>-<name>@<x>,<y>|<id>]
cfg - > setGroup ( * it ) ;
const int len = ( * it ) . length ( ) ;
const int dashIndex = ( * it ) . find ( " - " ) ;
const int holeNum = ( * it ) . left ( dashIndex ) . toInt ( ) ;
if ( holeNum > _highestHole )
_highestHole = holeNum ;
const int atIndex = ( * it ) . find ( " @ " ) ;
const TQString name = ( * it ) . mid ( dashIndex + 1 , atIndex - ( dashIndex + 1 ) ) ;
if ( holeNum ! = curHole )
{
// if we've had one, break, cause list is sorted
// erps, no, cause we need to know highest hole!
if ( numItems & & ! recalcHighestHole )
break ;
continue ;
}
numItems + + ;
const int commaIndex = ( * it ) . find ( " , " ) ;
const int pipeIndex = ( * it ) . find ( " | " ) ;
const int x = ( * it ) . mid ( atIndex + 1 , commaIndex - ( atIndex + 1 ) ) . toInt ( ) ;
const int y = ( * it ) . mid ( commaIndex + 1 , pipeIndex - ( commaIndex + 1 ) ) . toInt ( ) ;
// will tell where ball is
if ( name = = " ball " )
{
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > move ( x , y ) ;
whiteBall - > move ( x , y ) ;
continue ;
}
const int id = ( * it ) . right ( len - ( pipeIndex + 1 ) ) . toInt ( ) ;
bool loaded = false ;
for ( curObj = obj - > first ( ) ; curObj ; curObj = obj - > next ( ) )
{
if ( name ! = curObj - > _name ( ) )
continue ;
TQCanvasItem * newItem = curObj - > newObject ( course ) ;
items . append ( newItem ) ;
CanvasItem * canvasItem = dynamic_cast < CanvasItem * > ( newItem ) ;
if ( ! canvasItem )
continue ;
canvasItem - > setId ( id ) ;
canvasItem - > setGame ( this ) ;
canvasItem - > editModeChanged ( editing ) ;
canvasItem - > setName ( curObj - > _name ( ) ) ;
addItemsToMoveableList ( canvasItem - > moveableItems ( ) ) ;
if ( canvasItem - > fastAdvance ( ) )
addItemToFastAdvancersList ( canvasItem ) ;
newItem - > move ( x , y ) ;
canvasItem - > firstMove ( x , y ) ;
newItem - > setVisible ( true ) ;
// make things actually show
if ( ! hasFinalLoad )
{
cfg - > setGroup ( makeGroup ( id , curHole , canvasItem - > name ( ) , x , y ) ) ;
canvasItem - > load ( cfg ) ;
course - > update ( ) ;
}
// we don't allow multiple items for the same thing in
// the file!
loaded = true ;
break ;
}
if ( ! loaded & & name ! = " hole " & & missingPlugins . contains ( name ) < = 0 )
missingPlugins . append ( name ) ;
}
if ( ! missingPlugins . empty ( ) )
{
KMessageBox : : informationList ( this , TQString ( " <p><http://katzbrown.com/kolf/Plugins/></p><p> " ) + i18n ( " This hole uses the following plugins, which you do not have installed: " ) + TQString ( " </p> " ) , missingPlugins , TQString ( ) , TQString ( " %1 warning " ) . arg ( holeInfo . untranslatedName ( ) + TQString : : number ( curHole ) ) ) ;
}
lastDelId = - 1 ;
// if it's the first hole let's not
if ( ! numItems & & curHole > 1 & & ! addingNewHole & & curHole > = _highestHole )
{
// we're done, let's quit
curHole - - ;
pause ( ) ;
emit holesDone ( ) ;
// tidy things up
setBorderWalls ( false ) ;
clearHole ( ) ;
setModified ( false ) ;
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > setVisible ( false ) ;
return ;
}
// do it down here; if !hasFinalLoad, do it up there!
TQCanvasItem * qcanvasItem = 0 ;
TQPtrList < CanvasItem > todo ;
TQPtrList < TQCanvasItem > qtodo ;
if ( hasFinalLoad )
{
for ( qcanvasItem = items . first ( ) ; qcanvasItem ; qcanvasItem = items . next ( ) )
{
CanvasItem * item = dynamic_cast < CanvasItem * > ( qcanvasItem ) ;
if ( item )
{
if ( item - > loadLast ( ) )
{
qtodo . append ( qcanvasItem ) ;
todo . append ( item ) ;
}
else
{
TQString group = makeGroup ( item - > curId ( ) , curHole , item - > name ( ) , ( int ) qcanvasItem - > x ( ) , ( int ) qcanvasItem - > y ( ) ) ;
cfg - > setGroup ( group ) ;
item - > load ( cfg ) ;
}
}
}
CanvasItem * citem = 0 ;
qcanvasItem = qtodo . first ( ) ;
for ( citem = todo . first ( ) ; citem ; citem = todo . next ( ) )
{
cfg - > setGroup ( makeGroup ( citem - > curId ( ) , curHole , citem - > name ( ) , ( int ) qcanvasItem - > x ( ) , ( int ) qcanvasItem - > y ( ) ) ) ;
citem - > load ( cfg ) ;
qcanvasItem = qtodo . next ( ) ;
}
}
for ( qcanvasItem = items . first ( ) ; qcanvasItem ; qcanvasItem = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( qcanvasItem ) ;
if ( citem )
citem - > updateZ ( ) ;
}
if ( curHole > _highestHole )
_highestHole = curHole ;
if ( recalcHighestHole )
{
highestHole = _highestHole ;
recalcHighestHole = false ;
emit largestHole ( highestHole ) ;
}
if ( curHole = = 1 & & ! filename . isNull ( ) & & ! infoShown )
{
// let's not now, because they see it when they choose course
//showInfoDlg(true);
infoShown = true ;
}
setModified ( false ) ;
}
void KolfGame : : addItemsToMoveableList ( TQPtrList < TQCanvasItem > list )
{
TQCanvasItem * item = 0 ;
for ( item = list . first ( ) ; item ; item = list . next ( ) )
extraMoveable . append ( item ) ;
}
void KolfGame : : addItemToFastAdvancersList ( CanvasItem * item )
{
fastAdvancers . append ( item ) ;
fastAdvancedExist = fastAdvancers . count ( ) > 0 ;
}
void KolfGame : : addNewObject ( Object * newObj )
{
TQCanvasItem * newItem = newObj - > newObject ( course ) ;
items . append ( newItem ) ;
newItem - > setVisible ( true ) ;
CanvasItem * canvasItem = dynamic_cast < CanvasItem * > ( newItem ) ;
if ( ! canvasItem )
return ;
// we need to find a number that isn't taken
int i = lastDelId > 0 ? lastDelId : items . count ( ) - 30 ;
if ( i < = 0 )
i = 0 ;
for ( ; ; + + i )
{
bool found = false ;
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
{
if ( citem - > curId ( ) = = i )
{
found = true ;
break ;
}
}
}
if ( ! found )
break ;
}
canvasItem - > setId ( i ) ;
canvasItem - > setGame ( this ) ;
if ( m_showInfo )
canvasItem - > showInfo ( ) ;
else
canvasItem - > hideInfo ( ) ;
canvasItem - > editModeChanged ( editing ) ;
canvasItem - > setName ( newObj - > _name ( ) ) ;
addItemsToMoveableList ( canvasItem - > moveableItems ( ) ) ;
if ( canvasItem - > fastAdvance ( ) )
addItemToFastAdvancersList ( canvasItem ) ;
newItem - > move ( width / 2 - 18 , height / 2 - 18 ) ;
if ( selectedItem )
canvasItem - > selectedItem ( selectedItem ) ;
setModified ( true ) ;
}
bool KolfGame : : askSave ( bool noMoreChances )
{
if ( ! modified )
// not cancel, don't save
return false ;
int result = KMessageBox : : warningYesNoCancel ( this , i18n ( " There are unsaved changes to current hole. Save them? " ) , i18n ( " Unsaved Changes " ) , KStdGuiItem : : save ( ) , noMoreChances ? KStdGuiItem : : discard ( ) : i18n ( " Save &Later " ) , noMoreChances ? " DiscardAsk " : " SaveAsk " , true ) ;
switch ( result )
{
case KMessageBox : : Yes :
save ( ) ;
// fallthrough
case KMessageBox : : No :
return false ;
break ;
case KMessageBox : : Cancel :
return true ;
break ;
default :
break ;
}
return false ;
}
void KolfGame : : addNewHole ( )
{
if ( askSave ( true ) )
return ;
// either it's already false
// because it was saved by askSave(),
// or the user pressed the 'discard' button
setModified ( false ) ;
// find highest hole num, and create new hole
// now openFile makes highest hole for us
addingNewHole = true ;
curHole = highestHole ;
recalcHighestHole = true ;
startNextHole ( ) ;
addingNewHole = false ;
emit currentHole ( curHole ) ;
// make sure even the current player isn't showing
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
( * it ) . ball ( ) - > setVisible ( false ) ;
whiteBall - > setVisible ( editing ) ;
highlighter - > setVisible ( false ) ;
putter - > setVisible ( ! editing ) ;
inPlay = false ;
// add default objects
Object * curObj = 0 ;
for ( curObj = obj - > first ( ) ; curObj ; curObj = obj - > next ( ) )
if ( curObj - > addOnNewHole ( ) )
addNewObject ( curObj ) ;
save ( ) ;
}
// kantan deshou ;-)
void KolfGame : : resetHole ( )
{
if ( askSave ( true ) )
return ;
setModified ( false ) ;
curHole - - ;
startNextHole ( ) ;
resetHoleScores ( ) ;
}
void KolfGame : : resetHoleScores ( )
{
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
( * it ) . resetScore ( curHole ) ;
emit scoreChanged ( ( * it ) . id ( ) , curHole , 0 ) ;
}
}
void KolfGame : : clearHole ( )
{
TQCanvasItem * qcanvasItem = 0 ;
for ( qcanvasItem = items . first ( ) ; qcanvasItem ; qcanvasItem = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( qcanvasItem ) ;
if ( citem )
citem - > aboutToDie ( ) ;
}
items . setAutoDelete ( true ) ;
items . clear ( ) ;
items . setAutoDelete ( false ) ;
emit newSelectedItem ( & holeInfo ) ;
// add default objects
Object * curObj = 0 ;
for ( curObj = obj - > first ( ) ; curObj ; curObj = obj - > next ( ) )
if ( curObj - > addOnNewHole ( ) )
addNewObject ( curObj ) ;
setModified ( true ) ;
}
void KolfGame : : switchHole ( int hole )
{
if ( inPlay )
return ;
if ( hole < 1 | | hole > highestHole )
return ;
bool wasEditing = editing ;
if ( editing )
toggleEditMode ( ) ;
if ( askSave ( true ) )
return ;
setModified ( false ) ;
curHole = hole ;
resetHole ( ) ;
if ( wasEditing )
toggleEditMode ( ) ;
}
void KolfGame : : switchHole ( const TQString & holestring )
{
bool ok ;
int hole = holestring . toInt ( & ok ) ;
if ( ! ok )
return ;
switchHole ( hole ) ;
}
void KolfGame : : nextHole ( )
{
switchHole ( curHole + 1 ) ;
}
void KolfGame : : prevHole ( )
{
switchHole ( curHole - 1 ) ;
}
void KolfGame : : firstHole ( )
{
switchHole ( 1 ) ;
}
void KolfGame : : lastHole ( )
{
switchHole ( highestHole ) ;
}
void KolfGame : : randHole ( )
{
int newHole = 1 + ( int ) ( ( double ) kapp - > random ( ) * ( ( double ) ( highestHole - 1 ) / ( double ) RAND_MAX ) ) ;
switchHole ( newHole ) ;
}
void KolfGame : : save ( )
{
if ( filename . isNull ( ) )
{
TQString newfilename = KFileDialog : : getSaveFileName ( " :kourses " , " application/x-kourse " , this , i18n ( " Pick Kolf Course to Save To " ) ) ;
if ( newfilename . isNull ( ) )
return ;
setFilename ( newfilename ) ;
}
emit parChanged ( curHole , holeInfo . par ( ) ) ;
emit titleChanged ( holeInfo . name ( ) ) ;
// we use this bool for optimization
// in openFile().
bool hasFinalLoad = false ;
fastAdvancedExist = false ;
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
{
citem - > aboutToSave ( ) ;
if ( citem - > loadLast ( ) )
hasFinalLoad = true ;
}
}
TQStringList groups = cfg - > groupList ( ) ;
// wipe out all groups from this hole
for ( TQStringList : : Iterator it = groups . begin ( ) ; it ! = groups . end ( ) ; + + it )
{
int holeNum = ( * it ) . left ( ( * it ) . find ( " - " ) ) . toInt ( ) ;
if ( holeNum = = curHole )
cfg - > deleteGroup ( * it ) ;
}
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
{
citem - > clean ( ) ;
cfg - > setGroup ( makeGroup ( citem - > curId ( ) , curHole , citem - > name ( ) , ( int ) item - > x ( ) , ( int ) item - > y ( ) ) ) ;
citem - > save ( cfg ) ;
}
}
// save where ball starts (whiteBall tells all)
cfg - > setGroup ( TQString ( " %1-ball@%2,%3 " ) . arg ( curHole ) . arg ( ( int ) whiteBall - > x ( ) ) . arg ( ( int ) whiteBall - > y ( ) ) ) ;
cfg - > writeEntry ( " dummykey " , true ) ;
cfg - > setGroup ( " 0-course@-50,-50 " ) ;
cfg - > writeEntry ( " author " , holeInfo . author ( ) ) ;
cfg - > writeEntry ( " Name " , holeInfo . untranslatedName ( ) ) ;
// save hole info
cfg - > setGroup ( TQString ( " %1-hole@-50,-50|0 " ) . arg ( curHole ) ) ;
cfg - > writeEntry ( " par " , holeInfo . par ( ) ) ;
cfg - > writeEntry ( " maxstrokes " , holeInfo . maxStrokes ( ) ) ;
cfg - > writeEntry ( " borderWalls " , holeInfo . borderWalls ( ) ) ;
cfg - > writeEntry ( " hasFinalLoad " , hasFinalLoad ) ;
cfg - > sync ( ) ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
citem - > savingDone ( ) ;
}
setModified ( false ) ;
}
void KolfGame : : toggleEditMode ( )
{
// won't be editing anymore, and user wants to cancel, we return
// this is pretty useless. when the person leaves the hole,
// he gets asked again
/*
if ( editing & & modified )
{
if ( askSave ( false ) )
{
emit checkEditing ( ) ;
return ;
}
}
*/
moving = false ;
selectedItem = 0 ;
editing = ! editing ;
if ( editing )
{
emit editingStarted ( ) ;
emit newSelectedItem ( & holeInfo ) ;
}
else
{
emit editingEnded ( ) ;
setCursor ( KCursor : : arrowCursor ( ) ) ;
}
// alert our items
TQCanvasItem * item = 0 ;
for ( item = items . first ( ) ; item ; item = items . next ( ) )
{
CanvasItem * citem = dynamic_cast < CanvasItem * > ( item ) ;
if ( citem )
citem - > editModeChanged ( editing ) ;
}
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
// curplayer shouldn't be hidden no matter what
if ( ( * it ) . ball ( ) - > beginningOfHole ( ) & & it ! = curPlayer )
( * it ) . ball ( ) - > setVisible ( false ) ;
else
( * it ) . ball ( ) - > setVisible ( ! editing ) ;
}
whiteBall - > setVisible ( editing ) ;
highlighter - > setVisible ( false ) ;
// shouldn't see putter whilst editing
putter - > setVisible ( ! editing ) ;
if ( editing )
autoSaveTimer - > start ( autoSaveMsec ) ;
else
autoSaveTimer - > stop ( ) ;
inPlay = false ;
}
void KolfGame : : playSound ( TQString file , double vol )
{
if ( m_sound )
{
KPlayObject * oldPlayObject = 0 ;
for ( oldPlayObject = oldPlayObjects . first ( ) ; oldPlayObject ; oldPlayObject = oldPlayObjects . next ( ) )
{
if ( oldPlayObject & & oldPlayObject - > state ( ) ! = Arts : : posPlaying )
{
oldPlayObjects . remove ( ) ;
// because we will go to next() next time
// and after remove current item is one after
// removed item
( void ) oldPlayObjects . prev ( ) ;
}
}
file = soundDir + file + TQString : : fromLatin1 ( " .wav " ) ;
// not needed when all of the files are in the distribution
//if (!TQFile::exists(file))
//return;
KPlayObjectFactory factory ( artsServer . server ( ) ) ;
KPlayObject * playObject = factory . createPlayObject ( KURL ( file ) , true ) ;
if ( playObject & & ! playObject - > isNull ( ) )
{
if ( vol > 1 )
vol = 1 ;
else if ( vol < = .01 )
{
delete playObject ;
return ;
}
if ( vol < .99 )
{
//new KVolumeControl(vol, artsServer.server(), playObject);
}
playObject - > play ( ) ;
oldPlayObjects . append ( playObject ) ;
}
}
}
void HoleInfo : : borderWallsChanged ( bool yes )
{
m_borderWalls = yes ;
game - > setBorderWalls ( yes ) ;
}
void KolfGame : : print ( KPrinter & pr )
{
TQPainter p ( & pr ) ;
TQPaintDeviceMetrics metrics ( & pr ) ;
// translate to center
p . translate ( metrics . width ( ) / 2 - course - > rect ( ) . width ( ) / 2 , metrics . height ( ) / 2 - course - > rect ( ) . height ( ) / 2 ) ;
TQPixmap pix ( width , height ) ;
TQPainter pixp ( & pix ) ;
course - > drawArea ( course - > rect ( ) , & pixp ) ;
p . drawPixmap ( 0 , 0 , pix ) ;
p . setPen ( TQPen ( black , 2 ) ) ;
p . drawRect ( course - > rect ( ) ) ;
p . resetXForm ( ) ;
if ( pr . option ( " kde-kolf-title " ) = = " true " )
{
TQString text = i18n ( " %1 - Hole %2; by %3 " ) . arg ( holeInfo . name ( ) ) . arg ( curHole ) . arg ( holeInfo . author ( ) ) ;
TQFont font ( kapp - > font ( ) ) ;
font . setPointSize ( 18 ) ;
TQRect rect = TQFontMetrics ( font ) . boundingRect ( text ) ;
p . setFont ( font ) ;
p . drawText ( metrics . width ( ) / 2 - rect . width ( ) / 2 , metrics . height ( ) / 2 - course - > rect ( ) . height ( ) / 2 - 20 - rect . height ( ) , text ) ;
}
}
bool KolfGame : : allPlayersDone ( )
{
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
if ( ( * it ) . ball ( ) - > curState ( ) ! = Holed )
return false ;
return true ;
}
void KolfGame : : setBorderWalls ( bool showing )
{
Wall * wall = 0 ;
for ( wall = borderWalls . first ( ) ; wall ; wall = borderWalls . next ( ) )
wall - > setVisible ( showing ) ;
}
void KolfGame : : setUseAdvancedPutting ( bool yes )
{
m_useAdvancedPutting = yes ;
// increase maxStrength in advanced putting mode
if ( yes )
maxStrength = 65 ;
else
maxStrength = 55 ;
}
void KolfGame : : setShowGuideLine ( bool yes )
{
putter - > setShowGuideLine ( yes ) ;
}
void KolfGame : : setSound ( bool yes )
{
m_sound = yes ;
}
void KolfGame : : courseInfo ( CourseInfo & info , const TQString & filename )
{
KConfig cfg ( filename ) ;
cfg . setGroup ( " 0-course@-50,-50 " ) ;
info . author = cfg . readEntry ( " author " , info . author ) ;
info . name = cfg . readEntry ( " Name " , cfg . readEntry ( " name " , info . name ) ) ;
info . untranslatedName = cfg . readEntryUntranslated ( " Name " , cfg . readEntryUntranslated ( " name " , info . name ) ) ;
unsigned int hole = 1 ;
unsigned int par = 0 ;
while ( 1 )
{
TQString group = TQString ( " %1-hole@-50,-50|0 " ) . arg ( hole ) ;
if ( ! cfg . hasGroup ( group ) )
{
hole - - ;
break ;
}
cfg . setGroup ( group ) ;
par + = cfg . readNumEntry ( " par " , 3 ) ;
hole + + ;
}
info . par = par ;
info . holes = hole ;
}
void KolfGame : : scoresFromSaved ( KConfig * config , PlayerList & players )
{
config - > setGroup ( " 0 Saved Game " ) ;
int numPlayers = config - > readNumEntry ( " Players " , 0 ) ;
if ( numPlayers < = 0 )
return ;
for ( int i = 1 ; i < = numPlayers ; + + i )
{
// this is same as in kolf.cpp, but we use saved game values
config - > setGroup ( TQString : : number ( i ) ) ;
players . append ( Player ( ) ) ;
players . last ( ) . ball ( ) - > setColor ( config - > readEntry ( " Color " , " #ffffff " ) ) ;
players . last ( ) . setName ( config - > readEntry ( " Name " ) ) ;
players . last ( ) . setId ( i ) ;
TQStringList scores ( config - > readListEntry ( " Scores " ) ) ;
TQValueList < int > intscores ;
for ( TQStringList : : Iterator it = scores . begin ( ) ; it ! = scores . end ( ) ; + + it )
intscores . append ( ( * it ) . toInt ( ) ) ;
players . last ( ) . setScores ( intscores ) ;
}
}
void KolfGame : : saveScores ( KConfig * config )
{
// wipe out old player info
TQStringList groups = config - > groupList ( ) ;
for ( TQStringList : : Iterator it = groups . begin ( ) ; it ! = groups . end ( ) ; + + it )
{
// this deletes all int groups, ie, the player info groups
bool ok = false ;
( * it ) . toInt ( & ok ) ;
if ( ok )
config - > deleteGroup ( * it ) ;
}
config - > setGroup ( " 0 Saved Game " ) ;
config - > writeEntry ( " Players " , players - > count ( ) ) ;
config - > writeEntry ( " Course " , filename ) ;
config - > writeEntry ( " Current Hole " , curHole ) ;
for ( PlayerList : : Iterator it = players - > begin ( ) ; it ! = players - > end ( ) ; + + it )
{
config - > setGroup ( TQString : : number ( ( * it ) . id ( ) ) ) ;
config - > writeEntry ( " Name " , ( * it ) . name ( ) ) ;
config - > writeEntry ( " Color " , TQString ( ( * it ) . ball ( ) - > color ( ) . name ( ) ) ) ;
TQStringList scores ;
TQValueList < int > intscores = ( * it ) . scores ( ) ;
for ( TQValueList < int > : : Iterator it = intscores . begin ( ) ; it ! = intscores . end ( ) ; + + it )
scores . append ( TQString : : number ( * it ) ) ;
config - > writeEntry ( " Scores " , scores ) ;
}
}
CourseInfo : : CourseInfo ( )
: name ( i18n ( " Course Name " ) ) , author ( i18n ( " Course Author " ) ) , holes ( 0 ) , par ( 0 )
{
}
# include "game.moc"