Project

General

Profile

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

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

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.main_old.RubikActivity.SHOW_IAP_DEBUG;
24
import static org.distorted.main_old.RubikActivity.USE_IAP;
25
import static org.distorted.objectlib.main.TwistyObject.MESH_NICE;
26
import static org.distorted.objectlib.main.ObjectType.NUM_OBJECTS;
27
import static org.distorted.main_old.RubikActivity.SHOW_DOWNLOADED_DEBUG;
28
import static org.distorted.screens.RubikScreenPlay.LEVELS_SHOWN;
29

    
30
///////////////////////////////////////////////////////////////////////////////////////////////////
31

    
32
public class RubikObjectList
33
{
34
  public static final int DEF_OBJECT= ObjectConstants.CUBE_3;
35
  private static RubikObjectList mThis;
36
  private static int mNumObjects;
37
  private static int mNumExtras;
38
  private static ArrayList<RubikObject> mObjects;
39
  private static int mObject = DEF_OBJECT;
40

    
41
  public static class DownloadedObject
42
    {
43
    String shortName;
44
    boolean icon,object,extras;
45
    int numScrambles, objectVersion, extrasVersion, price;
46

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

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

    
61
  private static ArrayList<DownloadedObject> mDownloadedObjects;
62

    
63
  private static String mBoughtObjects;
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

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

    
74
    createBuiltinObjects();
75
    }
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

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

    
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87

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

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

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

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

    
113
///////////////////////////////////////////////////////////////////////////////////////////////////
114

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

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

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

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

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

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

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

    
149
    return true;
150
    }
151

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

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

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

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

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

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187
// PUBLIC API
188

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

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

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

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

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

    
210
        return false;
211
        }
212
      }
213

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

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

    
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

    
237
  public static void setMeshState(int ordinal, int state)
238
    {
239
    if( ordinal>=0 && ordinal<mNumObjects ) mObjects.get(ordinal).setMeshState(state);
240
    }
241

    
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

    
244
  public static int getMeshState(int ordinal)
245
    {
246
    return (ordinal>=0 && ordinal<mNumObjects) ? mObjects.get(ordinal).getMeshState() : MESH_NICE;
247
    }
248

    
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

    
251
  public static void saveMeshState(SharedPreferences.Editor editor)
