Project

General

Profile

Download (16.7 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 83018ac4

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objects;
11

    
12
import java.util.ArrayList;
13
import java.util.Locale;
14

    
15
import android.content.Context;
16
import android.content.SharedPreferences;
17

    
18
import org.distorted.external.RubikFiles;
19
import org.distorted.main.RubikActivity;
20
import org.distorted.objectlib.main.ObjectSignatures;
21
import org.distorted.objectlib.main.ObjectType;
22

    
23
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
24
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
25
import static org.distorted.main.RubikActivity.SHOW_DOWNLOADED_DEBUG;
26

    
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

    
29
public class RubikObjectList
30
{
31
  public static final int DEF_OBJECT= ObjectSignatures.CUBE_3;
32
  public static int MAX_LEVEL;
33

    
34
  private static RubikObjectList mThis;
35
  private static int mNumObjects;
36
  private static int mNumExtras;
37
  private static ArrayList<RubikObject> mObjects;
38
  private static int mObject = DEF_OBJECT;
39

    
40
  public static class DownloadedObject
41
    {
42
    String shortName;
43
    boolean icon,object,extras;
44
    int numScrambles, objectMinor, extrasMinor;
45

    
46
    DownloadedObject(String sName, int scrambles, int oMinor, int eMinor, boolean i, boolean o, boolean e)
47
      {
48
      shortName = sName;
49

    
50
      numScrambles= scrambles;
51
      objectMinor = oMinor;
52
      extrasMinor = eMinor;
53

    
54
      icon   = i;
55
      object = o;
56
      extras = e;
57
      }
58
    }
59

    
60
  private static ArrayList<DownloadedObject> mDownloadedObjects;
61

    
62
  static
63
    {
64
    int max = Integer.MIN_VALUE;
65

    
66
    for (int i=0; i<NUM_OBJECTS; i++)
67
      {
68
      int cur = getDBLevel(i);
69
      if( cur>max ) max = cur;
70
      }
71

    
72
    MAX_LEVEL = max;
73
    }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
  private RubikObjectList()
78
    {
79
    mNumObjects= 0;
80
    mNumExtras = 0;
81

    
82
    mObjects           = new ArrayList<>();
83
    mDownloadedObjects = new ArrayList<>();
84

    
85
    createBuiltinObjects();
86
    }
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

    
90
  private void createBuiltinObjects()
91
    {
92
    for(int i=0; i<NUM_OBJECTS; i++)
93
      {
94
      ObjectType type = ObjectType.getObject(i);
95
      RubikObject obj = new RubikObject(type);
96
      mObjects.add(obj);
97
      mNumObjects++;
98

    
99
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "creating local object "+type.name() );
100

    
101
      if( obj.hasExtras() )
102
        {
103
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
104

    
105
        obj.setExtrasOrdinal(mNumExtras);
106
        mNumExtras++;
107
        }
108
      else
109
        {
110
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
111
        }
112
      }
113
    }
114

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

    
117
  private static boolean internalAddDownloadedObject(DownloadedObject object)
118
    {
119
    String name = object.shortName;
120

    
121
    for(RubikObject ro : mObjects )
122
      if( ro.getLowerName().equals(name) )
123
        {
124
        return ro.updateObject(object);
125
        }
126

    
127
    RubikObject obj = new RubikObject(object);
128
    mObjects.add(obj);
129
    mNumObjects++;
130

    
131
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "creating downloaded object "+obj.getUpperName() );
132

    
133
    if( obj.hasExtras() )
134
      {
135
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
136

    
137
      obj.setExtrasOrdinal(mNumExtras);
138
      mNumExtras++;
139
      }
140
    else
141
      {
142
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
143
      }
144

    
145
    return true;
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
// PUBLIC API
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
// historically older versions of the app had lower 'maxScrambles' in case of several objects and
152
// those got remembered in the server-side DB already, so we need to keep using them. This function
153
// provides a map between 'maxScramble' of an object and its 'dbLevel'. All new objects will have
154
// those two values the same.
155
//
156
// all of those need to be > RubikStatePlay.LEVELS_SHOWN.
157

    
158
  public static int getDBLevel(int ordinal)
159
    {
160
    if( ordinal== ObjectSignatures.CUBE_3 ) return 16;
161
    if( ordinal== ObjectSignatures.CUBE_4 ) return 20;
162
    if( ordinal== ObjectSignatures.CUBE_5 ) return 24;
163
    if( ordinal== ObjectSignatures.BAN2_3 ) return 16;
164
    if( ordinal== ObjectSignatures.BAN4_3 ) return 16;
165
    if( ordinal== ObjectSignatures.PYRA_4 ) return 15;
166
    if( ordinal== ObjectSignatures.PYRA_5 ) return 20;
167
    if( ordinal== ObjectSignatures.MEGA_5 ) return 35;
168
    if( ordinal== ObjectSignatures.DIAM_2 ) return 10;
169
    if( ordinal== ObjectSignatures.DIAM_3 ) return 18;
170
    if( ordinal== ObjectSignatures.REDI_3 ) return 14;
171
    if( ordinal== ObjectSignatures.HELI_3 ) return 18;
172
    if( ordinal== ObjectSignatures.SKEW_3 ) return 17;
173
    if( ordinal== ObjectSignatures.REX_3  ) return 16;
174
    if( ordinal== ObjectSignatures.MIRR_3 ) return 16;
175
    if( ordinal== ObjectSignatures.IVY_2  ) return  9;
176
    if( ordinal== ObjectSignatures.DIN4_3 ) return  9;
177

    
178
    // in 1.9.6 & 1.9.7 there is a bug with downloadable objects (in this very function!):
179
    // All of those have DBLevel equal to CUBE_3's DBlevel (in 1.9.7!), i.e. 17.
180
    // This will be a problem when we release a new version of the app which has some of the
181
    // previously downloadable objects built-in. Thus: in case of those, we need to keep using
182
    // 17.
183

    
184
    if( ObjectType.wasDownloadableButNowIsBuiltIn(ordinal) )
185
      {
186
      return 17;
187
      }
188

    
189
    return ObjectType.getObject(ordinal).getNumScramble();
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193

    
194
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, int objectMinor,
195
                                         int extrasMinor, boolean icon, boolean object, boolean extras)
196
    {
197
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
198

    
199
    for( DownloadedObject obj : mDownloadedObjects )
200
      {
201
      if( obj.shortName.equals(shortName) )
202
        {
203
        obj.icon  |= icon;
204
        obj.object|= object;
205
        obj.extras|= extras;
206

    
207
        if( !obj.object ) objectMinor=-1;
208
        if( !obj.extras ) extrasMinor=-1;
209

    
210
        obj.objectMinor = objectMinor;
211
        obj.extrasMinor = extrasMinor;
212

    
213
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Updating downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
214

    
215
        try
216
          {
217
          RubikActivity ract = (RubikActivity)context;
218
          ract.reloadObject(shortName);
219
          }
220
        catch(Exception ex)
221
          {
222
          android.util.Log.e("D", "exception trying to reload object: "+ex.getMessage() );
223
          }
224

    
225
        return false;
226
        }
227
      }
228

    
229
    if( !object ) objectMinor=-1;
230
    if( !extras ) extrasMinor=-1;
231

    
232
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,objectMinor,extrasMinor,icon,object,extras);
233
    if ( internalAddDownloadedObject(obj) )
234
      {
235
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Adding new downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
236
      mDownloadedObjects.add(obj);
237
      return true;
238
      }
239
    else
240
      {
241
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" is already built-in, deleting");
242
      RubikFiles files = RubikFiles.getInstance();
243
      files.deleteIcon(context,shortName);
244
      files.deleteJsonObject(context,shortName);
245
      files.deleteJsonExtras(context,shortName);
246
      return false;
247
      }
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

    
252
  public static void setMeshState(int ordinal, int state)
