Browse Source

init : affiche la liste des personnages définit avec des actions leurs permettans de combattre

nas 2 years ago
parent
commit
434e4fb4a5
7 changed files with 1605 additions and 0 deletions
  1. 768
    0
      game/character.js
  2. 55
    0
      game/dice.js
  3. 42
    0
      game/display.js
  4. 165
    0
      game/l5r.js
  5. 156
    0
      helper/random.js
  6. 416
    0
      index.html
  7. 3
    0
      style/anim.css

+ 768
- 0
game/character.js View File

@@ -0,0 +1,768 @@
1
+class baseCharacter{
2
+
3
+    constructor( aRole, skills, gender, name, experience, gempukku ){
4
+        if( aRole in roleSkills )
5
+            this.role = aRole;
6
+        else
7
+            this.role = randomFromAssociative(roleSkills);
8
+
9
+        this.gempukku = gempukku || 0;
10
+        this.stamina = (this.rank() < 1)? 1 : 2 ;
11
+        this.willpower = (this.rank() < 1)? 1 : 2 ;
12
+        this.perception = (this.rank() < 1)? 1 : 2 ;
13
+        this.strength = (this.rank() < 1)? 1 : 2 ;
14
+        this.reflexes = (this.rank() < 1)? 1 : 2 ;
15
+        this.awarness = (this.rank() < 1)? 1 : 2 ;
16
+        this.agility = (this.rank() < 1)? 1 : 2 ;
17
+        this.intelligence = (this.rank() < 1)? 1 : 2 ;
18
+        this.void = (this.rank() < 1)? 1 : 2 ;
19
+
20
+        this.skills = ( typeof skills === "object")? skills : {};
21
+        this.gender = (typeof gender !== "undefined")? gender : r_gender();
22
+        this.name = (name !== "undefined")? { "name" : name, "gender" : gender}: names.randomFromFilters([{ filter : "gender", value : this.gender },{ filter : "gender", value : "n" }]) ;
23
+        this.experience = (typeof experience === "undefined")? 25 : experience ;
24
+        this.expandedExperience = 0;
25
+        this.malus = 0 ;
26
+        this.actualizeWounds();
27
+        this.currentWounds = this.maxWounds;
28
+
29
+        this.actions[ 'attack' ] = { actionType : "complex" };
30
+        this.actions[ 'unarmed attack' ] = { actionType : "complex" };
31
+        this.actions[ 'move' ] = { actionType : "simple" };
32
+        this.actions[ 'draw small' ] = { actionType : "free" };
33
+        this.actions[ 'draw medium' ] = { actionType : "simple" };
34
+        this.actions[ 'draw large' ] = { actionType : "simple" };
35
+    }
36
+
37
+    actions = new Array();
38
+    tatoos = new Array();
39
+    
40
+    earth () { return ( this.stamina < this.willpower)? this.stamina : this.willpower ;}
41
+    water () { return ( this.strength < this.perception)? this.strength : this.perception ;}
42
+    air () { return ( this.reflexes < this.awarness)? this.reflexes : this.awarness ;}
43
+    fire () { return ( this.agility < this.intelligence)? this.agility : this.intelligence ;}
44
+
45
+    insight(){
46
+        let resultat = (this.earth() + this.water() + this.air() + this.fire() + this.void) * 10 ;
47
+
48
+        if(typeof this.skills == "object")
49
+        for(let i in this.skills)
50
+            resultat += parseInt(this.skills[i]);
51
+        return resultat;    
52
+    }
53
+
54
+    rank(){
55
+        let insight = this.insight();
56
+        switch( insight ){
57
+        case( !this.gempukku ):
58
+            return 0;
59
+            break;
60
+        case ( insight > 150 ):
61
+            return 1;
62
+        default :
63
+            return Math.round((insight - 125)/25);
64
+        }
65
+    }
66
+    
67
+    skills = {};
68
+    skillsFromAction(){
69
+
70
+    }
71
+    
72
+    actionPoints = 2 ;
73
+    freeAction = false;
74
+
75
+    complexAction(){
76
+	if (this.actionPoints >= 2){
77
+	    this.actionPoints -= 2 ;
78
+	    return true;
79
+	}
80
+	return false;
81
+    }
82
+
83
+    simpleAction(){
84
+	if(this.actionPoints > 1){
85
+	    this.actionPoints -= 1;
86
+	    return true
87
+	}
88
+    }
89
+
90
+    freeAction(){
91
+	if( this.freeAction ){
92
+	    return false;
93
+	}else{
94
+	    return this.freeAction = true ;
95
+	}	
96
+    }
97
+
98
+    chooseTatoo(){
99
+
100
+    };
101
+    
102
+    weapons = {
103
+        "wakizachi" : weapons["wakizachi"]
104
+    };
105
+
106
+    armors = [];
107
+    equippedArmor = "kimono";
108
+
109
+    equippedArrow = "willow leaf";
110
+
111
+    rollMade = {};
112
+
113
+    baseGetTN(){
114
+        let armorTN = 0;
115
+        let modifier = 0;
116
+
117
+        switch(this.stance){
118
+        case "full attack":
119
+            modifier = -10;
120
+            break;
121
+        case "full defense":
122
+            modifier = this.rollMade["defense"];
123
+            break;
124
+        case "defense":
125
+            modifier = this.air() + this.getSkillRank( 'defense' );
126
+            break;
127
+        }
128
+        if ( typeof armors[ this.equippedArmor ].TN !== "undefined")
129
+            armorTN = armors[ this.equippedArmor ].TN;
130
+
131
+        return 5 + armorTN + (this.reflexes * 5) + modifier;
132
+    }
133
+
134
+    naturalDR = 0;
135
+
136
+    getName(){
137
+        return capitalize( this.name.familly ) + " " + capitalize( this.name.name );
138
+    }
139
+    
140
+    dr(){
141
+        let armorDR = 0;
142
+        for (var armor in this.equippedArmor)
143
+            if ( typeof armor.DR !== "undefined")
144
+                armorDR = armor.DR;
145
+
146
+        return this.naturalDR + armorDR;
147
+    }
148
+
149
+    addWeapon( weapon ){
150
+        if( typeof this.weapons[ weapon ] === "objects" )
151
+           return null;              
152
+        this.weapons[ weapon ] = weapons[ weapon ];
153
+    };
154
+
155
+    advantages = [];
156
+    addAdvantages ( newAdvantage ){
157
+        if( typeof this.advantages.find(element => element == newAdvantage ) === "undefined" ){
158
+            return null;
159
+        }
160
+        let cost;                            
161
+        for( advantage in  advantages[ newAdvantage ] )
162
+             if( this.name.familly in advantages[ newAdvantage ] ){
163
+                cost = advantages[ newAdvantage ][ this.name.familly ];
164
+             } else if ( this.clan in advantages[ newAdvantage ] ){
165
+                advantages[ newAdvantage ][ this.clan ];
166
+             } else if ( this.clan in advantages[ newAdvantage ] ){
167
+                advantages[ newAdvantage ][ this.role ];
168
+             } else {
169
+                cost = advantages[ newAdvantage ][ "default" ];
170
+             }
171
+    }
172
+
173
+    hasAdvantage( advantage){
174
+         if( typeof this.advantages.find(element => element == advantage ) === "undefined" ){
175
+            return 0;
176
+         }
177
+            return 1;
178
+    }
179
+
180
+    act( action ){
181
+	if( this.actions.indexOf( action ) == -1){
182
+	    return this.complexAction();
183
+	}else{
184
+	    return this[ actions[ action ].actionType + 'Action' ]();
185
+	}
186
+    }
187
+    
188
+    baseAttack( attackType ){
189
+        let modifier_r = 0;
190
+        let modifier_k = 0;
191
+        if( this.stance = "full attack"){
192
+            modifier_r = 2;
193
+            modifier_k = 1;
194
+        };
195
+
196
+	if( typeof attackType !== "undefined" ){
197
+	    
198
+        }else if( (typeof defaultAttacks === "undefined") ||
199
+            (typeof defaultAttacks.expandedExperience === "undefined") ||
200
+            (defaultAttacks.expandedExperience < this.expandedExperience)){
201
+
202
+                let attack =  Object.keys(this.updateAttacks())[0];
203
+                if( attack == "jiujutsu" ){
204
+                    return {"r" : this.strength + modifier_r, "k" : 1 + modifier_k};
205
+                }else{
206
+                    let skill =  0;
207
+                    if((skill = this.skills[ this.weapons[ attack ].skill ]) in this.skills){
208
+                        return {"r" : skill[0] + modifier_r, "k" : skill[1] + modifier_k};
209
+                    }
210
+
211
+                    return {"r" : this[skills[weapons[ attack ].skill].trait] + modifier_r, "k" : this[skills[weapons[ attack ].skill].trait] + modifier_k, "x" : 11};
212
+               }
213
+        }
214
+        return { "r" : this.defaultAttacks[ Object.keys(this.defaultAttacks)[0] ]['attack'].r + modifier_r,
215
+                 "k" : this.defaultAttacks[ Object.keys(this.defaultAttacks)[0] ]['attack'].k + modifier_k };
216
+   }
217
+
218
+    attackFromWeapon( weapon ){
219
+        let trait = parseInt( this[skills[ this.weapons[weapon].skill ].trait], 10);
220
+        let skill = parseInt( this.skills[ this.weapons[weapon].skill ], 10) || 0;
221
+        return({ "r" : trait + skill, "k" : trait, "x" : (skill)? 10: 11});
222
+    }
223
+
224
+    damageFromWeapon( weapon ){
225
+        if( weapons[ weapon ].type == "bow"){
226
+                let arrow = arrows[ this.equippedArrow ];
227
+                return {
228
+                    "r" : arrow.r + ( weapon.strength <= this.strength )? weapon.strength : this.strength,
229
+                    "k" : arrow.k}
230
+        }
231
+        return({ "r" : parseInt(this.strength, 10) +  parseInt(weapons[ weapon ].damage.split("G")[0], 10) ,
232
+                 "k" :  parseInt(weapons[ weapon ].damage.split("G")[1], 10) });
233
+    }
234
+
235
+    damage(){
236
+        if( (typeof defaultAttacks === "undefined") ||
237
+            (typeof defaultAttacks.expandedExperience === "undefined") ||
238
+            (defaultAttacks.expandedExperience < this.expandedExperience)){
239
+
240
+            let weapon = Object.keys(this.updateAttacks())[0]
241
+
242
+            if( weapon == "jiujutsu")
243
+                return {"r" : this.strength, "k" : 1};
244
+            else if( weapon.type == "bow"){
245
+                let arrow = arrows[ this.equippedArrow ];
246
+                return {
247
+                    "r" : arrow.r + ( bow_strength <= this.strength )? weapon.strength : this.strength,
248
+                    "k" : arrow.k
249
+                }
250
+            }else{
251
+                let damage = weapons[ weapon ]['damage'].split("G");
252
+                return {"r" :damage[0], "k" : damage[1]};
253
+            }
254
+        }
255
+
256
+        return  this.defaultAttacks[ (Object.keys( this.defaultAttacks)[0]) ];
257
+    }
258
+
259
+    initiative(){
260
+        return { "r" : this.rank() + this.reflexes , "k" : this.reflexes };
261
+    }
262
+    
263
+    getAttack(){
264
+        let roll = this.attack();
265
+        let modifier_r = 0;
266
+        let modifier_k = 0;
267
+        if( this.stance = "full attack"){
268
+            modifier_r = 2;
269
+            modifier_k = 1;
270
+        }
271
+        return RNG.rk10(roll.r, roll.k, this.malus);
272
+    }
273
+
274
+    getInitiative(){
275
+        let roll = this.initiative();
276
+        return RNG.rk10(roll.r, roll.k);
277
+    }
278
+
279
+    getDamage(){
280
+        let roll = this.damage();
281
+        return RNG.rk10(roll.r, roll.k);
282
+    }
283
+
284
+    getSkillRank( aSkill ){
285
+	return this.skills[ aSkill ] || 0; 
286
+    }
287
+    
288
+    allAttacks(){
289
+        let result = {};
290
+        if( "jiujutsu" in this.skills ){
291
+            result['jiujutsu'] = { "attack" : { "r" : parseInt(this.agility, 10) + parseInt(this.skills[ 'jiujutsu' ], 10), "k": this.agility }, "damage" : { "r" : this.strength, "k" : 1} };
292
+        }
293
+        for(let i in this.weapons){
294
+            result[ i ] = { "attack" : this.attackFromWeapon( i ), "damage" : this.damageFromWeapon( i ) };
295
+        }
296
+        /*(result)*/
297
+        return result;
298
+    }
299
+
300
+    attacking( charac ){
301
+        if( this.getAttack() > charac.getTN()){
302
+            charac.getWounded ( this.getDamage() );
303
+        }
304
+    }
305
+    
306
+    defaultAttacks = {};
307
+    attacks(){
308
+        if( (typeof defaultAttacks === "undefined") ||
309
+            (typeof defaultAttacks.expandedExperience === "undefined") ||
310
+            (defaultAttacks.expandedExperience < this.expandedExperience))
311
+            return this.updateAttacks();
312
+        return this.defaultAttacks[1]['attack'];
313
+    }
314
+    
315
+    updateAttacks(){
316
+        let bestAttack = 0;
317
+        let bestDamage = 0;
318
+        let attacks = this.allAttacks();
319
+
320
+        for(let i in attacks){
321
+            if( !bestAttack )
322
+                bestAttack = i ;
323
+            if( (attacks[i].k > attacks[ bestAttack ].k ) ||
324
+                ((attacks[i].k = attacks[ bestAttack ]) && (attacks[i].r < attacks[ bestAttack ].r )) ||
325
+                ( attacks[i].r < (attacks[ bestAttack ].r + 2 ))){
326
+                bestAttack = i ;
327
+            };
328
+            if( !bestDamage )
329
+                bestDamage = i ;
330
+            if( (attacks[i].k > attacks[ bestDamage ].k ) ||
331
+                ((attacks[i].k = attacks[ bestDamage ]) && (attacks[i].r < attacks[ bestDamage ]).r ) ||
332
+                ( attacks[i].r < (attacks[ bestDamage ].r + 2 ))){
333
+                bestDamage = i ;
334
+            };            
335
+            if( !bestDamage )
336
+                bestDamage = i ;
337
+        }
338
+        this.defaultAttacks[bestAttack] = attacks[ bestAttack ];
339
+        this.defaultAttacks[bestDamage] = attacks[ bestDamage ];
340
+        this.defaultAttacks['expandedExperience'] = this.expandedExperience;
341
+
342
+        return this.defaultAttacks;
343
+    }
344
+
345
+    expanseExperience( value ){
346
+        if(!this.experience){
347
+            this.experience = 0;
348
+            return 0;
349
+        }else if ( value > this.experience){
350
+            return 0;
351
+        }
352
+
353
+        if( typeof value == "undefined"){
354
+            this.experience = this.experience - 1;
355
+            this.expandedExperience = this.expandedExperience + 1;
356
+        }else{
357
+            this.experience = this.experience - value;
358
+            this.expandedExperience = this.expandedExperience + value;
359
+        }
360
+        return value || 1;
361
+    }
362
+
363
+    increaseSkill( skill ){
364
+        if(( typeof this.skills[ skill ] === "number" ) && ( this.skills[ skill ] < 10 )){
365
+            var cost = this.skills[ skill ] + 1;
366
+            if( (this.experience - cost) >= 0 ){
367
+                this.expanseExperience( cost );
368
+                return this.skills[ skill ]++;
369
+            }
370
+        } else {
371
+            if( this.experience > 0){
372
+                this.expanseExperience();
373
+                return this.skills[ skill ] = 1;
374
+            }
375
+        }
376
+        return 0;
377
+    }
378
+
379
+    increaseTrait( trait ){
380
+        let factor = ( trait == "void")? 12 : 6  ;
381
+        let cost = (this[ trait ] + 1) * factor;
382
+        this.actualizeWounds();
383
+
384
+        if(this.expanseExperience( cost ))
385
+            this[ trait ]++;
386
+    };
387
+                 
388
+    actualizeWounds(){
389
+        this.maxWounds = 17 * this.earth();
390
+        return this.fullHeal;
391
+    };
392
+
393
+    fullHeal(){
394
+        return this.currentWounds = this.maxWounds;
395
+    }
396
+    
397
+    actualizeMalus(){
398
+        switch(this.state){
399
+            case "healthy" :
400
+                 this.malus = 0;
401
+            break;
402
+            case "nicked" :
403
+                this.malus = ( this.hasAdvantage( "strength of the earth" )  )? 0 : 3 ;
404
+            break;
405
+            case "grazed" :
406
+                this.malus = ( this.hasAdvantage( "strength of the earth" )  )? 2 : 5 ;
407
+            break;
408
+            case "hurt" :
409
+                this.malus = ( this.hasAdvantage( "strength of the earth" )  )? 7 : 10 ;
410
+            break;
411
+            case "injured" :
412
+                this.malus = ( this.hasAdvantage( "strength of the earth" )  )? 12 : 15 ;
413
+            break;
414
+            case "crippled" :
415
+                this.malus = ( this.hasAdvantage( "strength of the earth" )  )? 17 : 20 ;
416
+            break;
417
+            case "down" :
418
+                this.malus = ( this.hasAdvantage( "strength of the earth" )  )? 37 : 40 ;
419
+            break;
420
+            case "out" :
421
+                this.malus = 100 ;
422
+            break;
423
+            case "dead" :
424
+                this.malus = 1000 ;
425
+            break;
426
+        }
427
+    };
428
+    
429
+    getWounded( wounds ){
430
+       let inflicted = wounds - this.dr();
431
+        this.currentWounds = this.currentWounds - inflicted;
432
+       if( this.currentWounds < 1 )
433
+            this.state = "dead";
434
+       else if( this.currentWounds < (5 * this.earth()) )
435
+            this.state = "out";
436
+       else if( this.currentWounds < (7 * this.earth()) )
437
+           this.state = "down";
438
+       else if( this.currentWounds < (9 * this.earth()) )
439
+           this.state = "crippled";
440
+       else if( this.currentWounds < (11 * this.earth()) )
441
+            this.state = "injured";
442
+       else if( this.currentWounds < (13 * this.earth()) )
443
+            this.state = "hurt";
444
+       else if( this.currentWounds < (15 * this.earth()) )
445
+            this.state = "grazed";
446
+       else if( this.currentWounds < (17 * this.earth()) )
447
+            this.state = "nicked";
448
+       else if( this.currentWounds < (7 * this.earth()) )
449
+            this.state = "healthy";                                                                                                                   
450
+       this.actualizeMalus();
451
+
452
+        return inflicted;
453
+    }
454
+
455
+    getHeal( value ){
456
+        this.currentWounds = ( value < this.maxWounds)? this.currentWounds + value : this.maxWounds;
457
+        this.actualizeMalus();
458
+    }
459
+
460
+    fullHeal(){
461
+        this.currentWounds = this.maxWounds;
462
+        this.actualizeMalus();
463
+    }
464
+
465
+    generate( level, role ){
466
+        this.role =( typeof role === "undefined" )? this.role : role ;
467
+        this.experience = 25 + Math.round(level * 30 + Math.pow(15, level/10));
468
+        this.randomTraits( level );
469
+        this.randomSkill( level );
470
+        this.armedFromSkills();
471
+    }
472
+    
473
+    getWeaponsKeyword( keyword ){
474
+       let result = [];
475
+       for(let i = 0; i < weapons.length ; i++){
476
+           if( keyword in weapons[i].keyword )
477
+               result.push( weapons[i] );
478
+       }
479
+       return result ;
480
+    }
481
+
482
+    getWeaponKeyword( keyword ){
483
+       let weapons = getWeaponsKeyword( keyword );
484
+       let hasIt = 1;
485
+       while( hasIt ){
486
+           let index = random( weapons.length );
487
+           hasIt = this.weapons[ weapons[ index ] ];
488
+           if( !hasIt )
489
+               this.weapons.push( weapons[ index ] );
490
+       }
491
+    }
492
+
493
+    getRandomWeaponFromSkill( skill ){
494
+        if( typeof skill == "unsigned") return null;
495
+        let results = {};
496
+        let atLeastOne = false;
497
+        for(let weapon in weapons){
498
+            if((typeof weapon != "undefined") && (typeof weapons[weapon].skill != "undefined")){
499
+                if(weapons[weapon].skill == skill){
500
+                    atLeastOne = true;
501
+                    results[weapon] = weapons[weapon];
502
+                }
503
+            }
504
+        }
505
+        return ( atLeastOne)? randomFromAssociative( results ) : null ;
506
+    }
507
+
508
+    getWeaponsFromSkills( skills ){
509
+        let result = {};
510
+        for(let skill in skills){
511
+            let weapon = this.getRandomWeaponFromSkill( skill );
512
+            if(weapon)
513
+                Object.assign( result, weapon );
514
+        }
515
+        return result;
516
+    }
517
+
518
+    armedFromSkills(){
519
+        Object.assign( this.weapons, this.getWeaponsFromSkills( this.skills )) ;
520
+    }
521
+
522
+    allSkills(){
523
+        let skillList = roleSkills[ this.role ];
524
+        for(let skill in skillList){
525
+            skillList[skill].occurrence *= 10;
526
+        }
527
+        return Object.assign({}, skillList, skills);
528
+    }
529
+    
530
+     randomSkill(){
531
+         let hasMain = 0;
532
+         let skill ;
533
+         let skillList = this.allSkills();
534
+
535
+         while(  this.experience > 2 ){
536
+             skill = randomFromWeight( skillList );
537
+	     
538
+             if( hasMain ){
539
+                if( skill == hasMain ){
540
+                    if(!this.increaseSkill( Object.keys(skill)[0] )){
541
+                        skill = Object.keys( randomFromWeight( skillList ))[0];
542
+
543
+                        for(let i = 0 ; !this.increaseSkill( skill ) && (i < arrayLength( skillList)); i++ ){
544
+                            skill = Object.keys( randomFromWeight( skillList ))[0];
545
+                        };
546
+                    };
547
+                }
548
+             } else if(( typeof skill !== "undefined" ) && ( skill !== null )){
549
+	        if( typeof skill.main !== "undefined"){
550
+		    hasMain = skill;
551
+		    this.increaseSkill( Object.keys(skill)[0] ) ;
552
+		}
553
+            } else {
554
+                this.increaseSkill( Object.keys(skill)[0] ) ;
555
+            }
556
+         }
557
+    }
558
+
559
+    randomFromWeight( skills ){
560
+	let weight = [];
561
+
562
+	for(skill in skills)
563
+	    if(typeof skill.occurence !== "undefined")
564
+		/*size +=*/;
565
+    }
566
+    
567
+   randomTraits( level ){
568
+        let pass = level * random(2) + random(2);
569
+        switch( this.role ){
570
+        case "bushi" :
571
+           while(pass){
572
+               let asset = random(3);
573
+               switch( asset ){
574
+               case 0 :
575
+                   if( this.experience >= ((6 * this.increaseTrait("stamina") + (6 * this.increaseTrait("willpower"))))){
576
+                       this.increaseTrait("willpower");
577
+                       this.increaseTrait("stamina");
578
+                   }else
579
+                       this.increaseTrait("void")
580
+               break;
581
+               case 1 :
582
+                   this.increaseTrait("strength") ;
583
+               break;
584
+               case 2 :
585
+                   this.increaseTrait("reflexes");
586
+               break;
587
+               case 3 :
588
+                   this.increaseTrait("agility");
589
+               break;
590
+              };
591
+          pass--;
592
+          }
593
+        break;
594
+        case "shugenja" :
595
+           switch( random(3) ){
596
+           case 0 :
597
+               while(pass){
598
+                   this.increaseTrait("stamina") ;
599
+                   this.increaseTrait("willpower");}
600
+            break;
601
+            case 1 :
602
+               while(pass){
603
+                   this.increaseTrait("perception");
604
+                   this.increaseTrait("strength") ;}
605
+            break;
606
+           case 2 :
607
+               while(pass){
608
+                   this.increaseTrait("reflexes") ;
609
+                   this.increaseTrait("awarness") ;}
610
+            break;
611
+            case 3 :
612
+               while(pass){
613
+                   this.increaseTrait("intelligence") ;
614
+                   this.increaseTrait("agility") ;}
615
+            break;
616
+            }
617
+       break;
618
+        case "monk" :
619
+            while(pass){
620
+               let asset = random(3);
621
+               switch( asset ){
622
+               case 0 :
623
+                   this.increaseTrait("void") ;
624
+               break;
625
+               case 1 :
626
+                   this.increaseTrait("strength") ;
627
+                   this.increaseTrait("agility");
628
+               break;
629
+               case 2 :
630
+                   this.increaseTrait("awarness");
631
+                   this.increaseTrait("reflexes");
632
+               break;
633
+               case 3 :
634
+                   this.increaseTrait("void");
635
+                   this.increaseTrait("strength");
636
+               break;
637
+              };
638
+          pass--;
639
+            }
640
+       break;
641
+       case "scout" :
642
+            while(pass){
643
+               let asset = random(2);
644
+               switch( asset ){
645
+               case 0 :
646
+                   this.increaseTrait("perception");
647
+                   this.increaseTrait("strength");
648
+               break;
649
+               case 1 :
650
+                   this.increaseTrait("agility");
651
+               break;
652
+               case 2 :
653
+                   this.increaseTrait("reflexes");
654
+               break;
655
+              };
656
+          pass--;
657
+          }
658
+           break;
659
+           case "ninja" :
660
+            while(pass){
661
+               let asset = random(2);
662
+               switch( asset ){
663
+               case 0 :
664
+                   this.increaseTrait("void")
665
+               break;
666
+               case 1 :
667
+                   this.increaseTrait("agility") ;
668
+               break;
669
+               case 2 :
670
+                   this.increaseTrait("reflexes");
671
+               break;
672
+              };
673
+          pass--;
674
+          }           
675
+       break;
676
+       }
677
+    this.actualizeWounds();
678
+    }
679
+
680
+    getWounds(){
681
+        return this.currentWounds ;
682
+    }
683
+
684
+    stance = "attack";
685
+    
686
+    switchStance( aStance ){
687
+        if( stances.includes( aStance ) ){
688
+            this.stance = aStance;
689
+	}else if( typeof aStance === "undefined" ){
690
+	    let nextStanceIndex = stances.indexOf( this.stance ) + 1;
691
+	    nextStanceIndex = (nextStanceIndex >= stances.length )? 0 : nextStanceIndex;
692
+	    this.stance = stances[ nextStanceIndex ];
693
+	}
694
+	if( this.stance == "full defense")
695
+	    this.rollMade["defense"] = this.skillRoll( "defense" ) ;
696
+    }
697
+    
698
+    skillRoll( skill ){
699
+        let skillRank = this.getSkillRank( "defense" );
700
+        let traitRank = this[ skills[skill].trait ];
701
+        return RNG.rk10( traitRank + skillRank, traitRank );
702
+    }
703
+}
704
+
705
+class Character extends baseCharacter{
706
+
707
+    constructor( aRole, skills, gender, name, experience, gempukku ){
708
+	super( aRole, skills, gender, name, experience, gempukku );
709
+    }
710
+
711
+    getTN(){
712
+	return this.baseGetTN();
713
+    }
714
+
715
+    attack(){
716
+        return this.baseAttack();
717
+    }
718
+}
719
+
720
+class Samourai extends Character {
721
+    constructor( aRole, gender, name, familly, school, experience, gempukku, skills){
722
+        super( aRole, skills, gender, name, experience, gempukku );
723
+
724
+        this.setFamilly( familly );
725
+        this.setBasicSchool( school );
726
+        this.autoWearArmor();
727
+    }
728
+
729
+    setFamilly( familly_name ){
730
+        let familly = famillies[ familly_name ];
731
+        this[ familly.trait ]++;
732
+        this.name['familly'] = familly_name;
733
+    }
734
+
735
+    setBasicSchool( school_name ){
736
+        let school = basicSchool[ school_name ];
737
+        this[ school.trait ]++;
738
+        for(let i = 0 ; i < school.outfit.weapon.length ; i++){
739
+            let weapon = (school.outfit.weapon[ i ] == "any")? Object.keys( randomFromAssociative( weapons ) ) : school.outfit.weapon[ i ];
740
+
741
+            if( !(weapon in this.weapons) )
742
+                this.weapons[ weapon ] = weapons[ weapon ];
743
+        }
744
+        this.armors = school.outfit.armor || this.armors;
745
+
746
+	for( let i = 0; i < school.skills.length ; i++ ){
747
+	    if( !(school.skills[i] in this.skills) )
748
+		this.skills[ school.skills[i] ] = 1;
749
+	}
750
+    }
751
+
752
+    autoWearArmor(){
753
+        let maxArmor = "kimono";
754
+        for(let i = 0 ; i < this.armors.length ; i++){
755
+            if( armors[ this.armors[ i ] ].TN >  armors[ maxArmor ].TN ){
756
+                maxArmor = this.armors[i];
757
+            }
758
+        };
759
+        this.equippedArmor = maxArmor;
760
+    }
761
+}
762
+
763
+class People extends Samourai {
764
+    constructor( gender, name, familly, school, experience, skills){
765
+	super( "people", gender, name, familly, school, experience, 0, skills );
766
+    }
767
+    
768
+}

