mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-27 09:58:45 +01:00
Merge remote branch 'origin/android_branch' into android_branch
This commit is contained in:
commit
de59408cb0
22 changed files with 195 additions and 127 deletions
|
@ -1171,15 +1171,14 @@
|
|||
<!-- The invitation process beging with this query. The choice is
|
||||
between html and plaintext formatting but I also provide some
|
||||
explanation/guidance. -->
|
||||
<string name="text_or_html">Send invitation using plain text or
|
||||
html? Text links are harder to open but can be sent via SMS.
|
||||
Most devices let you send html only via email.</string>
|
||||
<string name="sms_or_email">Send invitation using SMS (texting) or
|
||||
email?</string>
|
||||
|
||||
<!-- When an invitation is sent, the user gets to choose between
|
||||
plaintext and html formatting. These two strings are shown in the
|
||||
two buttons in the dialog. -->
|
||||
<string name="button_text">Text</string>
|
||||
<string name="button_html">Html</string>
|
||||
<string name="button_text">SMS/Text</string>
|
||||
<string name="button_html">Email</string>
|
||||
|
||||
<!-- This is the subject line of the email/text sent to invite
|
||||
someone to join a game. -->
|
||||
|
@ -1200,8 +1199,8 @@
|
|||
<!-- This is the body of the text version of the invitation. A URL
|
||||
is created with parameters describing the game and
|
||||
substituted for "%1$s".-->
|
||||
<string name="invite_txtf">Accept my invitation and join this
|
||||
game: %1$s . (But install Crosswords first:
|
||||
<string name="invite_txtf">Play Crosswords? Join this
|
||||
game: %1$s . (But install Crosswords first if you haven\'t:
|
||||
http://eehouse.org/market_redir.php ).</string>
|
||||
|
||||
<!-- When I've created the invitation, in text or html, I ask
|
||||
|
@ -1747,7 +1746,7 @@
|
|||
<!-- Another paragraph in the about dialog -->
|
||||
<string name="about_web">For a manual or sourcecode see:
|
||||
http://xwords.sf.net. To report bugs, suggest features, offer to
|
||||
help, etc., please email: eehouse@eehouse.org.</string>
|
||||
help, etc., please email: xwords@eehouse.org.</string>
|
||||
|
||||
<!-- Empty in English, this should contain the name of the
|
||||
translator/creator of the strings.xml file for this
|
||||
|
|
|
@ -353,7 +353,7 @@ public class BoardActivity extends XWActivity
|
|||
lstnr = new DialogInterface.OnClickListener() {
|
||||
public void onClick( DialogInterface dialog,
|
||||
int item ) {
|
||||
showTextOrHtmlThen( LAUNCH_INVITE_ACTION );
|
||||
showEmailOrSMSThen( LAUNCH_INVITE_ACTION );
|
||||
}
|
||||
};
|
||||
dialog = new AlertDialog.Builder( this )
|
||||
|
@ -669,7 +669,7 @@ public class BoardActivity extends XWActivity
|
|||
if ( LAUNCH_INVITE_ACTION == id ) {
|
||||
if ( DlgDelegate.DISMISS_BUTTON != which ) {
|
||||
GameUtils.launchInviteActivity( BoardActivity.this,
|
||||
DlgDelegate.TEXT_BTN == which,
|
||||
DlgDelegate.EMAIL_BTN == which,
|
||||
m_room,
|
||||
m_gi.dictLang,
|
||||
m_gi.nPlayers );
|
||||
|
|
|
@ -46,8 +46,8 @@ public class DlgDelegate {
|
|||
public static final int DLG_LOOKUP = 7;
|
||||
public static final int DIALOG_LAST = DLG_LOOKUP;
|
||||
|
||||
public static final int TEXT_BTN = AlertDialog.BUTTON_POSITIVE;
|
||||
public static final int HTML_BTN = AlertDialog.BUTTON_NEGATIVE;
|
||||
public static final int SMS_BTN = AlertDialog.BUTTON_POSITIVE;
|
||||
public static final int EMAIL_BTN = AlertDialog.BUTTON_NEGATIVE;
|
||||
public static final int DISMISS_BUTTON = 0;
|
||||
public static final int SKIP_CALLBACK = -1;
|
||||
|
||||
|
@ -232,7 +232,7 @@ public class DlgDelegate {
|
|||
m_activity.showDialog( CONFIRM_THEN );
|
||||
}
|
||||
|
||||
public void showTextOrHtmlThen( int callbackID )
|
||||
public void showEmailOrSMSThen( int callbackID )
|
||||
{
|
||||
Assert.assertTrue( 0 != callbackID );
|
||||
Assert.assertTrue( 0 == m_cbckID );
|
||||
|
@ -351,7 +351,7 @@ public class DlgDelegate {
|
|||
DialogInterface.OnClickListener lstnr = mkCallbackClickListener();
|
||||
Dialog dialog = new AlertDialog.Builder( m_activity )
|
||||
.setTitle( R.string.query_title )
|
||||
.setMessage( R.string.text_or_html )
|
||||
.setMessage( R.string.sms_or_email )
|
||||
.setPositiveButton( R.string.button_text, lstnr )
|
||||
.setNegativeButton( R.string.button_html, lstnr )
|
||||
.create();
|
||||
|
|
|
@ -412,7 +412,7 @@ public class GameUtils {
|
|||
}
|
||||
|
||||
public static void launchInviteActivity( Context context,
|
||||
boolean choseText,
|
||||
boolean choseEmail,
|
||||
String room,
|
||||
int lang, int nPlayers )
|
||||
{
|
||||
|
@ -421,16 +421,22 @@ public class GameUtils {
|
|||
lang, nPlayers );
|
||||
|
||||
if ( null != gameUri ) {
|
||||
Intent intent = new Intent( Intent.ACTION_SEND );
|
||||
intent.setType( choseText? "text/plain" : "text/html");
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT,
|
||||
context.getString( R.string.invite_subject ) );
|
||||
|
||||
int fmtId = choseText? R.string.invite_txtf : R.string.invite_htmf;
|
||||
int fmtId = choseEmail? R.string.invite_htmf : R.string.invite_txtf;
|
||||
String format = context.getString( fmtId );
|
||||
String message = String.format( format, gameUri.toString() );
|
||||
intent.putExtra( Intent.EXTRA_TEXT,
|
||||
choseText ? message : Html.fromHtml(message) );
|
||||
|
||||
Intent intent = new Intent();
|
||||
if ( choseEmail ) {
|
||||
intent.setAction( Intent.ACTION_SEND );
|
||||
intent.setType( "message/rfc822");
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT,
|
||||
context.getString( R.string.invite_subject ) );
|
||||
intent.putExtra( Intent.EXTRA_TEXT, Html.fromHtml(message) );
|
||||
} else {
|
||||
intent.setAction( Intent.ACTION_VIEW );
|
||||
intent.setType( "vnd.android-dir/mms-sms" );
|
||||
intent.putExtra( "sms_body", message );
|
||||
}
|
||||
|
||||
String chooserMsg = context.getString( R.string.invite_chooser );
|
||||
context.startActivity( Intent.createChooser( intent, chooserMsg ) );
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
// package org.eehouse.android.xw4;
|
||||
|
||||
// import android.app.PendingIntent;
|
||||
// import android.content.BroadcastReceiver;
|
||||
// import android.content.Context;
|
||||
// import android.content.Intent;
|
||||
|
@ -35,15 +36,22 @@
|
|||
// intent.toString() );
|
||||
// }
|
||||
|
||||
// static void tryNBSMessage()
|
||||
// static void tryNBSMessage( Context context )
|
||||
// {
|
||||
// byte[] data = { 'a', 'b', 'c' };
|
||||
|
||||
// SmsManager mgr = SmsManager.getDefault();
|
||||
|
||||
// try {
|
||||
// /* online comment says providing PendingIntents prevents
|
||||
// random crashes */
|
||||
// PendingIntent sent = PendingIntent.getBroadcast( context,
|
||||
// 0, new Intent(), 0 );
|
||||
// PendingIntent dlvrd = PendingIntent.getBroadcast( context, 0,
|
||||
// new Intent(), 0 );
|
||||
|
||||
// mgr.sendDataMessage( "123-456-7890", null, (short)50009,
|
||||
// data, null, null );
|
||||
// data, sent, dlvrd );
|
||||
// // PendingIntent sentIntent,
|
||||
// // PendingIntent deliveryIntent );
|
||||
// DbgUtils.logf( "sendDataMessage finished" );
|
||||
|
|
|
@ -94,7 +94,7 @@ public class NewGameActivity extends XWActivity {
|
|||
switch( id ) {
|
||||
case NEW_GAME_ACTION:
|
||||
if ( DlgDelegate.DISMISS_BUTTON != which ) {
|
||||
makeNewGame( true, true, DlgDelegate.TEXT_BTN == which );
|
||||
makeNewGame( true, true, DlgDelegate.EMAIL_BTN == which );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -106,14 +106,14 @@ public class NewGameActivity extends XWActivity {
|
|||
{
|
||||
if ( launch && networked ) {
|
||||
// Let 'em cancel before we make the game
|
||||
showTextOrHtmlThen( NEW_GAME_ACTION );
|
||||
showEmailOrSMSThen( NEW_GAME_ACTION );
|
||||
} else {
|
||||
makeNewGame( networked, launch, false );
|
||||
}
|
||||
}
|
||||
|
||||
private void makeNewGame( boolean networked, boolean launch,
|
||||
boolean choseText )
|
||||
boolean choseEmail )
|
||||
{
|
||||
String room = null;
|
||||
long rowid;
|
||||
|
@ -131,7 +131,7 @@ public class NewGameActivity extends XWActivity {
|
|||
if ( launch ) {
|
||||
GameUtils.launchGame( this, rowid, networked );
|
||||
if ( networked ) {
|
||||
GameUtils.launchInviteActivity( this, choseText, room,
|
||||
GameUtils.launchInviteActivity( this, choseEmail, room,
|
||||
lang[0], nPlayers );
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -18,34 +18,34 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
// package org.eehouse.android.xw4;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.SmsMessage;
|
||||
// import android.content.BroadcastReceiver;
|
||||
// import android.content.Context;
|
||||
// import android.content.Intent;
|
||||
// import android.os.Bundle;
|
||||
// import android.telephony.SmsMessage;
|
||||
|
||||
public class ReceiveNBS extends BroadcastReceiver {
|
||||
// public class ReceiveNBS extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive( Context context, Intent intent )
|
||||
{
|
||||
DbgUtils.logf( "onReceive called: %s", intent.toString() );
|
||||
// @Override
|
||||
// public void onReceive( Context context, Intent intent )
|
||||
// {
|
||||
// DbgUtils.logf( "onReceive called: %s", intent.toString() );
|
||||
|
||||
Bundle bundle = intent.getExtras();
|
||||
SmsMessage[] smsarr = null;
|
||||
if (bundle != null) {
|
||||
Object[] pdus = (Object[]) bundle.get("pdus");
|
||||
smsarr = new SmsMessage[pdus.length];
|
||||
for ( int ii = 0; ii < pdus.length; ii++){
|
||||
smsarr[ii] = SmsMessage.createFromPdu((byte[])pdus[ii]);
|
||||
DbgUtils.logf( "from %s", smsarr[ii].getOriginatingAddress() );
|
||||
// buf.append( smsarr[ii].getMessageBody() );
|
||||
// XwJni.handle( XwJni.JNICmd.CMD_RECEIVE,
|
||||
// smsarr[ii].getMessageBody() );
|
||||
}
|
||||
}
|
||||
} // onReceive
|
||||
// Bundle bundle = intent.getExtras();
|
||||
// SmsMessage[] smsarr = null;
|
||||
// if (bundle != null) {
|
||||
// Object[] pdus = (Object[]) bundle.get("pdus");
|
||||
// smsarr = new SmsMessage[pdus.length];
|
||||
// for ( int ii = 0; ii < pdus.length; ii++){
|
||||
// smsarr[ii] = SmsMessage.createFromPdu((byte[])pdus[ii]);
|
||||
// DbgUtils.logf( "from %s", smsarr[ii].getOriginatingAddress() );
|
||||
// // buf.append( smsarr[ii].getMessageBody() );
|
||||
// // XwJni.handle( XwJni.JNICmd.CMD_RECEIVE,
|
||||
// // smsarr[ii].getMessageBody() );
|
||||
// }
|
||||
// }
|
||||
// } // onReceive
|
||||
|
||||
}
|
||||
// }
|
||||
|
|
|
@ -60,7 +60,7 @@ public class Utils {
|
|||
public static void emailAuthor( Context context )
|
||||
{
|
||||
Intent intent = new Intent( Intent.ACTION_SEND );
|
||||
intent.setType( "text/html" );
|
||||
intent.setType( "message/rfc822" ); // force email
|
||||
intent.putExtra( Intent.EXTRA_SUBJECT,
|
||||
context.getString( R.string.email_author_subject ) );
|
||||
String[] addrs = { context.getString( R.string.email_author_email ) };
|
||||
|
|
|
@ -141,9 +141,9 @@ public class XWActivity extends Activity
|
|||
m_delegate.showConfirmThen( getString(msgID), action );
|
||||
}
|
||||
|
||||
public void showTextOrHtmlThen( int action )
|
||||
public void showEmailOrSMSThen( int action )
|
||||
{
|
||||
m_delegate.showTextOrHtmlThen( action );
|
||||
m_delegate.showEmailOrSMSThen( action );
|
||||
}
|
||||
|
||||
protected void doSyncMenuitem()
|
||||
|
|
|
@ -44,7 +44,7 @@ enum {
|
|||
|
||||
STRD_ROBOT_TRADED,
|
||||
STR_ROBOT_MOVED,
|
||||
STR_REMOTE_MOVED,
|
||||
STRS_REMOTE_MOVED,
|
||||
|
||||
STR_PASSED,
|
||||
STRSD_SUMMARYSCORED,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- compile-command: "make -j3 TARGET_OS=wince DEBUG=TRUE"; -*-
|
||||
# Copyright 2002-2009 by Eric House (xwords@eehouse.org). All rights
|
||||
# reserved.
|
||||
|
||||
# -*- compile-command: "make -j3 DEBUG=TRUE"; -*-
|
||||
# Copyright 2002 - 2011 by Eric House (xwords@eehouse.org). All
|
||||
# rights reserved.
|
||||
#
|
||||
# This Makefile is meant to allow building Crosswords for PocketPC and
|
||||
# Windows using Linux. As of March 2006, it compiles and runs on
|
||||
# PocketPC as well as when built with eVC. Better, since bugs have
|
||||
|
@ -25,8 +25,6 @@ TARGET_OS ?= win32
|
|||
RELAY_NAME_DEFAULT ?= eehouse.org
|
||||
RELAY_PORT_DEFAULT ?= 10999
|
||||
|
||||
NATIVE_CC = gcc
|
||||
STRIDS = strids
|
||||
#TARGET_OS = wince
|
||||
#NO_DRAW = -DNO_DRAW
|
||||
|
||||
|
@ -99,7 +97,7 @@ WINDRES = i586-mingw32msvc-windres
|
|||
STRIP = i586-mingw32msvc-strip
|
||||
CELIBS += -lws2_32
|
||||
|
||||
CFLAGS += -DCANT_DO_CMDBAR -DDRAW_LINK_DIRECT -DXWFEATURE_TURNCHANGENOTIFY
|
||||
CFLAGS += -DCANT_DO_CMDBAR -DDRAW_LINK_DIRECT -DXWFEATURE_TURNCHANGENOTIFY -DXWFEATURE_MINIWIN
|
||||
# CFLAGS += -DFORCE_FONT="L\"Segoe Condensed\""
|
||||
#CFLAGS += -DFORCE_HEIGHT=240 -DFORCE_WIDTH=320
|
||||
endif
|
||||
|
|
|
@ -66,10 +66,10 @@ loadLettersList( BlankDialogState* bState )
|
|||
static void
|
||||
showCurTray( HWND hDlg, BlankDialogState* bState )
|
||||
{
|
||||
if ( bState->pi->why == PICK_FOR_CHEAT ) {
|
||||
if ( NULL != bState->pi ) {
|
||||
const PickInfo* pi = bState->pi;
|
||||
XP_U16 lenSoFar = 0;
|
||||
XP_U16 i;
|
||||
XP_U16 ii;
|
||||
XP_UCHAR labelBuf[48];
|
||||
wchar_t widebuf[48];
|
||||
XP_UCHAR* name;
|
||||
|
@ -82,10 +82,10 @@ showCurTray( HWND hDlg, BlankDialogState* bState )
|
|||
"%d of %d for %s" XP_CR "Cur",
|
||||
pi->thisPick + 1, pi->nTotal, name );
|
||||
|
||||
for ( i = 0; i < pi->nCurTiles; ++i ) {
|
||||
for ( ii = 0; ii < pi->nCurTiles; ++ii ) {
|
||||
lenSoFar += XP_SNPRINTF( labelBuf+lenSoFar,
|
||||
sizeof(labelBuf)-lenSoFar, "%s%s",
|
||||
i==0?": ":", ", pi->curTiles[i] );
|
||||
ii==0?": ":", ", pi->curTiles[ii] );
|
||||
}
|
||||
|
||||
(void)MultiByteToWideChar( CP_UTF8, 0, labelBuf, lenSoFar + 1, widebuf,
|
||||
|
@ -108,15 +108,14 @@ BlankDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
bState = (BlankDialogState*)lParam;
|
||||
|
||||
#ifdef FEATURE_TRAY_EDIT
|
||||
if ( bState->pi->why == PICK_FOR_CHEAT ) {
|
||||
if ( NULL != bState->pi ) {
|
||||
showCurTray( hDlg, bState );
|
||||
ceShowOrHide( hDlg, IDC_BPICK, XP_FALSE );
|
||||
} else {
|
||||
XP_ASSERT( bState->pi->why == PICK_FOR_BLANK );
|
||||
ceShowOrHide( hDlg, IDC_CPICK, XP_FALSE );
|
||||
ceShowOrHide( hDlg, IDC_PICKMSG, XP_FALSE );
|
||||
}
|
||||
bState->canBackup = (bState->pi->why == PICK_FOR_CHEAT)
|
||||
bState->canBackup = (NULL != bState->pi)
|
||||
&& (bState->pi->thisPick > 0);
|
||||
ceShowOrHide( hDlg, IDC_BACKUP, bState->canBackup );
|
||||
#endif
|
||||
|
|
|
@ -102,8 +102,13 @@ ce_dictionary_make( CEAppGlobals* globals, const char* dictName )
|
|||
void* mappedBase = (void*)ptr;
|
||||
XP_U8 nodeSize;
|
||||
XP_Bool isUTF8 = XP_FALSE;
|
||||
XP_Bool hasHeader;
|
||||
|
||||
flags = n_ptr_tohs( &ptr );
|
||||
hasHeader = 0 != (DICT_HEADER_MASK & flags);
|
||||
if ( hasHeader ) {
|
||||
flags &= ~DICT_HEADER_MASK;
|
||||
}
|
||||
|
||||
#ifdef NODE_CAN_4
|
||||
if ( flags == 0x0002 ) {
|
||||
|
@ -124,6 +129,23 @@ ce_dictionary_make( CEAppGlobals* globals, const char* dictName )
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
XP_U32 wordCount = 0;
|
||||
if ( hasHeader ) {
|
||||
XP_U16 headerLen;
|
||||
|
||||
XP_MEMCPY( &headerLen, ptr, sizeof(headerLen) );
|
||||
ptr += sizeof(headerLen);
|
||||
headerLen = XP_NTOHS( headerLen );
|
||||
if ( headerLen != sizeof(wordCount) ) { /* the only case we know right now */
|
||||
XP_LOGF( "%s: bad header size %d", __func__, headerLen );
|
||||
break;
|
||||
}
|
||||
XP_MEMCPY( &wordCount, ptr, sizeof(wordCount) );
|
||||
ptr += sizeof(wordCount);
|
||||
wordCount = XP_NTOHL( wordCount );
|
||||
}
|
||||
|
||||
if ( isUTF8 ) {
|
||||
numFaceBytes = (XP_U16)(*ptr++);
|
||||
}
|
||||
|
@ -137,6 +159,7 @@ ce_dictionary_make( CEAppGlobals* globals, const char* dictName )
|
|||
ctxt->mappedFile = mappedFile;
|
||||
ctxt->mappedBase = mappedBase;
|
||||
ctxt->super.nodeSize = nodeSize;
|
||||
ctxt->super.nWords = wordCount;
|
||||
ctxt->super.destructor = ce_dict_destroy;
|
||||
ctxt->super.func_dict_getShortName = ce_dict_getShortName;
|
||||
|
||||
|
@ -618,6 +641,7 @@ checkIfDictAndLegal( MPFORMAL wchar_t* path, XP_U16 pathLen,
|
|||
XP_U8* ptr = base;
|
||||
|
||||
flags = n_ptr_tohs( &ptr );
|
||||
flags &= ~DICT_HEADER_MASK;
|
||||
closeMappedFile( MPPARM(mpool) base, mappedFile );
|
||||
#ifdef NODE_CAN_4
|
||||
/* are the flags what we expect */
|
||||
|
|
|
@ -1200,9 +1200,9 @@ DLSTATIC XP_Bool
|
|||
DRAW_FUNC_NAME(drawCell)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
||||
const XP_UCHAR* letters,
|
||||
const XP_Bitmaps* bitmaps,
|
||||
Tile XP_UNUSED(tile), XP_S16 owner,
|
||||
XWBonusType bonus, HintAtts hintAtts,
|
||||
CellFlags flags )
|
||||
Tile XP_UNUSED(tile), XP_U16 XP_UNUSED(value),
|
||||
XP_S16 owner, XWBonusType bonus,
|
||||
HintAtts hintAtts, CellFlags flags )
|
||||
{
|
||||
#ifndef NO_DRAW
|
||||
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
||||
|
@ -1325,7 +1325,8 @@ logClipResult( int icrResult )
|
|||
|
||||
DLSTATIC XP_Bool
|
||||
DRAW_FUNC_NAME(trayBegin)( DrawCtx* p_dctx, const XP_Rect* XP_UNUSED(rect),
|
||||
XP_U16 owner, DrawFocusState dfs )
|
||||
XP_U16 owner, XP_S16 XP_UNUSED(score),
|
||||
DrawFocusState dfs )
|
||||
{
|
||||
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
||||
CEAppGlobals* globals = dctx->globals;
|
||||
|
@ -1468,7 +1469,7 @@ DRAW_FUNC_NAME(drawTileMidDrag)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|||
const XP_Bitmaps* bitmaps, XP_U16 val,
|
||||
XP_U16 owner, CellFlags flags )
|
||||
{
|
||||
if ( draw_trayBegin( p_dctx, xprect, owner, DFS_NONE ) ) {
|
||||
if ( draw_trayBegin( p_dctx, xprect, owner, 0, DFS_NONE ) ) {
|
||||
drawDrawTileGuts( p_dctx, xprect, letters, bitmaps, val, flags );
|
||||
}
|
||||
} /* ce_draw_drawTile */
|
||||
|
@ -2100,7 +2101,8 @@ DRAW_FUNC_NAME(destroyCtxt)( DrawCtx* p_dctx )
|
|||
} /* ce_draw_destroyCtxt */
|
||||
|
||||
DLSTATIC void
|
||||
DRAW_FUNC_NAME(dictChanged)( DrawCtx* p_dctx, const DictionaryCtxt* dict )
|
||||
DRAW_FUNC_NAME(dictChanged)( DrawCtx* p_dctx, XP_S16 XP_UNUSED(playerNum),
|
||||
const DictionaryCtxt* dict )
|
||||
{
|
||||
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
||||
XP_ASSERT( !!dict );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- fill-column: 77; compile-command: "make -j2 TARGET_OS=wince DEBUG=TRUE" -*- */
|
||||
/* -*- fill-column: 77; compile-command: "make -j2 DEBUG=TRUE" -*- */
|
||||
/*
|
||||
* Copyright 2002-2009 by Eric House (xwords@eehouse.org). All rights
|
||||
* reserved.
|
||||
|
@ -85,11 +85,11 @@ static XP_S16 ce_send_proc( const XP_U8* buf, XP_U16 len,
|
|||
static void ce_relay_status( void* closure,
|
||||
CommsRelayState newState );
|
||||
static void ce_relay_connd( void* closure, XP_UCHAR* const room,
|
||||
XP_U16 devOrder, XP_Bool allHere,
|
||||
XP_U16 nMissing );
|
||||
XP_Bool reconnect,
|
||||
XP_U16 devOrder, /* 1 means created room, etc. */
|
||||
XP_Bool allHere, XP_U16 nMissing );
|
||||
static void ce_relay_error( void* closure, XWREASON relayErr );
|
||||
|
||||
|
||||
# ifdef COMMS_HEARTBEAT
|
||||
static void ce_reset_proc( void* closure );
|
||||
# endif
|
||||
|
@ -99,12 +99,16 @@ static VTableMgr* ce_util_getVTManager( XW_UtilCtxt* uc );
|
|||
static void ce_util_userError( XW_UtilCtxt* uc, UtilErrID id );
|
||||
static XP_Bool ce_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id,
|
||||
XWStreamCtxt* stream );
|
||||
static XWBonusType ce_util_getSquareBonus( XW_UtilCtxt* uc,
|
||||
const ModelCtxt* model,
|
||||
static XP_Bool ce_util_confirmTrade( XW_UtilCtxt* uc, const XP_UCHAR** tiles,
|
||||
XP_U16 nTiles );
|
||||
static XWBonusType ce_util_getSquareBonus( XW_UtilCtxt* uc, XP_U16 boardSize,
|
||||
XP_U16 col, XP_U16 row );
|
||||
static XP_S16 ce_util_userPickTile( XW_UtilCtxt* uc, const PickInfo* pi,
|
||||
XP_U16 playerNum,
|
||||
const XP_UCHAR** texts, XP_U16 nTiles );
|
||||
static XP_S16 ce_util_userPickTileBlank( XW_UtilCtxt* uc, XP_U16 playerNum,
|
||||
const XP_UCHAR** tileFaces,
|
||||
XP_U16 nTiles );
|
||||
static XP_S16 ce_util_userPickTileTray( XW_UtilCtxt* uc, const PickInfo* pi,
|
||||
XP_U16 playerNum,
|
||||
const XP_UCHAR** texts, XP_U16 nTiles );
|
||||
static XP_Bool ce_util_askPassword( XW_UtilCtxt* uc, const XP_UCHAR* name,
|
||||
XP_UCHAR* buf, XP_U16* len );
|
||||
static void ce_util_trayHiddenChange( XW_UtilCtxt* uc,
|
||||
|
@ -114,6 +118,9 @@ static void ce_util_yOffsetChange( XW_UtilCtxt* uc, XP_U16 maxOffset,
|
|||
XP_U16 oldOffset, XP_U16 newOffset );
|
||||
static void ce_util_turnChanged( XW_UtilCtxt* uc );
|
||||
static void ce_util_notifyGameOver( XW_UtilCtxt* uc );
|
||||
static void ce_util_informMove( XW_UtilCtxt* uc, XWStreamCtxt* expl,
|
||||
XWStreamCtxt* words );
|
||||
|
||||
static XP_Bool ce_util_hiliteCell( XW_UtilCtxt* uc, XP_U16 col,
|
||||
XP_U16 row );
|
||||
static XP_Bool ce_util_engineProgressCallback( XW_UtilCtxt* uc );
|
||||
|
@ -360,12 +367,15 @@ ceInitUtilFuncs( CEAppGlobals* globals )
|
|||
vtable->m_util_userError = ce_util_userError;
|
||||
vtable->m_util_getSquareBonus = ce_util_getSquareBonus;
|
||||
vtable->m_util_userQuery = ce_util_userQuery;
|
||||
vtable->m_util_userPickTile = ce_util_userPickTile;
|
||||
vtable->m_util_confirmTrade = ce_util_confirmTrade;
|
||||
vtable->m_util_userPickTileBlank = ce_util_userPickTileBlank;
|
||||
vtable->m_util_userPickTileTray = ce_util_userPickTileTray;
|
||||
vtable->m_util_askPassword = ce_util_askPassword;
|
||||
vtable->m_util_trayHiddenChange = ce_util_trayHiddenChange;
|
||||
vtable->m_util_yOffsetChange = ce_util_yOffsetChange;
|
||||
vtable->m_util_turnChanged = ce_util_turnChanged;
|
||||
vtable->m_util_notifyGameOver = ce_util_notifyGameOver;
|
||||
vtable->m_util_informMove = ce_util_informMove;
|
||||
vtable->m_util_hiliteCell = ce_util_hiliteCell;
|
||||
vtable->m_util_engineProgressCallback = ce_util_engineProgressCallback;
|
||||
vtable->m_util_setTimer = ce_util_setTimer;
|
||||
|
@ -1214,7 +1224,7 @@ ceLoadSavedGame( CEAppGlobals* globals )
|
|||
XP_DEBUGF( "calling game_makeFromStream" );
|
||||
ceInitTProcs( globals, &procs );
|
||||
success = game_makeFromStream( MEMPOOL stream, &globals->game,
|
||||
&globals->gameInfo, dict,
|
||||
&globals->gameInfo, dict, NULL,
|
||||
&globals->util,
|
||||
(DrawCtx*)globals->draw,
|
||||
&globals->appPrefs.cp, &procs );
|
||||
|
@ -3182,9 +3192,9 @@ ce_relay_status( void* closure, CommsRelayState newState )
|
|||
|
||||
static void
|
||||
ce_relay_connd( void* closure, XP_UCHAR* const XP_UNUSED(room),
|
||||
XP_Bool XP_UNUSED(reconnect),
|
||||
XP_U16 XP_UNUSED(devOrder), /* 1 means created room, etc. */
|
||||
XP_Bool allHere,
|
||||
XP_U16 nMissing )
|
||||
XP_Bool allHere, XP_U16 nMissing )
|
||||
{
|
||||
CEAppGlobals* globals = (CEAppGlobals*)closure;
|
||||
XP_U16 strID = 0;
|
||||
|
@ -3334,12 +3344,12 @@ ce_util_userError( XW_UtilCtxt* uc, UtilErrID id )
|
|||
case ERR_NO_PEEK_ROBOT_TILES:
|
||||
resID = IDS_NO_PEEK_ROBOT_TILES;
|
||||
break;
|
||||
case ERR_CANT_TRADE_MID_MOVE:
|
||||
resID = IDS_CANT_TRADE_MID_MOVE;
|
||||
break;
|
||||
case ERR_TOO_FEW_TILES_LEFT_TO_TRADE:
|
||||
resID = IDS_TOO_FEW_TILES_LEFT_TO_TRADE;
|
||||
break;
|
||||
case ERR_NO_EMPTY_TRADE:
|
||||
resID = IDS_NO_EMPTY_TRADE;
|
||||
break;
|
||||
case ERR_CANT_UNDO_TILEASSIGN:
|
||||
resID = IDS_CANT_UNDO_TILEASSIGN;
|
||||
break;
|
||||
|
@ -3410,22 +3420,21 @@ ce_util_userError( XW_UtilCtxt* uc, UtilErrID id )
|
|||
static XP_Bool
|
||||
ce_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id, XWStreamCtxt* stream )
|
||||
{
|
||||
const char* query = NULL;
|
||||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
|
||||
switch( id ) {
|
||||
case QUERY_COMMIT_TURN:
|
||||
return ceQueryFromStream( globals, stream );
|
||||
|
||||
case QUERY_COMMIT_TRADE:
|
||||
query = ceGetResString( globals, IDS_QUERY_TRADE );
|
||||
assertOnTop( globals->hWnd );
|
||||
return queryBoxChar( globals, globals->hWnd, query );
|
||||
/* case QUERY_COMMIT_TRADE: */
|
||||
/* query = ceGetResString( globals, IDS_QUERY_TRADE ); */
|
||||
/* assertOnTop( globals->hWnd ); */
|
||||
/* return queryBoxChar( globals, globals->hWnd, query ); */
|
||||
|
||||
case QUERY_ROBOT_MOVE:
|
||||
return ceMsgFromStream( globals, stream,
|
||||
ceGetResStringL( globals, IDS_FYI_L),
|
||||
MB_OK | MB_ICONINFORMATION, XP_FALSE );
|
||||
/* case QUERY_ROBOT_MOVE: */
|
||||
/* return ceMsgFromStream( globals, stream, */
|
||||
/* ceGetResStringL( globals, IDS_FYI_L), */
|
||||
/* MB_OK | MB_ICONINFORMATION, XP_FALSE ); */
|
||||
|
||||
case QUERY_ROBOT_TRADE:
|
||||
messageBoxStream( globals, stream,
|
||||
|
@ -3440,10 +3449,21 @@ ce_util_userQuery( XW_UtilCtxt* uc, UtilQueryID id, XWStreamCtxt* stream )
|
|||
return XP_FALSE;
|
||||
} /* ce_util_userQuery */
|
||||
|
||||
static XP_Bool
|
||||
ce_util_confirmTrade( XW_UtilCtxt* uc, const XP_UCHAR** XP_UNUSED(tiles),
|
||||
XP_U16 XP_UNUSED(nTiles) )
|
||||
{
|
||||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
const XP_UCHAR* query = ceGetResString( globals, IDS_QUERY_TRADE );
|
||||
assertOnTop( globals->hWnd );
|
||||
return queryBoxChar( globals, globals->hWnd, query );
|
||||
}
|
||||
|
||||
static XWBonusType
|
||||
ce_util_getSquareBonus( XW_UtilCtxt* uc, const ModelCtxt* XP_UNUSED(model),
|
||||
ce_util_getSquareBonus( XW_UtilCtxt* uc, XP_U16 XP_UNUSED(boardSize),
|
||||
XP_U16 col, XP_U16 row )
|
||||
{
|
||||
XWBonusType result = BONUS_NONE;
|
||||
XP_U16 index;
|
||||
|
||||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
|
@ -3473,23 +3493,30 @@ ce_util_getSquareBonus( XW_UtilCtxt* uc, const ModelCtxt* XP_UNUSED(model),
|
|||
|
||||
if ( !globals->bonusInfo || (index >= 8*8) ) {
|
||||
XP_ASSERT( 0 );
|
||||
return (XWBonusType)BONUS_NONE;
|
||||
} else {
|
||||
/* This is probably a bit slow. Consider caching the resource in
|
||||
memory with one bonus value per byte. */
|
||||
XP_U16 value = globals->bonusInfo[index/4];
|
||||
value >>= ((3 - (index % 4)) * 4);
|
||||
return value & 0x0F;
|
||||
result = value & 0x0F;
|
||||
}
|
||||
return result;
|
||||
} /* ce_util_getSquareBonus */
|
||||
|
||||
static XP_S16
|
||||
ce_util_userPickTile( XW_UtilCtxt* uc, const PickInfo* pi,
|
||||
XP_U16 playerNum,
|
||||
const XP_UCHAR** texts, XP_U16 nTiles )
|
||||
ce_util_userPickTileBlank( XW_UtilCtxt* uc, XP_U16 playerNum,
|
||||
const XP_UCHAR** tileFaces, XP_U16 nTiles )
|
||||
{
|
||||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
return WrapBlankDlg( globals, pi, playerNum, texts, nTiles );
|
||||
return WrapBlankDlg( globals, NULL, playerNum, tileFaces, nTiles );
|
||||
} /* ce_util_userPickTile */
|
||||
|
||||
static XP_S16
|
||||
ce_util_userPickTileTray( XW_UtilCtxt* uc, const PickInfo* pi, XP_U16 playerNum,
|
||||
const XP_UCHAR** tileFaces, XP_U16 nTiles )
|
||||
{
|
||||
CEAppGlobals* globals = (CEAppGlobals*)uc->closure;
|
||||
return WrapBlankDlg( globals, pi, playerNum, tileFaces, nTiles );
|
||||
} /* ce_util_userPickTile */
|
||||
|
||||
static XP_Bool
|
||||
|
@ -3561,6 +3588,16 @@ ce_util_notifyGameOver( XW_UtilCtxt* uc )
|
|||
ceSetLeftSoftkey( globals, ID_FILE_NEWGAME );
|
||||
} /* ce_util_notifyGameOver */
|
||||
|
||||
|
||||
static void
|
||||
ce_util_informMove( XW_UtilCtxt* uc, XWStreamCtxt* expl, XWStreamCtxt* words )
|
||||
{
|
||||
XP_USE( uc );
|
||||
XP_USE( expl );
|
||||
XP_USE( words );
|
||||
LOG_FUNC();
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
ce_util_hiliteCell( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 XP_UNUSED(col),
|
||||
XP_U16 XP_UNUSED(row) )
|
||||
|
@ -3740,8 +3777,9 @@ ce_util_getUserString( XW_UtilCtxt* uc, XP_U16 stringCode )
|
|||
case STR_ROBOT_MOVED:
|
||||
resID = IDS_ROBOT_MOVED;
|
||||
break;
|
||||
case STR_REMOTE_MOVED:
|
||||
resID = IDS_REMOTE_MOVED;
|
||||
|
||||
case STRS_REMOTE_MOVED:
|
||||
resID = IDS_REMOTE_MOVEDF;
|
||||
break;
|
||||
|
||||
case STR_PASSED:
|
||||
|
|
|
@ -143,7 +143,6 @@ loadStateFromCurPrefs( CEAppGlobals* XP_UNUSED_STANDALONE(globals),
|
|||
const CurGameInfo* gi, CePrefsPrefs* prefsPrefs )
|
||||
{
|
||||
prefsPrefs->gp.hintsNotAllowed = gi->hintsNotAllowed;
|
||||
prefsPrefs->gp.robotSmartness = gi->robotSmartness;
|
||||
prefsPrefs->gp.timerEnabled = gi->timerEnabled;
|
||||
prefsPrefs->gp.gameSeconds = gi->gameSeconds;
|
||||
prefsPrefs->gp.phoniesAction = gi->phoniesAction;
|
||||
|
@ -177,7 +176,6 @@ loadCurPrefsFromState( CEAppGlobals* XP_UNUSED_STANDALONE(globals),
|
|||
CurGameInfo* gi, const CePrefsPrefs* prefsPrefs )
|
||||
{
|
||||
gi->hintsNotAllowed = prefsPrefs->gp.hintsNotAllowed;
|
||||
gi->robotSmartness = prefsPrefs->gp.robotSmartness;
|
||||
gi->timerEnabled = prefsPrefs->gp.timerEnabled;
|
||||
gi->gameSeconds = prefsPrefs->gp.gameSeconds;
|
||||
gi->phoniesAction = prefsPrefs->gp.phoniesAction;
|
||||
|
|
|
@ -934,7 +934,7 @@ BEGIN
|
|||
IDS_PHONY_REJECTED "Hi ha una o més paraules no vàlides a la jugada; torn perdut!" XP_CR
|
||||
IDS_ROBOT_TRADED "El robot ha canviat %d fitxes al seu torn."
|
||||
IDS_ROBOT_MOVED "El robot ha fet la seva jugada:" XP_CR
|
||||
IDS_REMOTE_MOVED "El jugador remot ha fet la seva jugada:" XP_CR
|
||||
IDS_REMOTE_MOVEDF "El jugador remot ha fet la seva jugada:" XP_CR
|
||||
IDS_PASSED "Ha passat"
|
||||
IDS_SUMMARYSCORED "%s:%d"
|
||||
IDS_TRADED "N'ha canviat %d"
|
||||
|
@ -956,7 +956,6 @@ BEGIN
|
|||
"la casella central en la primera jugada)."
|
||||
IDS_NOT_YOUR_TURN "No podeu fer això, no és el vostre torn!"
|
||||
IDS_NO_PEEK_ROBOT_TILES "No podeu mirar les fitxes del robot!"
|
||||
IDS_CANT_TRADE_MID_MOVE "Recolliu les fitxes posades al tauler abans de canviar fitxer."
|
||||
IDS_TOO_FEW_TILES_LEFT_TO_TRADE "Hi ha poques fitxes al saquet i ja no podeu canviar-les."
|
||||
IDS_CANT_UNDO_TILEASSIGN "L'assignació de fitxers no es pot desfer."
|
||||
IDS_CANT_HINT_WHILE_DISABLED "Les pistes es troben inhabilitades per a aquesta partida. Habiliteu-les"\
|
||||
|
|
|
@ -937,7 +937,7 @@ BEGIN
|
|||
IDS_PHONY_REJECTED "Neplatné slovo v tahu. Tah ztracen!" XP_CR
|
||||
IDS_ROBOT_TRADED "Robot tento tah směnil kameny %d."
|
||||
IDS_ROBOT_MOVED "Robot hrál takto:" XP_CR
|
||||
IDS_REMOTE_MOVED "Vzdálený hráč hrál takto:" XP_CR
|
||||
IDS_REMOTE_MOVEDF "Vzdálený hráč hrál takto:" XP_CR
|
||||
IDS_PASSED "Vynecháno"
|
||||
IDS_SUMMARYSCORED "%s:%d"
|
||||
IDS_TRADED "Směněno %d"
|
||||
|
@ -961,7 +961,6 @@ BEGIN
|
|||
"nebo v prvním tahu procházet středovým políčkem ."
|
||||
IDS_NOT_YOUR_TURN "Toto nelze, nejste na tahu!"
|
||||
IDS_NO_PEEK_ROBOT_TILES "Nelze prohlížet kameny robota"
|
||||
IDS_CANT_TRADE_MID_MOVE "Odstraňta rozehrané kameny před směnou."
|
||||
IDS_TOO_FEW_TILES_LEFT_TO_TRADE "Pro směnu je málo kamenů v zásobníku."
|
||||
IDS_CANT_UNDO_TILEASSIGN "Návrat zpět nelze provést."
|
||||
IDS_CANT_HINT_WHILE_DISABLED "Pro tuto hru je nápověda vypnuta."\
|
||||
|
|
|
@ -942,7 +942,7 @@ BEGIN
|
|||
IDS_PHONY_REJECTED "Illegal word in move; turn lost!" XP_CR
|
||||
IDS_ROBOT_TRADED "Robot traded tiles %d this turn."
|
||||
IDS_ROBOT_MOVED "The robot made this move:" XP_CR
|
||||
IDS_REMOTE_MOVED "Remote player made this move:" XP_CR
|
||||
IDS_REMOTE_MOVEDF "Remote player %s made this move:" XP_CR
|
||||
IDS_PASSED "Passed"
|
||||
IDS_SUMMARYSCORED "%s:%d"
|
||||
IDS_TRADED "Traded %d"
|
||||
|
@ -964,9 +964,9 @@ BEGIN
|
|||
"the middle square on the first move)."
|
||||
IDS_NOT_YOUR_TURN "You can't do that; it's not your turn!"
|
||||
IDS_NO_PEEK_ROBOT_TILES "No peeking at the robot's tiles!"
|
||||
IDS_CANT_TRADE_MID_MOVE "Remove played tiles before trading."
|
||||
IDS_TOO_FEW_TILES_LEFT_TO_TRADE "Too few tiles left to trade."
|
||||
IDS_CANT_UNDO_TILEASSIGN "Tile assignment can't be undone."
|
||||
IDS_NO_EMPTY_TRADE "No tiles selected; trade cancelled."
|
||||
IDS_CANT_HINT_WHILE_DISABLED "The hint feature is disabled for this game. Enable "\
|
||||
"it for a new game using the Preferences dialog."
|
||||
|
||||
|
|
|
@ -907,7 +907,7 @@ BEGIN
|
|||
IDS_PHONY_REJECTED "Mot refusé dans ce coup; tour perdu!" XP_CR
|
||||
IDS_ROBOT_TRADED "Le robot a échangé %d lettre(s) durant ce tour."
|
||||
IDS_ROBOT_MOVED "Le robot a joué ce coup:" XP_CR
|
||||
IDS_REMOTE_MOVED "Le joueur distant a joué ce coup:" XP_CR
|
||||
IDS_REMOTE_MOVEDF "Le joueur distant a joué ce coup:" XP_CR
|
||||
IDS_PASSED "Passé"
|
||||
IDS_SUMMARYSCORED "%s:%d"
|
||||
IDS_TRADED "Echangé %d"
|
||||
|
@ -929,7 +929,6 @@ BEGIN
|
|||
"recouvrir la case centrale du plateau lors du premier coup)."
|
||||
IDS_NOT_YOUR_TURN "Vous ne pouvez pas faire cela, ce n'est pas votre tour!"
|
||||
IDS_NO_PEEK_ROBOT_TILES "Pas de coup d'oeil sur les lettres du robot!"
|
||||
IDS_CANT_TRADE_MID_MOVE "Retirez les lettres placées avant d'échanger."
|
||||
IDS_TOO_FEW_TILES_LEFT_TO_TRADE "Il reste trop peu de lettres pour l'échange."
|
||||
IDS_CANT_UNDO_TILEASSIGN "L'attribution des lettres ne peut ętre annulé."
|
||||
IDS_CANT_HINT_WHILE_DISABLED "Les conseils sont désactivés dans cette partie. "\
|
||||
|
|
|
@ -910,7 +910,7 @@ BEGIN
|
|||
IDS_PHONY_REJECTED "niedozwolone słowo; kolejka stracona!" XP_CR
|
||||
IDS_ROBOT_TRADED "Robot wymienił %d klocków."
|
||||
IDS_ROBOT_MOVED "Robot wykonał ruch:" XP_CR
|
||||
IDS_REMOTE_MOVED "Zdalny gracz wykonał ruch:" XP_CR
|
||||
IDS_REMOTE_MOVEDF "Zdalny gracz wykonał ruch:" XP_CR
|
||||
IDS_PASSED "spasował"
|
||||
IDS_SUMMARYSCORED "%s:%d"
|
||||
IDS_TRADED "wymienione %d"
|
||||
|
@ -932,7 +932,6 @@ BEGIN
|
|||
"środkowego pola przy pierwszym ruchu)."
|
||||
IDS_NOT_YOUR_TURN "Nie możesz tego zrobić; To nie Twoja kolejka!"
|
||||
IDS_NO_PEEK_ROBOT_TILES "Nie można podglądać klocków Robota!"
|
||||
IDS_CANT_TRADE_MID_MOVE "Usuń klocki z planszy zanim je wymienisz."
|
||||
IDS_TOO_FEW_TILES_LEFT_TO_TRADE "Zbyt mało klocków by dokonać wymiany."
|
||||
IDS_CANT_UNDO_TILEASSIGN "Nie można zmienić ułożenia klocków."
|
||||
IDS_CANT_HINT_WHILE_DISABLED "Podpowiedzi są wyłączone dla tej gry. "\
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define IDS_PHONY_REJECTED 40031
|
||||
#define IDS_ROBOT_TRADED 40032
|
||||
#define IDS_ROBOT_MOVED 40033
|
||||
#define IDS_REMOTE_MOVED 40034
|
||||
#define IDS_REMOTE_MOVEDF 40034
|
||||
#define IDS_PASSED 40035
|
||||
#define IDS_REMTILES_L 40036
|
||||
#define IDS_SUMMARYSCORED 40037
|
||||
|
@ -63,7 +63,7 @@
|
|||
#define IDS_TILES_MUST_CONTACT 40045
|
||||
#define IDS_NOT_YOUR_TURN 40046
|
||||
#define IDS_NO_PEEK_ROBOT_TILES 40047
|
||||
#define IDS_CANT_TRADE_MID_MOVE 40048
|
||||
#define IDS_NO_EMPTY_TRADE 40048
|
||||
#define IDS_TOO_FEW_TILES_LEFT_TO_TRADE 40049
|
||||
#define IDS_CANT_UNDO_TILEASSIGN 40050
|
||||
#define IDS_CANT_HINT_WHILE_DISABLED 40051
|
||||
|
|
Loading…
Reference in a new issue