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
1cf4d1c8
Commit
1cf4d1c8
authored
Jan 09, 2009
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
the new pack system now actually works (yay!)
parent
41b7ae72
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
353 additions
and
446 deletions
+353
-446
src/data/pack.cpp
src/data/pack.cpp
+237
-331
src/data/pack.hpp
src/data/pack.hpp
+63
-86
src/gui/set/random_pack_panel.cpp
src/gui/set/random_pack_panel.cpp
+49
-28
src/gui/set/random_pack_panel.hpp
src/gui/set/random_pack_panel.hpp
+4
-1
No files found.
src/data/pack.cpp
View file @
1cf4d1c8
...
@@ -153,26 +153,27 @@ vector<CardP>& PackItemCache::cardsFor(const String& name) {
...
@@ -153,26 +153,27 @@ vector<CardP>& PackItemCache::cardsFor(const String& name) {
}
}
#else
#else
// =================================================================================================== NEW
// =================================================================================================== NEW
DECLARE_TYPEOF_COLLECTION
(
PackTypeP
);
DECLARE_TYPEOF_COLLECTION
(
PackTypeP
);
DECLARE_TYPEOF_COLLECTION
(
PackItemP
);
DECLARE_TYPEOF_COLLECTION
(
PackItemP
);
DECLARE_TYPEOF_COLLECTION
(
CardP
);
DECLARE_TYPEOF_COLLECTION
(
CardP
);
DECLARE_TYPEOF_CONST
(
map
<
String
COMMA
PackInstanceP
>
);
// ----------------------------------------------------------------------------- : PackType
// ----------------------------------------------------------------------------- : PackType
PackType
::
PackType
()
:
enabled
(
true
)
,
selectable
(
true
)
,
summary
(
true
)
,
select
(
SELECT_ALL
)
{}
IMPLEMENT_REFLECTION_ENUM
(
OneMany
)
{
IMPLEMENT_REFLECTION_ENUM
(
PackSelectType
)
{
VALUE_N
(
"auto"
,
SELECT_AUTO
);
VALUE_N
(
"all"
,
SELECT_ALL
);
VALUE_N
(
"all"
,
SELECT_ALL
);
VALUE_N
(
"at most one"
,
SELECT_ONE_OR_EMPTY
);
VALUE_N
(
"replace"
,
SELECT_REPLACE
);
VALUE_N
(
"one"
,
SELECT_ONE
);
VALUE_N
(
"no replace"
,
SELECT_NO_REPLACE
);
VALUE_N
(
"cyclic"
,
SELECT_CYCLIC
);
VALUE_N
(
"one"
,
SELECT_PROPORTIONAL
);
VALUE_N
(
"nonempty"
,
SELECT_NONEMPTY
);
VALUE_N
(
"first"
,
SELECT_FIRST
);
VALUE_N
(
"first"
,
SELECT_FIRST
);
}
}
...
@@ -182,133 +183,133 @@ IMPLEMENT_REFLECTION(PackType) {
...
@@ -182,133 +183,133 @@ IMPLEMENT_REFLECTION(PackType) {
REFLECT
(
selectable
);
REFLECT
(
selectable
);
REFLECT
(
summary
);
REFLECT
(
summary
);
REFLECT
(
select
);
REFLECT
(
select
);
REFLECT
(
cards
);
REFLECT
(
filter
);
REFLECT
(
items
);
REFLECT
(
items
);
REFLECT_IF_READING
{
if
(
select
==
SELECT_AUTO
)
{
if
(
filter
)
select
=
SELECT_NO_REPLACE
;
else
if
(
!
items
.
empty
())
select
=
SELECT_ALL
;
}
}
}
}
bool
PackType
::
update
(
Context
&
ctx
)
{
IMPLEMENT_REFLECTION
(
PackItem
)
{
bool
change
=
enabled
.
update
(
ctx
);
REFLECT
(
name
);
FOR_EACH
(
item
,
items
)
{
REFLECT
(
amount
);
change
|=
item
->
update
(
ctx
);
REFLECT
(
probability
);
}
return
change
;
}
}
// ----------------------------------------------------------------------------- : PackItem
PackType
::
PackType
()
:
enabled
(
true
)
,
selectable
(
true
)
,
summary
(
true
)
,
select
(
SELECT_AUTO
)
{}
PackItem
::
PackItem
()
PackItem
::
PackItem
()
:
amount
(
1
)
:
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
)
{
bool
PackType
::
update
(
Context
&
ctx
)
{
REFLECT
(
pack
);
bool
change
=
enabled
.
update
(
ctx
);
REFLECT
(
amount
);
FOR_EACH
(
item
,
items
)
{
REFLECT
(
type
);
change
|=
item
->
update
(
ctx
);
}
return
change
;
}
}
bool
PackItem
::
update
(
Context
&
ctx
)
{
bool
PackItem
::
update
(
Context
&
ctx
)
{
return
amount
.
update
(
ctx
);
return
amount
.
update
(
ctx
)
|
probability
.
update
(
ctx
);
}
}
// ----------------------------------------------------------------------------- : PackItemCache
ScriptValueP
PackItemCache
::
cardsFor
(
const
ScriptValueP
&
generate
)
{
// ----------------------------------------------------------------------------- : PackInstance
// lookup name
ScriptValueP
&
value
=
item_cards
[
generate
];
if
(
!
value
)
{
value
=
generate
->
eval
(
set
.
getContext
());
}
return
value
;
}
const
PackType
&
PackItemCache
::
pack
(
const
String
&
name
)
{
PackInstance
::
PackInstance
(
const
PackType
&
pack_type
,
PackGenerator
&
parent
)
// not used before, generate list and cache
:
pack_type
(
pack_type
)
FOR_EACH
(
pack
,
set
.
game
->
pack_types
)
{
,
parent
(
parent
)
if
(
pack
->
name
==
name
)
{
,
requested_copies
(
0
)
return
*
pack
;
,
card_copies
(
0
)
,
expected_copies
(
0
)
{
// Filter cards
if
(
pack_type
.
filter
)
{
FOR_EACH
(
card
,
parent
.
set
->
cards
)
{
Context
&
ctx
=
parent
.
set
->
getContext
(
card
);
bool
keep
=
*
pack_type
.
filter
.
invoke
(
ctx
);
if
(
keep
)
{
cards
.
push_back
(
card
);
}
}
}
}
// 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
;
}
}
}
// Count items
double
PackItemCounter
::
probabilityNonEmpty
(
const
PackItem
&
item
)
{
if
(
pack_type
.
select
==
SELECT_FIRST
)
{
return
item
.
amount
<=
0
?
0
:
probabilityNonEmpty
(
pack
(
item
.
pack
));
// count = count of first nonempty thing
if
(
!
cards
.
empty
())
{
count
=
1
;
}
else
{
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
count
+=
parent
.
get
(
item
->
name
).
count
;
if
(
count
>
0
)
break
;
}
}
}
else
{
count
=
cards
.
size
();
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
count
+=
parent
.
get
(
item
->
name
).
count
;
}
}
// Sum of probabilities
total_probability
=
cards
.
size
();
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
if
(
pack_type
.
select
==
SELECT_PROPORTIONAL
)
{
total_probability
+=
item
->
probability
*
parent
.
get
(
item
->
name
).
count
;
}
else
if
(
pack_type
.
select
==
SELECT_NONEMPTY
)
{
if
(
parent
.
get
(
item
->
name
).
count
>
0
)
{
total_probability
+=
item
->
probability
;
}
}
else
{
total_probability
+=
item
->
probability
;
}
}
// Depth
depth
=
0
;
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
depth
=
max
(
depth
,
1
+
parent
.
get
(
item
->
name
).
depth
);
}
}
}
void
PackItemCounter
::
addCountRecursive
(
const
PackType
&
pack
,
double
copies
)
{
void
PackInstance
::
expect_copy
(
double
copies
)
{
// add
this
->
expected_copies
+=
copies
;
counts
[
&
pack
]
+=
copies
*
probabilityNonEmpty
(
pack
);
// propagate
// recurse
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
if
(
pack
.
cards
)
{
PackInstance
&
i
=
parent
.
get
(
item
->
name
);
// done
if
(
pack_type
.
select
==
SELECT_ALL
)
{
}
else
if
(
pack
.
select
==
SELECT_FIRST
)
{
i
.
expect_copy
(
copies
*
item
->
amount
);
double
p
=
1
;
}
else
if
(
pack_type
.
select
==
SELECT_PROPORTIONAL
)
{
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
i
.
expect_copy
(
copies
*
item
->
amount
*
item
->
probability
*
i
.
count
/
total_probability
);
addCountRecursive
(
*
i
,
p
*
copies
);
}
else
if
(
pack_type
.
select
==
SELECT_NONEMPTY
)
{
p
*=
1
-
probabilityNonEmpty
(
*
i
);
if
(
i
.
count
>=
0
)
{
if
(
p
<
1e-6
)
return
;
i
.
expect_copy
(
copies
*
item
->
amount
*
item
->
probability
/
total_probability
);
}
}
}
else
if
(
pack
.
select
==
SELECT_ONE_OR_EMPTY
||
pack
.
select
==
SELECT_ONE
)
{
}
else
if
(
pack_type
.
select
==
SELECT_FIRST
)
{
double
total_weight
=
0.0
;
if
(
i
.
count
>=
0
&&
cards
.
empty
())
{
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
i
.
expect_copy
(
copies
*
item
->
amount
);
total_weight
+=
i
->
weight
*
(
pack
.
select
==
SELECT_ONE
?
probabilityNonEmpty
(
*
i
)
:
1.0
);
break
;
}
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
{
}
else
{
throw
InternalError
(
_
(
"unknown OneMany value"
));
i
.
expect_copy
(
copies
*
item
->
amount
*
item
->
probability
/
total_probability
);
}
}
}
}
}
void
PackI
temCounter
::
addCountRecursive
(
const
PackItem
&
item
,
double
copies
)
{
void
PackI
nstance
::
request_copy
(
size_t
copies
)
{
addCountRecursive
(
pack
(
item
.
pack
),
item
.
amount
*
copies
)
;
requested_copies
+=
copies
;
}
}
// ----------------------------------------------------------------------------- : Generating
DECLARE_TYPEOF
(
PackItemGenerator
::
OfTypeCount
);
/// Random generator with random numbers in a range
/// Random generator with random numbers in a range
template
<
typename
Gen
>
template
<
typename
Gen
>
struct
RandomRange
{
struct
RandomRange
{
...
@@ -317,256 +318,161 @@ struct RandomRange {
...
@@ -317,256 +318,161 @@ struct RandomRange {
Gen
&
gen
;
Gen
&
gen
;
};
};
bool
PackItemGenerator
::
generateCount
(
const
PackType
&
pack
,
int
copies
,
PackSelectType
type
,
OfTypeCount
&
out
)
{
void
PackInstance
::
generate
(
vector
<
CardP
>*
out
)
{
if
(
copies
<=
0
)
return
false
;
card_copies
=
0
;
bool
non_empty
=
false
;
if
(
pack_type
.
select
==
SELECT_ALL
)
{
if
(
pack
.
cards
)
{
// add all cards
ScriptValueP
the_cards
=
cardsFor
(
pack
.
cards
.
getScriptP
()
);
card_copies
+=
requested_copies
*
cards
.
size
(
);
non_empty
=
the_cards
->
itemCount
()
>
0
;
if
(
out
)
{
if
(
non_empty
)
{
for
(
size_t
i
=
0
;
i
<
requested_copies
;
++
i
)
{
out
[
make_pair
(
the_cards
,
type
)]
+=
copies
;
out
->
insert
(
out
->
end
(),
cards
.
begin
(),
cards
.
end
())
;
}
}
}
else
if
(
pack
.
select
==
SELECT_ALL
)
{
// just generate all
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
non_empty
|=
generateCount
(
*
i
,
1
,
type
,
out
);
}
}
}
else
{
// and all items
// generate each copy separately
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
for
(
int
j
=
0
;
j
<
copies
;
++
j
)
{
PackInstance
&
i
=
parent
.
get
(
item
->
name
);
non_empty
|=
generateSingleCount
(
pack
,
type
,
ou
t
);
i
.
request_copy
(
requested_copies
*
item
->
amoun
t
);
}
}
}
return
non_empty
;
}
bool
PackItemGenerator
::
generateSingleCount
(
const
PackType
&
pack
,
PackSelectType
type
,
OfTypeCount
&
out
)
{
}
else
if
(
pack_type
.
select
==
SELECT_REPLACE
if
(
pack
.
select
==
SELECT_ONE_OR_EMPTY
)
{
||
pack_type
.
select
==
SELECT_PROPORTIONAL
// pick a random item by weight
||
pack_type
.
select
==
SELECT_NONEMPTY
)
{
double
total_weight
=
0.0
;
// multiple copies
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
for
(
size_t
i
=
0
;
i
<
requested_copies
;
++
i
)
{
total_weight
+=
i
->
weight
;
double
r
=
rand
()
*
total_probability
;
}
if
(
r
<
cards
.
size
())
{
double
choice
=
gen
()
*
total_weight
/
gen
.
max
();
// pick a card
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
card_copies
++
;
if
((
choice
-=
i
->
weight
)
<=
0
)
{
if
(
out
)
{
// pick this one
int
i
=
(
int
)
r
;
return
generateCount
(
*
i
,
1
,
type
,
out
);
out
->
push_back
(
cards
[
i
]);
}
}
}
}
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
{
}
else
{
// try again, exclude this item
// pick an item
possible
&=
~
(
1
<<
i
);
r
-=
cards
.
size
();
total_weight
-=
item
.
weight
;
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
PackInstance
&
i
=
parent
.
get
(
item
->
name
);
if
(
pack_type
.
select
==
SELECT_REPLACE
)
{
r
-=
item
->
probability
;
}
else
if
(
pack_type
.
select
==
SELECT_PROPORTIONAL
)
{
r
-=
item
->
probability
*
i
.
count
;
}
else
{
// SELECT_NONEMPTY
if
(
i
.
count
>
0
)
r
-=
item
->
probability
;
}
// have we reached the item we were looking for?
if
(
r
<
0
)
{
i
.
request_copy
(
requested_copies
*
item
->
amount
);
break
;
break
;
}
}
}
}
}
}
}
}
}
else
if
(
pack
.
select
==
SELECT_FIRST
)
{
// pick the first one that is not empty
}
else
if
(
pack_type
.
select
==
SELECT_NO_REPLACE
)
{
FOR_EACH_CONST
(
i
,
pack
.
items
)
{
card_copies
+=
requested_copies
;
bool
non_empty
=
generateCount
(
*
i
,
1
,
type
,
out
);
// NOTE: there is no way to pick items without replacement
if
(
non_empty
)
return
true
;
if
(
out
)
{
// to prevent us from being too predictable for small sets, periodically reshuffle
RandomRange
<
boost
::
mt19937
>
gen_range
(
parent
.
gen
);
int
max_per_batch
=
((
int
)
cards
.
size
()
+
1
)
/
2
;
int
rem
=
(
int
)
requested_copies
;
while
(
rem
>
0
)
{
random_shuffle
(
cards
.
begin
(),
cards
.
end
(),
gen_range
);
out
->
insert
(
out
->
end
(),
cards
.
begin
(),
cards
.
begin
()
+
min
(
rem
,
max_per_batch
));
rem
-=
max_per_batch
;
}
}
}
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
)
{
}
else
if
(
pack_type
.
select
==
SELECT_CYCLIC
)
{
// first determine how many cards of each basic type we need
size_t
total
=
cards
.
size
()
+
pack_type
.
items
.
size
();
OfTypeCount
counts
;
size_t
div
=
requested_copies
/
total
;
generateCount
(
pack
,
1
,
PACK_REF_NO_REPLACE
,
counts
);
size_t
rem
=
requested_copies
%
total
;
// now select these cards
for
(
size_t
i
=
0
;
i
<
total
;
++
i
)
{
FOR_EACH
(
c
,
counts
)
{
// how many copies of this card/item do we need?
pickCards
(
c
.
first
.
first
,
c
.
first
.
second
,
c
.
second
);
size_t
copies
=
div
+
(
i
<
rem
?
1
:
0
);
if
(
i
<
cards
.
size
())
{
card_copies
+=
copies
;
if
(
out
)
out
->
insert
(
out
->
end
(),
copies
,
cards
[
i
]);
}
else
{
const
PackItemP
&
item
=
pack_type
.
items
[
i
];
parent
.
get
(
item
->
name
).
request_copy
(
copies
*
item
->
amount
);
}
}
}
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
}
else
if
(
pack_type
.
select
==
SELECT_FIRST
)
{
// to prevent us from being too predictable for small sets, periodically reshuffle
if
(
!
cards
.
empty
())
{
int
max_per_batch
=
(
cards_size
+
1
)
/
2
;
// there is a card, pick it
while
(
amount
>
0
)
{
card_copies
+=
requested_copies
;
int
to_add
=
min
(
amount
,
max_per_batch
);
if
(
out
)
out
->
push_back
(
cards
.
front
());
size_t
old_out_size
=
out
.
size
();
}
else
{
// add all to output temporarily
// pick first nonempty item
ScriptValueP
it
=
cards
->
makeIterator
(
cards
);
FOR_EACH_CONST
(
item
,
pack_type
.
items
)
{
while
(
ScriptValueP
card
=
it
->
next
())
{
PackInstance
&
i
=
parent
.
get
(
item
->
name
);
out
.
push_back
(
from_script
<
CardP
>
(
card
));
if
(
i
.
count
>=
0
)
{
}
i
.
request_copy
(
requested_copies
*
item
->
amount
);
// shuffle and keep only the first to_add
break
;
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
)));
}
}
}
}
requested_copies
=
0
;
}
}
// ----------------------------------------------------------------------------- : PackGenerator
/*//%
void
PackGenerator
::
reset
(
const
SetP
&
set
,
int
seed
)
{
// ----------------------------------------------------------------------------- : PackItem
this
->
set
=
set
;
gen
.
seed
((
unsigned
)
seed
);
void PackItemCounter::count(const String& name, double amount) {
max_depth
=
0
;
map<PackItemRef*,double>::iterator it = sizes.find(name);
instances
.
clear
();
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;
PackInstance
&
PackGenerator
::
get
(
const
String
&
name
)
{
if (pack.select = ONE) {
PackInstanceP
&
instance
=
instances
[
name
];
double total_size;
if
(
instance
)
{
FOR_EACH(item, pack.items) {
return
*
instance
;
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
{
}
else
{
total_size += 1;
FOR_EACH_CONST
(
type
,
set
->
game
->
pack_types
)
{
max_size += 1;
if
(
type
->
name
==
name
)
{
instance
=
PackInstanceP
(
new
PackInstance
(
*
type
,
*
this
));
max_depth
=
max
(
max_depth
,
instance
->
get_depth
());
return
*
instance
;
}
}
}
}
throw
Error
(
_ERROR_1_
(
"pack type not found"
,
name
));
}
}
} else { // MANY
}
amounts[pack.name] += amount;
}
}
double PackItemCounter::size(const String& name) {
PackInstance
&
PackGenerator
::
get
(
const
PackTypeP
&
type
)
{
map<PackItemRef*,double>::iterator it = sizes.find(name);
return
get
(
type
->
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;
void
PackGenerator
::
generate
(
vector
<
CardP
>&
out
)
{
double the_size;
if
(
!
set
)
return
;
if (cards) {
// We generate from depth max_depth to 0
the_size = cards.invokeOn(ctx)->itemCount() > 0 ? 1 : 0;
// instances can refer to other instances of lower depth, and generate
} else {
// can change the number of copies of those lower depth instances
the_size = size(name);
for
(
int
depth
=
max_depth
;
depth
>=
0
;
--
depth
)
{
the_name = name;
// in game file order
FOR_EACH_CONST
(
type
,
set
->
game
->
pack_types
)
{
PackInstance
&
i
=
get
(
type
);
if
(
i
.
get_depth
()
==
depth
)
{
i
.
generate
(
&
out
);
}
}
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
PackGenerator
::
update_card_counts
()
{
void PackItemCounter::count(const PackType& pack, int copies, type) {
if
(
!
set
)
return
;
if (pack.cards) {
// update card_counts by using generate()
//
for
(
int
depth
=
max_depth
;
depth
>=
0
;
--
depth
)
{
cards =..
FOR_EACH_CONST
(
i
,
instances
)
{
if (!cards.empty()) {
if
(
i
.
second
->
get_depth
()
==
depth
)
{
i
.
second
->
generate
(
nullptr
);
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
#endif
src/data/pack.hpp
View file @
1cf4d1c8
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
#include <script/scriptable.hpp>
#include <script/scriptable.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/mersenne_twister.hpp>
#define USE_NEW_PACK_SYSTEM
0
#define USE_NEW_PACK_SYSTEM
1
#if !USE_NEW_PACK_SYSTEM
#if !USE_NEW_PACK_SYSTEM
// =================================================================================================== OLD
// =================================================================================================== OLD
...
@@ -103,20 +103,29 @@ class PackItemCache {
...
@@ -103,20 +103,29 @@ class PackItemCache {
};
};
#else
#else
// =================================================================================================== NEW
// =================================================================================================== NEW
DECLARE_POINTER_TYPE
(
PackType
);
DECLARE_POINTER_TYPE
(
PackItem
);
DECLARE_POINTER_TYPE
(
PackItem
);
DECLARE_POINTER_TYPE
(
PackInstance
);
DECLARE_POINTER_TYPE
(
Card
);
DECLARE_POINTER_TYPE
(
Card
);
class
Set
;
DECLARE_POINTER_TYPE
(
Set
);
class
PackGenerator
;
// ----------------------------------------------------------------------------- : PackType
// ----------------------------------------------------------------------------- : PackType
enum
OneMany
enum
PackSelectType
{
SELECT_ONE_OR_EMPTY
{
SELECT_AUTO
,
SELECT_ONE
,
SELECT_FIRST
,
SELECT_ALL
,
SELECT_ALL
,
SELECT_REPLACE
,
SELECT_NO_REPLACE
,
SELECT_CYCLIC
,
SELECT_PROPORTIONAL
,
SELECT_NONEMPTY
,
SELECT_FIRST
};
};
/// A card pack description for playtesting
/// A card pack description for playtesting
...
@@ -128,8 +137,7 @@ class PackType : public IntrusivePtrBase<PackType> {
...
@@ -128,8 +137,7 @@ class PackType : public IntrusivePtrBase<PackType> {
Scriptable
<
bool
>
enabled
;
///< Is this pack enabled?
Scriptable
<
bool
>
enabled
;
///< Is this pack enabled?
bool
selectable
;
///< Is this pack listed in the UI?
bool
selectable
;
///< Is this pack listed in the UI?
bool
summary
;
///< Should the total be listed for this type?
bool
summary
;
///< Should the total be listed for this type?
OneMany
select
;
///< Select one or many?
PackSelectType
select
;
///< What cards/items to select
OptionalScript
cards
;
///< Script to select this type of cards (there are no items)
OptionalScript
filter
;
///< Filter to select this type of cards
OptionalScript
filter
;
///< Filter to select this type of cards
vector
<
PackItemP
>
items
;
///< Subpacks in this pack
vector
<
PackItemP
>
items
;
///< Subpacks in this pack
...
@@ -140,24 +148,14 @@ class PackType : public IntrusivePtrBase<PackType> {
...
@@ -140,24 +148,14 @@ class PackType : public IntrusivePtrBase<PackType> {
DECLARE_REFLECTION
();
DECLARE_REFLECTION
();
};
};
// ----------------------------------------------------------------------------- : PackItem
enum
PackSelectType
{
PACK_REF_INHERIT
,
PACK_REF_REPLACE
,
PACK_REF_NO_REPLACE
,
PACK_REF_CYCLIC
};
/// An item in a PackType
/// An item in a PackType
class
PackItem
:
public
IntrusivePtrBase
<
PackItem
>
{
class
PackItem
:
public
IntrusivePtrBase
<
PackItem
>
{
public:
public:
PackItem
();
PackItem
();
String
pack
;
///< Name of the pack to select cards from
String
name
;
///< Name of the pack to select cards from
Scriptable
<
int
>
amount
;
///< Number of cards of this type
Scriptable
<
int
>
amount
;
///< Number of cards of this type
Scriptable
<
double
>
weight
;
///< Relative probability of picking this item
Scriptable
<
double
>
probability
;
///< Relative probability of picking this item
PackSelectType
type
;
/// Update scripts, returns true if there is a change
/// Update scripts, returns true if there is a change
bool
update
(
Context
&
ctx
);
bool
update
(
Context
&
ctx
);
...
@@ -166,86 +164,65 @@ class PackItem : public IntrusivePtrBase<PackItem> {
...
@@ -166,86 +164,65 @@ class PackItem : public IntrusivePtrBase<PackItem> {
DECLARE_REFLECTION
();
DECLARE_REFLECTION
();
};
};
// ----------------------------------------------------------------------------- : Generating / counting
// ---------------------------------------------------
: PackItemCache
// ---------------------------------------------------
-------------------------- : Generating / counting
class
PackItemCache
{
// A PackType that is instantiated for a particular Set,
// i.e. we now know the actual cards
class
PackInstance
:
public
IntrusivePtrBase
<
PackInstance
>
{
public:
public:
PackI
temCache
(
Set
&
set
)
:
set
(
set
)
{}
PackI
nstance
(
const
PackType
&
pack_type
,
PackGenerator
&
parent
);
/// Look up a pack type by name
/// Expect to pick this many copies from this pack, updates expected_copies
const
PackType
&
pack
(
const
String
&
name
);
void
expect_copy
(
double
copies
=
1
);
/// Request some copies of this pack
void
request_copy
(
size_t
copies
=
1
);
protected:
/// Generate cards if depth == at_depth
Set
&
set
;
/** Some cards are (optionally) added to out and card_copies
* And also the copies of referenced items might be incremented
*
* Resets the count of this instance to 0 */
void
generate
(
vector
<
CardP
>*
out
);
/// The cards for a given PackItem
inline
int
get_depth
()
const
{
return
depth
;
}
ScriptValueP
cardsFor
(
const
ScriptValueP
&
cards_script
);
inline
bool
has_cards
()
const
{
return
!
cards
.
empty
();
}
inline
size_t
get_card_copies
()
const
{
return
card_copies
;
}
inline
double
get_expected_copies
()
const
{
return
expected_copies
;
}
private:
private:
/// Lookup PackTypes by name
const
PackType
&
pack_type
;
//%%
PackGenerator
&
parent
;
/// Cards for each PackType
int
depth
;
//< 0 = no items, otherwise 1+max depth of items refered to
map
<
ScriptValueP
,
ScriptValueP
>
item_cards
;
vector
<
CardP
>
cards
;
//< All cards that pass the filter
size_t
count
;
//< Total number of non-empty cards/items
double
total_probability
;
//< Sum of item and card probabilities
size_t
requested_copies
;
//< The requested number of copies of this pack
size_t
card_copies
;
//< The number of cards that were chosen to come from this pack
double
expected_copies
;
};
};
// --------------------------------------------------- : Counting expected cards
class
PackGenerator
{
/// Class for determining the *expected* number of cards from each type
class
PackItemCounter
:
PackItemCache
{
public:
public:
PackItemCounter
(
Set
&
set
,
map
<
const
PackType
*
,
double
>&
counts
)
/// Reset the generator, possibly switching the set or reseeding
:
PackItemCache
(
set
),
counts
(
counts
)
void
reset
(
const
SetP
&
set
,
int
seed
);
{}
///
Add a number of copies of the PackType to the counts, recurse into child items
///
Find the PackInstance for the PackType with the given name
void
addCountRecursive
(
const
PackType
&
pack
,
double
copies
);
PackInstance
&
get
(
const
String
&
name
);
void
addCountRecursive
(
const
PackItem
&
item
,
double
copies
);
PackInstance
&
get
(
const
PackTypeP
&
type
);
/// The probability that the given pack is non-empty
/// Generate all cards, resets copies
double
probabilityNonEmpty
(
const
PackType
&
pack
);
void
generate
(
vector
<
CardP
>&
out
);
double
probabilityNonEmpty
(
const
PackItem
&
item
);
/// Update all card_copies counters, resets copies
void
update_card_counts
();
/// The counts will be stored here
map
<
const
PackType
*
,
double
>&
counts
;
// only for PackInstance
SetP
set
;
///< The set
boost
::
mt19937
gen
;
///< Random generator
private:
private:
/// The probability that a pack type is empty (cache)
/// Details for each PackType
//%map<const PackItem*,double> probability_empty;
map
<
String
,
PackInstanceP
>
instances
;
};
int
max_depth
;
// --------------------------------------------------- : 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
// ----------------------------------------------------------------------------- : EOF
...
...
src/gui/set/random_pack_panel.cpp
View file @
1cf4d1c8
...
@@ -88,10 +88,14 @@ void RandomCardList::getItems(vector<VoidP>& out) const {
...
@@ -88,10 +88,14 @@ void RandomCardList::getItems(vector<VoidP>& out) const {
class
PackTotalsPanel
:
public
wxPanel
{
class
PackTotalsPanel
:
public
wxPanel
{
public:
public:
#if USE_NEW_PACK_SYSTEM
PackTotalsPanel
(
Window
*
parent
,
int
id
,
PackGenerator
&
generator
)
:
wxPanel
(
parent
,
id
),
generator
(
generator
)
{}
#else
PackTotalsPanel
(
Window
*
parent
,
int
id
)
:
wxPanel
(
parent
,
id
)
{}
PackTotalsPanel
(
Window
*
parent
,
int
id
)
:
wxPanel
(
parent
,
id
)
{}
#endif
void
setGame
(
const
GameP
&
game
);
void
setGame
(
const
GameP
&
game
);
void
clear
();
#if !USE_NEW_PACK_SYSTEM
#if !USE_NEW_PACK_SYSTEM
void
clear
();
void
addPack
(
PackType
&
pack
,
int
copies
);
void
addPack
(
PackType
&
pack
,
int
copies
);
void
addItemRef
(
PackItemRef
&
item
,
int
copies
);
void
addItemRef
(
PackItemRef
&
item
,
int
copies
);
#endif
#endif
...
@@ -101,12 +105,11 @@ class PackTotalsPanel : public wxPanel {
...
@@ -101,12 +105,11 @@ class PackTotalsPanel : public wxPanel {
void
onPaint
(
wxPaintEvent
&
);
void
onPaint
(
wxPaintEvent
&
);
void
draw
(
DC
&
dc
);
void
draw
(
DC
&
dc
);
void
drawItem
(
DC
&
dc
,
int
&
y
,
const
String
&
name
,
double
value
);
void
drawItem
(
DC
&
dc
,
int
&
y
,
const
String
&
name
,
double
value
);
#if USE_NEW_PACK_SYSTEM
#if USE_NEW_PACK_SYSTEM
public:
PackGenerator
&
generator
;
map
<
const
PackType
*
,
double
>
amounts
;
#else
#else
map
<
String
,
int
>
amounts
;
map
<
String
,
int
>
amounts
;
#endif
#endif
};
};
void
PackTotalsPanel
::
onPaint
(
wxPaintEvent
&
)
{
void
PackTotalsPanel
::
onPaint
(
wxPaintEvent
&
)
{
...
@@ -126,10 +129,10 @@ void PackTotalsPanel::draw(DC& dc) {
...
@@ -126,10 +129,10 @@ void PackTotalsPanel::draw(DC& dc) {
int
total
=
0
;
int
total
=
0
;
#if USE_NEW_PACK_SYSTEM
#if USE_NEW_PACK_SYSTEM
FOR_EACH
(
pack
,
game
->
pack_types
)
{
FOR_EACH
(
pack
,
game
->
pack_types
)
{
if
(
pack
->
summary
)
{
PackInstance
&
i
=
generator
.
get
(
pack
);
int
value
=
amounts
[
pack
.
get
()];
if
(
pack
->
summary
&&
i
.
has_cards
())
{
drawItem
(
dc
,
y
,
tr
(
*
game
,
pack
->
name
,
capitalize
),
value
);
drawItem
(
dc
,
y
,
tr
(
*
game
,
pack
->
name
,
capitalize
),
i
.
get_card_copies
()
);
total
+=
value
;
total
+=
(
int
)
i
.
get_card_copies
()
;
}
}
}
}
#else
#else
...
@@ -160,12 +163,14 @@ void PackTotalsPanel::drawItem(DC& dc, int& y, const String& name, double value
...
@@ -160,12 +163,14 @@ void PackTotalsPanel::drawItem(DC& dc, int& y, const String& name, double value
void
PackTotalsPanel
::
setGame
(
const
GameP
&
game
)
{
void
PackTotalsPanel
::
setGame
(
const
GameP
&
game
)
{
this
->
game
=
game
;
this
->
game
=
game
;
#if !USE_NEW_PACK_SYSTEM
clear
();
clear
();
}
#endif
void
PackTotalsPanel
::
clear
()
{
amounts
.
clear
();
}
}
#if !USE_NEW_PACK_SYSTEM
#if !USE_NEW_PACK_SYSTEM
void
PackTotalsPanel
::
clear
()
{
amounts
.
clear
();
}
void
PackTotalsPanel
::
addPack
(
PackType
&
pack
,
int
copies
)
{
void
PackTotalsPanel
::
addPack
(
PackType
&
pack
,
int
copies
)
{
FOR_EACH
(
item
,
pack
.
items
)
{
FOR_EACH
(
item
,
pack
.
items
)
{
addItemRef
(
*
item
,
copies
*
item
->
amount
);
addItemRef
(
*
item
,
copies
*
item
->
amount
);
...
@@ -196,7 +201,11 @@ void RandomPackPanel::initControls() {
...
@@ -196,7 +201,11 @@ void RandomPackPanel::initControls() {
seed_random
=
new
wxRadioButton
(
this
,
ID_SEED_RANDOM
,
_BUTTON_
(
"random seed"
));
seed_random
=
new
wxRadioButton
(
this
,
ID_SEED_RANDOM
,
_BUTTON_
(
"random seed"
));
seed_fixed
=
new
wxRadioButton
(
this
,
ID_SEED_FIXED
,
_BUTTON_
(
"fixed seed"
));
seed_fixed
=
new
wxRadioButton
(
this
,
ID_SEED_FIXED
,
_BUTTON_
(
"fixed seed"
));
seed
=
new
wxTextCtrl
(
this
,
wxID_ANY
);
seed
=
new
wxTextCtrl
(
this
,
wxID_ANY
);
#if USE_NEW_PACK_SYSTEM
totals
=
new
PackTotalsPanel
(
this
,
wxID_ANY
,
generator
);
#else
totals
=
new
PackTotalsPanel
(
this
,
wxID_ANY
);
totals
=
new
PackTotalsPanel
(
this
,
wxID_ANY
);
#endif
static_cast
<
SetWindow
*>
(
GetParent
())
->
setControlStatusText
(
seed_random
,
_HELP_
(
"random seed"
));
static_cast
<
SetWindow
*>
(
GetParent
())
->
setControlStatusText
(
seed_random
,
_HELP_
(
"random seed"
));
static_cast
<
SetWindow
*>
(
GetParent
())
->
setControlStatusText
(
seed_fixed
,
_HELP_
(
"fixed seed"
));
static_cast
<
SetWindow
*>
(
GetParent
())
->
setControlStatusText
(
seed_fixed
,
_HELP_
(
"fixed seed"
));
static_cast
<
SetWindow
*>
(
GetParent
())
->
setControlStatusText
(
seed
,
_HELP_
(
"seed"
));
static_cast
<
SetWindow
*>
(
GetParent
())
->
setControlStatusText
(
seed
,
_HELP_
(
"seed"
));
...
@@ -259,6 +268,9 @@ void RandomPackPanel::onChangeSet() {
...
@@ -259,6 +268,9 @@ void RandomPackPanel::onChangeSet() {
// add pack controls
// add pack controls
FOR_EACH
(
pack
,
set
->
game
->
pack_types
)
{
FOR_EACH
(
pack
,
set
->
game
->
pack_types
)
{
#if NEW_PACK_SYSTEM
if
(
pack
->
selectable
)
{
#endif
PackItem
i
;
PackItem
i
;
i
.
pack
=
pack
;
i
.
pack
=
pack
;
i
.
label
=
new
wxStaticText
(
this
,
wxID_ANY
,
capitalize_sentence
(
pack
->
name
));
i
.
label
=
new
wxStaticText
(
this
,
wxID_ANY
,
capitalize_sentence
(
pack
->
name
));
...
@@ -266,6 +278,9 @@ void RandomPackPanel::onChangeSet() {
...
@@ -266,6 +278,9 @@ void RandomPackPanel::onChangeSet() {
packsSizer
->
Add
(
i
.
label
,
0
,
wxALIGN_CENTER_VERTICAL
);
packsSizer
->
Add
(
i
.
label
,
0
,
wxALIGN_CENTER_VERTICAL
);
packsSizer
->
Add
(
i
.
value
,
0
,
wxEXPAND
|
wxALIGN_CENTER
);
packsSizer
->
Add
(
i
.
value
,
0
,
wxEXPAND
|
wxALIGN_CENTER
);
packs
.
push_back
(
i
);
packs
.
push_back
(
i
);
#if NEW_PACK_SYSTEM
}
#endif
}
}
Layout
();
Layout
();
...
@@ -280,6 +295,9 @@ void RandomPackPanel::onChangeSet() {
...
@@ -280,6 +295,9 @@ void RandomPackPanel::onChangeSet() {
i
.
value
->
SetValue
(
gs
.
pack_amounts
[
i
.
pack
->
name
]);
i
.
value
->
SetValue
(
gs
.
pack_amounts
[
i
.
pack
->
name
]);
}
}
#if USE_NEW_PACK_SYSTEM
generator
.
reset
(
set
,
0
);
#endif
updateTotals
();
updateTotals
();
}
}
...
@@ -328,20 +346,22 @@ void RandomPackPanel::onCommand(int id) {
...
@@ -328,20 +346,22 @@ void RandomPackPanel::onCommand(int id) {
// ----------------------------------------------------------------------------- : Generating
// ----------------------------------------------------------------------------- : Generating
void
RandomPackPanel
::
updateTotals
()
{
void
RandomPackPanel
::
updateTotals
()
{
#if USE_NEW_PACK_SYSTEM
#if !USE_NEW_PACK_SYSTEM
PackItemCounter
counter
(
*
set
,
totals
->
amounts
);
#endif
totals
->
clear
();
totals
->
clear
();
total_packs
=
0
;
#endif
int
total_packs
=
0
;
FOR_EACH
(
i
,
packs
)
{
FOR_EACH
(
i
,
packs
)
{
int
copies
=
i
.
value
->
GetValue
();
int
copies
=
i
.
value
->
GetValue
();
total_packs
+=
copies
;
total_packs
+=
copies
;
#if USE_NEW_PACK_SYSTEM
#if USE_NEW_PACK_SYSTEM
counter
.
addCountRecursive
(
*
i
.
pack
,
copies
);
generator
.
get
(
i
.
pack
).
request_copy
(
copies
);
#else
#else
totals
->
addPack
(
*
i
.
pack
,
copies
);
totals
->
addPack
(
*
i
.
pack
,
copies
);
#endif
#endif
}
}
#if USE_NEW_PACK_SYSTEM
generator
.
update_card_counts
();
#endif
// update UI
// update UI
totals
->
Refresh
(
false
);
totals
->
Refresh
(
false
);
generate_button
->
Enable
(
total_packs
>
0
);
generate_button
->
Enable
(
total_packs
>
0
);
...
@@ -373,10 +393,10 @@ void RandomPackPanel::setSeed(int seed) {
...
@@ -373,10 +393,10 @@ void RandomPackPanel::setSeed(int seed) {
}
}
void
RandomPackPanel
::
generate
()
{
void
RandomPackPanel
::
generate
()
{
boost
::
mt19937
gen
((
unsigned
)
getSeed
());
#if USE_NEW_PACK_SYSTEM
#if USE_NEW_PACK_SYSTEM
PackItemGenerator
generator
(
*
set
,
card_list
->
cards
,
gen
);
generator
.
reset
(
set
,
getSeed
()
);
#else
#else
boost
::
mt19937
gen
((
unsigned
)
getSeed
());
PackItemCache
pack_cache
(
*
set
);
PackItemCache
pack_cache
(
*
set
);
#endif
#endif
// add packs to card list
// add packs to card list
...
@@ -385,7 +405,8 @@ void RandomPackPanel::generate() {
...
@@ -385,7 +405,8 @@ void RandomPackPanel::generate() {
int
copies
=
item
.
value
->
GetValue
();
int
copies
=
item
.
value
->
GetValue
();
for
(
int
i
=
0
;
i
<
copies
;
++
i
)
{
for
(
int
i
=
0
;
i
<
copies
;
++
i
)
{
#if USE_NEW_PACK_SYSTEM
#if USE_NEW_PACK_SYSTEM
generator
.
generate
(
*
item
.
pack
);
generator
.
get
(
item
.
pack
).
request_copy
();
generator
.
generate
(
card_list
->
cards
);
#else
#else
card_list
->
add
(
pack_cache
,
gen
,
*
item
.
pack
);
card_list
->
add
(
pack_cache
,
gen
,
*
item
.
pack
);
#endif
#endif
...
...
src/gui/set/random_pack_panel.hpp
View file @
1cf4d1c8
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <util/prec.hpp>
#include <util/prec.hpp>
#include <gui/set/panel.hpp>
#include <gui/set/panel.hpp>
#include <data/pack.hpp>
#include <wx/spinctrl.h>
#include <wx/spinctrl.h>
class
CardViewer
;
class
CardViewer
;
...
@@ -66,7 +67,9 @@ class RandomPackPanel : public SetWindowPanel {
...
@@ -66,7 +67,9 @@ class RandomPackPanel : public SetWindowPanel {
};
};
vector
<
PackItem
>
packs
;
vector
<
PackItem
>
packs
;
int
total_packs
;
#if USE_NEW_PACK_SYSTEM
PackGenerator
generator
;
#endif
/// Actual intialization of the controls
/// Actual intialization of the controls
void
initControls
();
void
initControls
();
...
...
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