+ 55
- 0
game/dice.js View File

@@ -0,0 +1,55 @@
1
+var roll = Array();
2
+roll[1] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
3
+roll[2] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
4
+roll[3] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
5
+roll[4] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
6
+roll[5] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
7
+roll[6] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
8
+roll[7] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
9
+roll[8] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
10
+roll[9] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
11
+roll[1][1] = [5, 8, 9, 3, 11, 4, 7, 9, 1, 5, 3, 1, 3, 1, 6, 4, 3, 5, 9, 2, 1, 3, 5, 4];
12
+roll[2][1] = [9, 7, 12, 9, 8, 9, 8, 16, 2, 9, 4, 8, 6, 8, 9, 16, 16, 8, 7, 4, 11, 5, 8, 17];
13
+roll[3][1] = [17, 9, 12, 9, 7, 19, 9, 4, 12, 9, 8, 14, 7, 8, 7, 9, 7, 19, 9];
14
+roll[4][1] = [];
15
+roll[5][1] = [];
16
+roll[6][1] = [];
17
+roll[7][1] = [];
18
+roll[8][1] = [];
19
+roll[9][1] = [];
20
+roll[2][2] = [25, 15, 15, 13, 10, 19, 9, 7, 7, 12, 12, 11, 10, 25, 8, 12, 5, 14, 5, 6, 15];
21
+roll[3][2] = [];
22
+roll[4][2] = [25, 15, 27, 9, 23, 18, 9, 15, 18, 18, 12, 12, 44, 12, 22, 25, 10, 14, 8, 14, 27, 25] ;
23
+roll[5][2] = [];
24
+roll[6][2] = [];
25
+roll[7][2] = [];
26
+roll[8][2] = [];
27
+roll[9][2] = [];
28
+roll[3][3] = [];
29
+roll[4][3] = [];
30
+roll[5][3] = [];
31
+roll[6][3] = [25, 29, 29, 17, 26, 26, 19, 32, 52, 25, 18, 24, 34, 28, 47, 21, 16, 20, 49, 14, 21, 37];
32
+roll[7][3] = [26, 32, 29, 32, 31, 28, 25, 37, 23, 35, 20, 32, 24, 44, 40, 19, 14, 22, 43, 44];
33
+roll[8][3] = [];
34
+roll[9][3] = [];
35
+roll[4][4] = [];
36
+roll[5][4] = [];
37
+roll[6][4] = [];
38
+roll[7][4] = [];
39
+roll[8][4] = [21, 30, 37, 56, 29, 39, 28, 24, 40, 36];
40
+roll[9][4] = [];
41
+roll[5][5] = [];
42
+roll[6][5] = [];
43
+roll[7][5] = [];
44
+roll[8][5] = [];
45
+roll[9][5] = [];
46
+roll[6][6] = [];
47
+roll[7][6] = [];
48
+roll[8][6] = [];
49
+roll[9][6] = [];
50
+roll[7][7] = [];
51
+roll[8][6] = [];
52
+roll[9][6] = [];
53
+roll[8][8] = [];
54
+roll[9][8] = [];
55
+roll[9][9] = [];

