Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 7bb30586

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.external.RubikScores;
20
import org.distorted.objectlib.signature.ObjectConstants;
21
import org.distorted.objectlib.main.ObjectType;
22

    
23
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
24

    
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

    
27
public class RubikObjectList
28
{
29
  public static final boolean SHOW_DOWNLOADED_DEBUG = false;
30
  public static final boolean SHOW_IAP_DEBUG        = false;
31
  public static final boolean USE_IAP               = false;
32

    
33
  public static final int DEF_OBJECT= ObjectConstants.CUBE_3;
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, objectVersion, extrasVersion, price;
45

    
46
    DownloadedObject(String sName, int scrambles, int pr, int oVersion, int eVersion, boolean i, boolean o, boolean e)
47
      {
48
      shortName     = sName;
49
      numScrambles  = scrambles;
50
      price         = pr;
51
      objectVersion = oVersion;
52
      extrasVersion = eVersion;
53

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

    
60
  private static ArrayList<DownloadedObject> mDownloadedObjects;
61

    
62
  private static String mBoughtObjects;
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

    
66
  private RubikObjectList()
67
    {
68
    mNumObjects        = 0;
69
    mNumExtras         = 0;
70
    mObjects           = new ArrayList<>();
71
    mDownloadedObjects = new ArrayList<>();
72

    
73
    createBuiltinObjects();
74
    }
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

    
78
  private static boolean allObjectsUnlocked()
79
    {
80
    return mBoughtObjects!=null       &&
81
           mBoughtObjects.length()>0  &&
82
           mBoughtObjects.charAt(0)=='*';
83
    }
84

    
85
///////////////////////////////////////////////////////////////////////////////////////////////////
86

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

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

    
98
      if( obj.hasExtras() )
99
        {
100
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
101

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

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  private static boolean internalAddDownloadedObject(DownloadedObject object)
115
    {
116
    String name = object.shortName;
117

    
118
    for(RubikObject ro : mObjects )
119
      if( ro.getLowerName().equals(name) )
120
        {
121
        return ro.updateObject(object);
122
        }
123

    
124
    RubikObject obj = new RubikObject(object);
125
    mObjects.add(obj);
126
    mNumObjects++;
127

    
128
    if( USE_IAP && !obj.isFree() && allObjectsUnlocked() )
129
      {
130
      if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "everything unlocked, so setting downloaded object free: "+obj.getUpperName() );
131
      obj.markFree();
132
      }
133

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

    
136
    if( obj.hasExtras() )
137
      {
138
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
139

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

    
148
    return true;
149
    }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
  private static void restoreFreedObjects(SharedPreferences preferences)
154
    {
155
    mBoughtObjects = preferences.getString("rol_bought", "");
156

    
157
    if( SHOW_IAP_DEBUG )
158
      {
159
      android.util.Log.e("D", "bought objects: "+mBoughtObjects);
160
      }
161

    
162
    if( mBoughtObjects.length()>0 )
163
      {
164
      if( mBoughtObjects.charAt(0)=='*' )
165
        {
166
        for(int i=0; i<mNumObjects; i++)
167
          {
168
          RubikObject o = mObjects.get(i);
169
          if( o!=null ) o.markFree();
170
          }
171
        }
172
      else
173
        {
174
        String[] objs = mBoughtObjects.split(",");
175

    
176
        for( String obj : objs )
177
          {
178
          RubikObject o = getObject(obj);
179
          if( o!=null ) o.markFree();
180
          }
181
        }
182
      }
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186
// PUBLIC API
187

    
188
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, int price, int objectVersion,
189
                                         int extrasVersion, boolean icon, boolean object, boolean extras)
190
    {
191
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
192

    
193
    for( DownloadedObject obj : mDownloadedObjects )
194
      {
195
      if( obj.shortName.equals(shortName) )
196
        {
197
        obj.icon  |= icon;
198
        obj.object|= object;
199
        obj.extras|= extras;
200

    
201
        if( !obj.object ) objectVersion=-1;
202
        if( !obj.extras ) extrasVersion=-1;
203

    
204
        obj.objectVersion = objectVersion;
205
        obj.extrasVersion = extrasVersion;
206

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

    
209
        return false;
210
        }
211
      }
212

    
213
    if( !object ) objectVersion=-1;
214
    if( !extras ) extrasVersion=-1;
215

    
216
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,price,objectVersion,extrasVersion,icon,object,extras);
217
    if ( internalAddDownloadedObject(obj) )
218
      {
219
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Adding new downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
220
      mDownloadedObjects.add(obj);
221
      return true;
222
      }
223
    else
224
      {
225
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" is already built-in, deleting");
226
      RubikFiles files = RubikFiles.getInstance();
227
      files.deleteIcon(context,shortName);
228
      files.deleteJsonObject(context,shortName);
229
      files.deleteJsonExtras(context,shortName);
230
      return false;
231
      }
232
    }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
  public static boolean thereAreLockedObjects()
237
    {
238
    for(int i=0; i<mNumObjects; i++)
239
      {
240
      RubikObject o = mObjects.get(i);
241
      if( !o.isFree() ) return true;
242
      }
243

    
244
    return false;
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  public static boolean objectAlreadyBought(RubikObject object)
250
    {
251
    return ( object!=null && object.isFree() );
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255
// calling PurchaseScreenPane charges the user.
256

    
257
  public static void buyAll()
258
    {
259
    mBoughtObjects = "*";
260
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
261

    
262
    for(int i=0; i<mNumObjects; i++)
263
      {
264
      RubikObject o = mObjects.get(i);
265
      o.markFree();
266
      }
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270
// calling PurchaseScreenPane charges the user.
271

    
272
  public static void buyObject(RubikObject object)
273
    {
274
    if( object!=null && !object.isFree() )
275
      {
276
      String shortName = object.getUpperName();
277
      if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as bought");
278
      object.markFree();
279
      String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
280
      mBoughtObjects += add;
281
      }
282
    }
283

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

    
286
  public static void savePreferences(SharedPreferences.Editor editor)
287
    {
288
    RubikObject obj = getObject(mObject);
289
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
290

    
291
    int numDownloaded = mDownloadedObjects.size();
292

    
293
    if( numDownloaded>0 )
294
      {
295
      StringBuilder downloadedObjects = new StringBuilder();
296

    
297
      for(int i=0; i<numDownloaded; i++)
298
        {
299
        if( i>0 ) downloadedObjects.append(',');
300

    
301
        DownloadedObject object = mDownloadedObjects.get(i);
302
        downloadedObjects.append(object.shortName);
303
        downloadedObjects.append(' ');
304
        downloadedObjects.append(object.numScrambles);
305
        downloadedObjects.append(' ');
306
        downloadedObjects.append(object.objectVersion);
307
        downloadedObjects.append(' ');
308
        downloadedObjects.append(object.extrasVersion);
309
        downloadedObjects.append(' ');
310
        downloadedObjects.append(object.icon   ? "1":"0");
311
        downloadedObjects.append(' ');
312
        downloadedObjects.append(object.object ? "1":"0");
313
        downloadedObjects.append(' ');
314
        downloadedObjects.append(object.extras ? "1":"0");
315
        downloadedObjects.append(' ');
316
        downloadedObjects.append(object.price);
317
        }
318

    
319
      String objects = downloadedObjects.toString();
320
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
321
      editor.putString("rol_downloaded", objects );
322
      }
323
    else
324
      {
325
      editor.putString("rol_downloaded", "" );
326
      }
327

    
328
    if( USE_IAP )
329
      {
330
      editor.putString("rol_bought", mBoughtObjects);
331

    
332
      if( SHOW_IAP_DEBUG )
333
        {
334
        android.util.Log.e("D", "saving bought objects: "+mBoughtObjects);
335
        }
336
      }
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  public static void savePreferencesMinimal(SharedPreferences.Editor editor)
342
    {
343
    RubikObject obj = getObject(mObject);
344
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
350
    {
351
    if( mThis==null ) mThis = new RubikObjectList();
352

    
353
    String downloaded = preferences.getString("rol_downloaded","");
354

    
355
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
356

    
357
    if( !downloaded.equals(""))
358
      {
359
      String[] dObjects = downloaded.split(",");
360

    
361
      for(String dObj : dObjects)
362
        {
363
        String[] parts = dObj.split(" ");
364
        int length = parts.length;
365

    
366
        if( length==7 || length==8 )
367
          {
368
          String name = parts[0];
369
          String scra = parts[1];
370
          String objV = parts[2];
371
          String extV = parts[3];
372
          String icon = parts[4];
373
          String obje = parts[5];
374
          String extr = parts[6];
375

    
376
          int price;
377

    
378
          if( length==7 ) price=0;
379
          else
380
            {
381
            char c = parts[7].charAt(0);
382
            if( c=='t' )      price = 0;
383
            else if( c=='f' ) price = ObjectType.DEFAULT_PRICE_OF_OLD_OBJECTS;
384
            else              price = Integer.parseInt(parts[7]);
385
            }
386

    
387
          int scrambles = Integer.parseInt(scra);
388
          int oVersion  = Integer.parseInt(objV);
389
          int eVersion  = Integer.parseInt(extV);
390

    
391
          boolean bIcon = icon.equals("1");
392
          boolean bObje = obje.equals("1");
393
          boolean bExtr = extr.equals("1");
394

    
395
          addDownloadedObject(context,name,scrambles,price,oVersion,eVersion,bIcon,bObje,bExtr);
396
          }
397
        }
398
      }
399

    
400
    RubikObject object = getObject(DEF_OBJECT);
401
    String defName = object==null ? "CUBE_3" : object.getUpperName();
402
    String objName= preferences.getString("rol_objName",defName);
403
    mObject = getOrdinal(objName);
404
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
405

    
406
    if( USE_IAP && justStarted ) restoreFreedObjects(preferences);
407
    }
408

    
409
///////////////////////////////////////////////////////////////////////////////////////////////////
410

    
411
  public static void firstUpgradeMarkAllSolvedAsFree()
412
    {
413
    RubikScores scores = RubikScores.getInstance();
414
    int numUnclaimed = scores.numberOfSolvedMAXes();
415

    
416
    if( numUnclaimed>0 )
417
      {
418
      int marked = markAllSolvedAsFree(scores);
419
      int stillUnclaimed = numUnclaimed-marked;
420
      if( stillUnclaimed>0) markObjectsAsFree(scores,stillUnclaimed);
421
      }
422
    }
423

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

    
426
  private static int markAllSolvedAsFree(RubikScores scores)
427
    {
428
    int numObjects = RubikObjectList.getNumObjects();
429
    int ret = 0;
430

    
431
    for(int obj=0; obj<numObjects; obj++)
432
      {
433
      RubikObject object = getObject(obj);
434

    
435
      if( object!=null && !object.isFree() && scores.isSolved(obj,RubikScores.LEVELS_SHOWN) )
436
        {
437
        markAsFree(object,scores);
438
        ret++;
439
        }
440
      }
441

    
442
    return ret;
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

    
447
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
448
    {
449
    int numObjects = RubikObjectList.getNumObjects();
450

    
451
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
452
      {
453
      RubikObject object = getObject(obj);
454

    
455
      if( object!=null && !object.isFree() )
456
        {
457
        markAsFree(object,scores);
458
        numToBeMarked--;
459
        }
460
      }
461
    }
462

    
463
///////////////////////////////////////////////////////////////////////////////////////////////////
464

    
465
  private static void markAsFree(RubikObject object, RubikScores scores)
466
    {
467
    String shortName = object.getUpperName();
468
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
469
    object.markFree();
470
    int price = object.getPrice();
471
    scores.changeNumStars(-price);
472
    String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
473
    mBoughtObjects += add;
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public static boolean setCurrObject(int ordinal)
479
    {
480
    if( mObject!=ordinal )
481
      {
482
      mObject = ordinal;
483
      return true;
484
      }
485

    
486
    return false;
487
    }
488

    
489
///////////////////////////////////////////////////////////////////////////////////////////////////
490

    
491
  public static int getCurrObject()
492
    {
493
    return mObject;
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public static String getCurrentName()
499
    {
500
    RubikObject object = mObjects.get(mObject);
501
    return object==null ? "" : object.getUpperName();
502
    }
503

    
504
///////////////////////////////////////////////////////////////////////////////////////////////////
505

    
506
  public static RubikObject getObject(int ordinal)
507
    {
508
    if( mThis==null ) mThis = new RubikObjectList();
509
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
510
    }
511

    
512
///////////////////////////////////////////////////////////////////////////////////////////////////
513

    
514
  public static RubikObject getObject(String shortUpperName)
515
    {
516
    if( mThis==null ) mThis = new RubikObjectList();
517

    
518
    for(int i=0; i<mNumObjects; i++)
519
      {
520
      RubikObject object = mObjects.get(i);
521
      if( object.getUpperName().equals(shortUpperName) )
522
        {
523
        return object;
524
        }
525
      }
526

    
527
    return null;
528
    }
529

    
530
///////////////////////////////////////////////////////////////////////////////////////////////////
531

    
532
  public static int getNumObjects()
533
    {
534
    if( mThis==null ) mThis = new RubikObjectList();
535
    return mNumObjects;
536
    }
537

    
538
///////////////////////////////////////////////////////////////////////////////////////////////////
539

    
540
  public static int getOrdinal(String name)
541
    {
542
    if( mThis==null ) mThis = new RubikObjectList();
543

    
544
    String lowerName = name.toLowerCase(Locale.ENGLISH);
545

    
546
    for(int i=0; i<mNumObjects; i++)
547
      {
548
      RubikObject obj = mObjects.get(i);
549
      if( obj.getLowerName().equals(lowerName) ) return i;
550
      }
551

    
552
    return -1;
553
    }
554

    
555
///////////////////////////////////////////////////////////////////////////////////////////////////
556

    
557
  public static int getNumExtrasObjects()
558
    {
559
    return mNumExtras;
560
    }
561

    
562
///////////////////////////////////////////////////////////////////////////////////////////////////
563

    
564
  public static int getNumTutorialObjects()
565
    {
566
    return mNumExtras;
567
    }
568

    
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570

    
571
  public static int getObjectOrdinal(int extrasOrdinal)
572
    {
573
    for(int i=extrasOrdinal; i<mNumObjects; i++)
574
      {
575
      RubikObject object = getObject(i);
576
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
577
      if( extOrd==extrasOrdinal ) return i;
578
      }
579

    
580
    return -1;
581
    }
582

    
583
///////////////////////////////////////////////////////////////////////////////////////////////////
584

    
585
  public static int getExtrasOrdinal(int objectOrdinal)
586
    {
587
    RubikObject object = getObject(objectOrdinal);
588
    return object!=null ? object.getExtrasOrdinal() : -1;
589
    }
590

    
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592

    
593
  public static int getTutorialOrdinal(int objectOrdinal)
594
    {
595
    RubikObject object = getObject(objectOrdinal);
596
    return object!=null ? object.getExtrasOrdinal() : -1;
597
    }
598

    
599
///////////////////////////////////////////////////////////////////////////////////////////////////
600

    
601
  public static int getLocalObjectVersion(int objectOrdinal)
602
    {
603
    RubikObject object = getObject(objectOrdinal);
604
    return object!=null ? object.getObjectVersion() : -1;
605
    }
606

    
607
///////////////////////////////////////////////////////////////////////////////////////////////////
608

    
609
  public static int getLocalExtrasVersion(int objectOrdinal)
610
    {
611
    RubikObject object = getObject(objectOrdinal);
612
    return object!=null ? object.getExtrasVersion() : -1;
613
    }
614
}
(2-2/2)