Project

General

Profile

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

magiccube / src / main / java / org / distorted / objects / RubikObjectList.java @ 43382be6

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.main.RubikActivity;
21
import org.distorted.objectlib.main.ObjectSignatures;
22
import org.distorted.objectlib.main.ObjectType;
23

    
24
import static org.distorted.main.RubikActivity.SHOW_IAP_DEBUG;
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.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= ObjectSignatures.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, objectMinor, extrasMinor, price;
46

    
47
    DownloadedObject(String sName, int scrambles, int pr, int oMinor, int eMinor, boolean i, boolean o, boolean e)
48
      {
49
      shortName   = sName;
50
      numScrambles= scrambles;
51
      price       = pr;
52
      objectMinor = oMinor;
53
      extrasMinor = eMinor;
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 void createBuiltinObjects()
80
    {
81
    for(int i=0; i<NUM_OBJECTS; i++)
82
      {
83
      ObjectType type = ObjectType.getObject(i);
84
      RubikObject obj = new RubikObject(type);
85
      mObjects.add(obj);
86
      mNumObjects++;
87

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

    
90
      if( obj.hasExtras() )
91
        {
92
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
93

    
94
        obj.setExtrasOrdinal(mNumExtras);
95
        mNumExtras++;
96
        }
97
      else
98
        {
99
        if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
100
        }
101
      }
102
    }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
  private static boolean internalAddDownloadedObject(DownloadedObject object)
107
    {
108
    String name = object.shortName;
109

    
110
    for(RubikObject ro : mObjects )
111
      if( ro.getLowerName().equals(name) )
112
        {
113
        return ro.updateObject(object);
114
        }
115

    
116
    RubikObject obj = new RubikObject(object);
117
    mObjects.add(obj);
118
    mNumObjects++;
119

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

    
122
    if( obj.hasExtras() )
123
      {
124
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "has extras "+mNumExtras );
125

    
126
      obj.setExtrasOrdinal(mNumExtras);
127
      mNumExtras++;
128
      }
129
    else
130
      {
131
      if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "no extras");
132
      }
133

    
134
    return true;
135
    }
136

    
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

    
139
  private static void restoreFreedObjects(SharedPreferences preferences)