+ 42
- 0
game/display.js View File

@@ -0,0 +1,42 @@
1
+function capitalize( str ) {
2
+    return str.charAt(0).toUpperCase() + str.slice(1);
3
+}
4
+
5
+function toHeader(array){
6
+    let resultat = document.createElement("tr");
7
+
8
+    for(let i = 0; i < array.length ; i++ ){
9
+        let cell = document.createElement("th");
10
+        cell.innerText = array[i];
11
+        resultat.appendChild( cell );
12
+    }
13
+    return resultat;
14
+}
15
+
16
+function characterToLine(){
17
+    let line = document.CreateElement('td');
18
+    let cell = document.CreateElement('tr');
19
+}
20
+
21
+function display(html_id, data){
22
+    let anchor = document.getElementById( html_id ) ;
23
+    let resultat = document.createElement( "table" );
24
+
25
+    let header = toHeader( Object.keys(data) );
26
+
27
+    for(let i = 0 ; i < data.length ; i++){
28
+    }
29
+    html_id.appendChild( resultat );
30
+}
31
+
32
+function setElementValue( elem, value ){
33
+    elem.style.transitionDuration = "0s";
34
+    elem.style.backgroundColor = "red";
35
+    elem.style.color = "white";
36
+    elem.value = value ;
37
+    window.setTimeout(() => {
38
+	elem.style.transitionDuration = "7s";
39
+	elem.style.backgroundColor = "inherit";
40
+	elem.style.color = "inherit";
41
+    }, 1000);
42
+}

