forked from joonspk-research/generative_agents
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcombatd.c
2239 lines (1955 loc) · 87.9 KB
/
combatd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// combatd.c
// Update by Doing for HELL
#pragma optimize
#pragma save_binary
#include <ansi.h>
#include <skill.h>
#include <weapon.h>
#include <combat.h>
inherit F_DBASE;
// 关于玩家数据(/combat/)的说明
// PKS:杀害的玩家数目
// MKS;杀死的NPC数目(动物不计算)
// WPK:主动杀死玩家的次数
// WPK_NOTGOOD:主动杀死非正派(shen < 500)玩家的次数
// WPK_BAD: 主动杀死的邪派(shen <-500)玩家的次数
// WPK_NOTBAD: 主动杀死非邪派(shen >-500)玩家的次数
// WPK_GOOD: 主动杀死的正派(shen > 500)玩家的次数
// DPS:主动打晕玩家的次数
// DPS_NOTGOOD:主动打晕非正派(shen < 500)玩家的次数
// DPS_BAD: 主动打晕的邪派(shen <-500)玩家的次数
// DPS_NOTBAD: 主动打晕非邪派(shen >-500)玩家的次数
// DPS_GOOD: 主动打晕的正派(shen > 500)玩家的次数
// dietimes: 死亡的次数
// combat/today纪录(mapping)
// which_day: 日期(实际时间中日期)
// id : n, 主动打晕某个ID的次数
#define DEFAULT_MAX_PK_PERDAY 3
#define DEFAULT_MAX_PK_PERMAN 1
// 经验底线(random(my_exp) > EXP_LIMIT,则不加经验)
#define EXP_LIMIT 20000000
string *guard_msg = ({
append_color(CYN "$N注视著$n的行动,企图寻找机会出手。"NOR"\n", CYN),
append_color(CYN "$N正盯著$n的一举一动,随时准备发动攻势。"NOR"\n", CYN),
append_color(CYN "$N缓缓地移动脚步,想要找出$n的破绽。"NOR"\n", CYN),
append_color(CYN "$N目不转睛地盯著$n的动作,寻找进攻的最佳时机。"NOR"\n", CYN),
append_color(CYN "$N慢慢地移动著脚步,伺机出手。"NOR"\n", CYN),
});
string *catch_hunt_msg = ({
append_color(HIW "$N和$n仇人相见分外眼红,立刻打了起来!"NOR"\n", HIW),
append_color(HIW "$N对著$n大喝:「可恶,又是你!」"NOR"\n", HIW),
append_color(HIW "$N和$n一碰面,二话不说就打了起来!"NOR"\n", HIW),
append_color(HIW "$N一眼瞥见$n,「哼」的一声冲了过来!"NOR"\n", HIW),
append_color(HIW "$N一见到$n,愣了一愣,大叫:「我宰了你!」"NOR"\n", HIW),
append_color(HIW "$N喝道:「$n,我们的帐还没算完,看招!」"NOR"\n", HIW),
append_color(HIW "$N喝道:「$n,看招!」"NOR"\n", HIW) });
string *winner_msg = ({
append_color(CYN "\n$N哈哈大笑,说道:承让了!"NOR"\n", CYN),
append_color(CYN "\n$N双手一拱,笑著说道:承让!"NOR"\n", CYN),
append_color(CYN "\n$N胜了这招,向后跃开三尺,笑道:承让!"NOR"\n", CYN),
append_color(CYN "\n$N双手一拱,笑著说道:知道我的利害了吧!"NOR"\n", CYN),
append_color(CYN "\n$n向后退了几步,说道:这场比试算我输了,下回看我怎么收拾你!"NOR"\n", CYN),
append_color(CYN "\n$n向后一纵,恨恨地说道:君子报仇,十年不晚!"NOR"\n", CYN),
append_color(CYN "\n$n脸色一寒,说道:算了算了,就当是我让你吧!"NOR"\n", CYN),
append_color(CYN "\n$n纵声而笑,叫道:“你运气好!你运气好!”一面身子向后跳开。"NOR"\n", CYN),
append_color(CYN "\n$n脸色微变,说道:佩服,佩服!"NOR"\n", CYN),
append_color(CYN "\n$n向后退了几步,说道:这场比试算我输了,佩服,佩服!"NOR"\n", CYN),
append_color(CYN "\n$n向后一纵,躬身做揖说道:阁下武艺不凡,果然高明!"NOR"\n", CYN),
});
void create()
{
int pd, pm;
seteuid(getuid());
set("channel_id", "战斗精灵");
if (undefinedp(pd = CONFIG_D->query_int("max pk perday")))
pd = DEFAULT_MAX_PK_PERDAY;
if (undefinedp(pm = CONFIG_D->query_int("max pk perman")))
pm = DEFAULT_MAX_PK_PERMAN;
set("pk_perday", pd);
set("pk_perman", pm);
}
// message after damage info
static string foo_before_hit = 0;
static string foo_after_hit = 0;
void set_bhinfo(string msg)
{
if (! foo_before_hit)
{
foo_before_hit = msg;
return;
}
foo_before_hit += msg;
}
void set_ahinfo(string msg)
{
if (! foo_after_hit)
{
foo_after_hit = msg;
return;
}
foo_after_hit += msg;
}
string query_bhinfo() { return foo_before_hit; }
string query_ahinfo() { return foo_after_hit; }
void clear_bhinfo() { foo_before_hit = 0; }
void clear_ahinfo() { foo_after_hit = 0; }
string damage_msg(int damage, string type)
{
string str;
if (damage == 0)
return "结果没有造成任何伤害。\n";
switch (type)
{
case "擦伤":
case "割伤":
if (damage < 15) str = "结果只是轻轻地划破$p的皮肉。"; else
if (damage < 40) str = "结果在$p$l划出一道细长的血痕。"; else
if (damage < 100) str = "结果「嗤」地一声划出一道伤口!"; else
if (damage < 200) str = "结果「嗤」地一声划出一道血淋淋的伤口!"; else
if (damage < 400) str = "结果「嗤」地一声划出一道又长又深的伤口,溅得$N满脸鲜血!"; else
str = "结果只听见$n一声惨嚎,$w已在$p$l划出一道深及见骨的可怕伤口!!";
return str +"\n";
break;
case "刺伤":
if (damage < 15) str = "结果只是轻轻地刺破$p的皮肉。"; else
if (damage < 40) str = "结果在$p$l刺出一个创口。"; else
if (damage < 100) str = "结果「噗」地一声刺入了$n$l寸许!"; else
if (damage < 200) str = "结果「噗」地一声刺进$n的$l,使$p不由自主地退了几步!"; else
if (damage < 400) str = "结果「噗嗤」地一声,$w已在$p$l刺出一个血肉模糊的血窟窿!"; else
str = "结果只听见$n一声惨嚎,$w已在$p的$l对穿而出,鲜血溅得满地!!";
return str +"\n";
break;
case "瘀伤":
case "震伤":
if (damage < 15) str = "结果只是轻轻地碰到,比拍苍蝇稍微重了点。"; else
if (damage < 40) str = "结果在$p的$l造成一处瘀青。"; else
if (damage < 100) str = "结果一击命中,$n的$l登时肿了一块老高!"; else
if (damage < 150) str = "结果一击命中,$n闷哼了一声显然吃了不小的亏!"; else
if (damage < 200) str = "结果「砰」地一声,$n退了两步!"; else
if (damage < 400) str = "结果这一下「砰」地一声打得$n连退了好几步,差一点摔倒!"; else
if (damage < 800) str = "结果重重地击中,$n「哇」地一声吐出一口鲜血!"; else
str = "结果只听见「砰」地一声巨响,$n像一捆稻草般飞了出去!!";
return str +"\n";
break;
case "内伤":
if (damage < 15) str = "结果只是把$n打得退了半步,毫发无损。"; else
if (damage < 40) str = "结果$n痛哼一声,在$p的$l造成一处瘀伤。"; else
if (damage < 100) str = "结果一击命中,把$n打得痛得弯下腰去!"; else
if (damage < 150) str = "结果$n闷哼了一声,脸上一阵青一阵白,显然受了点内伤!"; else
if (damage < 200) str = "结果$n脸色一下变得惨白,昏昏沉沉接连退了好几步!"; else
if (damage < 400) str = "结果重重地击中,$n「哇」地一声吐出一口鲜血!"; else
if (damage < 800) str = "结果「轰」地一声,$n全身气血倒流,口中鲜血狂喷而出!"; else
str = "结果只听见几声喀喀轻响,$n一声惨叫,像滩软泥般塌了下去!!";
return str +"\n";
break;
case "点穴":
if (damage < 15) str = "结果只是轻轻的碰到$n的$l,根本没有点到穴道。"; else
if (damage < 40) str = "结果$n痛哼一声,在$p的$l造成一处淤青。"; else
if (damage < 100) str = "结果一击命中,$N点中了$n$l上的穴道,$n只觉一阵麻木!"; else
if (damage < 200) str = "结果$n闷哼了一声,脸上一阵青一阵白,登时觉得$l麻木!"; else
if (damage < 400) str = "结果$n脸色一下变得惨白,被$N点中$l的穴道,一阵疼痛遍布整个$l!"; else
if (damage < 800) str = "结果$n一声大叫,$l的穴道被点中,疼痛直入心肺!"; else
str = "结果只听见$n一声惨叫,一阵剧痛游遍全身,跟着直挺挺的倒了下去!";
return str +"\n";
break;
case "抽伤":
if (damage < 15) str = "结果只是在$n的皮肉上碰了碰,好象只蹭破点皮。"; else
if (damage < 40) str = "结果在$n$l抽出一道轻微的紫痕。"; else
if (damage < 100) str = "结果「啪」地一声在$n$l抽出一道长长的血痕!"; else
if (damage < 200) str = "结果只听「啪」地一声,$n的$l被抽得皮开肉绽,痛得$p咬牙切齿!"; else
if (damage < 400) str = "结果只听「啪」地一声,$n的$l被抽得皮开肉绽,痛得$p咬牙切齿!"; else
if (damage < 800) str = "结果「啪」地一声爆响!这一下好厉害,只抽得$n皮开肉绽,血花飞溅!"; else
str = "结果只听见$n一声惨嚎,$w重重地抽上了$p的$l,$n顿时血肉横飞!";
return str +"\n";
break;
case "反震伤":
if (damage < 15) str = "结果$N受到$n的内力反震,闷哼一声。"; else
if (damage < 40) str = "结果$N被$n的反震得气血翻腾,大惊失色。"; else
if (damage < 100) str = "结果$N被$n的反震得站立不稳,摇摇晃晃。"; else
if (damage < 200) str = "结果$N被$n以内力反震,「嘿」地一声退了两步。"; else
if (damage < 300) str = "结果$N被$n的震得反弹回来的力量震得半身发麻。"; else
if (damage < 400) str = "结果$N被$n的内力反震,胸口有如受到一记重击,连退了五六步!"; else
if (damage < 600) str = "结果$N被$n内力反震,眼前一黑,身子向後飞出丈许!!"; else
str = "结果$N被$n内力反震,狂吐鲜血,身子象断了线的风筝向後飞去!!";
return str +"\n";
break;
case "砸伤":
if (damage < 10) str = "结果只是轻轻地碰到,像是给$n搔了一下痒。"; else
if (damage < 40) str = "结果在$n的$l砸出一个小臌包。"; else
if (damage < 100) str = "结果$N这一下砸个正着,$n的$l登时肿了一块老高!"; else
if (damage < 150) str = "结果$N这一下砸个正着,$n闷哼一声显然吃了不小的亏!"; else
if (damage < 200) str = "结果只听「砰」地一声,$n疼得连腰都弯了下来!"; else
if (damage < 400) str = "结果这一下「轰」地一声砸得$n眼冒金星,差一点摔倒!"; else
if (damage < 800) str = "结果重重地砸中,$n眼前一黑,「哇」地一声吐出一口鲜血!"; else
str = "结果只听见「轰」地一声巨响,$n被砸得血肉模糊,惨不忍睹!";
return str +"\n";
break;
default:
if (! type) type = "伤害";
if (damage < 15) str = "结果只是勉强造成一处轻微"; else
if (damage < 40) str = "结果造成轻微的"; else
if (damage < 100) str = "结果造成一处"; else
if (damage < 150) str = "造成一处严重"; else
if (damage < 200) str = "结果造成颇为严重的"; else
if (damage < 300) str = "结果造成相当严重的"; else
if (damage < 400) str = "结果造成十分严重的"; else
if (damage < 600) str = "结果造成极其严重的"; else
str = "结果造成非常可怕的严重";
return str+ type +"!\n";
}
}
string eff_status_msg(int ratio)
{
if (ratio==100) return HIG "看起来气血充盈,并没有受伤。" NOR;
if (ratio > 95) return HIG "似乎受了点轻伤,不过光从外表看不大出来。" NOR;
if (ratio > 90) return HIY "看起来可能受了点轻伤。" NOR;
if (ratio > 80) return HIY "受了几处伤,不过似乎并不碍事。" NOR;
if (ratio > 60) return HIY "受伤不轻,看起来状况并不太好。" NOR;
if (ratio > 50) return HIR "气息粗重,动作开始散乱,看来所受的伤著实不轻。" NOR;
if (ratio > 40) return HIR "已经伤痕累累,正在勉力支撑著不倒下去。" NOR;
if (ratio > 30) return HIR "受了相当重的伤,只怕会有生命危险。" NOR;
if (ratio > 20) return RED "伤重之下已经难以支撑,眼看就要倒在地上。" NOR;
if (ratio > 10 ) return RED "摇头晃脑、歪歪斜斜地站都站不稳,眼看就要倒在地上。" NOR;
if (ratio > 5 )return RED "已经陷入半昏迷状态,随时都可能摔倒晕去。" NOR;
return RED "受伤过重,已经奄奄一息,命在旦夕了" NOR;
}
int valid_power(int combat_exp)
{
if (combat_exp < 2000000)
return combat_exp / 1000;
combat_exp -= 2000000;
if (combat_exp < 1000000)
return 2000 + combat_exp / 10000;
combat_exp -= 1000000;
return 2000 + (1000 / 10) + (combat_exp / 2000);
}
varargs int skill_power(object ob, string skill, int usage, int delta)
{
int status, level, power;
mapping dbase;
mapping temp;
mapping fight;
mapping apply;
if (! living(ob)) return 0;
level = ob->query_skill(skill);
dbase = ob->query_entire_dbase();
temp = ob->query_entire_temp_dbase();
if (temp)
{
apply = temp["apply"];
fight = temp["fight"];
}
switch (usage)
{
case SKILL_USAGE_ATTACK:
if (apply) level += apply["attack"];
break;
case SKILL_USAGE_DEFENSE:
if (apply) level += apply["defense"];
break;
}
level += delta;
if (level < 1)
{
power = valid_power((int)ob->query("combat_exp")) / 1000;
if (usage == SKILL_USAGE_ATTACK)
power = power / 100 * dbase["str"];
else
power = power / 100 * dbase["dex"];
return power;
}
if (level > 500)
power = level * level / 500000 * level;
else
power = level * level * level / 500000;
power += valid_power(dbase["combat_exp"])/500;
if (usage == SKILL_USAGE_ATTACK)
{
power = power / 30 * (dbase["str"] + (temp ? temp["str"] : 0));
if (fight && ob->is_fighting())
power += power / 100 * fight["attack"];
} else
{
power = power / 30 * (dbase["dex"] + (temp ? temp["dex"] : 0));
if (fight && ob->is_fighting())
power += power / 100 * fight[skill];
}
return power;
}
varargs int do_attack(object me, object victim, object weapon, int attack_type)
{
mapping my, your;
mapping my_temp, your_temp;
mapping prepare, action;
string limb, *limbs;
string attack_skill, force_skill, martial_skill, dodge_skill, parry_skill;
string parry_msg;
mixed foo;
int delta;
int ap, dp, pp;
int damage, damage_bonus, defense_factor;
int wounded;
int has_weapon;
object weapon2; // weapon of victim
object cloth; // armor of victim
string result;
string damage_info;
mapping fight;
object env_me;
object env_v;
if (environment(me)->query("no_fight"))
{
message_vision("$N和$n各自退了一步,收住了招。\n",me, victim);
me->remove_enemy(victim);
victim->remove_enemy(me);
return 0;
}
if (environment(me) != environment(victim))
{
me->remove_enemy(victim);
victim->remove_enemy(me);
return 0;
}
my = me->query_entire_dbase();
your = victim->query_entire_dbase();
if (! (my_temp = me->query_entire_temp_dbase()))
my_temp = allocate_mapping(5);
if (! (your_temp = victim->query_entire_temp_dbase()))
your_temp = allocate_mapping(5);
//
// (0) Choose skills.
//
prepare = me->query_skill_prepare();
if (! prepare) prepare = ([]);
if (objectp(weapon))
attack_skill = weapon->query("skill_type");
else
{
switch (sizeof(prepare))
{
case 0: attack_skill = "unarmed"; break;
case 1: attack_skill = (keys(prepare))[0]; break;
case 2: attack_skill = (keys(prepare))[me->query_temp("action_flag")]; break;
}
}
if (attack_skill == "pin")
attack_skill = "sword";
// (1) Find out what action the offenser will take.
//
me->reset_action();
action = me->query_action();
has_weapon = weapon || me->query_temp("armor/hands");
if (! action)
{
// reconfirm
me->reset_action();
action = me->query_action();
if (! mapp(action))
{
CHANNEL_D->do_channel( this_object(), "sys",
sprintf("%s(%s): bad action = %O",
me->query("name"), me->query("id"),
me->query_action(1)));
return 0;
}
}
if (me->query_temp("action_flag") == 0)
result = "\n" + action["action"] + "!\n";
else
result = "\n紧跟着" + action["action"] + "!\n";
//
// (2) Prepare AP, DP for checking if hit.
//
limbs = victim->query("limbs");
if (! arrayp(limbs))
{
limbs = ({ "身体" });
victim->set("limbs", limbs);
}
limb = limbs[random(sizeof(limbs))];
if (! my["not_living"])
{
fight = allocate_mapping(5);
fight["attack"] = action["attack"];
fight["dodge"] = action["dodge"];
fight["parry"] = action["parry"];
my_temp["fight"] = fight;
}
//计算攻击者技能 攻击力
ap = skill_power(me, attack_skill, SKILL_USAGE_ATTACK, 0);
if (ap < 1) ap = 1;
if (my["character"] == "阴险奸诈")
//阴险性格AP加乘120%
ap += ap * 20 / 100;
//计算被 攻击者 的 轻功 躲闪值
dp = skill_power(victim, "dodge", SKILL_USAGE_DEFENSE, 0);
if (stringp(dodge_skill = victim->query_skill_mapped("dodge")))
{
//如果装备特殊轻功,则计算特殊轻功的加乘率
dp += dp / 200 * SKILL_D(dodge_skill)->query_effect_dodge(me, victim);
}
if (dp < 1) dp = 1;
//如果被攻击者处于繁忙状态,躲闪值降低3倍
if (victim->is_busy()) dp /= 3;
//
// (3) Fight!
damage = 0; //破坏
wounded = 0; //创伤
damage_info = ""; //破坏信息
//如果随机(攻击值+被攻击者的躲闪值)小于躲闪值,认为躲闪成功
if (random(ap + dp) < dp && victim->query("qi")!=0)
{ // Does the victim dodge this hit?
#if INSTALL_COMBAT_TEST
if (wizardp(me) && me->query("env/combat_test"))
tell_object(me, HIY "【测试精灵】:己方 AP:" + ap +
",DP:" + dp + "。"NOR"\n");
if (wizardp(victim) && victim->query("env/combat_test"))
tell_object(victim, HIC "【测试精灵】:对方 AP:" + ap +
",DP:" + dp + "。"NOR"\n");
#endif
//如果没有装备特殊轻功,就给与基本轻功
if (! dodge_skill) dodge_skill = "dodge";
//取出轻功的躲闪信息。
result += SKILL_D(dodge_skill)->query_dodge_msg(limb);
//判断是否增加轻功的熟练度
//如果躲闪值小于攻击值,而且还躲过了攻击
if (userp(me) || userp(victim))
{
if (random(dp+ap) < dp && random(my["int"]) > 1)
{
//如果随即被攻击者的经验不大于极限经验,并且随机到真就加奖励
// tell_object(victim,PTEXT("你在"HIC"躲避"NOR+me->query("name")+"时对"HIG"【"+to_chinese(dodge_skill)+"】"NOR"顿有所悟: "YEL"武功熟练度 "HIY"↑"NOR","YEL"实战经验 "HIY"↑ " NOR));
your["combat_exp"]++;
victim->improve_skill(dodge_skill, 100);
}
}
}
else //如果躲闪不成功,就判断是否增加攻击的奖励
{
//
// (4) Check if the victim can parry this attack.
// 都是可以互动的
if (userp(me) || userp(victim))
{
//计算是否给予攻击奖励。
//如果攻击小于躲闪 并且 随机悟性大于14 ,并且潜能是否超出
if (random(my["int"]) > 1 )
{
if( me->query("combat_exp") < victim->query("combat_exp"))
{
if(me->query("potential") < me->query_potential_limit())
{
// tell_object(me,PTEXT("你在"HIR"攻击"NOR+victim->query("name")+"时对"HIG"【"+to_chinese(attack_skill)+"】"NOR"顿有所悟:"YEL" 武功熟练度 "HIY"↑"NOR","YEL"经验点 "HIY"↑ " NOR)); my["potential"]++;
your_temp["give_potential"] += my["mud_age"] / 86400;
victim->improve_skill(attack_skill, 100);
}
else
{
// tell_object(victim,PTEXT(WHT+"【你的潜能到极限了!!!】"NOR));
}
}
}
}
delta = 0;
//取出装备主手的兵器对象
if (weapon2 = your_temp["weapon"])
{
if (! weapon) delta = 10; //如果没有兵器,delta=10
}
else
{
if (weapon) delta = -10; //有装备兵器,delta=-10
}
//计算被攻击者 招架技能 的值
pp = skill_power(victim, "parry", SKILL_USAGE_DEFENSE, delta);
//如果被攻击者 繁忙,招架值减少3倍
if (victim->is_busy()) pp /= 3;
if (pp < 1) pp = 1;
//计算特殊招架技能给予的招架值加乘。
if (stringp(parry_skill = victim->query_skill_mapped("parry")))
pp += pp / 200 * SKILL_D(parry_skill)->query_effect_parry(me, victim);
//如果随机(攻击值+招架值)小于招架值 则判断 招架成功,除非气血为0
if (random(ap + pp) < pp && victim->query("qi")!=0)
{
#if INSTALL_COMBAT_TEST
if (wizardp(me) && me->query("env/combat_test"))
tell_object(me, HIY "【测试精灵】:己方 AP:" + ap +
",PP:" + pp + "。"NOR"\n");
if (wizardp(victim) && victim->query("env/combat_test"))
tell_object(victim, HIC "【测试精灵】:对方 AP:" + ap +
",PP:" + pp + "。"NOR"\n");
#endif
//如果没有特殊招架,则给予 [基本招架]
if (! parry_skill) parry_skill = "parry";
// change to SKILL_D(parry_skill) after added parry msg to those
// martial arts that can parry.
//取出有带兵器的[特殊招架]信息
parry_msg = SKILL_D(parry_skill)->query_parry_msg(weapon2);
//如果没有[特殊招架]兵器的招架信息
if (! stringp(parry_msg))
//就取出[基本招架]兵器信息
parry_msg = SKILL_D("parry")->query_parry_msg(weapon2);
//如果有招架信息,则赋予result+招架信息
if (stringp(parry_msg))
result += parry_msg;
//判断是否给予招架奖励
//如果招架值小于攻击,而招架成功,并且计算 xx>30
if (userp(me) || userp(victim))
{
if (random(my["int"]) > 1)
{
//如上,通过就给予招架奖励
if (your["combat_exp"] < EXP_LIMIT && victim->query("combat_exp")<me->query("combat_exp"))
{
// tell_object(victim,PTEXT("你在"HIM"招架"NOR+me->query("name")+"时对"HIG"【"+to_chinese(parry_skill)+"】"NOR"顿有所悟:"YEL" 武功熟练度 "HIY"↑"NOR","YEL"经验点 "HIY"↑ " NOR));
your["combat_exp"]++;
victim->improve_skill(parry_skill, 1);
}
else
{
// tell_object(victim,PTEXT(WHT+"【你的对手太弱了,无法取得任何经验!!!】"NOR));
}
}
}
}
else
{
//
// (5) We hit the victim and the victim failed to parry
//
//如果有兵器,则取出兵器的攻击力,否则取出空手攻击力
if (weapon)
damage = me->query_temp("apply/damage");
else
damage = me->query_temp("apply/unarmed_damage");
//将攻击力变成在一定的随机范围波动。
damage = (damage + random(damage)) / 2;
if (action["damage"])
damage += action["damage"] * damage / 100;
//攻击者力量取出
damage_bonus = me->query_str();
//判断是否是 愤怒状态
if (my["jianu"])
{
// does angry bnous
damage_bonus += me->cost_craze(my["jianu"]);
//是否为狂化状态,计算狂化状态信息
if (me->query_craze() > 1000 &&
random(my["jianu"] + 200) > 200)
{
damage_info += random(2) ? HIR "$N" HIR "大喝一声,双目圆睁,一股凌厉的杀气油然而起!"NOR"\n"
: HIR "$N" HIR "奋不顾身的扑上前来,招招紧逼$n" HIR ",毫不容情。"NOR"\n";
//消耗怒气值
me->cost_craze(200 + random(300));
damage_bonus += my["jianu"] * 2;
}
}
// Clear the special message info after damage info
foo_before_hit = 0;
foo_after_hit = 0;
// Let force skill take effect.
if (my["jiali"] && (my["neili"] > my["jiali"]))
{
if (force_skill = me->query_skill_mapped("force"))
{
foo = SKILL_D(force_skill)->force_hit_ob(me, victim, damage_bonus, my["jiali"]);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage_bonus += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage_bonus += foo["damage"];
}
}
#if INSTALL_COMBAT_TEST
if (wizardp(me) && me->query("env/combat_test"))
tell_object(me, HIY "【测试精灵】:己方 AP:" + ap +
",DP:" + dp + ",PP:" + pp +
",伤害效果:" + damage +
",额外伤害效果:" + damage_bonus + "。"NOR"\n");
if (wizardp(victim) && victim->query("env/combat_test"))
tell_object(victim, HIC "【测试精灵】:对方 AP:" + ap +
",DP:" + dp + ",PP:" + pp +
",伤害效果:" + damage +
",额外伤害效果:" + damage_bonus + "。"NOR"\n");
#endif
}
if (action["force"])
damage_bonus += action["force"] * damage_bonus / 100;
// calculate the damage
if (damage_bonus > 0)
damage += (damage_bonus + random(damage_bonus)) / 3;
// Let's attack & parry skill, weapon & armor do effect
while (damage > 0)
{
if (my["not_living"] || your["not_living"])
// Only two living do this
break;
if (damage < 1) break;
// Let parry skill take its special effort.
if (stringp(dodge_skill = victim->query_skill_mapped("dodge")))
{
victim->set_temp("dodge_valid_damage", 1);
foo = SKILL_D(dodge_skill)->valid_damage(me, victim, damage, weapon);
victim->delete_temp("dodge_valid_damage");
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
if (damage < 1) break;
}
if (stringp(parry_skill = victim->query_skill_mapped("parry")))
{
foo = SKILL_D(parry_skill)->valid_damage(me, victim, damage, weapon);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
if (damage < 1) break;
}
// 魔幻兽
if (mapp(your_temp["armor"]) && objectp(cloth = your_temp["armor"]["beast"]))
{
foo = cloth->valid_damage(me, victim, damage, weapon);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
} else
// Let armor/cloth take its special effort
if (mapp(your_temp["armor"]) && objectp(cloth = your_temp["armor"]["armor"]))
{
foo = cloth->valid_damage(me, victim, damage, weapon);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
} else
if (mapp(your_temp["armor"]) && objectp(cloth = your_temp["armor"]["cloth"]))
{
foo = cloth->valid_damage(me, victim, damage, weapon);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
}
if (damage < 1) break;
// Let attack skill take its special effort.
if (martial_skill = me->query_skill_mapped(attack_skill))
{
foo = SKILL_D(martial_skill)->hit_ob(me, victim, damage);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
if (damage < 1) break;
}
// Let weapon or living have their special damage.
if (weapon)
{
foo = weapon->hit_ob(me, victim, damage);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
} else
{
foo = me->hit_ob(me, victim, damage);
if (stringp(foo)) damage_info += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
damage_info += foo["msg"];
damage += foo["damage"];
}
}
// finish
break;
}
//
// (6) Inflict the damage.
//
if (damage > 0)
{
if (my["character"] == "心狠手辣")
damage += damage * 20 / 100;
// calculate wounded
wounded = damage;
if (mapp(your_temp["apply"]) && your_temp["apply"]["armor"] > 0)
wounded -= random(your_temp["apply"]["armor"]);
if (wounded > 400)
wounded = (wounded - 400) / 4 + 300;
else
if (wounded > 200)
wounded = (wounded - 200) / 2 + 200;
else
if (wounded < 1)
wounded = 0;
// recalculate damage
if (damage > 400)
damage = (damage - 400) / 4 + 300;
else
if (damage > 200)
damage = (damage - 200) / 2 + 200;
if (your["character"] == "光明磊落")
wounded -= wounded * 20 / 100;
damage = COMBAT_D->calc_damage(me, victim, damage);
damage = victim->receive_damage("qi", damage, me);
if (wounded > 0 &&
(has_weapon || random(3) == 1))
{
// We are sure that damage is greater than victim's armor here.
wounded = COMBAT_D->calc_wound(me, victim, wounded);
victim->receive_wound("qi", wounded, me);
}
#if INSTALL_COMBAT_TEST
if (wizardp(me) && me->query("env/combat_test"))
tell_object(me, HIY "【测试精灵】:你对" +
victim->query("name") + "造成" +
damage + "点伤害," +
wounded + "点创伤。"NOR"\n");
if (wizardp(victim) && victim->query("env/combat_test"))
tell_object(victim, HIG "【测试精灵】:你受到" +
me->query("name") + damage + "点伤害," +
wounded + "点创伤。"NOR"\n");
#endif
// add message before hit in victim
if (foo_before_hit)
result += foo_before_hit;
result += damage_msg(damage, action["damage_type"]);
damage_info += "( $n" + eff_status_msg(victim->query("qi") * 100 / victim->query("max_qi")) + ")\n";
}
if (foo_after_hit)
damage_info += foo_after_hit;
}
}
result = replace_string(result, "$l", limb);
if (objectp(weapon))
result = replace_string(result, "$w", weapon->name());
else if (stringp(action["weapon"]))
result = replace_string(result, "$w", action["weapon"]);
else if (attack_skill == "finger" || attack_skill == "hand")
result = replace_string(result, "$w", "手指" );
else if (attack_skill == "strike" || attack_skill == "claw")
result = replace_string(result, "$w", "手掌" );
else result = replace_string(result, "$w", "拳头" );
message_combatd(result, me, victim, damage_info,damage,action["damage_type"]);
if (damage > 0)
{
tell_object(me, HIW "( 你对" + victim->query("name")+HIW"造成"+ damage + "点伤害," + wounded + "点创伤。)\n" NOR);
tell_object(victim, HIG "( 你受到" + me->query("name")+HIG+damage+"点伤害,"+ wounded + "点创伤。)\n" NOR);
if (victim->is_busy())
victim->interrupt_me(victim, 3 + random(3));
if ((! me->is_killing(your["id"])) &&
(! victim->is_killing(my["id"])) &&
! victim->query("not_living") &&
your["qi"] * 3 <= your["max_qi"])
{
me->remove_enemy(victim);
victim->remove_enemy(me);
if (me->query("can_speak") && victim->query("can_speak"))
message_vision(winner_msg[random(sizeof(winner_msg))],
me, victim);
if (me == victim->query_competitor())
{
me->win();
victim->lost();
}
}
}
if (functionp(action["post_action"]))
evaluate(action["post_action"], me, victim, weapon, damage);
// See if the victim can make a riposte.
if (attack_type == TYPE_REGULAR && damage < 1 && your_temp["guarding"])
{
// your_temp["guarding"];
if (random(my["dex"]) < 8)
{
message_combatd("$N一击不中,露出了破绽!\n",me,victim,"",damage,"");
do_attack(victim, me, your_temp["weapon"],TYPE_QUICK);
} else
{
message_combatd("$N见$n攻击失误,趁机发动攻击!\n",me,victim,"",damage,"");
do_attack(victim, me, your_temp["weapon"],TYPE_RIPOSTE);
}
}
}
// do damage when perform
// I will consider the damage of the weapon
// what is final: final may be a function with result type string,
// or a single string.
// The syntax of the final string is info:damage_type@limb or info only,
// If the limb if ?, the system will auto select limb of
// target, if the final is a single string, the system will
// treat as damage infomation.
varargs string do_damage(object me, object target, mixed type,
int damage, int percent, mixed final)
{
mapping my;
object weapon;
object cloth;
int apply;
int armor;
int wound;
int jiali;
int bonus;
mixed foo;
string msg;
string skill;
string *limbs;
string limb;
string damage_type;
string result;
int str;
int damage_bonus;
// Am I use weapon
if (type == WEAPON_ATTACK)
{
apply = me->query_temp("apply/damage");
weapon = me->query_temp("weapon");
} else
if (type == UNARMED_ATTACK)
{
apply = me->query_temp("apply/unarmed_damage");
weapon = 0;
} else
{
apply = 0;
weapon = 0;
}
// Check the target's armor
armor = target->query_temp("apply/armor");
damage += apply;
msg = "";
foo_after_hit = 0;
while (type == UNARMED_ATTACK || type == WEAPON_ATTACK)
{
if (random(100) < 40)
break;
// Let parry skill take its special effort
if (skill = target->query_skill_mapped("parry"))
{
foo = SKILL_D(skill)->valid_damage(me, target, damage, weapon);
if (stringp(foo)) msg += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
msg += foo["msg"];
damage += foo["damage"];
}
}
if (damage < 1) break;
// Let dodge skill take its special effort
if (skill = target->query_skill_mapped("dodge"))
{
target->set_temp("dodge_valid_damage", 1);
foo = SKILL_D(skill)->valid_damage(me, target, damage, weapon);
target->delete_temp("dodge_valid_damage", 1);
if (stringp(foo)) msg += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
msg += foo["msg"];
damage += foo["damage"];
}
}
if (damage < 1) break;
//魔幻兽
if (cloth = target->query_temp("armor/beast"))
{
foo = cloth->valid_damage(me, target, damage, weapon);
if (stringp(foo)) msg += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
msg += foo["msg"];
damage += foo["damage"];
}
} else
// Let cloth & armor take its special effort
if (cloth = target->query_temp("armor/armor"))
{
foo = cloth->valid_damage(me, target, damage, weapon);
if (stringp(foo)) msg += foo; else
if (intp(foo)) damage += foo; else
if (mapp(foo))
{
msg += foo["msg"];