Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
magicseteditor
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
magicseteditor
Commits
8a5ca866
Commit
8a5ca866
authored
Dec 11, 2008
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
working on an improved random pack system, #ifdefed out for now
parent
911fcd2a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
634 additions
and
15 deletions
+634
-15
src/data/pack.cpp
src/data/pack.cpp
+422
-0
src/data/pack.hpp
src/data/pack.hpp
+152
-0
src/gui/set/random_pack_panel.cpp
src/gui/set/random_pack_panel.cpp
+60
-15
No files found.
src/data/pack.cpp
View file @
8a5ca866
...
...
@@ -12,6 +12,9 @@
#include <data/game.hpp>
#include <data/card.hpp>
#if !USE_NEW_PACK_SYSTEM
// =================================================================================================== OLD
DECLARE_TYPEOF_COLLECTION
(
PackItemRefP
);
DECLARE_TYPEOF_COLLECTION
(
PackItemP
);
DECLARE_TYPEOF_COLLECTION
(
CardP
);
...
...
@@ -148,3 +151,422 @@ vector<CardP>& PackItemCache::cardsFor(const String& name) {
throw
Error
(
_ERROR_1_
(
"pack item not found"
,
name
));
}
}
#else
// =================================================================================================== NEW
DECLARE_TYPEOF_COLLECTION
(
PackTypeP
);
DECLARE_TYPEOF_COLLECTION
(
PackItemP
);
DECLARE_TYPEOF_COLLECTION
(
CardP
);
// ----------------------------------------------------------------------------- : PackType
PackType
::
PackType
()
:
enabled
(
true
)
,
selectable
(
true
)
,
summary
(
true
)
,
select
(
SELECT_ALL
)
{}
IMPLEMENT_REFLECTION_ENUM
(
OneMany
)
{
VALUE_N
(
"all"
,
SELECT_ALL
);
VALUE_N
(
"at most one"
,
SELECT_ONE_OR_EMPTY
);
VALUE_N
(
"one"
,
SELECT_ONE
);
VALUE_N
(
"first"
,
SELECT_FIRST
);
}
IMPLEMENT_REFLECTION
(
PackType
)
{
REFLECT
(
name
);
REFLECT
(
enabled
);
REFLECT
(
selectable
);
REFLECT
(
summary
);
REFLECT
(
select
);
REFLECT
(
cards
);
REFLECT
(
items
);
}
bool
PackType
::
update
(
Context
&
ctx
)
{
bool
change
=
enabled
.
update
(
ctx
);
FOR_EACH
(
item
,
items
)
{
change
|=
item
->
update
(
ctx
);
}
return
change
;
}
// ----------------------------------------------------------------------------- : PackItem
PackItem
::
PackItem
()
:
amount
(
1
)
,
type
(
PACK_REF_INHERIT
)
{}
IMPLEMENT_REFLECTION_ENUM
(
PackSelectType
)
{
VALUE_N
(
"inherit"
,
PACK_REF_INHERIT
);
VALUE_N
(
"replace"
,
PACK_REF_REPLACE
);
VALUE_N
(
"no replace"
,
PACK_REF_NO_REPLACE
);
VALUE_N
(
"cyclic"
,
PACK_REF_CYCLIC
);
}
IMPLEMENT_REFLECTION
(
PackItem
)
{
REFLECT
(
pack
);
REFLECT
(
amount
);
REFLECT
(
type
);
}
bool
PackItem
::
update
(
Context
&
ctx
)
{
return
amount
.
update
(
ctx
);
}
// ----------------------------------------------------------------------------- : PackItemCache
ScriptValueP
PackItemCache
::
cardsFor
(
const
ScriptValueP
&
generate
)
{
// lookup name
ScriptValueP
&
value
=
item_cards
[
generate
];
if
(
!
value
)
{
value
=
generate
->
eval
(
set
.
getContext
());
}
return
value
;
}
const
PackType
&
PackItemCache
::
pack
(
const
String
&
name
)
{
// not used before, generate list and cache
FOR_EACH
(
pack
,
set
.
game
->
pack_types
)
{
if
(
pack
->
name
==
name
)
{
return
*
pack
;
}
}
// not found
throw
Error
(
_ERROR_1_
(
"pack type not found"
,
name
));
}
// ----------------------------------------------------------------------------- : Counting expected cards
double
PackItemCounter
::
probabilityNonEmpty
(
const
PackType
&
pack
)
{
// TODO: cache?
if
(
pack
.
cards
)
{
return
cardsFor
(
pack
.
cards
.
getScriptP
())
->
itemCount
();
}
else
if
(
pack
.
select
==
SELECT_ONE_OR_EMPTY
)
{
// weighted avarage
double
p
=
0.0
;
double
total_weight
=
0.0
;
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
p
+=
i
->
weight
*
probabilityNonEmpty
(
*
i
);
total_weight
+=
i
->
weight
;
}
return
p
/
total_weight
;
}
else
{
// SELECT_ONE, SELECT_FIRST, SELECT_ALL
// disjunction
double
p
=
0.0
;
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
// either already non-empty, or all previous items were empty so pick this one
p
+=
(
1
-
p
)
*
probabilityNonEmpty
(
*
i
);
if
(
p
>=
1
-
1e-6
)
return
1.0
;
}
return
p
;
}
}
double
PackItemCounter
::
probabilityNonEmpty
(
const
PackItem
&
item
)
{
return
item
.
amount
<=
0
?
0
:
probabilityNonEmpty
(
pack
(
item
.
pack
));
}
void
PackItemCounter
::
addCountRecursive
(
const
PackType
&
pack
,
double
copies
)
{
// add
counts
[
&
pack
]
+=
copies
*
probabilityNonEmpty
(
pack
);
// recurse
if
(
pack
.
cards
)
{
// done
}
else
if
(
pack
.
select
==
SELECT_FIRST
)
{
double
p
=
1
;
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
addCountRecursive
(
*
i
,
p
*
copies
);
p
*=
1
-
probabilityNonEmpty
(
*
i
);
if
(
p
<
1e-6
)
return
;
}
}
else
if
(
pack
.
select
==
SELECT_ONE_OR_EMPTY
||
pack
.
select
==
SELECT_ONE
)
{
double
total_weight
=
0.0
;
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
total_weight
+=
i
->
weight
*
(
pack
.
select
==
SELECT_ONE
?
probabilityNonEmpty
(
*
i
)
:
1.0
);
}
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
addCountRecursive
(
*
i
,
copies
*
i
->
weight
/
total_weight
);
}
}
else
if
(
pack
.
select
==
SELECT_ALL
)
{
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
addCountRecursive
(
*
i
,
copies
);
}
}
else
{
throw
InternalError
(
_
(
"unknown OneMany value"
));
}
}
void
PackItemCounter
::
addCountRecursive
(
const
PackItem
&
item
,
double
copies
)
{
addCountRecursive
(
pack
(
item
.
pack
),
item
.
amount
*
copies
);
}
// ----------------------------------------------------------------------------- : Generating
DECLARE_TYPEOF
(
PackItemGenerator
::
OfTypeCount
);
/// Random generator with random numbers in a range
template
<
typename
Gen
>
struct
RandomRange
{
RandomRange
(
Gen
&
gen
)
:
gen
(
gen
)
{}
unsigned
operator
()
(
unsigned
max
)
{
return
gen
()
%
max
;
}
Gen
&
gen
;
};
bool
PackItemGenerator
::
generateCount
(
const
PackType
&
pack
,
int
copies
,
PackSelectType
type
,
OfTypeCount
&
out
)
{
if
(
copies
<=
0
)
return
false
;
bool
non_empty
=
false
;
if
(
pack
.
cards
)
{
ScriptValueP
the_cards
=
cardsFor
(
pack
.
cards
.
getScriptP
());
non_empty
=
the_cards
->
itemCount
()
>
0
;
if
(
non_empty
)
{
out
[
make_pair
(
the_cards
,
type
)]
+=
copies
;
}
}
else
if
(
pack
.
select
==
SELECT_ALL
)
{
// just generate all
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
non_empty
|=
generateCount
(
*
i
,
1
,
type
,
out
);
}
}
else
{
// generate each copy separately
for
(
int
j
=
0
;
j
<
copies
;
++
j
)
{
non_empty
|=
generateSingleCount
(
pack
,
type
,
out
);
}
}
return
non_empty
;
}
bool
PackItemGenerator
::
generateSingleCount
(
const
PackType
&
pack
,
PackSelectType
type
,
OfTypeCount
&
out
)
{
if
(
pack
.
select
==
SELECT_ONE_OR_EMPTY
)
{
// pick a random item by weight
double
total_weight
=
0.0
;
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
total_weight
+=
i
->
weight
;
}
double
choice
=
gen
()
*
total_weight
/
gen
.
max
();
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
if
((
choice
-=
i
->
weight
)
<=
0
)
{
// pick this one
return
generateCount
(
*
i
,
1
,
type
,
out
);
}
}
}
else
if
(
pack
.
select
==
SELECT_ONE
)
{
// pick a random item by weight that is not empty
UInt
possible
=
0
;
// bitmask
double
total_weight
=
0.0
;
for
(
size_t
i
=
0
;
i
<
pack
.
items
.
size
()
;
++
i
)
{
total_weight
+=
pack
.
items
[
i
]
->
weight
;
possible
|=
1
<<
i
;
}
while
(
possible
)
{
// try to make a choice we have not made before
int
choice
=
gen
()
*
total_weight
/
gen
.
max
();
for
(
size_t
i
=
0
;
i
<
pack
.
items
.
size
()
;
++
i
)
{
const
PackItem
&
item
=
*
pack
.
items
[
i
];
if
(
!
(
possible
&
(
1
<<
i
)))
continue
;
// already tried this item?
if
((
choice
-=
item
.
weight
)
<=
0
)
{
bool
non_empty
=
generateCount
(
item
,
1
,
type
,
out
);
if
(
non_empty
)
{
// found a non-empty choice, done
return
true
;
}
else
{
// try again, exclude this item
possible
&=
~
(
1
<<
i
);
total_weight
-=
item
.
weight
;
break
;
}
}
}
}
}
else
if
(
pack
.
select
==
SELECT_FIRST
)
{
// pick the first one that is not empty
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
bool
non_empty
=
generateCount
(
*
i
,
1
,
type
,
out
);
if
(
non_empty
)
return
true
;
}
}
else
{
throw
InternalError
(
_
(
"unknown OneMany value"
));
}
return
false
;
}
bool
PackItemGenerator
::
generateCount
(
const
PackItem
&
item
,
int
copies
,
PackSelectType
type
,
OfTypeCount
&
out
)
{
return
generateCount
(
pack
(
item
.
pack
),
copies
*
item
.
amount
,
item
.
type
==
PACK_REF_INHERIT
?
type
:
item
.
type
,
out
);
}
void
PackItemGenerator
::
generate
(
const
PackType
&
pack
)
{
// first determine how many cards of each basic type we need
OfTypeCount
counts
;
generateCount
(
pack
,
1
,
PACK_REF_NO_REPLACE
,
counts
);
// now select these cards
FOR_EACH
(
c
,
counts
)
{
pickCards
(
c
.
first
.
first
,
c
.
first
.
second
,
c
.
second
);
}
}
void
PackItemGenerator
::
pickCards
(
const
ScriptValueP
&
cards
,
PackSelectType
type
,
int
amount
)
{
// generate 'amount' cards and add them to out
int
cards_size
=
cards
->
itemCount
();
if
(
cards_size
<=
0
)
return
;
RandomRange
<
boost
::
mt19937
>
gen_range
(
gen
);
if
(
type
==
PACK_REF_REPLACE
)
{
// amount random numbers
for
(
int
i
=
0
;
i
<
amount
;
++
i
)
{
int
index
=
gen_range
(
cards_size
);
out
.
push_back
(
from_script
<
CardP
>
(
cards
->
getIndex
(
index
)));
}
}
else
if
(
type
==
PACK_REF_NO_REPLACE
)
{
// random shuffle
// to prevent us from being too predictable for small sets, periodically reshuffle
int
max_per_batch
=
(
cards_size
+
1
)
/
2
;
while
(
amount
>
0
)
{
int
to_add
=
min
(
amount
,
max_per_batch
);
size_t
old_out_size
=
out
.
size
();
// add all to output temporarily
ScriptValueP
it
=
cards
->
makeIterator
(
cards
);
while
(
ScriptValueP
card
=
it
->
next
())
{
out
.
push_back
(
from_script
<
CardP
>
(
card
));
}
// shuffle and keep only the first to_add
random_shuffle
(
out
.
begin
()
+
old_out_size
,
out
.
end
(),
gen_range
);
out
.
resize
(
old_out_size
+
to_add
);
amount
-=
to_add
;
}
}
else
if
(
type
==
PACK_REF_CYCLIC
)
{
// multiple copies
int
copies
=
amount
/
cards_size
;
ScriptValueP
it
=
cards
->
makeIterator
(
cards
);
while
(
ScriptValueP
card
=
it
->
next
())
{
out
.
insert
(
out
.
end
(),
copies
,
from_script
<
CardP
>
(
card
));
}
amount
-=
copies
*
cards_size
;
// if amount is not a multiple of the number of cards, pick the rest at random
for
(
int
i
=
0
;
i
<
amount
;
++
i
)
{
int
index
=
gen_range
(
cards_size
);
out
.
push_back
(
from_script
<
CardP
>
(
cards
->
getIndex
(
index
)));
}
}
}
/*//%
// ----------------------------------------------------------------------------- : PackItem
void PackItemCounter::count(const String& name, double amount) {
map<PackItemRef*,double>::iterator it = sizes.find(name);
if (it != sizes.end()) return it->second;
size *= amount * probability;
return sizes[&item] = size;
}
void PackItemCounter::count(const PackType& pack, int copies) {
double size = 0;
if (pack.select = ONE) {
double total_size;
FOR_EACH(item, pack.items) {
double item_size = size(item);
if (item->type == OTHER_IF_EMPTY) {
// is it empty?
total_size += item_size > 0 ? 1 : 0;
max_size += 1;
} else if (item->type == WEIGHTED) {
total_size += item_size;
max_size += item_size;
} else {
total_size += 1;
max_size += 1;
}
}
size += total_size / max_size;
// count
FOR_EACH(item, pack.items) {
double item_size = size(item);
if (item_size > 0 && !item->cards) {
if (item->type == OTHER_IF_EMPTY) {
// is it empty?
total_size += item_size > 0 ? 1 : 0;
max_size += 1;
} else if (item->type == WEIGHTED) {
total_size += item_size;
max_size += item_size;
} else {
total_size += 1;
max_size += 1;
}
}
}
} else { // MANY
}
amounts[pack.name] += amount;
}
double PackItemCounter::size(const String& name) {
map<PackItemRef*,double>::iterator it = sizes.find(name);
if (it != sizes.end()) return it->second;
double the_size = 0;
FOR_EACH() {
the_size += size(item);
}
return sizes[&item] = the_size;
}
double PackItemCounter::size(const PackItemRef& item) {
String the_name;
double the_size;
if (cards) {
the_size = cards.invokeOn(ctx)->itemCount() > 0 ? 1 : 0;
} else {
the_size = size(name);
the_name = name;
}
if (the_size == 0 && !if_empty.empty())
the_name = if_empty;
the_size = size(if_empty);
}
if (!the_name.empty()) {
counts[the_name] += amount * probability;
}
return the_size * amount * probability;
}
void PackItemCounter::count(const PackType& pack, int copies, type) {
if (pack.cards) {
//
cards =..
if (!cards.empty()) {
return true;
} else {
return false;
}
} else {
}
}
// ----------------------------------------------------------------------------- : PackItem
IMPLEMENT_REFLECTION(PackItem) {
REFLECT(name);
REFLECT(filter);
}
void PackItem::generate(Set& set, vector<CardP>& out) const {
FOR_EACH(card, set.cards) {
Context& ctx = set.getContext(card);
bool keep = *filter.invoke(ctx);
if (keep) {
out.push_back(card);
}
}
}
// ----------------------------------------------------------------------------- : PackItemCache
PackItemCache::PackItemCache(Set& set)
: set(set)
{}*/
#endif
src/data/pack.hpp
View file @
8a5ca866
...
...
@@ -14,6 +14,11 @@
#include <script/scriptable.hpp>
#include <boost/random/mersenne_twister.hpp>
#define USE_NEW_PACK_SYSTEM 0
#if !USE_NEW_PACK_SYSTEM
// =================================================================================================== OLD
DECLARE_POINTER_TYPE
(
PackItemRef
);
DECLARE_POINTER_TYPE
(
Card
);
class
Set
;
...
...
@@ -97,5 +102,152 @@ class PackItemCache {
map
<
String
,
Cards
>
item_cards
;
};
#else
// =================================================================================================== NEW
DECLARE_POINTER_TYPE
(
PackItem
);
DECLARE_POINTER_TYPE
(
Card
);
class
Set
;
// ----------------------------------------------------------------------------- : PackType
enum
OneMany
{
SELECT_ONE_OR_EMPTY
,
SELECT_ONE
,
SELECT_FIRST
,
SELECT_ALL
};
/// A card pack description for playtesting
class
PackType
:
public
IntrusivePtrBase
<
PackType
>
{
public:
PackType
();
String
name
;
///< Name of this pack
Scriptable
<
bool
>
enabled
;
///< Is this pack enabled?
bool
selectable
;
///< Is this pack listed in the UI?
bool
summary
;
///< Should the total be listed for this type?
OneMany
select
;
///< Select one or many?
OptionalScript
cards
;
///< Script to select this type of cards (there are no items)
OptionalScript
filter
;
///< Filter to select this type of cards
vector
<
PackItemP
>
items
;
///< Subpacks in this pack
/// Update scripts, returns true if there is a change
bool
update
(
Context
&
ctx
);
private:
DECLARE_REFLECTION
();
};
// ----------------------------------------------------------------------------- : PackItem
enum
PackSelectType
{
PACK_REF_INHERIT
,
PACK_REF_REPLACE
,
PACK_REF_NO_REPLACE
,
PACK_REF_CYCLIC
};
/// An item in a PackType
class
PackItem
:
public
IntrusivePtrBase
<
PackItem
>
{
public:
PackItem
();
String
pack
;
///< Name of the pack to select cards from
Scriptable
<
int
>
amount
;
///< Number of cards of this type
Scriptable
<
double
>
weight
;
///< Relative probability of picking this item
PackSelectType
type
;
/// Update scripts, returns true if there is a change
bool
update
(
Context
&
ctx
);
private:
DECLARE_REFLECTION
();
};
// ----------------------------------------------------------------------------- : Generating / counting
// --------------------------------------------------- : PackItemCache
class
PackItemCache
{
public:
PackItemCache
(
Set
&
set
)
:
set
(
set
)
{}
/// Look up a pack type by name
const
PackType
&
pack
(
const
String
&
name
);
protected:
Set
&
set
;
/// The cards for a given PackItem
ScriptValueP
cardsFor
(
const
ScriptValueP
&
cards_script
);
private:
/// Lookup PackTypes by name
//%%
/// Cards for each PackType
map
<
ScriptValueP
,
ScriptValueP
>
item_cards
;
};
// --------------------------------------------------- : Counting expected cards
/// Class for determining the *expected* number of cards from each type
class
PackItemCounter
:
PackItemCache
{
public:
PackItemCounter
(
Set
&
set
,
map
<
const
PackType
*
,
double
>&
counts
)
:
PackItemCache
(
set
),
counts
(
counts
)
{}
/// Add a number of copies of the PackType to the counts, recurse into child items
void
addCountRecursive
(
const
PackType
&
pack
,
double
copies
);
void
addCountRecursive
(
const
PackItem
&
item
,
double
copies
);
/// The probability that the given pack is non-empty
double
probabilityNonEmpty
(
const
PackType
&
pack
);
double
probabilityNonEmpty
(
const
PackItem
&
item
);
/// The counts will be stored here
map
<
const
PackType
*
,
double
>&
counts
;
private:
/// The probability that a pack type is empty (cache)
//%map<const PackItem*,double> probability_empty;
};
// --------------------------------------------------- : PackItemCounter
/// Class for generating card packs
class
PackItemGenerator
:
PackItemCache
{
public:
PackItemGenerator
(
Set
&
set
,
vector
<
CardP
>&
cards
,
boost
::
mt19937
&
gen
)
:
PackItemCache
(
set
),
out
(
cards
),
gen
(
gen
)
{}
/// Generate a pack, adding it to cards
void
generate
(
const
PackType
&
pack
);
/// Number of cards of a type
typedef
map
<
pair
<
ScriptValueP
,
PackSelectType
>
,
int
>
OfTypeCount
;
/// Determine what *types* of cards to pick (store in out)
/** Does NOT add cards yet.
* Returns true if non-empty.
*/
bool
generateCount
(
const
PackType
&
pack
,
int
copies
,
PackSelectType
type
,
OfTypeCount
&
out
);
bool
generateCount
(
const
PackItem
&
item
,
int
copies
,
PackSelectType
type
,
OfTypeCount
&
out
);
bool
generateSingleCount
(
const
PackType
&
pack
,
PackSelectType
type
,
OfTypeCount
&
out
);
/// Pick cards from a list
void
pickCards
(
const
ScriptValueP
&
cards
,
PackSelectType
type
,
int
amount
);
/// The cards will be stored here
vector
<
CardP
>&
out
;
/// Random generator
boost
::
mt19937
&
gen
;
};
// ----------------------------------------------------------------------------- : EOF
#endif
#endif
src/gui/set/random_pack_panel.cpp
View file @
8a5ca866
...
...
@@ -21,7 +21,9 @@
DECLARE_TYPEOF_COLLECTION
(
PackTypeP
);
DECLARE_TYPEOF_COLLECTION
(
PackItemP
);
DECLARE_TYPEOF_COLLECTION
(
PackItemRefP
);
#if !USE_NEW_PACK_SYSTEM
DECLARE_TYPEOF_COLLECTION
(
PackItemRefP
);
#endif
DECLARE_TYPEOF_COLLECTION
(
CardP
);
DECLARE_TYPEOF_COLLECTION
(
RandomPackPanel
::
PackItem_for_typeof
);
...
...
@@ -34,8 +36,10 @@ class RandomCardList : public CardListBase {
/// Reset the list
void
reset
();
#if !USE_NEW_PACK_SYSTEM
/// Add a pack of cards
void
add
(
PackItemCache
&
packs
,
boost
::
mt19937
&
gen
,
const
PackType
&
pack
);
#endif
using
CardListBase
::
rebuild
;
...
...
@@ -45,7 +49,11 @@ class RandomCardList : public CardListBase {
virtual
void
getItems
(
vector
<
VoidP
>&
out
)
const
;
virtual
void
onChangeSet
();
private:
#if USE_NEW_PACK_SYSTEM
public:
#else
private:
#endif
vector
<
CardP
>
cards
;
};
...
...
@@ -56,9 +64,12 @@ RandomCardList::RandomCardList(Window* parent, int id, long style)
void
RandomCardList
::
reset
()
{
cards
.
clear
();
}
void
RandomCardList
::
add
(
PackItemCache
&
packs
,
boost
::
mt19937
&
gen
,
const
PackType
&
pack
)
{
pack
.
generate
(
packs
,
gen
,
cards
);
}
#if !USE_NEW_PACK_SYSTEM
void
RandomCardList
::
add
(
PackItemCache
&
packs
,
boost
::
mt19937
&
gen
,
const
PackType
&
pack
)
{
pack
.
generate
(
packs
,
gen
,
cards
);
}
#endif
void
RandomCardList
::
onChangeSet
()
{
reset
();
...
...
@@ -80,15 +91,22 @@ class PackTotalsPanel : public wxPanel {
PackTotalsPanel
(
Window
*
parent
,
int
id
)
:
wxPanel
(
parent
,
id
)
{}
void
setGame
(
const
GameP
&
game
);
void
clear
();
#if !USE_NEW_PACK_SYSTEM
void
addPack
(
PackType
&
pack
,
int
copies
);
void
addItemRef
(
PackItemRef
&
item
,
int
copies
);
#endif
private:
DECLARE_EVENT_TABLE
();
GameP
game
;
void
onPaint
(
wxPaintEvent
&
);
void
draw
(
DC
&
dc
);
void
drawItem
(
DC
&
dc
,
int
&
y
,
const
String
&
name
,
int
value
);
void
drawItem
(
DC
&
dc
,
int
&
y
,
const
String
&
name
,
double
value
);
#if USE_NEW_PACK_SYSTEM
public:
map
<
const
PackType
*
,
double
>
amounts
;
#else
map
<
String
,
int
>
amounts
;
#endif
};
void
PackTotalsPanel
::
onPaint
(
wxPaintEvent
&
)
{
...
...
@@ -106,11 +124,21 @@ void PackTotalsPanel::draw(DC& dc) {
dc
.
SetFont
(
*
wxNORMAL_FONT
);
int
y
=
0
;
int
total
=
0
;
#if USE_NEW_PACK_SYSTEM
FOR_EACH
(
pack
,
game
->
pack_types
)
{
if
(
pack
->
summary
)
{
int
value
=
amounts
[
pack
.
get
()];
drawItem
(
dc
,
y
,
tr
(
*
game
,
pack
->
name
,
capitalize
),
value
);
total
+=
value
;
}
}
#else
FOR_EACH
(
item
,
game
->
pack_items
)
{
int
value
=
amounts
[
item
->
name
];
drawItem
(
dc
,
y
,
tr
(
*
game
,
item
->
name
,
capitalize
),
value
);
total
+=
value
;
}
#endif
// draw total
dc
.
SetPen
(
wxSystemSettings
::
GetColour
(
wxSYS_COLOUR_3DSHADOW
));
dc
.
DrawLine
(
0
,
y
-
3
,
size
.
x
,
y
-
3
);
...
...
@@ -120,10 +148,10 @@ void PackTotalsPanel::draw(DC& dc) {
drawItem
(
dc
,
y
,
_LABEL_
(
"total cards"
),
total
);
}
void
PackTotalsPanel
::
drawItem
(
DC
&
dc
,
int
&
y
,
const
String
&
name
,
int
value
)
{
void
PackTotalsPanel
::
drawItem
(
DC
&
dc
,
int
&
y
,
const
String
&
name
,
double
value
)
{
wxSize
size
=
dc
.
GetSize
();
int
w
,
h
;
String
amount
;
amount
<<
value
;
String
amount
=
String
::
Format
(
_
(
"%.f"
),
value
)
;
dc
.
GetTextExtent
(
amount
,
&
w
,
&
h
);
dc
.
DrawText
(
name
,
0
,
y
);
dc
.
DrawText
(
amount
,
size
.
x
-
w
,
y
);
//align right
...
...
@@ -137,14 +165,16 @@ void PackTotalsPanel::setGame(const GameP& game) {
void
PackTotalsPanel
::
clear
()
{
amounts
.
clear
();
}
void
PackTotalsPanel
::
addPack
(
PackType
&
pack
,
int
copies
)
{
FOR_EACH
(
item
,
pack
.
items
)
{
addItemRef
(
*
item
,
copies
*
item
->
amount
);
#if !USE_NEW_PACK_SYSTEM
void
PackTotalsPanel
::
addPack
(
PackType
&
pack
,
int
copies
)
{
FOR_EACH
(
item
,
pack
.
items
)
{
addItemRef
(
*
item
,
copies
*
item
->
amount
);
}
}
}
void
PackTotalsPanel
::
addItemRef
(
PackItemRef
&
item
,
int
copies
)
{
amounts
[
item
.
name
]
+=
copies
;
}
void
PackTotalsPanel
::
addItemRef
(
PackItemRef
&
item
,
int
copies
)
{
amounts
[
item
.
name
]
+=
copies
;
}
#endif
BEGIN_EVENT_TABLE
(
PackTotalsPanel
,
wxPanel
)
EVT_PAINT
(
PackTotalsPanel
::
onPaint
)
...
...
@@ -298,12 +328,19 @@ void RandomPackPanel::onCommand(int id) {
// ----------------------------------------------------------------------------- : Generating
void
RandomPackPanel
::
updateTotals
()
{
#if USE_NEW_PACK_SYSTEM
PackItemCounter
counter
(
*
set
,
totals
->
amounts
);
#endif
totals
->
clear
();
total_packs
=
0
;
FOR_EACH
(
i
,
packs
)
{
int
copies
=
i
.
value
->
GetValue
();
total_packs
+=
copies
;
#if USE_NEW_PACK_SYSTEM
counter
.
addCountRecursive
(
*
i
.
pack
,
copies
);
#else
totals
->
addPack
(
*
i
.
pack
,
copies
);
#endif
}
// update UI
totals
->
Refresh
(
false
);
...
...
@@ -337,13 +374,21 @@ void RandomPackPanel::setSeed(int seed) {
void
RandomPackPanel
::
generate
()
{
boost
::
mt19937
gen
((
unsigned
)
getSeed
());
#if USE_NEW_PACK_SYSTEM
PackItemGenerator
generator
(
*
set
,
card_list
->
cards
,
gen
);
#else
PackItemCache
pack_cache
(
*
set
);
#endif
// add packs to card list
card_list
->
reset
();
FOR_EACH
(
item
,
packs
)
{
int
copies
=
item
.
value
->
GetValue
();
for
(
int
i
=
0
;
i
<
copies
;
++
i
)
{
#if USE_NEW_PACK_SYSTEM
generator
.
generate
(
*
item
.
pack
);
#else
card_list
->
add
(
pack_cache
,
gen
,
*
item
.
pack
);
#endif
}
}
card_list
->
rebuild
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment