Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 50a82b23

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.metadata.ListObjects;
21

    
22
import static org.distorted.objectlib.metadata.ListObjects.NUM_OBJECTS;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

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

    
32
  private static RubikObjectList mThis;
33
  private static int mNumObjects;
34
  private static int mNumExtras;
35
  private static ArrayList<RubikObject> mObjects;
36

    
37
  public static class DownloadedObject
38
    {
39
    String shortName;
40
    boolean icon,object,extras;
41
    int numScrambles, objectVersion, extrasVersion, price;
42
    int category, year;
43
    float difficulty;
44
    String author;
45

    
46
    DownloadedObject(String sName, int scrambles, int pr, int oVersion, int eVersion, boolean i,
47
                     boolean o, boolean e, float diff, int cat, int y, String a)
48
      {
49
      shortName     = sName;
50
      numScrambles  = scrambles;
51
      price         = pr;
52
      objectVersion = oVersion;
53
      extrasVersion = eVersion;
54
      difficulty    = diff;
55
      category      = cat;
56
      year          = y;
57
      author        = a;
58

    
59
      icon   = i;
60
      object = o;
61
      extras = e;
62
      }
63
    }
64

    
65
  private static ArrayList<DownloadedObject> mDownloadedObjects;
66
  private static String mBoughtObjects;
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  private RubikObjectList()
71
    {
72
    mNumObjects        = 0;
73
    mNumExtras         = 0;
74
    mObjects           = new ArrayList<>();
75
    mDownloadedObjects = new ArrayList<>();
76

    
77
    createBuiltinObjects();
78
    }
79

    
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81

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

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
  private void createBuiltinObjects()
92
    {
93
    for(int i=0; i<NUM_OBJECTS; i++)
94
      {
95
      ListObjects lo = ListObjects.getObject(i);
96

    
97
      if( lo.isEnabled() )
98
        {
99
        RubikObject obj = new RubikObject(lo);
100
        mObjects.add(obj);
101
        mNumObjects++;
102

    
103
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "creating local object "+lo.name() );
104

    
105
        if( obj.hasExtras() )
106
          {
107
          if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
108

    
109
          obj.setExtrasOrdinal(mNumExtras);
110
          mNumExtras++;
111
          }
112
        else
113
          {
114
          if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
115
          }
116
        }
117
      }
118
    }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
  private static boolean internalAddDownloadedObject(DownloadedObject object)
123
    {
124
    String name = object.shortName;
125

    
126
    for(RubikObject ro : mObjects )
127
      if( ro.getLowerName().equals(name) )
128
        {
129
        return ro.updateObject(object);
130
        }
131

    
132
    RubikObject obj = new RubikObject(object);
133
    mObjects.add(obj);
134
    mNumObjects++;
135

    
136
    if( USE_IAP && !obj.isFree() && allObjectsUnlocked() )
137
      {
138
      if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "everything unlocked, so setting downloaded object free: "+obj.getUpperName() );
139
      obj.markFree();
140
      }
141

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

    
144
    if( obj.hasExtras() )
145
      {
146
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
147

    
148
      obj.setExtrasOrdinal(mNumExtras);
149
      mNumExtras++;
150
      }
151
    else
152
      {
153
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
154
      }
155

    
156
    return true;
157
    }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
  private static void restoreFreedObjects(SharedPreferences preferences)
162
    {
163
    mBoughtObjects = preferences.getString("rol_bought", "");
164

    
165
    if( SHOW_IAP_DEBUG )
166
      {
167
      android.util.Log.e("D", "bought objects: "+mBoughtObjects);
168
      }
169

    
170
    if( mBoughtObjects.length()>0 )
171
      {
172
      if( mBoughtObjects.charAt(0)=='*' )
173
        {
174
        for(int i=0; i<mNumObjects; i++)
175
          {
176
          RubikObject o = mObjects.get(i);
177
          if( o!=null ) o.markFree();
178
          }
179
        }
180
      else
181
        {
182
        String[] objs = mBoughtObjects.split(",");
183

    
184
        for( String obj : objs )
185
          {
186
          RubikObject o = getObject(obj);
187
          if( o!=null ) o.markFree();
188
          }
189
        }
190
      }
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
// PUBLIC API
195

    
196
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, int price, int objectVersion,
197
                                         int extrasVersion, boolean icon, boolean object, boolean extras, float diff, int category, int year, String author)
