Project

General

Profile

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

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

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_SOLVED_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_SOLVED_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_SOLVED_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_SOLVED_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_SOLVED_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
        if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
480
        object.markFree();
481
        int price = object.getPrice();
482
        scores.changeNumStars(-price);
483
        ret++;
484
        }
485
      }
486

    
487
    return ret;
488
    }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
  private static void markObjectsAsFree(RubikScores scores, int numToBeMarked)
493
    {
494
    int numObjects = RubikObjectList.getNumObjects();
495

    
496
    for(int obj=0; obj<numObjects && numToBeMarked>0; obj++)
497
      {
498
      RubikObject object = getObject(obj);
499

    
500
      if( object!=null && !object.isFree() )
501
        {
502
        if( SHOW_SOLVED_DEBUG ) android.util.Log.e("D", "object "+object.getUpperName()+" marked as free");
503
        object.markFree();
504
        int price = object.getPrice();
505
        scores.changeNumStars(-price);
506
        numToBeMarked--;
507
        }
508
      }
509
    }
510

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

    
513
  public static boolean setCurrObject(int ordinal)
514
    {
515
    if( mObject!=ordinal )
516
      {
517
      mObject = ordinal;
518
      return true;
519
      }
520

    
521
    return false;
522
    }
523

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

    
526
  public static int getCurrObject()
527
    {
528
    return mObject;
529
    }
530

    
531
///////////////////////////////////////////////////////////////////////////////////////////////////
532

    
533
  public static String getCurrentName()
534
    {
535
    RubikObject object = mObjects.get(mObject);
536
    return object==null ? "" : object.getUpperName();
537
    }
538

    
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540

    
541
  public static RubikObject getObject(int ordinal)
542
    {
543
    if( mThis==null ) mThis = new RubikObjectList();
544
    return ordinal>=0 && ordinal<mNumObjects ? mObjects.get(ordinal) : null;
545
    }
546

    
547
///////////////////////////////////////////////////////////////////////////////////////////////////
548

    
549
  public static RubikObject getObject(String shortUpperName)
550
    {
551
    if( mThis==null ) mThis = new RubikObjectList();
552

    
553
    for(int i=0; i<mNumObjects; i++)
554
      {
555
      RubikObject object = mObjects.get(i);
556
      if( object.getUpperName().equals(shortUpperName) )
557
        {
558
        return object;
559
        }
560
      }
561

    
562
    return null;
563
    }
564

    
565
///////////////////////////////////////////////////////////////////////////////////////////////////
566

    
567
  public static int getNumObjects()
568
    {
569
    if( mThis==null ) mThis = new RubikObjectList();
570
    return mNumObjects;
571
    }
572

    
573
///////////////////////////////////////////////////////////////////////////////////////////////////
574

    
575
  public static int getOrdinal(String name)
576
    {
577
    if( mThis==null ) mThis = new RubikObjectList();
578

    
579
    String lowerName = name.toLowerCase(Locale.ENGLISH);
580

    
581
    for(int i=0; i<mNumObjects; i++)
582
      {
583
      RubikObject obj = mObjects.get(i);
584
      if( obj.getLowerName().equals(lowerName) ) return i;
585
      }
586

    
587
    return -1;
588
    }
589

    
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591

    
592
  public static int getNumExtrasObjects()
593
    {
594
    return mNumExtras;
595
    }
596

    
597
///////////////////////////////////////////////////////////////////////////////////////////////////
598

    
599
  public static int getNumTutorialObjects()
600
    {
601
    return mNumExtras;
602
    }
603

    
604
///////////////////////////////////////////////////////////////////////////////////////////////////
605

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

    
615
    return -1;
616
    }
617

    
618
///////////////////////////////////////////////////////////////////////////////////////////////////
619

    
620
  public static int getExtrasOrdinal(int objectOrdinal)
621
    {
622
    RubikObject object = getObject(objectOrdinal);
623
    return object!=null ? object.getExtrasOrdinal() : -1;
624
    }
625

    
626
///////////////////////////////////////////////////////////////////////////////////////////////////
627

    
628
  public static int getTutorialOrdinal(int objectOrdinal)
629
    {
630
    RubikObject object = getObject(objectOrdinal);
631
    return object!=null ? object.getExtrasOrdinal() : -1;
632
    }
633

    
634
///////////////////////////////////////////////////////////////////////////////////////////////////
635

    
636
  public static int getLocalObjectMinor(int objectOrdinal)
637
    {
638
    RubikObject object = getObject(objectOrdinal);
639
    return object!=null ? object.getObjectMinor() : -1;
640
    }
641

    
642
///////////////////////////////////////////////////////////////////////////////////////////////////
643

    
644
  public static int getLocalExtrasMinor(int objectOrdinal)
645
    {
646
    RubikObject object = getObject(objectOrdinal);
647
    return object!=null ? object.getExtrasMinor() : -1;
648
    }
649
}
(2-2/2)