252
    {
253
    for(int i=0; i<mNumObjects; i++)
254
      {
255
      RubikObject obj = getObject(i);
256

    
257
      if( obj!=null )
258
        {
259
        String name = obj.getUpperName();
260
        editor.putInt("rol_"+name, obj.getMeshState() );
261
        }
262
      }
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  public static boolean thereAreLockedObjects()
268
    {
269
    for(int i=0; i<mNumObjects; i++)
270
      {
271
      RubikObject o = mObjects.get(i);
272
      if( !o.isFree() ) return true;
273
      }
274

    
275
    return false;
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  public static boolean objectAlreadyBought(RubikObject object)
281
    {
282
    return ( object!=null && object.isFree() );
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286
// calling PurchaseScreenPane charges the user.
287

    
288
  public static void buyAll()
289
    {
290
    mBoughtObjects = "*";
291
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
292

    
293
    for(int i=0; i<mNumObjects; i++)
294
      {
295
      RubikObject o = mObjects.get(i);
296
      o.markFree();
297
      }
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301
// calling PurchaseScreenPane charges the user.
302

    
303
  public static void buyObject(RubikObject object)
304
    {
305
    if( object!=null && !object.isFree() )
306
      {
307
      String shortName = object.getUpperName();
308
      if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as bought");
309
      object.markFree();
310
      String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
311
      mBoughtObjects += add;
312
      }
313
    }
314

    
315
///////////////////////////////////////////////////////////////////////////////////////////////////
316

    
317
  public static void savePreferences(SharedPreferences.Editor editor)
318
    {
319
    RubikObject obj = getObject(mObject);
320
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
321

    
322
    int numDownloaded = mDownloadedObjects.size();
323

    
324
    if( numDownloaded>0 )
325
      {
326
      StringBuilder downloadedObjects = new StringBuilder();
327

    
328
      for(int i=0; i<numDownloaded; i++)
329
        {
330
        if( i>0 ) downloadedObjects.append(',');
331

    
332
        DownloadedObject object = mDownloadedObjects.get(i);
333
        downloadedObjects.append(object.shortName);
334
        downloadedObjects.append(' ');
335
        downloadedObjects.append(object.numScrambles);
336
        downloadedObjects.append(' ');
337
        downloadedObjects.append(object.objectVersion);
338
        downloadedObjects.append(' ');
339
        downloadedObjects.append(object.extrasVersion);
340
        downloadedObjects.append(' ');
341
        downloadedObjects.append(object.icon   ? "1":"0");
342
        downloadedObjects.append(' ');
343
        downloadedObjects.append(object.object ? "1":"0");
344
        downloadedObjects.append(' ');
345
        downloadedObjects.append(object.extras ? "1":"0");
346
        downloadedObjects.append(' ');
347
        downloadedObjects.append(object.price);
348
        }
349

    
350
      String objects = downloadedObjects.toString();
351
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
352
      editor.putString("rol_downloaded", objects );
353
      }
354
    else
355
      {
356
      editor.putString("rol_downloaded", "" );
357
      }
358

    
359
    if( USE_IAP )
360
      {
361
      editor.putString("rol_bought", mBoughtObjects);
362

    
363
      if( SHOW_IAP_DEBUG )
364
        {
365
        android.util.Log.e("D", "saving bought objects: "+mBoughtObjects);
366
        }
367
      }
368
    }
369

    
370
///////////////////////////////////////////////////////////////////////////////////////////////////
371

    
372
  public static void savePreferencesMinimal(SharedPreferences.Editor editor)
373
    {
374
    RubikObject obj = getObject(mObject);
375
    if( obj!=null ) editor.putString("rol_objName", obj.getUpperName() );
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
381
    {
382
    if( mThis==null ) mThis = new RubikObjectList();
383

    
384
    String downloaded = preferences.getString("rol_downloaded","");
385

    
386
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
387

    
388
    if( !downloaded.equals(""))
389
      {
390
      String[] dObjects = downloaded.split(",");
391

    
392
      for(String dObj : dObjects)
393
        {
394
        String[] parts = dObj.split(" ");
395
        int length = parts.length;
396

    
397
        if( length==7 || length==8 )
398
          {
399
          String name = parts[0];
400
          String scra = parts[1];
401
          String objV = parts[2];
402
          String extV = parts[3];
403
          String icon = parts[4];
404
          String obje = parts[5];
405
          String extr = parts[6];
406

    
407
          int price;
408

    
409
          if( length==7 ) price=0;
410
          else
411
            {
412
            char c = parts[7].charAt(0);
413
            if( c=='t' )      price = 0;
414
            else if( c=='f' ) price = ObjectType.DEFAULT_PRICE_OF_OLD_OBJECTS;
415
            else              price = Integer.parseInt(parts[7]);
416
            }
417

    
418
          int scrambles = Integer.parseInt(scra);
419
          int oVersion  = Integer.parseInt(objV);
420
          int eVersion  = Integer.parseInt(extV);
421

    
422
          boolean bIcon = icon.equals("1");
423
          boolean bObje = obje.equals("1");
424
          boolean bExtr = extr.equals("1");
425

    
426
          addDownloadedObject(context,name,scrambles,price,oVersion,eVersion,bIcon,bObje,bExtr);
427
          }
428
        }
429
      }
430

    
431
    RubikObject object = getObject(DEF_OBJECT);
432
    String defName = object==null ? "CUBE_3" : object.getUpperName();
433
    String objName= preferences.getString("rol_objName",defName);
434
    mObject = getOrdinal(objName);
435
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
436

    
437
    if( USE_IAP && justStarted ) restoreFreedObjects(preferences);
438
    }
439

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

    
442
  public static void restoreMeshState(SharedPreferences preferences)
443
    {
444
    for(int i=0; i<mNumObjects; i++)
445
      {
446
      RubikObject obj = getObject(i);
447

    
448
      if( obj!=null )
449
        {
450
        String name  = obj.getUpperName();
451
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
452
        obj.setMeshState(meshState);
453
        }
454
      }
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  public static void firstUpgradeMarkAllSolvedAsFree()
460
    {
461
    RubikScores scores = RubikScores.getInstance();
462
    int numUnclaimed = scores.numberOfSolvedMAXes();
463

    
464
    if( numUnclaimed>0 )
465
      {
466
      int marked = markAllSolvedAsFree(scores);
467
      int stillUnclaimed = numUnclaimed-marked;
468
      if( stillUnclaimed>0) markObjectsAsFree(scores,stillUnclaimed);
469
      }
470
    }
471

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

    
474
  private static int markAllSolvedAsFree(RubikScores scores)
475
    {
476
    int numObjects = RubikObjectList.getNumObjects();
477
    int ret = 0;
478

    
479
    for(int obj=0; obj<numObjects; obj++)
480
      {
481
      RubikObject object = getObject(obj);
482

    
483
      if( object!=null && !object.isFree() && scores.isSolved(obj,LEVELS_SHOWN) )
484
        {
485
        markAsFree(object,scores);
486
        ret++;
487
        }
488
      }
489

    
490
    return ret;
491
    }
492

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

    
495
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
496
    {
497
    int numObjects = RubikObjectList.getNumObjects();
498

    
499
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
500
      {
501
      RubikObject object = getObject(obj);
502

    
503
      if( object!=null && !object.isFree() )
504
        {
505
        markAsFree(object,scores);
506
        numToBeMarked--;
507
        }
508
      }
509
    }
510

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

    
513
  private static void markAsFree(RubikObject object, RubikScores scores)
514
    {
515
    String shortName = object.getUpperName();
516
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
517
    object.markFree();
518
    int price = object.getPrice();
519
    scores.changeNumStars(-price);
520
    String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
521
    mBoughtObjects += add;
522
    }
523

    
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525

    
526
  public static boolean setCurrObject(int ordinal)
527
    {
528
    if( mObject!=ordinal )
529
      {
530
      mObject = ordinal;
531
      return true;
532
      }
533

    
534
    return false;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public static int getCurrObject()
540
    {
541
    return mObject;
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

    
546
  public static String getCurrentName()
547
    {
548
    RubikObject object = mObjects.get(mObject);
549
    return object==null ? "" : object.getUpperName();
550
    }
551

    
552
///////////////////////////////////////////////////////////////////////////////////////////////////
553

    
554
  public static RubikObject getObject(int ordinal)
555
    {
556
    if( mThis==null ) mThis = new RubikObjectList();
557
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
558
    }
559

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
  public static RubikObject getObject(String shortUpperName)
563
    {
564
    if( mThis==null ) mThis = new RubikObjectList();
565

    
566
    for(int i=0; i<mNumObjects; i++)
567
      {
568
      RubikObject object = mObjects.get(i);
569
      if( object.getUpperName().equals(shortUpperName) )
570
        {
571
        return object;
572
        }
573
      }
574

    
575
    return null;
576
    }
577

    
578
///////////////////////////////////////////////////////////////////////////////////////////////////
579

    
580
  public static int getNumObjects()
581
    {
582
    if( mThis==null ) mThis = new RubikObjectList();
583
    return mNumObjects;
584
    }
585

    
586
///////////////////////////////////////////////////////////////////////////////////////////////////
587

    
588
  public static int getOrdinal(String name)
589
    {
590
    if( mThis==null ) mThis = new RubikObjectList();
591

    
592
    String lowerName = name.toLowerCase(Locale.ENGLISH);
593

    
594
    for(int i=0; i<mNumObjects; i++)
595
      {
596
      RubikObject obj = mObjects.get(i);
597
      if( obj.getLowerName().equals(lowerName) ) return i;
598
      }
599

    
600
    return -1;
601
    }
602

    
603
///////////////////////////////////////////////////////////////////////////////////////////////////
604

    
605
  public static int getNumExtrasObjects()
606
    {
607
    return mNumExtras;
608
    }
609

    
610
///////////////////////////////////////////////////////////////////////////////////////////////////
611

    
612
  public static int getNumTutorialObjects()
613
    {
614
    return mNumExtras;
615
    }
616

    
617
///////////////////////////////////////////////////////////////////////////////////////////////////
618

    
619
  public static int getObjectOrdinal(int extrasOrdinal)
620
    {
621
    for(int i=extrasOrdinal; i<mNumObjects; i++)
622
      {
623
      RubikObject object = getObject(i);
624
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
625
      if( extOrd==extrasOrdinal ) return i;
626
      }
627

    
628
    return -1;
629
    }
630

    
631
///////////////////////////////////////////////////////////////////////////////////////////////////
632

    
633
  public static int getExtrasOrdinal(int objectOrdinal)
634
    {
635
    RubikObject object = getObject(objectOrdinal);
636
    return object!=null ? object.getExtrasOrdinal() : -1;
637
    }
638

    
639
///////////////////////////////////////////////////////////////////////////////////////////////////
640

    
641
  public static int getTutorialOrdinal(int objectOrdinal)
642
    {
643
    RubikObject object = getObject(objectOrdinal);
644
    return object!=null ? object.getExtrasOrdinal() : -1;
645
    }
646

    
647
///////////////////////////////////////////////////////////////////////////////////////////////////
648

    
649
  public static int getLocalObjectVersion(int objectOrdinal)
650
    {
651
    RubikObject object = getObject(objectOrdinal);
652
    return object!=null ? object.getObjectVersion() : -1;
653
    }
654

    
655
///////////////////////////////////////////////////////////////////////////////////////////////////
656

    
657
  public static int getLocalExtrasVersion(int objectOrdinal)
658
    {
659
    RubikObject object = getObject(objectOrdinal);
660
    return object!=null ? object.getExtrasVersion() : -1;
661
    }
662
}
(2-2/2)