+ 165
- 0
game/l5r.js View File

@@ -0,0 +1,165 @@
1
+var stances = ["attack", "full attack", "defense", "full defense", "center"];
2
+
3
+const mechanics = new Array();
4
+// [ school name ][ mechanic name ][ action ][ function ]
5
+mechanics[ "œil de l'aigle" ] = { name : "kiho",
6
+			action : ()=> {
7
+			    console.log("En restant immobile et concentré, læ moine peut peut voir à un nombre de milles égal à son rang d'école, avec assez de précision pour reconnaître des individus, mais pas assez pour lire.");
8
+			          }
9
+				};
10
+mechanics[ "moine hitomi" ] = { name : "don de la dame",
11
+				mutator : ( charac ) => {
12
+				    charac['getTN'] = () => { return charac.defaultGetTN() + charac.reflexes;}
13
+				    addTatoo( charac );
14
+				}
15
+			      };
16
+mechanics[ "moine hitomi" ] = { name : "frapper la base",
17
+				mutator : ( charac ) => {
18
+				    charac['getTN'] = () => { return charac.defaultGetTN() + charac.reflexes;}
19
+				}
20
+			      };
21
+mechanics[ "moine hitomi" ] = { name : "déplacer le vent",
22
+				mutator : ( charac ) => {
23
+                                    charac[ 'actions' ][ 'unarmed attack' ].actionType = 'simple';
24
+				    charac.chooseTatoo();
25
+				}
26
+			      };
27
+
28
+class Characters {
29
+    constructor(){};
30
+
31
+    pool = [];
32
+    elements = ["Character", "Samourai", "People"];
33
+
34
+    at( index ){
35
+        return this.pool[ index ];
36
+    }
37
+
38
+    elementsType = Character;
39
+
40
+    create( json ){
41
+        let charac = new Character();
42
+
43
+        if( typeof json === "Object" )
44
+            charac.fromJson( json ) ;
45
+
46
+        this.add( charac );
47
+    }
48
+    
49
+    createCharacter( aRole, gender, name, familly,experience, gempukku, skills ){
50
+        let character = new Character( aRole, gender, name, familly, school, experience, gempukku, skills );
51
+        this.add( character );
52
+    }
53
+
54
+    createSamourai( aRole, gender, name, familly, school, experience, gempukku, skills ){
55
+        let samourai = new Samourai( aRole, gender, name, familly, school, experience, gempukku, skills );
56
+        this.add( samourai );
57
+    }
58
+
59
+    createPeople( gender, name, familly, school, experience, skills ){
60
+        let people = new People( gender, name, familly, school, experience, skills );
61
+        this.add( people );
62
+    }
63
+
64
+    fromJson( json ){
65
+
66
+        let data = JSON.parse(json);
67
+
68
+        for( prop in data){
69
+            this[ prop ] = data[ prop ];
70
+        }
71
+    }
72
+
73
+    /** add
74
+   * character, parameter, must be declare in the characters.elemets.list
75
+   * return boolean
76
+   **/
77
+    add(character){
78
+        if( this.elements.includes( character.constructor.name )){
79
+            this.pool.push( character );
80
+	    return true;
81
+        }else{
82
+	    return false;
83
+	}
84
+    }
85
+
86
+    indexOf( character ){
87
+        if(  this.elements.includes( character.constructor.name )){
88
+            for(let i = 0; i < this.pool.length ; i++){
89
+                if( character == this.pool[ i ] )
90
+                    return i;
91
+            }
92
+        }
93
+    }
94
+
95
+    getByName( name ){
96
+        for(let i = 0; i < this.pool.length ; i++){
97
+            if( this.pool[i].getName() == name)
98
+                return this.pool[i];
99
+        }
100
+    }
101
+
102
+    getIndexByName( name ){
103
+        for(let i = 0; i < this.pool.length ; i++){
104
+            if( this.pool[i].getName() == name)
105
+                return i;
106
+        }
107
+    }
108
+
109
+    size(){
110
+        return this.pool.length;
111
+    }
112
+}
113
+
114
+
115
+var RNG = new RandomGenerator(4);
116
+
117
+function characterFromJSON( json ){
118
+    let result = new Character();
119
+    let data = JSON.parse(json);
120
+
121
+    for( prop in data){
122
+        result[ prop ] = data[ prop ];
123
+    }
124
+
125
+    return result;
126
+}
127
+
128
+function fight(charac1, charac2){
129
+    let result = {
130
+        "attacker" : charac1.initiative(),
131
+        "defender" : charac2.initiative()
132
+    };
133
+    let first = (  charac1.initiative() + (charac1.water/10) > charac1.initiative() + (charac1.water()/10))? charac1 : charac2 ;
134
+    let second = ( charac1 == first)? charac2 : charac1 ;
135
+    let winner = 0
136
+    let round = 0;
137
+
138
+    while( !winner ){
139
+        round++;
140
+
141
+        result[round] = {
142
+            "attack" : {
143
+                "attacker" : first.attack(),
144
+                "defender" : second.attack()
145
+            },
146
+            "damage" : {
147
+                "attacker" : first.damage(),
148
+                "defender" : second.damage()
149
+            }
150
+        };
151
+        result[round]["wounds"] =  {
152
+                "attacker" : ( result[round]['attack']['attacker'] >= second.getTN() )? second.getWounded( result[round]['damage']['attacker'] ) : 0,
153
+                "defender" : (( result[round]['attack']['defender'] >= first.getTN() ) && second.malus < 100)? first.getWounded( result[round]['damage']['defender'] ) : 0,
154
+        }
155
+            
156
+        if( second.malus > 99 ){
157
+            winner = first;
158
+        } else if( first.malus > 99 )
159
+            winner = second;
160
+    }
161
+
162
+    result['winner'] = winner ;
163
+    result['winner_side'] = (winner == charac1)? "attacker": "defender";
164
+    return result;
165
+}