140
    {
141
    mBoughtObjects = preferences.getString("rol_bought", "");
142

    
143
    if( SHOW_IAP_DEBUG )
144
      {
145
      android.util.Log.e("D", "bought objects: "+mBoughtObjects);
146
      }
147

    
148
    if( mBoughtObjects.length()>0 )
149
      {
150
      if( mBoughtObjects.charAt(0)=='*' )
151
        {
152
        for(int i=0; i<mNumObjects; i++)
153
          {
154
          RubikObject o = mObjects.get(i);
155
          if( o!=null ) o.markFree();
156
          }
157
        }
158
      else
159
        {
160
        String[] objs = mBoughtObjects.split(",");
161

    
162
        for( String obj : objs )
163
          {
164
          RubikObject o = getObject(obj);
165
          if( o!=null ) o.markFree();
166
          }
167
        }
168
      }
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172
// PUBLIC API
173

    
174
  public static boolean addDownloadedObject(Context context, String shortName, int numScrambles, int price, int objectMinor,
175
                                         int extrasMinor, boolean icon, boolean object, boolean extras)
176
    {
177
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", "New downloaded object "+shortName+" icon="+icon+" object="+object+" extras="+extras);
178

    
179
    for( DownloadedObject obj : mDownloadedObjects )
180
      {
181
      if( obj.shortName.equals(shortName) )
182
        {
183
        obj.icon  |= icon;
184
        obj.object|= object;
185
        obj.extras|= extras;
186

    
187
        if( !obj.object ) objectMinor=-1;
188
        if( !obj.extras ) extrasMinor=-1;
189

    
190
        obj.objectMinor = objectMinor;
191
        obj.extrasMinor = extrasMinor;
192

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

    
195
        try
196
          {
197
          RubikActivity ract = (RubikActivity)context;
198
          ract.reloadObject(shortName);
199
          }
200
        catch(Exception ex)
201
          {
202
          android.util.Log.e("D", "exception trying to reload object: "+ex.getMessage() );
203
          }
204

    
205
        return false;
206
        }
207
      }
208

    
209
    if( !object ) objectMinor=-1;
210
    if( !extras ) extrasMinor=-1;
211

    
212
    DownloadedObject obj = new DownloadedObject(shortName,numScrambles,price,objectMinor,extrasMinor,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 void setMeshState(int ordinal, int state)
233
    {
234
    if( ordinal>=0 && ordinal<mNumObjects ) mObjects.get(ordinal).setMeshState(state);
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  public static int getMeshState(int ordinal)
240
    {
241
    return (ordinal>=0 && ordinal<mNumObjects) ? mObjects.get(ordinal).getMeshState() : MESH_NICE;
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  public static void saveMeshState(SharedPreferences.Editor editor)
247
    {
248
    for(int i=0; i<mNumObjects; i++)
249
      {
250
      RubikObject obj = getObject(i);
251

    
252
      if( obj!=null )
253
        {
254
        String name = obj.getUpperName();
255
        editor.putInt("rol_"+name, obj.getMeshState() );
256
        }
257
      }
258
    }
259

    
260
///////////////////////////////////////////////////////////////////////////////////////////////////
261

    
262
  public static boolean allAlreadyBought()
263
    {
264
    return mBoughtObjects.equals("*");
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

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

    
277
    return false;
278
    }
279

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

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

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288
// calling PurchaseScreenPane charges the user.
289

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

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

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303
// calling PurchaseScreenPane charges the user.
304

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

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

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

    
324
    int numDownloaded = mDownloadedObjects.size();
325

    
326
    if( numDownloaded>0 )
327
      {
328
      StringBuilder downloadedObjects = new StringBuilder();
329

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

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

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

    
361
    if( RubikActivity.USE_IAP )
362
      {
363
      editor.putString("rol_bought", mBoughtObjects);
364

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

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  public static void restorePreferences(Context context, SharedPreferences preferences, boolean justStarted)
375
    {
376
    if( mThis==null ) mThis = new RubikObjectList();
377

    
378
    String downloaded = preferences.getString("rol_downloaded","");
379

    
380
    if( SHOW_DOWNLOADED_DEBUG ) android.util.Log.e("D", downloaded);
381

    
382
    if( !downloaded.equals(""))
383
      {
384
      String[] dObjects = downloaded.split(",");
385

    
386
      for(String dObj : dObjects)
387
        {
388
        String[] parts = dObj.split(" ");
389
        int length = parts.length;
390

    
391
        if( length==7 || length==8 )
392
          {
393
          String name = parts[0];
394
          String scra = parts[1];
395
          String objM = parts[2];
396
          String extM = parts[3];
397
          String icon = parts[4];
398
          String obje = parts[5];
399
          String extr = parts[6];
400

    
401
          int price;
402

    
403
          if( length==7 ) price=0;
404
          else
405
            {
406
            char c = parts[7].charAt(0);
407
            if( c=='t' )      price = 0;
408
            else if( c=='f' ) price = ObjectType.DEFAULT_PRICE_OF_OLD_OBJECTS;
409
            else              price = Integer.parseInt(parts[7]);
410
            }
411

    
412
          int scrambles = Integer.parseInt(scra);
413
          int oMinor    = Integer.parseInt(objM);
414
          int eMinor    = Integer.parseInt(extM);
415

    
416
          boolean bIcon = icon.equals("1");
417
          boolean bObje = obje.equals("1");
418
          boolean bExtr = extr.equals("1");
419

    
420
          addDownloadedObject(context,name,scrambles,price,oMinor,eMinor,bIcon,bObje,bExtr);
421
          }
422
        }
423
      }
424

    
425
    RubikObject object = getObject(DEF_OBJECT);
426
    String defName = object==null ? "CUBE_3" : object.getUpperName();
427
    String objName= preferences.getString("rol_objName",defName);
428
    mObject = getOrdinal(objName);
429
    if( mObject<0 || mObject>=mNumObjects ) mObject = DEF_OBJECT;
430

    
431
    if( RubikActivity.USE_IAP && justStarted ) restoreFreedObjects(preferences);
432
    }
433

    
434
///////////////////////////////////////////////////////////////////////////////////////////////////
435

    
436
  public static void restoreMeshState(SharedPreferences preferences)
437
    {
438
    for(int i=0; i<mNumObjects; i++)
439
      {
440
      RubikObject obj = getObject(i);
441

    
442
      if( obj!=null )
443
        {
444
        String name  = obj.getUpperName();
445
        int meshState= preferences.getInt("rol_"+name,MESH_NICE);
446
        obj.setMeshState(meshState);
447
        }
448
      }
449
    }
450

    
451
///////////////////////////////////////////////////////////////////////////////////////////////////
452

    
453
  public static void firstUpgradeMarkAllSolvedAsFree()
454
    {
455
    RubikScores scores = RubikScores.getInstance();
456
    int numUnclaimed = scores.numberOfSolvedMAXes();
457

    
458
    if( numUnclaimed>0 )
459
      {
460
      int marked = markAllSolvedAsFree(scores);
461
      int stillUnclaimed = numUnclaimed-marked;
462
      if( stillUnclaimed>0) markObjectsAsFree(scores,stillUnclaimed);
463
      }
464
    }
465

    
466
///////////////////////////////////////////////////////////////////////////////////////////////////
467

    
468
  private static int markAllSolvedAsFree(RubikScores scores)
469
    {
470
    int numObjects = RubikObjectList.getNumObjects();
471
    int ret = 0;
472

    
473
    for(int obj=0; obj<numObjects; obj++)
474
      {
475
      RubikObject object = getObject(obj);
476

    
477
      if( object!=null && !object.isFree() && scores.isSolved(obj,LEVELS_SHOWN) )
478
        {
479
        markAsFree(object,scores);
480
        ret++;
481
        }
482
      }
483

    
484
    return ret;
485
    }
486

    
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488

    
489
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
490
    {
491
    int numObjects = RubikObjectList.getNumObjects();
492

    
493
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
494
      {
495
      RubikObject object = getObject(obj);
496

    
497
      if( object!=null && !object.isFree() )
498
        {
499
        markAsFree(object,scores);
500
        numToBeMarked--;
501
        }
502
      }
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506

    
507
  private static void markAsFree(RubikObject object, RubikScores scores)
508
    {
509
    if( SHOW_IAP_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
510
    object.markFree();
511
    int price = object.getPrice();
512
    scores.changeNumStars(-price);
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public static boolean setCurrObject(int ordinal)
518
    {
519
    if( mObject!=ordinal )
520
      {
521
      mObject = ordinal;
522
      return true;
523
      }
524

    
525
    return false;
526
    }
527

    
528
///////////////////////////////////////////////////////////////////////////////////////////////////
529

    
530
  public static int getCurrObject()
531
    {
532
    return mObject;
533
    }
534

    
535
///////////////////////////////////////////////////////////////////////////////////////////////////
536

    
537
  public static String getCurrentName()
538
    {
539
    RubikObject object = mObjects.get(mObject);
540
    return object==null ? "" : object.getUpperName();
541
    }
542

    
543
///////////////////////////////////////////////////////////////////////////////////////////////////
544

    
545
  public static RubikObject getObject(int ordinal)
546
    {
547
    if( mThis==null ) mThis = new RubikObjectList();
548
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
549
    }
550

    
551
///////////////////////////////////////////////////////////////////////////////////////////////////
552

    
553
  public static RubikObject getObject(String shortUpperName)
554
    {
555
    if( mThis==null ) mThis = new RubikObjectList();
556

    
557
    for(int i=0; i<mNumObjects; i++)
558
      {
559
      RubikObject object = mObjects.get(i);
560
      if( object.getUpperName().equals(shortUpperName) )
561
        {
562
        return object;
563
        }
564
      }
565

    
566
    return null;
567
    }
568

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

    
571
  public static int getNumObjects()
572
    {
573
    if( mThis==null ) mThis = new RubikObjectList();
574
    return mNumObjects;
575
    }
576

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

    
579
  public static int getOrdinal(String name)
580
    {
581
    if( mThis==null ) mThis = new RubikObjectList();
582

    
583
    String lowerName = name.toLowerCase(Locale.ENGLISH);
584

    
585
    for(int i=0; i<mNumObjects; i++)
586
      {
587
      RubikObject obj = mObjects.get(i);
588
      if( obj.getLowerName().equals(lowerName) ) return i;
589
      }
590

    
591
    return -1;
592
    }
593

    
594
///////////////////////////////////////////////////////////////////////////////////////////////////
595

    
596
  public static int getNumExtrasObjects()
597
    {
598
    return mNumExtras;
599
    }
600

    
601
///////////////////////////////////////////////////////////////////////////////////////////////////
602

    
603
  public static int getNumTutorialObjects()
604
    {
605
    return mNumExtras;
606
    }
607

    
608
///////////////////////////////////////////////////////////////////////////////////////////////////
609

    
610
  public static int getObjectOrdinal(int extrasOrdinal)
611
    {
612
    for(int i=extrasOrdinal; i<mNumObjects; i++)
613
      {
614
      RubikObject object = getObject(i);
615
      int extOrd = object!=null ? object.getExtrasOrdinal() : -1;
616
      if( extOrd==extrasOrdinal ) return i;
617
      }
618

    
619
    return -1;
620
    }
621

    
622
///////////////////////////////////////////////////////////////////////////////////////////////////
623

    
624
  public static int getExtrasOrdinal(int objectOrdinal)
625
    {
626
    RubikObject object = getObject(objectOrdinal);
627
    return object!=null ? object.getExtrasOrdinal() : -1;
628
    }
629

    
630
///////////////////////////////////////////////////////////////////////////////////////////////////
631

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

    
638
///////////////////////////////////////////////////////////////////////////////////////////////////
639

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

    
646
///////////////////////////////////////////////////////////////////////////////////////////////////
647

    
648
  public static int getLocalExtrasMinor(int objectOrdinal)
649
    {
650
    RubikObject object = getObject(objectOrdinal);
651
    return object!=null ? object.getExtrasMinor() : -1;
652
    }
653
}
(2-2/2)