Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ f05e0259

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

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

    
182
    if( ObjectType.wasDownloadableButNowIsBuiltIn(ordinal) )
183
      {
184
      return 17;
185
      }
186

    
187
    return ObjectType.getObject(ordinal).getNumScramble();
188
    }
189

    
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191

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

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

    
205
        if( !obj.object ) objectMinor=-1;
206
        if( !obj.extras ) extrasMinor=-1;
207

    
208
        obj.objectMinor = objectMinor;
209
        obj.extrasMinor = extrasMinor;
210

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

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

    
223
        return false;
224
        }
225
      }
226

    
227
    if( !object ) objectMinor=-1;
228
    if( !extras ) extrasMinor=-1;
229

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

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

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

    
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256

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

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

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

    
269
    int numDownloaded = mDownloadedObjects.size();
270

    
271
    if( numDownloaded>0 )
272
      {
273
      StringBuilder downloadedObjects = new StringBuilder();
274

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

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

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

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

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

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

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

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

    
327
    String downloaded = preferences.getString("rol_downloaded","");
328

    
329
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
330

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

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

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

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

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

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

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

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

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

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

    
386
///////////////////////////////////////////////////////////////////////////////////////////////////
387

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

    
396
    return false;
397
    }
398

    
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  public static int getCurrObject()
402
    {
403
    return mObject;
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

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

    
414
///////////////////////////////////////////////////////////////////////////////////////////////////
415

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

    
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423

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

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

    
437
    return null;
438
    }
439

    
440
///////////////////////////////////////////////////////////////////////////////////////////////////
441

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

    
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449

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

    
454
    String lowerName = name.toLowerCase(Locale.ENGLISH);
455

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

    
462
    return -1;
463
    }
464

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466

    
467
  public static int getNumExtrasObjects()
468
    {
469
    return mNumExtras;
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

    
474
  public static int getNumTutorialObjects()
475
    {
476
    return mNumExtras;
477
    }
478

    
479
///////////////////////////////////////////////////////////////////////////////////////////////////
480

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

    
490
    return -1;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

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

    
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

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

    
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510

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

    
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518

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