+ 156
- 0
helper/random.js View File

@@ -0,0 +1,156 @@
1
+
2
+class RandomGenerator{
3
+
4
+    constructor( cache ){
5
+        this.rng = new Uint8Array( cache  );
6
+        this.index = cache-- ;
7
+        this.generate();
8
+    }
9
+
10
+    generate(){
11
+        window.crypto.getRandomValues(this.rng);
12
+        this.index = this.rng.length - 2;
13
+        return  this.rng.length - 1;
14
+    }
15
+
16
+    next(){
17
+        return (this.index < 0)? this.generate() : this.index--;
18
+    }
19
+
20
+    rand(){
21
+        return this.rng[ this.next() ]/256 ;
22
+    }
23
+    
24
+    get( max, min ){
25
+        min = ( typeof min === "number")? min : 0 ;
26
+        return Math.round(this.rand() * (max - min) + min);
27
+    }
28
+
29
+    roll10( explode ){
30
+        explode = ( typeof explode === "number")? differenceToArray( explode, 10 ) : [10];
31
+        let dice = this.get( 10, 1 );
32
+        return  ( explode.indexOf( dice ) >= 0 )? 10 + this.roll10( explode ) : dice ;
33
+    }
34
+
35
+    rk10( r, k, malus, explode ){
36
+        let rolls = [];
37
+        if((typeof r === "unsigned") || (typeof k === "unsigned"))
38
+            return 0;
39
+        malus = ( typeof malus === "unsigned")? 0 : malus ;
40
+        for(let i = 0 ; i < r ; i++)
41
+            rolls[i] = this.roll10( explode );
42
+        sort( rolls );
43
+        return rolls.slice( 0, k ).reduce((a, b) => a + b) - (malus || 0);
44
+    }
45
+}
46
+
47
+function differenceToArray( min, max ) {
48
+    let result = []
49
+    for( let i = min; i <= max; i++)
50
+        result.push(i) ; 
51
+    return result;
52
+}
53
+
54
+function sort( array ){
55
+    let temp = 0;
56
+    var unsorted = true ;
57
+    while(unsorted){
58
+        unsorted = false;
59
+        for(let i = 0; i < array.length -1 ; i++){
60
+            if(array[ i ] < array[ i + 1 ]){
61
+               temp = array[ i ];
62
+               array[ i ] = array[ i + 1 ];
63
+               array[ i + 1 ] = temp;
64
+               unsorted =  true;
65
+           }
66
+       }
67
+    }
68
+}
69
+
70
+function sortAssociative( array_arg ){
71
+    let result = {};
72
+    let array = array_arg;
73
+    let higher = 1;
74
+    while( !higher ){
75
+        higher = 0;
76
+        for(let i in array){
77
+            higher = (higher)?
78
+                (array[higher] < array[i])? i : higher : i ;
79
+            if(array[ i ] < array[ i + 1 ]){
80
+                temp = array[ i ];
81
+                array[ i ] = array[ i + 1 ];
82
+                array[ i + 1 ] = temp;
83
+                unsorted =  true;
84
+            }
85
+        }
86
+        if(higher){
87
+            result.push(higher);
88
+            delete array[ higher ];
89
+            higher = 0;
90
+        }
91
+    }
92
+    return result;
93
+}
94
+
95
+
96
+function random( max, min ){
97
+    min = (typeof min == "undefined")? 0 : min;
98
+    return Math.floor(Math.random() * (max - min + 1) + min);
99
+}
100
+
101
+function r_gender(){
102
+    return (random(1))? "f": "m";
103
+}
104
+
105
+function arrayAt( index, array ){
106
+    let i = 0;
107
+    let result = {};
108
+    for(let obj in array){
109
+        if( index == ++i ){
110
+            result[obj] = array[obj];
111
+            return result;
112
+        }
113
+    }
114
+}
115
+
116
+function arrayAtWeight( index, array ){
117
+    let i = 0;
118
+    for(let obj in array){
119
+        if(( i <= index ) && ( index <= (i + array[obj].occurence))){
120
+            let rs = {};
121
+            rs[ obj ] = array[obj];
122
+            return rs;
123
+        }
124
+        i += array[obj].occurence ;
125
+    }
126
+    return null;
127
+}
128
+
129
+function arrayLength( array ){
130
+    let i = 0;
131
+    for(let obj in array){
132
+        i++;
133
+    };
134
+    return i;
135
+}
136
+
137
+function arrayWeight( array ){
138
+    let i = 0;
139
+    for(let obj in array){
140
+        i += array[obj].occurence;
141
+    };
142
+    return i;
143
+}
144
+
145
+function randomFromAssociative( array ){
146
+    return arrayAt( random( arrayLength( array ), 1), array) ;
147
+}
148
+
149
+function randomFromArray( array ){
150
+    return array[ random( arrayLength( array )) ] ;
151
+}
152
+
153
+function randomFromWeight( array ){
154
+    return arrayAtWeight( random( arrayWeight( array )), array) ;
155
+}
156
+