198
    {
199
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
200

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

    
209
        if( !obj.object ) objectVersion=-1;
210
        if( !obj.extras ) extrasVersion=-1;
211

    
212
        obj.objectVersion = objectVersion;
213
        obj.extrasVersion = extrasVersion;
214

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

    
217
        return false;
218
        }
219
      }
220

    
221
    if( !object ) objectVersion=-1;
222
    if( !extras ) extrasVersion=-1;
223

    
224
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,price,objectVersion,extrasVersion,icon,object,extras,diff,category,year,author);
225
    if ( internalAddDownloadedObject(obj) )
226
      {
227
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "Adding new downloaded object "+shortName+" icon="+obj.icon+" object="+obj.object+" extras="+obj.extras);
228
      mDownloadedObjects.add(obj);
229
      return true;
230
      }
231
    else
232
      {
233
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" is already built-in, deleting");
234
      RubikFiles files = RubikFiles.getInstance();
235
      files.deleteIcon(context,shortName);
236
      files.deleteJsonObject(context,shortName);
237
      files.deleteJsonExtras(context,shortName);
238
      return false;
239
      }
240
    }
241

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

    
244
  public static boolean thereAreLockedObjects()
245
    {
246
    for(int i=0; i<mNumObjects; i++)
247
      {
248
      RubikObject o = mObjects.get(i);
249
      if( !o.isFree() ) return true;
250
      }
251

    
252
    return false;
253
    }
254

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

    
257
  public static boolean objectAlreadyBought(RubikObject object)