253
    {
254
    if( ordinal>=0 && ordinal<mNumObjects ) mObjects.get(ordinal).setMeshState(state);
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  public static int getMeshState(int ordinal)
260
    {
261
    return (ordinal>=0 && ordinal<mNumObjects) ? mObjects.get(ordinal).getMeshState() : MESH_NICE;
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  public static void savePreferences(SharedPreferences.Editor editor)
267
    {
268
    RubikObject obj = getObject(mObject);
269
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
270

    
271
    int numDownloaded = mDownloadedObjects.size();
272

    
273
    if( numDownloaded>0 )
274
      {
275
      StringBuilder downloadedObjects = new StringBuilder();
276

    
277
      for(int i=0; i<numDownloaded; i++)
278
        {
279
        if( i>0 ) downloadedObjects.append(',');
280

    
281
        DownloadedObject object = mDownloadedObjects.get(i);
282
        downloadedObjects.append(object.shortName);
283
        downloadedObjects.append(' ');
284
        downloadedObjects.append(object.numScrambles);
285
        downloadedObjects.append(' ');
286
        downloadedObjects.append(object.objectMinor);
287
        downloadedObjects.append(' ');
288
        downloadedObjects.append(object.extrasMinor);
289
        downloadedObjects.append(' ');
290
        downloadedObjects.append(object.icon   ? "1":"0");
291
        downloadedObjects.append(' ');
292
        downloadedObjects.append(object.object ? "1":"0");
293
        downloadedObjects.append(' ');
294
        downloadedObjects.append(object.extras ? "1":"0");
295
        }
296

    
297
      String objects = downloadedObjects.toString();
298
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
299
      editor.putString("rol_downloaded", objects );
300
      }
301
    else
302
      {
303
      editor.putString("rol_downloaded", "" );
304
      }
305
    }
306

    
307
///////////////////////////////////////////////////////////////////////////////////////////////////
308

    
309
  public static void saveMeshState(SharedPreferences.Editor editor)
310
    {
311
    for(int i=0; i<mNumObjects; i++)
312
      {
313
      RubikObject obj = getObject(i);
314

    
315
      if( obj!=null )
316
        {
317
        String name = obj.getUpperName();
318
        editor.putInt("rol_"+name, obj.getMeshState() );
319
        }
320
      }
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

    
325
  public static void restorePreferences(Context context, SharedPreferences preferences)
326
    {
327
    if( mThis==null ) mThis = new RubikObjectList();
328

    
329
    String downloaded = preferences.getString("rol_downloaded","");
330

    
331
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
332

    
333
    if( !downloaded.equals(""))
334
      {
335
      String[] dObjects = downloaded.split(",");
336

    
337
      for(String dObj : dObjects)
338
        {
339
        String[] parts = dObj.split(" ");
340

    
341
        if( parts.length==7 )
342
          {
343
          String name = parts[0];
344
          String scra = parts[1];
345
          String objM = parts[2];
346
          String extM = parts[3];
347
          String icon = parts[4];
348
          String obje = parts[5];
349
          String extr = parts[6];
350

    
351
          int scrambles = Integer.parseInt(scra);
352
          int oMinor    = Integer.parseInt(objM);
353
          int eMinor    = Integer.parseInt(extM);
354

    
355
          boolean bIcon = icon.equals("1");
356
          boolean bObje = obje.equals("1");
357
          boolean bExtr = extr.equals("1");
358

    
359
          addDownloadedObject(context,name,scrambles,oMinor,eMinor,bIcon,bObje,bExtr);
360
          }
361
        }
362
      }
363

    
364
    RubikObject object = getObject(DEF_OBJECT);
365
    String defName = object==null ? "CUBE_3" : object.getUpperName();
366
    String objName= preferences.getString("rol_objName",defName);
367
    mObject = getOrdinal(objName);
368
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  public static void restoreMeshState(SharedPreferences preferences)
374
    {
375
    for(int i=0; i<mNumObjects; i++)
376
      {
377
      RubikObject obj = getObject(i);
378

    
379
      if( obj!=null )
380
        {
381
        String name  = obj.getUpperName();
382
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
383
        obj.setMeshState(meshState);
384
        }
385
      }
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  public static boolean setCurrObject(int ordinal)
391
    {
392
    if( mObject!=ordinal )
393
      {
394
      mObject = ordinal;
395
      return true;
396
      }
397

    
398
    return false;
399
    }
400

    
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402

    
403
  public static int getCurrObject()
404
    {
405
    return mObject;
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  public static String getCurrentName()
411
    {
412
    RubikObject object = mObjects.get(mObject);
413
    return object==null ? "" : object.getUpperName();
414
    }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
  public static RubikObject getObject(int ordinal)
419
    {
420
    if( mThis==null ) mThis = new RubikObjectList();
421
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

    
426
  public static RubikObject getObject(String shortUpperName)
427
    {
428
    if( mThis==null ) mThis = new RubikObjectList();
429

    
430
    for(int i=0; i<mNumObjects; i++)
431
      {
432
      RubikObject object = mObjects.get(i);
433
      if( object.getUpperName().equals(shortUpperName) )
434
        {
435
        return object;
436
        }
437
      }
438

    
439
    return null;
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

    
444
  public static int getNumObjects()
445
    {
446
    if( mThis==null ) mThis = new RubikObjectList();
447
    return mNumObjects;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  public static int getOrdinal(String name)
453
    {
454
    if( mThis==null ) mThis = new RubikObjectList();
455

    
456
    String lowerName = name.toLowerCase(Locale.ENGLISH);
457

    
458
    for(int i=0; i<mNumObjects; i++)
459
      {
460
      RubikObject obj = mObjects.get(i);
461
      if( obj.getLowerName().equals(lowerName) ) return i;
462
      }
463

    
464
    return -1;
465
    }
466

    
467
///////////////////////////////////////////////////////////////////////////////////////////////////
468

    
469
  public static int getNumExtrasObjects()
470
    {
471
    return mNumExtras;
472
    }
473

    
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public static int getNumTutorialObjects()
477
    {
478
    return mNumExtras;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  public static int getObjectOrdinal(int extrasOrdinal)
484
    {
485
    for(int i=extrasOrdinal; i<mNumObjects; i++)
486
      {
487
      RubikObject object = getObject(i);
488
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
489
      if( extOrd==extrasOrdinal ) return i;
490
      }
491

    
492
    return -1;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public static int getExtrasOrdinal(int objectOrdinal)
498
    {
499
    RubikObject object = getObject(objectOrdinal);
500
    return object!=null ? object.getExtrasOrdinal() : -1;
501
    }
502

    
503
///////////////////////////////////////////////////////////////////////////////////////////////////
504

    
505
  public static int getTutorialOrdinal(int objectOrdinal)
506
    {
507
    RubikObject object = getObject(objectOrdinal);
508
    return object!=null ? object.getExtrasOrdinal() : -1;
509
    }
510

    
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
  public static int getLocalObjectMinor(int objectOrdinal)
514
    {
515
    RubikObject object = getObject(objectOrdinal);
516
    return object!=null ? object.getObjectMinor() : -1;
517
    }
518

    
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520

    
521
  public static int getLocalExtrasMinor(int objectOrdinal)
522
    {
523
    RubikObject object = getObject(objectOrdinal);
524
    return object!=null ? object.getExtrasMinor() : -1;
525
    }
526
}
(4-4/4)