Project

General

Profile

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

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

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 type = ListObjects.getObject(i);
88
      RubikObject obj = new RubikObject(type);
89
      mObjects.add(obj);
90
      mNumObjects++;
91

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

    
94
      if( obj.hasExtras() )
95
        {
96
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
97

    
98
        obj.setExtrasOrdinal(mNumExtras);
99
        mNumExtras++;
100
        }
101
      else
102
        {
103
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
104
        }
105
      }
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  private static boolean internalAddDownloadedObject(DownloadedObject object)
111
    {
112
    String name = object.shortName;
113

    
114
    for(RubikObject ro : mObjects )
115
      if( ro.getLowerName().equals(name) )
116
        {
117
        return ro.updateObject(object);
118
        }
119

    
120
    RubikObject obj = new RubikObject(object);
121
    mObjects.add(obj);
122
    mNumObjects++;
123

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

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

    
132
    if( obj.hasExtras() )
133
      {
134
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
135

    
136
      obj.setExtrasOrdinal(mNumExtras);
137
      mNumExtras++;
138
      }
139
    else
140
      {
141
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
142
      }
143

    
144
    return true;
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
  private static void restoreFreedObjects(SharedPreferences preferences)
150
    {
151
    mBoughtObjects = preferences.getString("rol_bought", "");
152

    
153
    if( SHOW_IAP_DEBUG )
154
      {
155
      android.util.Log.e("D", "bought objects: "+mBoughtObjects);
156
      }
157

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

    
172
        for( String obj : objs )
173
          {
174
          RubikObject o = getObject(obj);
175
          if( o!=null ) o.markFree();
176
          }
177
        }
178
      }
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182
// PUBLIC API
183

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

    
189
    for( DownloadedObject obj : mDownloadedObjects )
190
      {
191
      if( obj.shortName.equals(shortName) )
192
        {
193
        obj.icon  |= icon;
194
        obj.object|= object;
195
        obj.extras|= extras;
196

    
197
        if( !obj.object ) objectVersion=-1;
198
        if( !obj.extras ) extrasVersion=-1;
199

    
200
        obj.objectVersion = objectVersion;
201
        obj.extrasVersion = extrasVersion;
202

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

    
205
        return false;
206
        }
207
      }
208

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

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

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  public static boolean thereAreLockedObjects()
233
    {
234
    for(int i=0; i<mNumObjects; i++)
235
      {
236
      RubikObject o = mObjects.get(i);
237
      if( !o.isFree() ) return true;
238
      }
239

    
240
    return false;
241
    }
242

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

    
245
  public static boolean objectAlreadyBought(RubikObject object)
246
    {
247
    return ( object!=null && object.isFree() );
248
    }
249

    
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251
// calling PurchaseScreenPane charges the user.
252

    
253
  public static void buyAll()
254
    {
255
    mBoughtObjects = "*";
256
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "all objects marked as bought");
257

    
258
    for(int i=0; i<mNumObjects; i++)