258
    {
259
    return ( object!=null && object.isFree() );
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
// calling PurchaseScreenPane charges the user.
264

    
265
  public static void buyAll()
266
    {
267
    mBoughtObjects = "*";
268
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
269

    
270
    for(int i=0; i<mNumObjects; i++)
271
      {
272
      RubikObject o = mObjects.get(i);
273
      o.markFree();
274
      }
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278
// calling PurchaseScreenPane charges the user.
279

    
280
  public static void buyObject(RubikObject object)
281
    {
282
    if( object!=null && !object.isFree() )
283
      {
284
      String shortName = object.getUpperName();
285
      if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+shortName+" marked as bought");
286
      object.markFree();
287
      String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
288
      mBoughtObjects += add;
289
      }
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  public static void savePreferences(SharedPreferences.Editor editor)
295
    {
296
    int numDownloaded = mDownloadedObjects.size();
297

    
298
    if( numDownloaded>0 )
299
      {
300
      StringBuilder downloadedObjects = new StringBuilder();
301

    
302
      for(int i=0; i<numDownloaded; i++)
303
        {
304
        if( i>0 ) downloadedObjects.append(',');
305

    
306
        DownloadedObject object = mDownloadedObjects.get(i);
307
        downloadedObjects.append(object.shortName);
308
        downloadedObjects.append(' ');
309
        downloadedObjects.append(object.numScrambles);
310
        downloadedObjects.append(' ');
311
        downloadedObjects.append(object.objectVersion);
312
        downloadedObjects.append(' ');
313
        downloadedObjects.append(object.extrasVersion);
314
        downloadedObjects.append(' ');
315
        downloadedObjects.append(object.icon   ? "1":"0");
316
        downloadedObjects.append(' ');
317
        downloadedObjects.append(object.object ? "1":"0");
318
        downloadedObjects.append(' ');
319
        downloadedObjects.append(object.extras ? "1":"0");
320
        downloadedObjects.append(' ');
321
        downloadedObjects.append(object.difficulty);
322
        downloadedObjects.append(' ');
323
        downloadedObjects.append(object.category);
324
        downloadedObjects.append(' ');
325
        downloadedObjects.append(object.year);
326
        downloadedObjects.append(' ');
327
        downloadedObjects.append(object.author.replace(' ','_'));
328
        downloadedObjects.append(' ');
329
        downloadedObjects.append(object.price);
330
        }
331

    
332
      String objects = downloadedObjects.toString();
333
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "saving: "+objects);
334
      editor.putString("rol_downloaded", objects );
335
      }
336
    else
337
      {
338
      editor.putString("rol_downloaded", "" );
339
      }
340

    
341
    if( USE_IAP )
342
      {
343
      editor.putString("rol_bought", mBoughtObjects);
344

    
345
      if( SHOW_IAP_DEBUG )
346
        {
347
        android.util.Log.e("D", "saving bought objects: "+mBoughtObjects);
348
        }
349
      }
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
355
    {
356
    if( mThis==null ) mThis = new RubikObjectList();
357

    
358
    String downloaded = preferences.getString("rol_downloaded","");
359

    
360
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
361

    
362
    if( !downloaded.equals(""))
363
      {
364
      String[] dObjects = downloaded.split(",");
365

    
366
      for(String dObj : dObjects)
367
        {
368
        String[] parts = dObj.split(" ");
369
        int length = parts.length;
370

    
371
        if( length>=7 )
372
          {
373
          String name = parts[0];
374
          String scra = parts[1];
375
          String objV = parts[2];
376
          String extV = parts[3];
377
          String icon = parts[4];
378
          String obje = parts[5];
379
          String extr = parts[6];
380

    
381
          int price=0,category=0,year=0;
382
          float diff=0.0f;
383
          String author="";
384

    
385
          if( length>=11 )
386
            {
387
            diff     = Float.parseFloat(parts[7]);
388
            category = Integer.parseInt(parts[8]);
389
            year     = Integer.parseInt(parts[9]);
390
            author   = parts[10].replace('_',' ');
391
            }
392
          if( length>=12 )
393
            {
394
            char c = parts[11].charAt(0);
395
            if( c=='t' )      price = 0;
396
            else if( c=='f' ) price = ListObjects.DEFAULT_PRICE_OF_OLD_OBJECTS;
397
            else              price = Integer.parseInt(parts[11]);
398
            }
399

    
400
          int scrambles = Integer.parseInt(scra);
401
          int oVersion  = Integer.parseInt(objV);
402
          int eVersion  = Integer.parseInt(extV);
403

    
404
          boolean bIcon = icon.equals("1");
405
          boolean bObje = obje.equals("1");
406
          boolean bExtr = extr.equals("1");
407

    
408
          addDownloadedObject(context,name,scrambles,price,oVersion,eVersion,bIcon,bObje,bExtr,diff,category,year,author);
409
          }
410
        }
411
      }
412

    
413
    if( USE_IAP && justStarted ) restoreFreedObjects(preferences);
414
    }
415

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

    
418
  public static void firstUpgradeMarkAllSolvedAsFree()
419
    {
420
    RubikScores scores = RubikScores.getInstance();
421
    int numUnclaimed = scores.numberOfSolvedMAXes();
422

    
423
    if( numUnclaimed>0 )
424
      {
425
      int marked = markAllSolvedAsFree(scores);
426
      int stillUnclaimed = numUnclaimed-marked;
427
      if( stillUnclaimed>0) markObjectsAsFree(scores,stillUnclaimed);
428
      }
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  private static int markAllSolvedAsFree(RubikScores scores)
434
    {
435
    int numObjects = RubikObjectList.getNumObjects();
436
    int ret = 0;
437

    
438
    for(int obj=0; obj<numObjects; obj++)
439
      {
440
      RubikObject object = getObject(obj);
441

    
442
      if( object!=null && !object.isFree() && scores.isSolved(obj,RubikScores.LEVELS_SHOWN) )
443
        {
444
        markAsFree(object,scores);
445
        ret++;
446
        }
447
      }
448

    
449
    return ret;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
455
    {
456
    int numObjects = RubikObjectList.getNumObjects();
457

    
458
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
459
      {
460
      RubikObject object = getObject(obj);
461

    
462
      if( object!=null && !object.isFree() )
463
        {
464
        markAsFree(object,scores);
465
        numToBeMarked--;
466
        }
467
      }
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

    
472
  private static void markAsFree(RubikObject object, RubikScores scores)
473
    {
474
    String shortName = object.getUpperName();
475
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
476
    object.markFree();
477
    int price = object.getPrice();
478
    scores.changeNumStars(-price);
479
    String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
480
    mBoughtObjects += add;
481
    }
482

    
483
///////////////////////////////////////////////////////////////////////////////////////////////////
484

    
485
  public static RubikObject getObject(int ordinal)
486
    {
487
    if( mThis==null ) mThis = new RubikObjectList();
488
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
489
    }
490

    
491
///////////////////////////////////////////////////////////////////////////////////////////////////
492

    
493
  public static RubikObject getObject(String shortUpperName)
494
    {
495
    if( mThis==null ) mThis = new RubikObjectList();
496

    
497
    for(int i=0; i<mNumObjects; i++)
498
      {
499
      RubikObject object = mObjects.get(i);
500
      if( object.getUpperName().equals(shortUpperName) )
501
        {
502
        return object;
503
        }
504
      }
505

    
506
    return null;
507
    }
508

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

    
511
  public static int getNumObjects()
512
    {
513
    if( mThis==null ) mThis = new RubikObjectList();
514
    return mNumObjects;
515
    }
516

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

    
519
  public static int getOrdinal(String name)
520
    {
521
    if( mThis==null ) mThis = new RubikObjectList();
522

    
523
    String lowerName = name.toLowerCase(Locale.ENGLISH);
524

    
525
    for(int i=0; i<mNumObjects; i++)
526
      {
527
      RubikObject obj = mObjects.get(i);
528
      if( obj.getLowerName().equals(lowerName) ) return i;
529
      }
530

    
531
    return -1;
532
    }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
  public static int getNumExtrasObjects()
537
    {
538
    return mNumExtras;
539
    }
540

    
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542

    
543
  public static int getNumTutorialObjects()
544
    {
545
    return mNumExtras;
546
    }
547

    
548
///////////////////////////////////////////////////////////////////////////////////////////////////
549

    
550
  public static int getObjectOrdinal(int extrasOrdinal)
551
    {
552
    for(int i=extrasOrdinal; i<mNumObjects; i++)
553
      {
554
      RubikObject object = getObject(i);
555
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
556
      if( extOrd==extrasOrdinal ) return i;
557
      }
558

    
559
    return -1;
560
    }
561

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

    
564
  public static int getExtrasOrdinal(int objectOrdinal)
565
    {
566
    RubikObject object = getObject(objectOrdinal);
567
    return object!=null ? object.getExtrasOrdinal() : -1;
568
    }
569

    
570
///////////////////////////////////////////////////////////////////////////////////////////////////
571

    
572
  public static int getTutorialOrdinal(int objectOrdinal)
573
    {
574
    RubikObject object = getObject(objectOrdinal);
575
    return object!=null ? object.getExtrasOrdinal() : -1;
576
    }
577

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

    
580
  public static int getLocalObjectVersion(int objectOrdinal)
581
    {
582
    RubikObject object = getObject(objectOrdinal);
583
    return object!=null ? object.getObjectVersion() : -1;
584
    }
585

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

    
588
  public static int getLocalExtrasVersion(int objectOrdinal)
589
    {
590
    RubikObject object = getObject(objectOrdinal);
591
    return object!=null ? object.getExtrasVersion() : -1;
592
    }
593
}
(7-7/7)