per mizar
Inviato: mer nov 25, 2009 2:54 am
CALCOLO DEL PWP DI UN PG:
Codice:
Questo blocco contiene le funzioni necessarie per calcolare il PWP di un pg e contiene la tabella di valori in pq degli apply (con solo un paio di apply inseriti per testing). c'e' anche la tabella delle weaponspell (anche da riempire)
Il test di un pg triclasse:
prac 90hp
prac 25 dam
train 3 damroll
pezzo di eq1: ARMA 45d1 5DAM TRIPLESLAY RES FIRE COLD ELECT BLUNT, affect SANC, WS critical
pezzo di eq2: ancora una volta la stessa spada
Codice:
C:\Test\Test>pwp.exe
VAL APPLY 1 VALORE PQ: 2000 (Tipo:19,Valore:5)
BTV APPLY 2 VALORE PQ: 4000 (Tipo:29,Valore:64)
SPC APPLY 3 VALORE PQ: 3200 (Tipo:30,Valore:56)
BTV APPLY 4 VALORE PQ: 12000 (Tipo:49,Valore:7)
BTV APPLY 5 VALORE PQ: 8800 (Tipo:26,Valore:31)
ARMA MEDIA DAM 45 (PQ 18000)
PWP TOTALE DELL OGGETTO 480
VAL APPLY 1 VALORE PQ: 2000 (Tipo:19,Valore:5)
BTV APPLY 2 VALORE PQ: 4000 (Tipo:29,Valore:64)
SPC APPLY 3 VALORE PQ: 3200 (Tipo:30,Valore:56)
BTV APPLY 4 VALORE PQ: 12000 (Tipo:49,Valore:7)
BTV APPLY 5 VALORE PQ: 8800 (Tipo:26,Valore:31)
ARMA MEDIA DAM 45 (PQ 18000)
PWP TOTALE DELL OGGETTO 480
PWP PRAC: 136
PWP TRAIN: 24
PWP LEVEL: 168
Valore PWP TOTALE DELL PG: 1288
Codice:
Codice: Seleziona tutto
#include "structs.h"
#include "utils.h"
#include "spells.h"
#include <iostream>
#define PWP_NORMALIZATION 100
using namespace std;
long GetPQValue(obj_data obj, int apply);
long CalcPWP(obj_data obj);
long CalcPWP(char_data *ch);
int FindApplyIndex(short type);
long calcProgressiveCost(long cost, long bitvector, int bits[]);
long getApplyCost(short apply);
int FindWSIndex(long ws);
// tabella dei costi in pq degli apply
static struct ApplyPwpPrice {
short type; /* tipo apply */
long cost; /* costo in pq per ogni unita dell apply */
int isbitvector; /* 1 se e uno slot che non tiene un valore ma un vettore di bit es. ALIGN SLAYER by GOOD NEUTRAL EVIL */
int bitprice[32];
} PwpCostTable[]={
{ APPLY_DAMROLL , 400, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
{ APPLY_HIT , 40, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
{ APPLY_WEAPON_SPELL , 0, 2, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
{ APPLY_ABSORB_DAMAGE , 400, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
/* spell affect: messo solo sanc */
{ APPLY_SPELL , 0, 1, {0,0,0,0,0,0,4000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
/* align slay: un bitvector con costo progressivo 1000 per ogni bit acceso: trislay: 3000+(3000+1000)+(3000+2*1000) */
{ APPLY_ALIGN_SLAYER , 1000, 1, {3000,3000,3000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
/* resistenze, da finire */
{ APPLY_IMMUNE , 0, 1, {1200,1200,1200,1200,4000,1800,3000,1200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
/* immunita, da finire */
{ APPLY_M_IMMUNE , 0, 1, {5000,5000,5000,5000,9000,5000,7000,5000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
/* AGGIUNGERE ALTRI APPLY */
};
// tabella dei costi in pq delle weaponspell
static struct WeaponSpellPwpPrice {
long ws; /* tipo weaponspell */
long cost; /* costo in pq per la weaponspell */
} PwpWSCostTable[]={
{ SPELL_CAUSE_CRITICAL , 3200},
{ SPELL_FREEZE , 400}
};
// per testing (calcola il pwp di un pg triclasse con qualche prac e 2 x arma 45d1, 5 Dam, affect sanc, ws critical, triple slay, res varie)
int main(int argc, char *argv[]) {
obj_data *ob = (obj_data*)calloc(1,sizeof(obj_data));
ob->obj_flags.type_flag = ITEM_WEAPON;
ob->obj_flags.value[1] = 45;
ob->obj_flags.value[2] = 1;
ob->affected[0].location = APPLY_DAMROLL;
ob->affected[0].modifier = 5;
ob->affected[1].location = APPLY_SPELL;
ob->affected[1].modifier = 64; // sanc
ob->affected[2].location = APPLY_WEAPON_SPELL;
ob->affected[2].modifier = SPELL_CAUSE_CRITICAL;
ob->affected[3].location = APPLY_ALIGN_SLAYER;
ob->affected[3].modifier = 7;
ob->affected[4].location = APPLY_IMMUNE; // resistenza
ob->affected[4].modifier = 31; // fire cold elect energy blunt
char_data *ch = (char_data*)calloc(1,sizeof(char_data));
ch->equipment[0] = ob; // metto la spada come eq pezzo 1
ch->equipment[1] = ob; // metto la spada come eq pezzo 2
ch->points.cindy.hit = 90; // prac 90 HP
ch->points.cindy.damroll = 25; // prac 25 dam
ch->points.sig_cindy.damroll = 3; // train 3 dam
ch->player.level[0] = 50; // superior classe 0
ch->player.level[1] = 50; // superior classe 1
ch->player.level[3] = 50; // superior classe 2
int value = CalcPWP(ch);
free(ch);
free(ob);
cout << "Valore PWP TOTALE DELL PG: " << value << endl;
}
// calcola il pwp totale di un oggetto (obj_data)
long CalcPWP(obj_data obj) {
long total = 0;
int isweapon = GET_ITEM_TYPE( &obj ) == ITEM_WEAPON ? 1 : 0;
int i = 0;
for (i = 0; i < MAX_OBJ_AFFECT; i++)
{
long pq = GetPQValue(obj, i);
cout << "APPLY " << i+1 << " VALORE PQ: " << pq
<< " (Tipo:" << obj.affected[i].location
<< ",Valore:" << obj.affected[i].modifier << ")" << endl;
total += pq;
}
if (isweapon) {
int numdadi = obj.obj_flags.value[1];
int numfacce = obj.obj_flags.value[2];
double media = (int)((double)numdadi * ((double)(numfacce+1) / 2));
cout << "ARMA MEDIA DAM " << media << " (PQ " << media * PwpCostTable[FindApplyIndex(APPLY_DAMROLL)].cost << ") " << endl;
total += (long)(media * PwpCostTable[FindApplyIndex(APPLY_DAMROLL)].cost);
}
cout << "PWP TOTALE DELL OGGETTO " << total / PWP_NORMALIZATION << endl;
return total / PWP_NORMALIZATION;
}
// da il valore in pq di un apply (type = tipo apply, value = valore)
long GetPQValue(obj_data obj, int apply) {
long ret = 0;
short type = obj.affected[apply].location;
long value = obj.affected[apply].modifier;
int index = FindApplyIndex(type);
if (index == -1) {
return 0;
}
// casi speciali: weaponspell e varie
if (PwpCostTable[index].isbitvector > 1) {
cout << "SPC ";
if (PwpCostTable[index].isbitvector == 2) { // weaponspell
int wsindex = FindWSIndex(value);
if ( wsindex != -1) {
ret = PwpWSCostTable[wsindex].cost;
}
}
}
// bitvector : resistenze, affect e simile
else if (PwpCostTable[index].isbitvector!=0) {
cout << "BTV ";
ret = (long)calcProgressiveCost(PwpCostTable[index].cost, value, PwpCostTable[index].bitprice);
// apply normali con valore: dam hit etc
} else {
cout << "VAL ";
ret = (long)PwpCostTable[index].cost * value;
}
return ret;
}
// eleva un numero ad una potenza (es. 2^3 - serve per calcolare i bitvector)
long powNum(long num, long power) {
long count = 1;
int i;
for (i=1; i <=power; i++)
count = count*num;
return count;
}
// somma i costi di ogni bit attivo nel bitvector
// (es. trislay ha bitvector: 11100000000000000000000000000000 - equivale a 7 in decimale)
// basecost si aggiunge n volte per ogni bit attivo, dove n e la somma progressiva di bit attivi)
// trislay si definisce con basecost 1000 e si mette ogni slay a 3000
// quindi per trislay fa: 3000 + (3000+1000) + (3000+2000)
long calcProgressiveCost(long basecost, long bitvector, int bits[]) {
int i,bitstotal = 0;
long mask, ret = 0;
for (i=0; i<32;i++) {
mask = powNum(2,i);
if (bitvector & mask) {
bitstotal++;
ret += (long)((bitstotal-1)*basecost + bits[i]);
}
}
return ret;
}
// cerca la posizione dell apply nella tabella di costo in pq degli apply)
int FindApplyIndex(short type) {
int index = -1;
int i = 0;
int max = (int)sizeof(PwpCostTable)/sizeof(ApplyPwpPrice);
for (i = 0; i < max; i++) {
if (type == PwpCostTable[i].type) {
index = i;
break;
}
}
return index;
}
// cerca la posizione della WS nella tabella di costo in pq delle weaponspell)
int FindWSIndex(long ws) {
int index = -1;
int i = 0;
int max = (int)sizeof(PwpWSCostTable)/sizeof(WeaponSpellPwpPrice);
for (i = 0; i < max; i++) {
if (ws == PwpWSCostTable[i].ws) {
index = i;
break;
}
}
return index;
}
// il costo per unita di un apply
long getApplyCost(short apply) {
int index = FindApplyIndex(apply);
if (index == -1) return 0;
return PwpCostTable[FindApplyIndex(apply)].cost;
}
// calcola il pwp totale di un pg
long CalcPWP(char_data *ch) {
int i;
obj_data *obj;
long pwp = 0;
long pwp_eq = 0;
long pwp_prac = 0;
long pwp_train = 0;
long pwp_lev = 0;
for (i=0;i<MAX_WEAR;i++) {
if((obj = ch->equipment[i])){
pwp_eq += CalcPWP(*(obj));
}
}
// prac cindy
pwp_prac += ch->points.cindy.hit * getApplyCost(APPLY_HIT) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.hit_gain * getApplyCost(APPLY_HIT_REGEN) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.mana * getApplyCost(APPLY_MANA) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.mana_gain * getApplyCost(APPLY_MANA_REGEN) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.mov * getApplyCost(APPLY_MOVE) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.mov_gain * getApplyCost(APPLY_MOVE_REGEN) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.memorize * getApplyCost(APPLY_DAMROLL) / PWP_NORMALIZATION; // non ce apply per memo, uso il damroll
pwp_prac += ch->points.cindy.spellpower * getApplyCost(APPLY_SPELL_POWER) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.damroll * getApplyCost(APPLY_DAMROLL) / PWP_NORMALIZATION;
pwp_prac += ch->points.cindy.hitroll * getApplyCost(APPLY_HITROLL) / PWP_NORMALIZATION;
cout << "PWP PRAC: " << pwp_prac << endl;
// train cindy
pwp_train += ch->points.sig_cindy.hit * 2 * getApplyCost(APPLY_HIT) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.hit_gain * 2 * getApplyCost(APPLY_HIT_REGEN) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.mana * 2 * getApplyCost(APPLY_MANA) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.mana_gain * 2 * getApplyCost(APPLY_MANA_REGEN) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.mov * 2 * getApplyCost(APPLY_MOVE) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.mov_gain * 2 * getApplyCost(APPLY_MOVE_REGEN) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.memorize * 2 * getApplyCost(APPLY_DAMROLL) / PWP_NORMALIZATION; // non ce apply per memo, uso il damroll
pwp_train += ch->points.sig_cindy.spellpower * 2 * getApplyCost(APPLY_SPELL_POWER) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.damroll * 2 * getApplyCost(APPLY_DAMROLL) / PWP_NORMALIZATION;
pwp_train += ch->points.sig_cindy.hitroll * 2 * getApplyCost(APPLY_HITROLL) / PWP_NORMALIZATION;
cout << "PWP TRAIN: " << pwp_train << endl;
// conta il num di classi
int classe, numclassi = 0;
for (classe = 0; classe < MAX_CLASS; classe++) {
if (ch->player.level[classe]>0) {
numclassi += 1;
}
}
pwp_lev = (pwp_eq + pwp_prac + pwp_train) * numclassi * 5/100; // pwp accumulato + 5% per classe
cout << "PWP LEVEL: " << pwp_lev << endl;
// sommiamo tutto
pwp = pwp_eq + pwp_prac + pwp_train + pwp_lev;
return pwp;
}
Il test di un pg triclasse:
prac 90hp
prac 25 dam
train 3 damroll
pezzo di eq1: ARMA 45d1 5DAM TRIPLESLAY RES FIRE COLD ELECT BLUNT, affect SANC, WS critical
pezzo di eq2: ancora una volta la stessa spada
Codice:
C:\Test\Test>pwp.exe
VAL APPLY 1 VALORE PQ: 2000 (Tipo:19,Valore:5)
BTV APPLY 2 VALORE PQ: 4000 (Tipo:29,Valore:64)
SPC APPLY 3 VALORE PQ: 3200 (Tipo:30,Valore:56)
BTV APPLY 4 VALORE PQ: 12000 (Tipo:49,Valore:7)
BTV APPLY 5 VALORE PQ: 8800 (Tipo:26,Valore:31)
ARMA MEDIA DAM 45 (PQ 18000)
PWP TOTALE DELL OGGETTO 480
VAL APPLY 1 VALORE PQ: 2000 (Tipo:19,Valore:5)
BTV APPLY 2 VALORE PQ: 4000 (Tipo:29,Valore:64)
SPC APPLY 3 VALORE PQ: 3200 (Tipo:30,Valore:56)
BTV APPLY 4 VALORE PQ: 12000 (Tipo:49,Valore:7)
BTV APPLY 5 VALORE PQ: 8800 (Tipo:26,Valore:31)
ARMA MEDIA DAM 45 (PQ 18000)
PWP TOTALE DELL OGGETTO 480
PWP PRAC: 136
PWP TRAIN: 24
PWP LEVEL: 168
Valore PWP TOTALE DELL PG: 1288