259
      {
260
      RubikObject o = mObjects.get(i);
261
      o.markFree();
262
      }
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266
// calling PurchaseScreenPane charges the user.
267

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

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  public static void savePreferences(SharedPreferences.Editor editor)
283
    {
284
    int numDownloaded = mDownloadedObjects.size();
285

    
286
    if( numDownloaded>0 )
287
      {
288
      StringBuilder downloadedObjects = new StringBuilder();
289

    
290
      for(int i=0; i<numDownloaded; i++)
291
        {
292
        if( i>0 ) downloadedObjects.append(',');
293

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

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

    
321
    if( USE_IAP )
322
      {
323
      editor.putString("rol_bought", mBoughtObjects);
324

    
325
      if( SHOW_IAP_DEBUG )
326
        {
327
        android.util.Log.e("D", "saving bought objects: "+mBoughtObjects);
328
        }
329
      }
330
    }
331

    
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333

    
334
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
335
    {
336
    if( mThis==null ) mThis = new RubikObjectList();
337

    
338
    String downloaded = preferences.getString("rol_downloaded","");
339

    
340
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
341

    
342
    if( !downloaded.equals(""))
343
      {
344
      String[] dObjects = downloaded.split(",");
345

    
346
      for(String dObj : dObjects)
347
        {
348
        String[] parts = dObj.split(" ");
349
        int length = parts.length;
350

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

    
361
          int price;
362

    
363
          if( length==7 ) price=0;
364
          else
365
            {
366
            char c = parts[7].charAt(0);
367
            if( c=='t' )      price = 0;
368
            else if( c=='f' ) price = ListObjects.DEFAULT_PRICE_OF_OLD_OBJECTS;
369
            else              price = Integer.parseInt(parts[7]);
370
            }
371

    
372
          int scrambles = Integer.parseInt(scra);
373
          int oVersion  = Integer.parseInt(objV);
374
          int eVersion  = Integer.parseInt(extV);
375

    
376
          boolean bIcon = icon.equals("1");
377
          boolean bObje = obje.equals("1");
378
          boolean bExtr = extr.equals("1");
379

    
380
          addDownloadedObject(context,name,scrambles,price,oVersion,eVersion,bIcon,bObje,bExtr);
381
          }
382
        }
383
      }
384

    
385
    if( USE_IAP && justStarted ) restoreFreedObjects(preferences);
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  public static void firstUpgradeMarkAllSolvedAsFree()
391
    {
392
    RubikScores scores = RubikScores.getInstance();
393
    int numUnclaimed = scores.numberOfSolvedMAXes();
394

    
395
    if( numUnclaimed>0 )
396
      {
397
      int marked = markAllSolvedAsFree(scores);
398
      int stillUnclaimed = numUnclaimed-marked;
399
      if( stillUnclaimed>0) markObjectsAsFree(scores,stillUnclaimed);
400
      }
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  private static int markAllSolvedAsFree(RubikScores scores)
406
    {
407
    int numObjects = RubikObjectList.getNumObjects();
408
    int ret = 0;
409

    
410
    for(int obj=0; obj<numObjects; obj++)
411
      {
412
      RubikObject object = getObject(obj);
413

    
414
      if( object!=null && !object.isFree() && scores.isSolved(obj,RubikScores.LEVELS_SHOWN) )
415
        {
416
        markAsFree(object,scores);
417
        ret++;
418
        }
419
      }
420

    
421
    return ret;
422
    }
423

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

    
426
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
427
    {
428
    int numObjects = RubikObjectList.getNumObjects();
429

    
430
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
431
      {
432
      RubikObject object = getObject(obj);
433

    
434
      if( object!=null && !object.isFree() )
435
        {
436
        markAsFree(object,scores);
437
        numToBeMarked--;
438
        }
439
      }
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

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

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  public static RubikObject getObject(int ordinal)
458
    {
459
    if( mThis==null ) mThis = new RubikObjectList();
460
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
461
    }
462

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

    
465
  public static RubikObject getObject(String shortUpperName)
466
    {
467
    if( mThis==null ) mThis = new RubikObjectList();
468

    
469
    for(int i=0; i<mNumObjects; i++)
470
      {
471
      RubikObject object = mObjects.get(i);
472
      if( object.getUpperName().equals(shortUpperName) )
473
        {
474
        return object;
475
        }
476
      }
477

    
478
    return null;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  public static int getNumObjects()
484
    {
485
    if( mThis==null ) mThis = new RubikObjectList();
486
    return mNumObjects;
487
    }
488

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

    
491
  public static int getOrdinal(String name)
492
    {
493
    if( mThis==null ) mThis = new RubikObjectList();
494

    
495
    String lowerName = name.toLowerCase(Locale.ENGLISH);
496

    
497
    for(int i=0; i<mNumObjects; i++)
498
      {
499
      RubikObject obj = mObjects.get(i);
500
      if( obj.getLowerName().equals(lowerName) ) return i;
501
      }
502

    
503
    return -1;
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  public static int getNumExtrasObjects()
509
    {
510
    return mNumExtras;
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514

    
515
  public static int getNumTutorialObjects()
516
    {
517
    return mNumExtras;
518
    }
519

    
520
///////////////////////////////////////////////////////////////////////////////////////////////////
521

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

    
531
    return -1;
532
    }
533

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

    
536
  public static int getExtrasOrdinal(int objectOrdinal)
537
    {
538
    RubikObject object = getObject(objectOrdinal);
539
    return object!=null ? object.getExtrasOrdinal() : -1;
540
    }
541

    
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543

    
544
  public static int getTutorialOrdinal(int objectOrdinal)
545
    {
546
    RubikObject object = getObject(objectOrdinal);
547
    return object!=null ? object.getExtrasOrdinal() : -1;
548
    }
549

    
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551

    
552
  public static int getLocalObjectVersion(int objectOrdinal)
553
    {
554
    RubikObject object = getObject(objectOrdinal);
555
    return object!=null ? object.getObjectVersion() : -1;
556
    }
557

    
558
///////////////////////////////////////////////////////////////////////////////////////////////////
559

    
560
  public static int getLocalExtrasVersion(int objectOrdinal)
561
    {
562
    RubikObject object = getObject(objectOrdinal);
563
    return object!=null ? object.getExtrasVersion() : -1;
564
    }
565
}
(2-2/2)