Project

General

Profile

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

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

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

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

    
51
      icon   = i;
52
      object = o;
53
      extras = e;
54
      }
55
    }
56

    
57
  private static ArrayList<DownloadedObject> mDownloadedObjects;
58
  private static String mBoughtObjects;
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  private RubikObjectList()
63
    {
64
    mNumObjects        = 0;
65
    mNumExtras         = 0;
66
    mObjects           = new ArrayList<>();
67
    mDownloadedObjects = new ArrayList<>();
68

    
69
    createBuiltinObjects();
70
    }
71

    
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

    
74
  private static boolean allObjectsUnlocked()
75
    {
76
    return mBoughtObjects!=null       &&
77
           mBoughtObjects.length()>0  &&
78
           mBoughtObjects.charAt(0)=='*';
79
    }
80

    
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

    
83
  private void createBuiltinObjects()
84
    {
85
    for(int i=0; i<NUM_OBJECTS; i++)
86
      {
87
      ListObjects lo = ListObjects.getObject(i);
88

    
89
      if( lo.isEnabled() )
90
        {
91
        RubikObject obj = new RubikObject(lo);
92
        mObjects.add(obj);
93
        mNumObjects++;
94

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

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

    
101
          obj.setExtrasOrdinal(mNumExtras);
102
          mNumExtras++;
103
          }
104
        else
105
          {
106
          if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
107
          }
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
    int numDownloaded = mDownloadedObjects.size();
289

    
290
    if( numDownloaded>0 )
291
      {
292
      StringBuilder downloadedObjects = new StringBuilder();
293

    
294
      for(int i=0; i<numDownloaded; i++)
295
        {
296
        if( i>0 ) downloadedObjects.append(',');
297

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

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

    
325
    if( USE_IAP )
326
      {
327
      editor.putString("rol_bought", mBoughtObjects);
328

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

    
336
///////////////////////////////////////////////////////////////////////////////////////////////////
337

    
338
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
339
    {
340
    if( mThis==null ) mThis = new RubikObjectList();
341

    
342
    String downloaded = preferences.getString("rol_downloaded","");
343

    
344
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
345

    
346
    if( !downloaded.equals(""))
347
      {
348
      String[] dObjects = downloaded.split(",");
349

    
350
      for(String dObj : dObjects)
351
        {
352
        String[] parts = dObj.split(" ");
353
        int length = parts.length;
354

    
355
        if( length==7 || length==8 )
356
          {
357
          String name = parts[0];
358
          String scra = parts[1];
359
          String objV = parts[2];
360
          String extV = parts[3];
361
          String icon = parts[4];
362
          String obje = parts[5];
363
          String extr = parts[6];
364

    
365
          int price;
366

    
367
          if( length==7 ) price=0;
368
          else
369
            {
370
            char c = parts[7].charAt(0);
371
            if( c=='t' )      price = 0;
372
            else if( c=='f' ) price = ListObjects.DEFAULT_PRICE_OF_OLD_OBJECTS;
373
            else              price = Integer.parseInt(parts[7]);
374
            }
375

    
376
          int scrambles = Integer.parseInt(scra);
377
          int oVersion  = Integer.parseInt(objV);
378
          int eVersion  = Integer.parseInt(extV);
379

    
380
          boolean bIcon = icon.equals("1");
381
          boolean bObje = obje.equals("1");
382
          boolean bExtr = extr.equals("1");
383

    
384
          addDownloadedObject(context,name,scrambles,price,oVersion,eVersion,bIcon,bObje,bExtr);
385
          }
386
        }
387
      }
388

    
389
    if( USE_IAP && justStarted ) restoreFreedObjects(preferences);
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

    
394
  public static void firstUpgradeMarkAllSolvedAsFree()
395
    {
396
    RubikScores scores = RubikScores.getInstance();
397
    int numUnclaimed = scores.numberOfSolvedMAXes();
398

    
399
    if( numUnclaimed>0 )
400
      {
401
      int marked = markAllSolvedAsFree(scores);
402
      int stillUnclaimed = numUnclaimed-marked;
403
      if( stillUnclaimed>0) markObjectsAsFree(scores,stillUnclaimed);
404
      }
405
    }
406

    
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

    
409
  private static int markAllSolvedAsFree(RubikScores scores)
410
    {
411
    int numObjects = RubikObjectList.getNumObjects();
412
    int ret = 0;
413

    
414
    for(int obj=0; obj<numObjects; obj++)
415
      {
416
      RubikObject object = getObject(obj);
417

    
418
      if( object!=null && !object.isFree() && scores.isSolved(obj,RubikScores.LEVELS_SHOWN) )
419
        {
420
        markAsFree(object,scores);
421
        ret++;
422
        }
423
      }
424

    
425
    return ret;
426
    }
427

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
431
    {
432
    int numObjects = RubikObjectList.getNumObjects();
433

    
434
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
435
      {
436
      RubikObject object = getObject(obj);
437

    
438
      if( object!=null && !object.isFree() )
439
        {
440
        markAsFree(object,scores);
441
        numToBeMarked--;
442
        }
443
      }
444
    }
445

    
446
///////////////////////////////////////////////////////////////////////////////////////////////////
447

    
448
  private static void markAsFree(RubikObject object, RubikScores scores)
449
    {
450
    String shortName = object.getUpperName();
451
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
452
    object.markFree();
453
    int price = object.getPrice();
454
    scores.changeNumStars(-price);
455
    String add = mBoughtObjects.length()==0 ? shortName : (","+shortName);
456
    mBoughtObjects += add;
457
    }
458

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460

    
461
  public static RubikObject getObject(int ordinal)
462
    {
463
    if( mThis==null ) mThis = new RubikObjectList();
464
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
465
    }
466

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

    
469
  public static RubikObject getObject(String shortUpperName)
470
    {
471
    if( mThis==null ) mThis = new RubikObjectList();
472

    
473
    for(int i=0; i<mNumObjects; i++)
474
      {
475
      RubikObject object = mObjects.get(i);
476
      if( object.getUpperName().equals(shortUpperName) )
477
        {
478
        return object;
479
        }
480
      }
481

    
482
    return null;
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public static int getNumObjects()
488
    {
489
    if( mThis==null ) mThis = new RubikObjectList();
490
    return mNumObjects;
491
    }
492

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

    
495
  public static int getOrdinal(String name)
496
    {
497
    if( mThis==null ) mThis = new RubikObjectList();
498

    
499
    String lowerName = name.toLowerCase(Locale.ENGLISH);
500

    
501
    for(int i=0; i<mNumObjects; i++)
502
      {
503
      RubikObject obj = mObjects.get(i);
504
      if( obj.getLowerName().equals(lowerName) ) return i;
505
      }
506

    
507
    return -1;
508
    }
509

    
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

    
512
  public static int getNumExtrasObjects()
513
    {
514
    return mNumExtras;
515
    }
516

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

    
519
  public static int getNumTutorialObjects()
520
    {
521
    return mNumExtras;
522
    }
523

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

    
526
  public static int getObjectOrdinal(int extrasOrdinal)
527
    {
528
    for(int i=extrasOrdinal; i<mNumObjects; i++)
529
      {
530
      RubikObject object = getObject(i);
531
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
532
      if( extOrd==extrasOrdinal ) return i;
533
      }
534

    
535
    return -1;
536
    }
537

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

    
540
  public static int getExtrasOrdinal(int objectOrdinal)
541
    {
542
    RubikObject object = getObject(objectOrdinal);
543
    return object!=null ? object.getExtrasOrdinal() : -1;
544
    }
545

    
546
///////////////////////////////////////////////////////////////////////////////////////////////////
547

    
548
  public static int getTutorialOrdinal(int objectOrdinal)
549
    {
550
    RubikObject object = getObject(objectOrdinal);
551
    return object!=null ? object.getExtrasOrdinal() : -1;
552
    }
553

    
554
///////////////////////////////////////////////////////////////////////////////////////////////////
555

    
556
  public static int getLocalObjectVersion(int objectOrdinal)
557
    {
558
    RubikObject object = getObject(objectOrdinal);
559
    return object!=null ? object.getObjectVersion() : -1;
560
    }
561

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

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