+ 416
- 0
index.html View File

@@ -0,0 +1,416 @@
1
+<html>
2
+  <head>
3
+    <meta charset="utf8">
4
+    <link rel="stylesheet" type="text/css" href="style/anim.css">
5
+    <script src="game/dice.js"></script>
6
+    <script src="data/names.js"></script>    
7
+    <script src="data/l5r_data.js"></script>
8
+    <script src="helper/random.js"></script>
9
+    <script src="game/display.js"></script>        
10
+    <script src="game/character.js"></script>        
11
+    <script src="game/l5r.js"></script>
12
+    <script src="data/players.js"></script>
13
+    <script src="data/npc.js"></script>
14
+    <script>
15
+
16
+    var npcs = [];
17
+    var result = [];
18
+    var result1 = [];
19
+    var result2 = [];
20
+    var current_target= 0;
21
+
22
+    function target(){
23
+        return characters.at(current_target) ;
24
+    }
25
+    
26
+    var npc_summary = document.getElementById("npc.summary");           
27
+    
28
+      function generateNPC(){
29
+        var newNPC = new Character();
30
+        newNPC.generate( document.getElementById("npc-level").value );
31
+        return newNPC;
32
+    }
33
+
34
+    function generateNPCs( size ){
35
+        let result = [];
36
+    
37
+        for(let i = 0; i < size ; i++){
38
+            result[i] = generateNPC( i );
39
+        }
40
+
41
+        return result;
42
+    }
43
+    
44
+    function skirmish( size ){
45
+        let npcs = generateNPCs( size );
46
+
47
+        for(let i = 0; i < size ; i+=2){
48
+            if( (npcs[i]) && (npcs[i + 1]))
49
+                result[i] = fight(npcs[i], npcs[i + 1]);
50
+        }
51
+
52
+        for( let i = 0; i < size ; i++ ){
53
+            ;
54
+        }    
55
+    }
56
+
57
+    function swissContest( size ){
58
+        let result = [];
59
+        let npcs = generateNPCs( size );
60
+
61
+        for(let i = 0; i < npcs.length; i++){
62
+             result[i] = [];
63
+                           
64
+            for(let j = 0; j < npcs.length; j++){
65
+                result[i][j] = ( fight( npcs[i], npcs[j] ) );
66
+                npcs[i].fullHeal();
67
+                npcs[j].fullHeal();
68
+            }
69
+        }
70
+        return result;
71
+    }
72
+
73
+    function winRateSwissContest( array, stat){
74
+        let result = [];
75
+
76
+        for(let i = 0; i < array.length; i++){
77
+            let winrate = 0;
78
+            let total = 0;
79
+            for(let j = 0; j < array[i].length; j++){
80
+                winrate += ( array[i][j].winner_side == "attacker" )? 1: 0;
81
+                total++;
82
+            }
83
+
84
+            result[i] = winrate/total;
85
+        }
86
+        return result; 
87
+    }
88
+
89
+    function hasClass( elem, className){
90
+
91
+        for( let i = 0 ; i < elem.classList.length ; i++ )
92
+            if( elem.classList[ i ] === className )
93
+                return elem;
94
+
95
+        return 0;
96
+    };
97
+                               
98
+    function getClassFromList( list, className ){
99
+        let result = [];
100
+
101
+        for( let i = 0 ; i < list.childNodes.length   ; i++ )
102
+            if( hasClass( list.childNodes[ i ], className ))
103
+                 result.push( list.childNodes[ i ] );
104
+
105
+        return result;
106
+    }
107
+
108
+    function inputFromElementList( list, input_type ){
109
+        let result = [];
110
+
111
+        for( let i = 0 ; i ; i++ )
112
+            if( list[ i ].getAttributeNames().includes( input_type ))
113
+                result.push( list[i] );
114
+
115
+        return result;
116
+    }
117
+
118
+    function display_data( data, anchor ){
119
+        let html_display = document.getElementById( anchor );
120
+        let headers = [ "name", "initiative", "TN", "attack", "damage", "wounds" ];
121
+        let hs = document.createElement("tr");
122
+
123
+                               
124
+        for(let i = 0; i < headers.length ; i++){
125
+            let h = document.createElement("th");
126
+            h.innerText = headers[ i ];
127
+            hs.appendChild( h );
128
+        }
129
+
130
+        html_display.appendChild( hs ) ;
131
+
132
+        for(let i = 0;  i < data.length ; i++){
133
+            let line = document.createElement( "tr" );
134
+            line.setAttribute("id", i + "-" + anchor );
135
+            let name = document.createElement("td");
136
+            name.innerText = data[i]["get"+capitalize( headers[0] )]();
137
+            line.appendChild( name );
138
+
139
+            for(let j = 1; j <  headers.length ; j++){
140
+                let cell = document.createElement("td");
141
+                let button = document.createElement("button");
142
+                button.setAttribute("class", headers[j]);
143
+                let id = i + "-"+j+"-" + anchor;
144
+
145
+                button.innerText = headers[j];
146
+
147
+                button.addEventListener('click', function(event) {
148
+                   document.getElementById( id ).value = data[i]["get"+capitalize( headers[j] )]();
149
+                });
150
+                cell.appendChild( button );
151
+
152
+                let result = document.createElement("input");
153
+                result.setAttribute("id", id);
154
+                result.setAttribute("type", "text");
155
+                result.setAttribute("class", "result");
156
+                cell.appendChild( result );
157
+                line.appendChild( cell );
158
+            }
159
+            let cell1 = document.createElement("td");
160
+            let targeted = document.createElement("input");
161
+            targeted.setAttribute("type", "checkbox");
162
+            targeted.setAttribute("class", "targeted");
163
+            targeted.checked = false;
164
+            targeted.addEventListener('click', function(event) {
165
+               let targeteds = document.getElementsByClassName( "targeted" );
166
+               for(let targeted in targeteds){
167
+                   if(targeteds[targeted] != this)
168
+                                targeteds[targeted].checked = false;
169
+
170
+                   current_target = this.parentNode.parentNode.id.split("-")[0];
171
+               }
172
+            });
173
+            cell1.appendChild( targeted );
174
+            line.appendChild( cell1 );
175
+
176
+            cell2 = document.createElement("td");
177
+            let attacking = document.createElement("input");
178
+            attacking.setAttribute("type", "button");
179
+            attacking.setAttribute("class", "attacking");
180
+            attacking.value = "Attack";
181
+            attacking.checked = false;
182
+            attacking.addEventListener('click', function(event) {
183
+                characters.at( this.parentNode.parentNode.id.split("-")[0] ).attacking( target() );
184
+                triggerField( "Wounds" );
185
+                triggerField( "TN" );
186
+            });
187
+            cell2.appendChild( attacking );
188
+            line.appendChild( cell2 );
189
+	    
190
+	    let cell_switchStance = document.createElement("td");
191
+	    let switchStance = document.createElement("input");
192
+            switchStance.setAttribute("type", "button");
193
+	    switchStance.value = "Attack Stance";
194
+	    cell_switchStance.appendChild( switchStance );
195
+	    cell_switchStance.addEventListener('click', function(event) {
196
+                let charac = characters.at( this.parentNode.id.split("-")[0] );
197
+		charac.switchStance();
198
+		event.target.value = charac.stance;
199
+		triggerField( "TN" );
200
+            });	    
201
+            line.appendChild( cell_switchStance );
202
+
203
+            html_display.appendChild( line );
204
+        }
205
+    }
206
+
207
+    function popAssociativeMaker( associative, anchor ){
208
+    
209
+        let result = document.createElement( "div" );
210
+        result.setAttribute( "class", "popup" );
211
+        let exit = document.createElement("input");
212
+        exit.setAttribute("type", "button");
213
+        exit.setAttribute("class", "exit");  
214
+        exit.value = "×";
215
+        exit.addEventListener('click', function(event) {
216
+            anchor.value = JSON.stringify( formToData( result ) );
217
+            result.parentNode.removeChild( result );
218
+         });
219
+
220
+        result.appendChild( exit );
221
+
222
+        for( let i in associative ){
223
+            switch( typeof varType ){
224
+            case "function":
225
+            break;
226
+            case "object":
227
+                result.appendChild( inputField( i, associative[ i ] || "", true, null, function(event) {
228
+                    this.value =  popObjectMaker( associative[ i ], line );
229
+                } ));
230
+            break;
231
+            default:
232
+                result.appendChild( inputField( i, associative[ i ] || "") );
233
+            }
234
+        }
235
+
236
+        let add = document.createElement("input");
237
+        add.setAttribute("type", "button");
238
+        add.setAttribute("class", "add");  
239
+        add.value = "+";
240
+        add.addEventListener('click', function(event) {
241
+            result.appendChild( inputField( "", "", true) );
242
+        });
243
+        result.appendChild( add );
244
+                                
245
+        document.getElementsByTagName('body')[0].appendChild( result );
246
+
247
+        return result;
248
+    }
249
+
250
+    function inputField( field, value, modifiable, label_onclick, input_onclick ){
251
+         field = (( typeof field === "unsigned" ) || !field )? "" : field;
252
+         value = (( typeof value === "unsigned" ) || !value )? "" : value;
253
+         modifiable = (( typeof modifiable === "unsigned" ) || !modifiable )? false : true ;
254
+
255
+         let  line= document.createElement("div");
256
+         let input = document.createElement("input");
257
+         let label ;
258
+
259
+         if( modifiable ){
260
+             label = document.createElement("input");
261
+             label.setAttribute("type", "text");                                
262
+         }else{
263
+             label = document.createElement("label");
264
+         }
265
+       
266
+         line.setAttribute("class", "line");
267
+         label.setAttribute("class", "label");
268
+         label.innerText = field;
269
+
270
+         if( label_onclick instanceof Function )
271
+             label.addEventListener('click', label_onclick );
272
+                                
273
+         line.appendChild( label );
274
+
275
+         input.setAttribute("type", "text");
276
+         input.setAttribute("class", "maker");
277
+         input.value = value;
278
+
279
+         if( input_onclick instanceof Function )
280
+             input.addEventListener('click', label_onclick );
281
+
282
+         input.checked = false;
283
+         line.appendChild( input );
284
+
285
+         return line;
286
+    }
287
+                                
288
+    function popObjectMaker( object, anchor, dictionnary ){
289
+        let prototype = new object;
290
+        let result = document.createElement( "div" );
291
+        result.setAttribute( "class", "popup" );
292
+
293
+        let exit = document.createElement("input");
294
+        exit.setAttribute("type", "button");
295
+        exit.setAttribute("class", "exit");  
296
+        exit.value = "×";
297
+
298
+        if( typeof dictionnary === "object" )
299
+            exit.addEventListener('click', function(event) {
300
+                 formToDictonnary( result, dictionnary);});
301
+        else
302
+            exit.addEventListener('click', function(event) {
303
+                 saveAndExitForm( result);});
304
+        result.appendChild( exit );
305
+                                  
306
+        for( let i in prototype ){
307
+            let varType = prototype[i];
308
+            let  line= document.createElement("div");
309
+            let input = document.createElement("input");
310
+            let label = document.createElement("label");
311
+
312
+            switch( typeof varType ){
313
+            case "function":
314
+            break;
315
+            case "object":
316
+                line= document.createElement("div");
317
+                line.setAttribute("class", "line");
318
+                label.setAttribute("type", "button");
319
+                label.classList.add("label");
320
+                label.innerText = i;
321
+                line.appendChild( label );
322
+
323
+                input.setAttribute("type", "text");
324
+                input.classList.add("json");
325
+                input.classList.add("maker");
326
+                input.value = prototype[ i ] || "";
327
+                input.checked = false;
328
+                input.addEventListener('click', function(event) {
329
+                    this.value = popAssociativeMaker( prototype[ i ], input );
330
+                });
331
+                line.appendChild( input );
332
+
333
+                result.appendChild( line );
334
+            break;
335
+            default:
336
+                line.setAttribute("class", "line");
337
+                label.setAttribute("type", "button");
338
+                label.classList.add("label");
339
+                label.innerText = i;
340
+                line.appendChild( label );
341
+
342
+                input.setAttribute("type", "text");
343
+                input.classList.add("maker");
344
+                input.value = prototype[ i ] || "";
345
+                input.checked = false;
346
+                line.appendChild( input );
347
+
348
+                result.appendChild( line );
349
+            }
350
+        }
351
+
352
+        if( anchor instanceof Element )
353
+            anchor.appendChild( result );
354
+        else
355
+            document.getElementsByTagName('body')[0].appendChild( result );
356
+
357
+       return result;
358
+    }
359
+                                  
360
+    function formToData( form ){
361
+        let lines = form.getElementsByClassName( "line" ) ;
362
+        let data = {} ;
363
+
364
+        for ( let i = 0 ; i < lines.length ; i++ ){
365
+            let labels = getClassFromList( lines[ i ], "label");
366
+            let makers = getClassFromList( lines[ i ], "maker");
367
+
368
+            if(( lines[ i ] instanceof Element ) && ( labels[0] || makers[0] )){
369
+                 let index = labels[0].value || labels[0].innerText;
370
+                 let value = makers[0].value || makers[0].innerText ;
371
+                 value = (hasClass( makers[0], "json" ))? JSON.parse( value ) : value ;
372
+                              
373
+                 data[ index ] = value ;
374
+            }
375
+        }
376
+        return data ;
377
+    }                                  
378
+                                  
379
+    function saveAndExitForm( form ){
380
+        form.value = JSON.stringify( formToData( form ) );
381
+        form.parentNode.removeChild( form );
382
+    }
383
+
384
+    function formToDictonnary( form, dictionnary){
385
+        return dictionnary.create( formToData( form ) );
386
+    }
387
+                              
388
+    function triggerField( field ){
389
+        let fields = document.getElementsByClassName( field ) ;
390
+                                
391
+        for (let i = 0 ; i < fields.length ; i++ ){
392
+            fields[i].click();
393
+        }
394
+    }
395
+
396
+    function main(){
397
+        display_data( characters.pool, "players_summary");
398
+        triggerField( "wounds" );
399
+        triggerField( "TN" );        
400
+    }
401
+    </script>
402
+    <style>
403
+      .result{
404
+          width : 3em;
405
+      }
406
+    </style>
407
+  </head>
408
+  <body onload="main()">
409
+    <button onclick="popObjectMaker( Character )">Créer un Personnage</button>
410
+    <table id="players_summary"></div>
411
+    <div id="npc_summary"></div>
412
+    </table>
413
+    <button onclick="generateNPC()">Générer NPC</button><input id="npc-level" type="number" value="1"/><select id="npc-role"></select>
414
+    <button onclick="popObjectMaker( Character, null, characters )">Générer Personnage</button>
415
+  </body>
416
+</html>

+ 3
- 0
style/anim.css View File

@@ -0,0 +1,3 @@
1
+input {
2
+    transition-property : color, background-color;
3
+}

Loading…
Cancel
Save