Commit 103fceb4 authored by VanillaSalt's avatar VanillaSalt

update attack/defence calculation

parent 989261c2
...@@ -390,15 +390,52 @@ uint32 card::get_type() { ...@@ -390,15 +390,52 @@ uint32 card::get_type() {
} }
// Atk and def are sepcial cases since text atk/def ? are involved. // Atk and def are sepcial cases since text atk/def ? are involved.
// Asuumption: we can only change the atk/def of cards in LOCATION_MZONE. // Asuumption: we can only change the atk/def of cards in LOCATION_MZONE.
int32 card::get_base_attack(uint8 swap) { int32 card::get_base_attack() {
if(!(data.type & TYPE_MONSTER) && !(get_type() & TYPE_MONSTER) && !is_affected_by_effect(EFFECT_PRE_MONSTER)) if(!(data.type & TYPE_MONSTER) && !(get_type() & TYPE_MONSTER) && !is_affected_by_effect(EFFECT_PRE_MONSTER))
return 0; return 0;
if (current.location != LOCATION_MZONE || is_status(STATUS_SUMMONING)) if (current.location != LOCATION_MZONE || is_status(STATUS_SUMMONING))
return data.attack; return data.attack;
if (temp.base_attack != -1) if (temp.base_attack != -1)
return temp.base_attack; return temp.base_attack;
int32 batk; int32 batk = data.attack;
calc_attack_defence(&batk, 0, 0, 0); if(batk < 0)
batk = 0;
int32 bdef = data.defence;
if(bdef < 0)
bdef = 0;
temp.base_attack = batk;
effect_set eset;
filter_effect(EFFECT_SWAP_BASE_AD, &eset, FALSE);
int32 swap = eset.size();
filter_effect(EFFECT_SET_BASE_ATTACK, &eset, FALSE);
if(swap)
filter_effect(EFFECT_SET_BASE_DEFENCE, &eset, FALSE);
eset.sort();
int32 swap_final_b = FALSE;
for(int32 i = 0; i < eset.size(); ++i) {
switch(eset[i]->code) {
case EFFECT_SET_BASE_ATTACK:
batk = eset[i]->get_value(this);
if(batk < 0)
batk = 0;
break;
case EFFECT_SET_BASE_DEFENCE:
bdef = eset[i]->get_value(this);
if(bdef < 0)
bdef = 0;
break;
case EFFECT_SWAP_BASE_AD:
if(!(eset[i]->type & EFFECT_TYPE_FIELD))
std::swap(batk, bdef);
else
swap_final_b = !swap_final_b;
break;
}
temp.base_attack = batk;
}
if(swap_final_b)
batk = bdef;
temp.base_attack = -1;
return batk; return batk;
} }
int32 card::get_attack() { int32 card::get_attack() {
...@@ -410,19 +447,207 @@ int32 card::get_attack() { ...@@ -410,19 +447,207 @@ int32 card::get_attack() {
return data.attack; return data.attack;
if (temp.attack != -1) if (temp.attack != -1)
return temp.attack; return temp.attack;
int32 atk; int32 batk = data.attack;
calc_attack_defence(0, 0, &atk, 0); if(batk < 0)
batk = 0;
int32 bdef = data.defence;
if(bdef < 0)
bdef = 0;
temp.base_attack = batk;
temp.attack = batk;
int32 atk = -1;
int32 def = -1;
int32 currect_def = bdef;
int32 up_atk = 0, upc_atk = 0;
int32 up_def = 0, upc_def = 0;
effect_set eset;
filter_effect(EFFECT_SWAP_AD, &eset, FALSE);
filter_effect(EFFECT_SWAP_BASE_AD, &eset, FALSE);
int32 swap = eset.size();
filter_effect(EFFECT_UPDATE_ATTACK, &eset, FALSE);
filter_effect(EFFECT_SET_ATTACK, &eset, FALSE);
filter_effect(EFFECT_SET_ATTACK_FINAL, &eset, FALSE);
filter_effect(EFFECT_SET_BASE_ATTACK, &eset, FALSE);
if(swap) {
filter_effect(EFFECT_UPDATE_DEFENCE, &eset, FALSE);
filter_effect(EFFECT_SET_DEFENCE, &eset, FALSE);
filter_effect(EFFECT_SET_DEFENCE_FINAL, &eset, FALSE);
filter_effect(EFFECT_SET_BASE_DEFENCE, &eset, FALSE);
}
eset.sort();
int32 rev = FALSE;
if(is_affected_by_effect(EFFECT_REVERSE_UPDATE))
rev = TRUE;
effect_set effects_atk, effects_def, effects_atk_r, effects_def_r;
int32 swap_final = FALSE, swap_final_b = FALSE;
for(int32 i = 0; i < eset.size(); ++i) {
switch(eset[i]->code) {
case EFFECT_UPDATE_ATTACK:
if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE))
up_atk += eset[i]->get_value(this);
else
upc_atk += eset[i]->get_value(this);
break;
case EFFECT_SET_ATTACK:
atk = eset[i]->get_value(this);
if(!(eset[i]->type & EFFECT_TYPE_SINGLE))
up_atk = 0;
break;
case EFFECT_SET_ATTACK_FINAL:
if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
atk = eset[i]->get_value(this);
up_atk = 0;
upc_atk = 0;
} else {
if(!eset[i]->is_flag(EFFECT_FLAG_DELAY))
effects_atk.add_item(eset[i]);
else
effects_atk_r.add_item(eset[i]);
}
break;
case EFFECT_SET_BASE_ATTACK:
batk = eset[i]->get_value(this);
if(batk < 0)
batk = 0;
temp.base_attack = batk;
atk = -1;
break;
case EFFECT_UPDATE_DEFENCE:
if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE))
up_def += eset[i]->get_value(this);
else
upc_def += eset[i]->get_value(this);
break;
case EFFECT_SET_DEFENCE:
def = eset[i]->get_value(this);
if(!(eset[i]->type & EFFECT_TYPE_SINGLE))
up_def = 0;
break;
case EFFECT_SET_DEFENCE_FINAL:
if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
def = eset[i]->get_value(this);
up_def = 0;
upc_def = 0;
} else {
if(!eset[i]->is_flag(EFFECT_FLAG_DELAY))
effects_def.add_item(eset[i]);
else
effects_def_r.add_item(eset[i]);
}
break;
case EFFECT_SET_BASE_DEFENCE:
bdef = eset[i]->get_value(this);
if(bdef < 0)
bdef = 0;
def = -1;
break;
case EFFECT_SWAP_AD:
if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
atk = currect_def;
up_atk = 0;
upc_atk = 0;
def = temp.attack;
up_def = 0;
upc_def = 0;
} else
swap_final = !swap_final;
break;
case EFFECT_SWAP_BASE_AD:
if(!(eset[i]->type & EFFECT_TYPE_FIELD)) {
std::swap(batk, bdef);
temp.base_attack = batk;
} else
swap_final_b = !swap_final_b;
break;
}
if(!rev) {
temp.attack = ((atk < 0) ? batk : atk) + up_atk + upc_atk;
currect_def = ((def < 0) ? bdef : def) + up_def + upc_def;
} else {
temp.attack = ((atk < 0) ? batk : atk) - up_atk - upc_atk;
currect_def = ((def < 0) ? bdef : def) - up_def - upc_def;
}
if(temp.attack < 0)
temp.attack = 0;
}
if(swap_final_b) {
batk = bdef;
temp.base_attack = batk;
if(!rev) {
temp.attack = ((atk < 0) ? batk : atk) + up_atk + upc_atk;
currect_def = ((def < 0) ? bdef : def) + up_def + upc_def;
} else {
temp.attack = ((atk < 0) ? batk : atk) - up_atk - upc_atk;
currect_def = ((def < 0) ? bdef : def) - up_def - upc_def;
}
if(temp.attack < 0)
temp.attack = 0;
}
if(swap_final) {
temp.attack = currect_def;
if(temp.attack < 0)
temp.attack = 0;
}
for(int32 i = 0; i < effects_atk.size(); ++i)
temp.attack = effects_atk[i]->get_value(this);
for(int32 i = 0; i < effects_atk_r.size(); ++i) {
temp.attack = effects_atk_r[i]->get_value(this);
if(effects_atk_r[i]->is_flag(EFFECT_FLAG_REPEAT))
temp.attack = effects_atk_r[i]->get_value(this);
}
atk = temp.attack;
if(atk < 0)
atk = 0;
temp.base_attack = -1;
temp.attack = -1;
return atk; return atk;
} }
int32 card::get_base_defence(uint8 swap) { int32 card::get_base_defence() {
if(!(data.type & TYPE_MONSTER) && !(get_type() & TYPE_MONSTER) && !is_affected_by_effect(EFFECT_PRE_MONSTER)) if(!(data.type & TYPE_MONSTER) && !(get_type() & TYPE_MONSTER) && !is_affected_by_effect(EFFECT_PRE_MONSTER))
return 0; return 0;
if (current.location != LOCATION_MZONE || is_status(STATUS_SUMMONING)) if (current.location != LOCATION_MZONE || is_status(STATUS_SUMMONING))
return data.defence; return data.defence;
if (temp.base_defence != -1) if (temp.base_defence != -1)
return temp.base_defence; return temp.base_defence;
int32 bdef; int32 batk = data.attack;
calc_attack_defence(0, &bdef, 0, 0); if(batk < 0)
batk = 0;
int32 bdef = data.defence;
if(bdef < 0)
bdef = 0;
temp.base_defence = bdef;
effect_set eset;
filter_effect(EFFECT_SWAP_BASE_AD, &eset, FALSE);
int32 swap = eset.size();
filter_effect(EFFECT_SET_BASE_DEFENCE, &eset, FALSE);
if(swap)
filter_effect(EFFECT_SET_BASE_ATTACK, &eset, FALSE);
eset.sort();
int32 swap_final_b = FALSE;
for(int32 i = 0; i < eset.size(); ++i) {
switch(eset[i]->code) {
case EFFECT_SET_BASE_ATTACK:
batk = eset[i]->get_value(this);
if(batk < 0)
batk = 0;
break;
case EFFECT_SET_BASE_DEFENCE:
bdef = eset[i]->get_value(this);
if(bdef < 0)
bdef = 0;
break;
case EFFECT_SWAP_BASE_AD:
if(!(eset[i]->type & EFFECT_TYPE_FIELD))
std::swap(batk, bdef);
else
swap_final_b = !swap_final_b;
break;
}
temp.base_defence = bdef;
}
if(swap_final_b)
bdef = batk;
temp.base_defence = -1;
return bdef; return bdef;
} }
int32 card::get_defence() { int32 card::get_defence() {
...@@ -434,54 +659,54 @@ int32 card::get_defence() { ...@@ -434,54 +659,54 @@ int32 card::get_defence() {
return data.defence; return data.defence;
if (temp.defence != -1) if (temp.defence != -1)
return temp.defence; return temp.defence;
int32 def; int32 batk = data.attack;
calc_attack_defence(0, 0, 0, &def); if(batk < 0)
return def; batk = 0;
} int32 bdef = data.defence;
void card::calc_attack_defence(int32 *pbatk, int32 *pbdef, int32 *patk, int32 *pdef) { if(bdef < 0)
int32 atk = data.attack; bdef = 0;
if(atk < 0) temp.base_defence = bdef;
atk = 0; temp.defence = bdef;
int32 def = data.defence; int32 atk = -1;
if(def < 0) int32 def = -1;
def = 0; int32 current_atk = batk;
temp.base_attack = atk;
temp.base_defence = def;
temp.attack = atk;
temp.defence = def;
int32 up_atk = 0, upc_atk = 0; int32 up_atk = 0, upc_atk = 0;
int32 up_def = 0, upc_def = 0; int32 up_def = 0, upc_def = 0;
effect_set eset; effect_set eset;
filter_effect(EFFECT_SWAP_AD, &eset, FALSE); filter_effect(EFFECT_SWAP_AD, &eset, FALSE);
filter_effect(EFFECT_UPDATE_ATTACK, &eset, FALSE); filter_effect(EFFECT_SWAP_BASE_AD, &eset, FALSE);
filter_effect(EFFECT_SET_ATTACK, &eset, FALSE); int32 swap = eset.size();
filter_effect(EFFECT_SET_ATTACK_FINAL, &eset, FALSE);
filter_effect(EFFECT_UPDATE_DEFENCE, &eset, FALSE); filter_effect(EFFECT_UPDATE_DEFENCE, &eset, FALSE);
filter_effect(EFFECT_SET_DEFENCE, &eset, FALSE); filter_effect(EFFECT_SET_DEFENCE, &eset, FALSE);
filter_effect(EFFECT_SET_DEFENCE_FINAL, &eset, FALSE); filter_effect(EFFECT_SET_DEFENCE_FINAL, &eset, FALSE);
filter_effect(EFFECT_SWAP_BASE_AD, &eset, FALSE); filter_effect(EFFECT_SET_BASE_DEFENCE, &eset, FALSE);
filter_effect(EFFECT_SET_BASE_ATTACK, &eset, FALSE); if(swap) {
filter_effect(EFFECT_SET_BASE_DEFENCE, &eset); filter_effect(EFFECT_UPDATE_ATTACK, &eset, FALSE);
filter_effect(EFFECT_SET_ATTACK, &eset, FALSE);
filter_effect(EFFECT_SET_ATTACK_FINAL, &eset, FALSE);
filter_effect(EFFECT_SET_BASE_ATTACK, &eset, FALSE);
}
eset.sort();
int32 rev = FALSE; int32 rev = FALSE;
if (is_affected_by_effect(EFFECT_REVERSE_UPDATE)) if(is_affected_by_effect(EFFECT_REVERSE_UPDATE))
rev = TRUE; rev = TRUE;
effect_set effects_atk, effects_def, effects_atk_r, effects_def_r; effect_set effects_atk, effects_def, effects_atk_r, effects_def_r;
int32 swap_b_final = FALSE, swap_final = FALSE; int32 swap_final = FALSE, swap_final_b = FALSE;
for (int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
switch (eset[i]->code) { switch(eset[i]->code) {
case EFFECT_UPDATE_ATTACK: case EFFECT_UPDATE_ATTACK:
if ((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE))
up_atk += eset[i]->get_value(this); up_atk += eset[i]->get_value(this);
else else
upc_atk += eset[i]->get_value(this); upc_atk += eset[i]->get_value(this);
break; break;
case EFFECT_SET_ATTACK: case EFFECT_SET_ATTACK:
atk = eset[i]->get_value(this); atk = eset[i]->get_value(this);
if (!(eset[i]->type & EFFECT_TYPE_SINGLE)) if(!(eset[i]->type & EFFECT_TYPE_SINGLE))
up_atk = 0; up_atk = 0;
break; break;
case EFFECT_SET_ATTACK_FINAL: case EFFECT_SET_ATTACK_FINAL:
if ((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) { if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
atk = eset[i]->get_value(this); atk = eset[i]->get_value(this);
up_atk = 0; up_atk = 0;
upc_atk = 0; upc_atk = 0;
...@@ -493,22 +718,24 @@ void card::calc_attack_defence(int32 *pbatk, int32 *pbdef, int32 *patk, int32 *p ...@@ -493,22 +718,24 @@ void card::calc_attack_defence(int32 *pbatk, int32 *pbdef, int32 *patk, int32 *p
} }
break; break;
case EFFECT_SET_BASE_ATTACK: case EFFECT_SET_BASE_ATTACK:
atk = eset[i]->get_value(this); batk = eset[i]->get_value(this);
temp.base_attack = atk; if(batk < 0)
batk = 0;
atk = -1;
break; break;
case EFFECT_UPDATE_DEFENCE: case EFFECT_UPDATE_DEFENCE:
if ((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE))
up_def += eset[i]->get_value(this); up_def += eset[i]->get_value(this);
else else
upc_def += eset[i]->get_value(this); upc_def += eset[i]->get_value(this);
break; break;
case EFFECT_SET_DEFENCE: case EFFECT_SET_DEFENCE:
def = eset[i]->get_value(this); def = eset[i]->get_value(this);
if (!(eset[i]->type & EFFECT_TYPE_SINGLE)) if(!(eset[i]->type & EFFECT_TYPE_SINGLE))
up_def = 0; up_def = 0;
break; break;
case EFFECT_SET_DEFENCE_FINAL: case EFFECT_SET_DEFENCE_FINAL:
if ((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) { if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
def = eset[i]->get_value(this); def = eset[i]->get_value(this);
up_def = 0; up_def = 0;
upc_def = 0; upc_def = 0;
...@@ -520,81 +747,72 @@ void card::calc_attack_defence(int32 *pbatk, int32 *pbdef, int32 *patk, int32 *p ...@@ -520,81 +747,72 @@ void card::calc_attack_defence(int32 *pbatk, int32 *pbdef, int32 *patk, int32 *p
} }
break; break;
case EFFECT_SET_BASE_DEFENCE: case EFFECT_SET_BASE_DEFENCE:
def = eset[i]->get_value(this); bdef = eset[i]->get_value(this);
temp.base_defence = def; if(bdef < 0)
bdef = 0;
temp.base_defence = bdef;
def = -1;
break; break;
case EFFECT_SWAP_AD: case EFFECT_SWAP_AD:
if ((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) { if((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
atk = temp.defence; atk = temp.defence;
up_atk = 0; up_atk = 0;
upc_atk = 0; upc_atk = 0;
def = temp.attack; def = current_atk;
up_def = 0; up_def = 0;
upc_def = 0; upc_def = 0;
} else } else
swap_final = !swap_final; swap_final = !swap_final;
break; break;
case EFFECT_SWAP_BASE_AD: case EFFECT_SWAP_BASE_AD:
if ((eset[i]->type & EFFECT_TYPE_SINGLE) && !eset[i]->is_flag(EFFECT_FLAG_SINGLE_RANGE)) if(!(eset[i]->type & EFFECT_TYPE_FIELD)) {
std::swap(temp.base_attack, temp.base_defence); std::swap(batk, bdef);
else temp.base_defence = bdef;
swap_b_final = !swap_b_final; } else
swap_final_b = !swap_final_b;
break; break;
} }
if (!rev) { if(!rev) {
temp.attack = atk + up_atk + upc_atk; current_atk = ((atk < 0) ? batk : atk) + up_atk + upc_atk;
temp.defence = def + up_def + upc_def; temp.defence = ((def < 0) ? bdef : def) + up_def + upc_def;
} else { } else {
temp.attack = atk - up_atk - upc_atk; current_atk = ((atk < 0) ? batk : atk) - up_atk - upc_atk;
temp.defence = def - up_def - upc_def; temp.defence = ((def < 0) ? bdef : def) - up_def - upc_def;
} }
} if(temp.defence < 0)
if (swap_b_final) temp.defence = 0;
std::swap(temp.base_attack, temp.base_defence); }
if (pbatk) { if(swap_final_b) {
int32 batk = temp.base_attack; bdef = batk;
if (batk < 0) temp.base_defence = bdef;
batk = 0; if(!rev) {
*pbatk = batk; current_atk = ((atk < 0) ? batk : atk) + up_atk + upc_atk;
} temp.defence = ((def < 0) ? bdef : def) + up_def + upc_def;
if (pbdef) { } else {
int32 bdef = temp.base_defence; current_atk = ((atk < 0) ? batk : atk) - up_atk - upc_atk;
if (bdef < 0) temp.defence = ((def < 0) ? bdef : def) - up_def - upc_def;
bdef = 0;
*pbdef = bdef;
}
if (swap_final)
std::swap(temp.attack, temp.defence);
if (patk) {
for (int32 i = 0; i < effects_atk.size(); ++i)
temp.attack = effects_atk[i]->get_value(this);
for(int32 i = 0; i < effects_atk_r.size(); ++i) {
temp.attack = effects_atk_r[i]->get_value(this);
if(effects_atk_r[i]->is_flag(EFFECT_FLAG_REPEAT))
temp.attack = effects_atk_r[i]->get_value(this);
} }
int32 atk = temp.attack; if(temp.defence < 0)
if (atk < 0) temp.defence = 0;
atk = 0; }
*patk = atk; if(swap_final) {
} temp.defence = current_atk;
if (pdef) { if(temp.defence < 0)
for (int32 i = 0; i < effects_def.size(); ++i) temp.defence = 0;
temp.defence = effects_def[i]->get_value(this); }
for(int32 i = 0; i < effects_def_r.size(); ++i) { for(int32 i = 0; i < effects_def.size(); ++i)
temp.defence = effects_def[i]->get_value(this);
for(int32 i = 0; i < effects_def_r.size(); ++i) {
temp.defence = effects_def_r[i]->get_value(this);
if(effects_def_r[i]->is_flag(EFFECT_FLAG_REPEAT))
temp.defence = effects_def_r[i]->get_value(this); temp.defence = effects_def_r[i]->get_value(this);
if(effects_def_r[i]->is_flag(EFFECT_FLAG_REPEAT))
temp.defence = effects_def_r[i]->get_value(this);
}
int32 def = temp.defence;
if (def < 0)
def = 0;
*pdef = def;
} }
temp.base_attack = -1; def = temp.defence;
temp.attack = -1; if(def < 0)
def = 0;
temp.base_defence = -1; temp.base_defence = -1;
temp.defence = -1; temp.defence = -1;
return def;
} }
// Level/Attribute/Race is available for: // Level/Attribute/Race is available for:
// 1. cards with original type TYPE_MONSTER or // 1. cards with original type TYPE_MONSTER or
......
...@@ -162,11 +162,10 @@ public: ...@@ -162,11 +162,10 @@ public:
int32 is_pre_set_card(uint32 set_code); int32 is_pre_set_card(uint32 set_code);
int32 is_fusion_set_card(uint32 set_code); int32 is_fusion_set_card(uint32 set_code);
uint32 get_type(); uint32 get_type();
int32 get_base_attack(uint8 swap = FALSE); int32 get_base_attack();
int32 get_attack(); int32 get_attack();
int32 get_base_defence(uint8 swap = FALSE); int32 get_base_defence();
int32 get_defence(); int32 get_defence();
void calc_attack_defence(int32 *pbatk, int32 *pbdef, int32 *patk, int32 *pdef);
uint32 get_level(); uint32 get_level();
uint32 get_rank(); uint32 get_rank();
uint32 get_synchro_level(card* pcard); uint32 get_synchro_level(card* pcard);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment