~case/dbns

ref: 0f9985edf4d2b9e98aaac388d30fd4ab8c4722cf dbns/src/skills_android.c -rw-r--r-- 70.7 KiB
0f9985edcase rm extern 10 months ago
                                                                                
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
/****************************************************************************
*                                                                           *
*        skills_android.c - skills and abilities unique to androids         *
*                                                                           *
****************************************************************************/

#include <sys/types.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include "mud.h"

extern void transStatApply args((CHAR_DATA * ch, int strMod, int spdMod, int intMod, int conMod));
extern void transStatRemove args((CHAR_DATA * ch));

void
do_absorb(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	char 	charBuf[MAX_STRING_LENGTH];
	char 	victBuf[MAX_STRING_LENGTH];
	char 	roomBuf[MAX_STRING_LENGTH];
	int 	absorbGsn = 0;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)) {
		if (ch->pcdata->learned[gsn_absorb2] > 0) {
			absorbGsn = gsn_absorb2;
		} else {
			absorbGsn = gsn_absorb;
		}
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[absorbGsn]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (is_android(victim)) {
		ch_printf(ch, "This won't work against other androids.\n\r");
		return;
	}
	if (ch->focus < skill_table[absorbGsn]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[absorbGsn]->focus;

	WAIT_STATE(ch, skill_table[absorbGsn]->beats);
	if (can_use_skill(ch, number_percent(), absorbGsn)) {
		if (absorbGsn == gsn_absorb2)
			dam = get_attmod(ch, victim) * number_range(3, 12);
		else
			dam = get_attmod(ch, victim) * number_range(2, 8);
		if (dam >= 0) {
			switch (number_range(1, 2)) {
			default:
				sprintf(charBuf, "You grab $N tightly, draining $M of some of $S energy. &W[$t]");
				sprintf(victBuf, "$n grabs you tightly, draining you of some of your energy. &W[$t]");
				sprintf(roomBuf, "$n grabs $N tightly, draining $M of some of $S energy. &W[$t]");
				break;

			case 1:
				sprintf(charBuf, "You grab $N tightly, draining $M of some of $S energy. &W[$t]");
				sprintf(victBuf, "$n grabs you tightly, draining you of some of your energy. &W[$t]");
				sprintf(roomBuf, "$n grabs $N tightly, draining $M of some of $S energy. &W[$t]");
				break;

			case 2:
				sprintf(charBuf, "You reach out and grab $N with one hand, draining $M of some of $S energy. &W[$t]");
				sprintf(victBuf, "$n reaches out and grabs you with one hand, draining you of some of your energy. &W[$t]");
				sprintf(roomBuf, "$n reaches out and grabs $N with one hand, draining $M of some of $S energy. &W[$t]");
				break;
			}

			act(AT_RED, charBuf, ch, num_punct(dam), victim, TO_CHAR);
			act(AT_RED, victBuf, ch, num_punct(dam), victim, TO_VICT);
			act(AT_RED, roomBuf, ch, num_punct(dam), victim, TO_NOTVICT);

			learn_from_success(ch, absorbGsn);
			xSET_BIT(ch->act, PLR_2XPL_GAIN);
			ch->melee = true;
			global_retcode = damage(ch, victim, dam, TYPE_HIT);
			ch->melee = false;

			if (xIS_SET(ch->act, PLR_2XPL_GAIN))
				xREMOVE_BIT(ch->act, PLR_2XPL_GAIN);
			if (xIS_SET(ch->act, PLR_3XPL_GAIN))
				xREMOVE_BIT(ch->act, PLR_3XPL_GAIN);
		}
		if (xIS_SET(ch->act, PLR_2XPL_GAIN))
			xREMOVE_BIT(ch->act, PLR_2XPL_GAIN);
		if (xIS_SET(ch->act, PLR_3XPL_GAIN))
			xREMOVE_BIT(ch->act, PLR_3XPL_GAIN);
	} else {
		act(AT_RED, "You missed $N while trying to grab $M.", ch, NULL, victim, TO_CHAR);
		act(AT_RED, "You quickly dodge out of the way from $n's open fist.", ch, NULL, victim, TO_VICT);
		act(AT_RED, "$N quickly dodges out of the way from $n's open fist.", ch, NULL, victim, TO_NOTVICT);

		if (xIS_SET(ch->act, PLR_2XPL_GAIN))
			xREMOVE_BIT(ch->act, PLR_2XPL_GAIN);
		if (xIS_SET(ch->act, PLR_3XPL_GAIN))
			xREMOVE_BIT(ch->act, PLR_3XPL_GAIN);

		learn_from_failure(ch, absorbGsn);
		ch->melee = true;
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
		ch->melee = false;
	}

	if (dam > 0) {
		if (absorbGsn == gsn_absorb2)
			dam = victim->mana * 0.10;
		else
			dam = victim->mana * 0.05;
		if (dam > 0) {
			if (victim->mana < dam) {
				dam = victim->mana;
				victim->mana = 0;
			} else
				victim->mana -= dam;

			ch->mana += dam;
		}
		if (ch->mana > ch->max_mana)
			ch->mana = ch->max_mana;
	}
}

void
do_battery(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (IS_NPC(ch) && is_split(ch)) {
		if (!ch->master)
			return;
		if (!can_use_skill(ch->master, number_percent(), gsn_battery))
			return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_battery]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if (!is_android_e(ch)) {
		ch_printf(ch, "Huh?\n\r");
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (ch->battery < 1) {
		ch_printf(ch, "You don't have any stored up ki energy!\n\r");
		return;
	}
	if (ch->focus < skill_table[gsn_battery]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_battery]->focus;

	sh_int 	z = get_aura(ch);

	WAIT_STATE(ch, skill_table[gsn_battery]->beats);
	if (can_use_skill(ch, number_percent(), gsn_battery)) {
		int 	min_batt = 0;
		int 	max_batt = 0;

		max_batt = ch->battery;
		min_batt = (int) (max_batt * 0.66);
		dam = get_attmod(ch, victim) * number_range(min_batt, max_batt);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);

		act(z, "You thrust your arm forward, and begin to charge up your stored ki energy. All of a sudden, you fire from your palm a roaring blast of energy the size of a large house. The blast wave quickly reaches $N, slamming into $M and exploding. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(z, "$n thrusts $s arm forward, and begins to charge up $s stored ki energy. All of a sudden, $n fires from $s palm a roaring blast of energy the size of a large house. The blast wave quickly reaches you, slamming into you and exploding. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
		act(z, "$n thrusts $s arm forward, and begins to charge up $s stored ki energy. All of a sudden, $n fires from $s palm a roaring blast of energy the size of a large house. The blast wave quickly reaches $N, slamming into $M and exploding. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

		dam = ki_absorb(victim, ch, dam, gsn_battery);
		learn_from_success(ch, gsn_battery);
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
	} else {
		act(z, "You missed $N with your battery blast.", ch, NULL, victim, TO_CHAR);
		act(z, "$n misses you with $s battery blast.", ch, NULL, victim, TO_VICT);
		act(z, "$n missed $N with a battery blast.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_battery);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}
	ch->battery = 0;
}

void
do_superandroid(CHAR_DATA * ch, char *argument)
{
	OBJ_DATA *o;

	if (IS_NPC(ch) && is_split(ch)) {
		if (!ch->master)
			return;
		if (!can_use_skill(ch->master, number_percent(), gsn_superandroid))
			return;
	}
	double 	pl_mult = 0;

	if ((o = get_eq_char(ch, WEAR_SHIELD)) != NULL) {
		ch_printf(ch, "You can't transform into a Super Android while you have a chip installed!\n\r");
		return;
	}
	if (xIS_SET((ch)->affected_by, AFF_SUPERANDROID)) {
		send_to_char("You power down and return to normal.\n\r", ch);
		xREMOVE_BIT((ch)->affected_by, AFF_SUPERANDROID);
		transStatRemove(ch);
		ch->pl = ch->exp;
		return;
	}
	pl_mult = 25;

	if (ch->mana < skill_table[gsn_superandroid]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	WAIT_STATE(ch, skill_table[gsn_superandroid]->beats);

	if (can_use_skill(ch, number_percent(), gsn_superandroid)) {
		act(AT_BLUE, "Your systems are suddenly flooded with power as you connect the absorbed android parts to your primary core. Your body bulges greatly with raw power as your very circuitry and framework changes within you, turning you into a Super Android.", ch, NULL, NULL, TO_CHAR);
		act(AT_BLUE, "$n's systems are suddenly flooded with power as $e connects absorbed android parts to $s primary core. $n's body bulges greatly with raw power as $s very circuitry and framework changes within $m, turning into a Super Android.", ch, NULL, NULL, TO_NOTVICT);

		xSET_BIT((ch)->affected_by, AFF_SUPERANDROID);

		ch->pl = ch->exp * pl_mult;

		transStatApply(ch, pl_mult, pl_mult, pl_mult, pl_mult);

		learn_from_success(ch, gsn_superandroid);
	} else {
		act(AT_BLUE, "You failed to properly interface your absorbed android parts to your primary systems.", ch, NULL, NULL, TO_CHAR);
		act(AT_BLUE, "$n failed to properly interface $s absorbed android parts to $s primary systems.", ch, NULL, NULL, TO_NOTVICT);
		learn_from_failure(ch, gsn_superandroid);
	}

	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_superandroid]->min_mana;
}

void
do_ehb(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (IS_NPC(ch) && is_split(ch)) {
		if (!ch->master)
			return;
		if (!can_use_skill(ch->master, number_percent(), gsn_ehb))
			return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_ehb]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (ch->mana < skill_table[gsn_ehb]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_ehb]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_ehb]->focus;

	WAIT_STATE(ch, skill_table[gsn_ehb]->beats);
	if (can_use_skill(ch, number_percent(), gsn_ehb)) {
		dam = get_attmod(ch, victim) * number_range(70, 80);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);

		act(AT_DGREY, "You bring your palms near each other infront of yourself and begin to charge an incredible amount of energy into a small space. You create an energy ball so dense it almost resembles a small black hole.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "Violent bolts of red electricity stream forth from the energy ball as the energy cannot be compacted any farther. Shouting 'NOW DIE' at your enemy, you fire the attack. The energy ball impacts with $N and explodes; engulfing $m in a gigantic explosion. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(AT_DGREY, "$n brings $s palms near each other infront of $mself and begins to charge an incredible amount of energy into a small space. $n creates an energy ball so dense it almost resembles a small black hole.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "Violent bolts of red electricity stream forth from the energy ball as the energy cannot be compacted any farther. Shouting 'NOW DIE' at you, $n fires the attack. The energy ball impacts with you and explodes; engulfing you in a gigantic explosion. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
		act(AT_DGREY, "$n brings $s palms near each other infront of $mself and begins to charge an incredible amount of energy into a small space. $n creates an energy ball so dense it almost resembles a small black hole.", ch, NULL, victim, TO_NOTVICT);
		act(AT_DGREY, "Violent bolts of red electricity stream forth from the energy ball as the energy cannot be compacted any farther. Shouting 'NOW DIE' at $N, $n fires the attack. The energy ball impacts with $N and explodes; engulfing $m in a gigantic explosion. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

		dam = ki_absorb(victim, ch, dam, gsn_ehb);
		learn_from_success(ch, gsn_ehb);
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
	} else {
		act(AT_DGREY, "You missed $N with your electric hell ball.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$n misses you with $s electric hell ball.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "$n missed $N with a electric hell ball.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_ehb);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}
	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_ehb]->min_mana;
}

void
do_androidfuse(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *rch;
	CHAR_DATA *vch;
	CHAR_DATA *dch;			/* dominant fuse char */
	CHAR_DATA *sch;			/* stasis fuse char */
	char 	arg[MAX_INPUT_LENGTH];
	char 	arg2[MAX_INPUT_LENGTH];
	int 	sn;
	int 	value;

	argument = one_argument(argument, arg);
	argument = one_argument(argument, arg2);

	if (ch->level < 63) {
		ch_printf(ch, "Huh?");
		return;
	}
	if (arg[0] == '\0') {
		ch_printf(ch, "\n\rSyntax: androidfuse (first person) (second person)\n\r");
		ch_printf(ch, "\n\rThe order in which you put the two people's names is very\n\r");
		ch_printf(ch, "important. The first person will be the dominant person, and\n\r");
		ch_printf(ch, "will control the resulting character. An android needs to\n\r");
		ch_printf(ch, "fuse with two androids in order to become a super android.\n\r");
		return;
	}
	if ((rch = get_char_room(ch, arg)) == NULL) {
		ch_printf(ch, "There is nobody here named %s.\n\r", arg);
		return;
	}
	if ((vch = get_char_room(ch, arg2)) == NULL) {
		ch_printf(ch, "There is nobody here named %s.\n\r", arg2);
		return;
	}
	if (IS_NPC(rch) || IS_NPC(vch)) {
		ch_printf(ch, "NPC's cannot fuse.\n\r");
		return;
	}
	if (is_superandroid(rch)) {
		ch_printf(ch, "%s already is a super android.\n\r", rch->name);
		return;
	}
	if (is_superandroid(vch)) {
		ch_printf(ch, "%s already is a super android.\n\r", vch->name);
		return;
	}
	if (!is_android(rch) || !is_android(vch)) {
		ch_printf(ch, "Only androids may fuse with other androids.\n\r");
		return;
	}
	if ((is_android_fm(rch) && is_android_fm(vch)) ||
	    (is_android_e(rch) && is_android_e(vch)) ||
	    (is_android_h(rch) && is_android_h(vch))) {
		ch_printf(ch, "Androids of the same type may not fuse.\n\r");
		return;
	}
	if ((rch->fm_core && is_android_fm(vch)) ||
	    (rch->e_core && is_android_e(vch)) ||
	    (rch->h_core && is_android_h(vch))) {
		ch_printf(ch, "%s has already absorbed a core of %s's android type.\n\r",
		    rch->name, vch->name);
		return;
	}
	if (IS_IMMORTAL(rch) || IS_IMMORTAL(vch)) {
		ch_printf(ch, "Admins may not fuse.\n\r");
		return;
	}
	if (is_transformed(rch)) {
		ch_printf(ch, "%s must power down completely first.\n\r", rch->name);
		return;
	}
	if (is_transformed(vch)) {
		ch_printf(ch, "%s must power down completely first.\n\r", vch->name);
		return;
	}
	dch = rch;
	sch = vch;

	dch->fused[dch->fusions] = STRALLOC(sch->name);
	sch->fused[sch->fusions] = STRALLOC(dch->name);
	dch->fusions++;
	sch->fusions++;
	dch->bck_name = STRALLOC(dch->name);
	sch->bck_name = STRALLOC(sch->name);
	dch->bck_race = dch->race;
	sch->bck_race = sch->race;
	dch->bck_pl = dch->exp;
	sch->bck_pl = sch->exp;

	if (is_android_h(sch))
		dch->h_core = true;
	if (is_android_e(sch))
		dch->e_core = true;
	if (is_android_fm(sch))
		dch->fm_core = true;

	dch->pcdata->quest_curr += sch->pcdata->quest_curr;
	dch->pcdata->quest_accum += sch->pcdata->quest_accum;
	dch->pcdata->pkills += sch->pcdata->pkills;
	dch->pcdata->pdeaths += sch->pcdata->pdeaths;
	dch->pcdata->mkills += sch->pcdata->mkills;
	dch->pcdata->mdeaths += sch->pcdata->mdeaths;
	dch->pcdata->spar_wins += sch->pcdata->spar_wins;
	dch->pcdata->spar_loss += sch->pcdata->spar_loss;
	dch->corespl += sch->exp;

	ch_printf(dch, "&G%s suddenly breaks apart. All of %'s body pieces drop the ground\n\r"
	    "in a pile, except for the CPU and power core. Acting as if they had\n\r"
	    "mind of their own, they fly towards you and absorb straight into\n\r"
	    "your body.\n\r",
	    sch->name, sch->name);

	ch_printf(sch, "&RYou suddenly lose control of your body. Your vision begins to twist\n\r"
	    "and distort wildly. You try to scream out, but before the signal can\n\r"
	    "reaches your voice systems, your body is ripped apart. The various\n\r"
	    "pieces of your body fall to the ground in a heap; while the CPU and\n\r"
	    "power core remain floating in the air, covered in a strange glow. Then,\n\r"
	    "as if they had a mind of their own, they fly directly towards %s and\n\r"
	    "are absorbed into %s's body. You cease to exist...\n\r",
	    dch->name, dch->name);

	if (dch->fusions == 2) {
		dch->exp += (dch->corespl / 2);
		dch->corespl = 0;

		dch->race = get_race_num("super-android");
		dch->class = get_class_num("super-android");

		value = 95;
		for (sn = 0; sn < top_sn; sn++) {
			if (skill_table[sn]->min_level[dch->class] == 0
			    || skill_table[sn]->skill_level[dch->class] == 0)
				continue;

			if (skill_table[sn]->name
			    && (dch->exp >= skill_table[sn]->skill_level[dch->class]
				|| value == 0)) {
				if (value > GET_ADEPT(dch, sn) && !IS_IMMORTAL(dch))
					dch->pcdata->learned[sn] = GET_ADEPT(dch, sn);
				else
					dch->pcdata->learned[sn] = value;
			}
		}
		SET_BIT(dch->fusionflags, FUSION_SUPERANDROID);
		SET_BIT(sch->fusionflags, FUSION_STASIS);
		char_to(sch, ROOM_VNUM_FUSIONSTASIS);
		save_char_obj(dch);
		save_char_obj(sch);
	} else {
		SET_BIT(sch->fusionflags, FUSION_STASIS);
		char_to(sch, ROOM_VNUM_FUSIONSTASIS);
		save_char_obj(dch);
		save_char_obj(sch);
	}

	ch_printf(ch, "%s and %s have been fused together.\n\r",
	    dch->name, sch->name);
}

void
do_rocket_punch(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_rocket_punch]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_rocket_punch]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_rocket_punch]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_rocket_punch]->focus;

	WAIT_STATE(ch, skill_table[gsn_rocket_punch]->beats);
	if (can_use_skill(ch, number_percent(), gsn_rocket_punch)) {
		dam = get_attmod(ch, victim) * number_range(22, 27);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);
		act(AT_DGREY, "Your fist detaches, a powerful rocket firing it towards $N.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$N is smashed by the flying fist, "
		    "which quickly returns and reattaches to your arm. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(AT_DGREY, "$n's fist detaches, a powerful rocket firing it toward you.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "You are smashed by the flying fist, "
		    "which quickly returns and reattaches to $n's arm. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
		act(AT_DGREY, "$n's fist detaches, a powerful rocket firing it toward $N.", ch, NULL, victim, TO_NOTVICT);
		act(AT_DGREY, "$N is smashed by the flying fist, "
		    "which quickly returns and reattaches to $n's arm. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

		learn_from_success(ch, gsn_rocket_punch);
		ch->melee = true;
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
		ch->melee = false;
	} else {
		act(AT_DGREY, "You missed $N with your rocket punch.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$n misses you with $s rocket punch.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "$n missed $N with a rocket punch.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_rocket_punch);
		ch->melee = true;
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
		ch->melee = false;
	}
	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_rocket_punch]->min_mana;
}

void
do_drp(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_drp]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_drp]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_drp]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_drp]->focus;

	WAIT_STATE(ch, skill_table[gsn_drp]->beats);
	if (can_use_skill(ch, number_percent(), gsn_drp)) {
		dam = get_attmod(ch, victim) * number_range(35, 45);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);
		act(AT_DGREY, "Both of your fists detach, powerful rockets firing them toward $N.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$N is smashed by the flying fists, "
		    "which quickly return and reattach to your arms. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(AT_DGREY, "Both of $n's fists detach, powerful rockets firing them toward you.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "You are smashed by the flying fists, "
		    "which quickly return and reattach to $n's arms. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
		act(AT_DGREY, "Both of $n's fists detach, powerful rockets firing them toward $N.", ch, NULL, victim, TO_NOTVICT);
		act(AT_DGREY, "$N is smashed by the flying fists, "
		    "which quickly return and reattach to $n's arms. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

		learn_from_success(ch, gsn_drp);
		ch->melee = true;
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
		ch->melee = false;
	} else {
		act(AT_DGREY, "You missed $N with your double rocket punch.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$n misses you with $s double rocket punch.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "$n missed $N with a double rocket punch.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_drp);
		ch->melee = true;
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
		ch->melee = false;
	}
	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_drp]->min_mana;
}

void
do_railgun(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (IS_NPC(ch) && is_split(ch)) {
		if (!ch->master)
			return;
		if (!can_use_skill(ch->master, number_percent(), gsn_railgun))
			return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->exp < skill_table[gsn_railgun]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (ch->mana < skill_table[gsn_railgun]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->pcdata->sd_charge < 10) {
		ch_printf(ch, "You don't have enough SD charges.\n\r");
		return;
	}
	if (ch->focus < skill_table[gsn_railgun]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_railgun]->focus;

	ch->pcdata->sd_charge -= 10;

	WAIT_STATE(ch, skill_table[gsn_railgun]->beats);
	if (can_use_skill(ch, number_percent(), gsn_railgun)) {
		switch (number_range(1, 100)) {
		case 100:
			if (IS_NPC(victim) || (!IS_NPC(victim) &&
				(!xIS_SET(ch->act, PLR_SPAR) || !xIS_SET(ch->act, PLR_SPAR)))) {

				/*
				 * Redone so that instant death can't be
				 * abused to instant kill players over 2x
				 * their power.
				 */
				if (victim->pl / ch->pl >= 2) {
					act(AT_BLUE, "Your hand suddenly turns into a mass of light, which disappears back down into your forearm. Your forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. You aim your arm at $N and begin to charge an immense amount of energy.", ch, NULL, victim, TO_CHAR);
					act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of your arm, bolt of lightning franticly racing between them as the energy gathers, your arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from your arm at random, striking at the ground and sky as the energy you charge goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from your arm at $N, leaving a spiral trail of faint blue electricity in its wake. $N dodges the projectile at the last second. Your arm returns to normal afterwards.", ch, NULL, victim, TO_CHAR);
					act(AT_BLUE, "$n's hand suddenly turns into a mass of light, which disappears back down into $s forearm. $n's forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. $n aims $s arm at you and begins to charge an immense amount of energy.", ch, NULL, victim, TO_VICT);
					act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of $n's arm, bolt of lightning franticly racing between them as the energy gathers, $s arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from $n's arm at random, striking at the ground and sky as the energy $e charges goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from $n's arm at you, leaving a spiral trail of faint blue electricity in its wake. You dodge the projectile at the last second. $n's arm returns to normal afterwards.", ch, NULL, victim, TO_VICT);
					act(AT_BLUE, "$n's hand suddenly turns into a mass of light, which disappears back down into $s forearm. $n's forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. $n aims $s arm at $N and begins to charge an immense amount of energy.", ch, NULL, victim, TO_NOTVICT);
					act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of $n's arm, bolt of lightning franticly racing between them as the energy gathers, $s arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from $n's arm at random, striking at the ground and sky as the energy $e charges goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from $n's arm at $N, leaving a spiral trail of faint blue electricity in its wake. $N dodges the projectile at the last second. $n's arm returns to normal afterwards.", ch, NULL, victim, TO_NOTVICT);
					dam = 0;
					break;
				}
				dam = 999999999;

				act(AT_BLUE, "Your hand suddenly turns into a mass of light, which disappears back down into your forearm. Your forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. You aim your arm at $N and begin to charge an immense amount of energy.", ch, NULL, victim, TO_CHAR);
				act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of your arm, bolt of lightning franticly racing between them as the energy gathers, your arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from your arm at random, striking at the ground and sky as the energy you charge goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from your arm at $N, leaving a spiral trail of faint blue electricity in its wake. &R$N is hit by the projectile, and instantly killed.&B Your arm returns to normal afterwards. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
				act(AT_BLUE, "$n's hand suddenly turns into a mass of light, which disappears back down into $s forearm. $n's forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. $n aims $s arm at you and begins to charge an immense amount of energy.", ch, NULL, victim, TO_VICT);
				act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of $n's arm, bolt of lightning franticly racing between them as the energy gathers, $s arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from $n's arm at random, striking at the ground and sky as the energy $e charges goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from $n's arm at you, leaving a spiral trail of faint blue electricity in its wake. &RYou are hit by the projectile, and instantly killed.&B $n's arm returns to normal afterwards. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
				act(AT_BLUE, "$n's hand suddenly turns into a mass of light, which disappears back down into $s forearm. $n's forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. $n aims $s arm at $N and begins to charge an immense amount of energy.", ch, NULL, victim, TO_NOTVICT);
				act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of $n's arm, bolt of lightning franticly racing between them as the energy gathers, $s arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from $n's arm at random, striking at the ground and sky as the energy $e charges goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from $n's arm at $N, leaving a spiral trail of faint blue electricity in its wake. &R$N is hit by the projectile, and instantly killed.&B $n's arm returns to normal afterwards. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

				learn_from_success(ch, gsn_railgun);
				global_retcode = damage(ch, victim, dam, TYPE_HIT);
				break;
			}
		default:
			dam = get_attmod(ch, victim) * number_range(60, 80);
			if (ch->charge > 0)
				dam = chargeDamMult(ch, dam);

			act(AT_BLUE, "Your hand suddenly turns into a mass of light, which disappears back down into your forearm. Your forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. You aim your arm at $N and begin to charge an immense amount of energy.", ch, NULL, victim, TO_CHAR);
			act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of your arm, bolt of lightning franticly racing between them as the energy gathers, your arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from your arm at random, striking at the ground and sky as the energy you charge goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from your arm at $N, leaving a spiral trail of faint blue electricity in its wake. $N is hit by the projectile, and dealt an incredible amount of damage. Your arm returns to normal afterwards. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
			act(AT_BLUE, "$n's hand suddenly turns into a mass of light, which disappears back down into $s forearm. $n's forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. $n aims $s arm at you and begins to charge an immense amount of energy.", ch, NULL, victim, TO_VICT);
			act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of $n's arm, bolt of lightning franticly racing between them as the energy gathers, $s arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from $n's arm at random, striking at the ground and sky as the energy $e charges goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from $n's arm at you, leaving a spiral trail of faint blue electricity in its wake. You are hit by the projectile, and dealt an incredible amount of damage. $n's arm returns to normal afterwards. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
			act(AT_BLUE, "$n's hand suddenly turns into a mass of light, which disappears back down into $s forearm. $n's forearm then clicks, and seperates into two parrallel halves, with random arcs of electricity jumping across the gap. $n aims $s arm at $N and begins to charge an immense amount of energy.", ch, NULL, victim, TO_NOTVICT);
			act(AT_BLUE, "As particles of light appear in the air and rush towards the gap between the halves of $n's arm, bolt of lightning franticly racing between them as the energy gathers, $s arm begins to spin. It spins faster, and faster, becoming a blinding, crackling blur of energy and metal. Gigantic bolts of energy arc out from $n's arm at random, striking at the ground and sky as the energy $e charges goes critical. Suddenly, there is a deafening sound of a thunder clap as a small, pulsing dart of light shoots out from $n's arm at $N, leaving a spiral trail of faint blue electricity in its wake. $N is hit by the projectile, and dealt an incredible amount of damage. $n's arm returns to normal afterwards. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

			learn_from_success(ch, gsn_railgun);
			global_retcode = damage(ch, victim, dam, TYPE_HIT);
			break;
		}
	} else {
		act(AT_BLUE, "You missed $N with your rail gun.", ch, NULL, victim, TO_CHAR);
		act(AT_BLUE, "$n misses you with $s rail gun.", ch, NULL, victim, TO_VICT);
		act(AT_BLUE, "$n missed $N with a rail gun.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_railgun);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}
	ch->mana -= skill_table[gsn_railgun]->min_mana;
}

void
do_cruise_punch(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	sh_int 	dir = 0;
	bool 	hasexit = true;
	EXIT_DATA *exit;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_cruise_punch]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!has_exits(ch->in_room)) {
		ch_printf(ch, "This room has no exits!\n\r");
		return;
	}
	if (IS_NPC(victim)) {
		ch_printf(ch, "You can't use cruise punch on NPC's!\n\r");
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_cruise_punch]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_cruise_punch]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_cruise_punch]->focus;

	WAIT_STATE(ch, skill_table[gsn_cruise_punch]->beats);
	if (can_use_skill(ch, number_percent(), gsn_cruise_punch)) {
		act(AT_DGREY, "Your fist detaches and launches towards $N. But instead of hitting $M, the arm grabs $N by the head and hits the afterburners; throwing $N out of the room at high speeds!", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$n's fist detaches and launches towards you. But instead of hitting you, the arm grabs you by the head and hits the afterburners; throwing you out of the room at high speeds!", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "$n's fist detaches and launches towards $N. But instead of hitting $M, the arm grabs $N by the head and hits the afterburners; throwing $N out of the room at high speeds!", ch, NULL, victim, TO_NOTVICT);


		if (get_exit(ch->in_room, DIR_NORTH))
			dir = DIR_NORTH;
		else if (get_exit(ch->in_room, DIR_EAST))
			dir = DIR_EAST;
		else if (get_exit(ch->in_room, DIR_WEST))
			dir = DIR_WEST;
		else if (get_exit(ch->in_room, DIR_SOUTH))
			dir = DIR_SOUTH;
		else if (get_exit(ch->in_room, DIR_NORTHEAST))
			dir = DIR_NORTHEAST;
		else if (get_exit(ch->in_room, DIR_NORTHWEST))
			dir = DIR_NORTHWEST;
		else if (get_exit(ch->in_room, DIR_SOUTHEAST))
			dir = DIR_SOUTHEAST;
		else if (get_exit(ch->in_room, DIR_SOUTHWEST))
			dir = DIR_SOUTHWEST;
		else if (get_exit(ch->in_room, DIR_DOWN))
			dir = DIR_DOWN;
		else if (get_exit(ch->in_room, DIR_UP))
			dir = DIR_UP;

		stop_fighting(ch, true);

		act(AT_RED, "$N is sent flying out of the room!", ch, NULL, victim, TO_CHAR);
		act(AT_RED, "You are sent flying out of the room!", ch, NULL, victim, TO_VICT);
		act(AT_RED, "$N is sent flying out of the room!", ch, NULL, victim, TO_NOTVICT);

		while (hasexit) {
			exit = get_exit(victim->in_room, dir);
			if (!exit) {
				do_look(victim, "");
				act(AT_RED, "$n is sent flying into the room!", victim, NULL, NULL, TO_ROOM);
				act(AT_RED, "$n slams into a wall!", victim, NULL, NULL, TO_ROOM);
				hasexit = false;
				break;
			}
			char_from_room(victim);
			char_to_room(victim, exit->to_room);
			do_look(victim, "");
			exit = get_exit(victim->in_room, dir);
			if (!exit || (victim->in_room == ch->in_room)) {
				act(AT_RED, "$n is sent flying into the room!", victim, NULL, NULL, TO_ROOM);
				act(AT_RED, "$n slams into a wall!", victim, NULL, NULL, TO_ROOM);
				hasexit = false;
				break;
			}
			act(AT_RED, "$n is sent flying into the room!", victim, NULL, NULL, TO_ROOM);
			act(AT_RED, "$n is sent flying back out of the room!", victim, NULL, NULL, TO_ROOM);
		}
		act(AT_RED, "Your fist returns to you.", ch, NULL, NULL, TO_CHAR);
		act(AT_RED, "$n's fist returns to him.", ch, NULL, NULL, TO_ROOM);

		learn_from_success(ch, gsn_cruise_punch);
	} else {
		act(AT_DGREY, "You missed $N with your cruise punch.", ch, NULL, victim, TO_CHAR);
		act(AT_DGREY, "$n misses you with $s cruise punch.", ch, NULL, victim, TO_VICT);
		act(AT_DGREY, "$n missed $N with a cruise punch.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_cruise_punch);
	}
	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_cruise_punch]->min_mana;
}

void
do_electric_shield(CHAR_DATA * ch, char *argument)
{
	AFFECT_DATA af;
	int 	shieldGsn = 0;
	int 	nacMod = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (!IS_NPC(ch)) {
		if (ch->pcdata->learned[gsn_electric_shield4] > 0) {
			shieldGsn = gsn_electric_shield4;
			nacMod = 1500;
		} else if (ch->pcdata->learned[gsn_electric_shield3] > 0) {
			shieldGsn = gsn_electric_shield3;
			nacMod = 1000;
		} else if (ch->pcdata->learned[gsn_electric_shield2] > 0) {
			shieldGsn = gsn_electric_shield2;
			nacMod = 750;
		} else {
			shieldGsn = gsn_electric_shield;
			nacMod = 500;
		}
	}
	if (!IS_NPC(ch)
	    && !xIS_SET(ch->affected_by, AFF_ELECTRICSHIELD)
	    && ch->mana < skill_table[shieldGsn]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (xIS_SET(ch->affected_by, AFF_ELECTRICSHIELD)) {
		//send_to_char("Your electric shield is already up.\n\r", ch);
		//return;
		act(AT_SKILL, "You clench your fists and power down your electric shield.", ch, NULL, NULL, TO_CHAR);
		act(AT_SKILL, "The crackling electric shield around $n vanishes.", ch, NULL, NULL, TO_NOTVICT);
		xREMOVE_BIT(ch->affected_by, AFF_ELECTRICSHIELD);
		affect_strip(ch, shieldGsn);
		return;
	}
	if (can_use_skill(ch, number_percent(), shieldGsn)) {
		act(AT_SKILL, "You clench your fists as a powerful electric shield sparks up around you.", ch, NULL, NULL, TO_CHAR);
		act(AT_SKILL, "A crackling electric shield sparks up around $n.", ch, NULL, NULL, TO_NOTVICT);

		learn_from_success(ch, shieldGsn);
		af.type = shieldGsn;
		af.duration = (24) * DUR_CONV;
		af.location = APPLY_NATURALAC;
		af.bitvector = meb(AFF_ELECTRICSHIELD);
		af.modifier = nacMod;
		affect_to_char(ch, &af);
	} else {
		act(AT_SKILL, "You clench your fists as nothing happens...", ch, NULL, NULL, TO_CHAR);
		act(AT_SKILL, "You see $n clench $s fists, for no apparent reason.", ch, NULL, NULL, TO_NOTVICT);
		learn_from_failure(ch, shieldGsn);
	}

	if (!is_android_h(ch))
		ch->mana -= skill_table[shieldGsn]->min_mana;
}

void
do_multi_eye(CHAR_DATA * ch, char *arg)
{
	char 	buf[MAX_STRING_LENGTH];
	char 	buf2[MAX_STRING_LENGTH];
	CHAR_DATA *victim;
	int 	shot = 0;
	int 	shots = 0;
	int 	dam = 0;
	int 	dam2 = 0;
	int 	energy = 0;

	if (IS_NPC(ch) && is_split(ch)) {
		if (!ch->master)
			return;
		if (!can_use_skill(ch->master, number_percent(), gsn_multi_eye))
			return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_multi_eye]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if (arg[0] == '\0' || atoi(arg) <= 0) {
		send_to_char("Syntax: 'multi eye beam' <# of beams>\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	int 	z = get_aura(ch);

	shot = atoi(arg);
	if (shot > 25)
		shot = 25;
	if (shot < 2)
		shot = 2;
	energy = shot * skill_table[gsn_multi_eye]->min_mana;
	shots = shot;
	strcpy(buf, num_punct(shot));

	if (ch->mana < energy) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	int 	focus = (skill_table[gsn_multi_eye]->focus * (shot / 10));

	if (focus < 12)
		focus = 12;

	if (ch->focus < focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= focus;

	WAIT_STATE(ch, (skill_table[gsn_multi_eye]->beats));

	if (can_use_skill(ch, number_percent(), gsn_multi_eye)) {
		while (shots > 0) {
			switch (number_range(1, 2)) {
			default:
			case 1:
				break;
			case 2:
				dam += number_range(0, 2);
				break;
			}
			shots--;
		}
		dam2 = number_range(2, 5);
		if (dam2 > 3)
			dam2--;
		strcpy(buf2, num_punct(get_attmod(ch, victim) * dam * dam2));

		act2(z, "Your eyes glow brightly as they begin rapid-firing twin beams of energy at $N like a machine gun. $N is bombarded by $t pairs of energy beams. &W[$T]", ch, buf, victim, TO_CHAR, buf2);
		act2(z, "$n's eyes glow brightly as they begin rapid-firing twin beams of energy at you like a machine gun. You are bombarded by $t pairs of energy beams. &W[$T]", ch, buf, victim, TO_VICT, buf2);
		act2(z, "$n's eyes glow brightly as they begin rapid-firing twin beams of energy at $N like a machine gun. $N is bombarded by $t pairs of energy beams. &W[$T]", ch, buf, victim, TO_NOTVICT, buf2);

		learn_from_success(ch, gsn_multi_eye);
		global_retcode = damage(ch, victim, (get_attmod(ch, victim) * dam * dam2), TYPE_HIT);
	} else {
		act(z, "$t beams of energy fly from your eyes towards $N but $E is too fast to hit.", ch, buf, victim, TO_CHAR);
		act(z, "$t beams of energy fly from $n's eyes towards you but you dodge them.", ch, buf, victim, TO_VICT);
		act(z, "$t beams of energy fly from $n's eyes towards $N but $E is too fast to hit.", ch, buf, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_multi_eye);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}
	if (!is_android_h(ch))
		ch->mana -= energy;
}

void
do_self_destruct(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch)) {
		send_to_char("Bad NPC!  Be nice to players.\n\r", ch);
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_self_destruct]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_self_destruct]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->pcdata->sd_charge < 100) {
		send_to_char("You need to charge up more first.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_self_destruct]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_self_destruct]->focus;

	WAIT_STATE(ch, skill_table[gsn_self_destruct]->beats);
	ch->pcdata->sd_charge -= 100;
	if (can_use_skill(ch, number_percent(), gsn_self_destruct)) {
		act(AT_SKILL, "You charge all your energy into a final deadly blast incinerating $N along with your self.", ch, NULL, victim, TO_CHAR);
		act(AT_SKILL, "$n charges all $s energy into a final deadly blast incinerating you along with $m.", ch, NULL, victim, TO_VICT);
		act(AT_SKILL, "$n charges all $s energy into a final deadly blast incinerating $N along with $m self.", ch, NULL, victim, TO_NOTVICT);

		learn_from_success(ch, gsn_self_destruct);
		dam = 999999999;
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
		dam = 999999999;
		global_retcode = damage(ch, ch, dam, TYPE_HIT);
	} else {
		act(AT_SKILL, "You charge all your energy into a final deadly blast, BUT $N DODGES YOUR ATTACK!", ch, NULL, victim, TO_CHAR);
		act(AT_SKILL, "$n charges all $s energy into a final deadly blast, you RUN!", ch, NULL, victim, TO_VICT);
		act(AT_SKILL, "$n changes all $s energy into a final deadly blast, but $N takes off like a bat outa hell and $n misses!", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_self_destruct);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
		dam = 999999999;
		global_retcode = damage(ch, ch, dam, TYPE_HIT);
	}
	ch->mana -= skill_table[gsn_self_destruct]->min_mana;
	return;
}

void
do_duplicate(CHAR_DATA * ch, char *argument)
{
	return;
}

void
do_uppercut(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_uppercut]->skill_level[ch->class]) {
		send_to_char(
		    "You better leave the martial arts to fighters.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_uppercut]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_uppercut]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_uppercut]->focus;

	WAIT_STATE(ch, skill_table[gsn_uppercut]->beats);

	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_uppercut]->min_mana;

	if (can_use_skill(ch, number_percent(), gsn_uppercut)) {
		act(AT_SKILL, "You launch your fist upwards, hitting $N.", ch, NULL, victim, TO_CHAR);
		act(AT_SKILL, "$n launchs $s fist upwards, hitting you.", ch, NULL, victim, TO_VICT);
		act(AT_SKILL, "$n launchs $s fist upwards, hitting $N.", ch, NULL, victim, TO_NOTVICT);

		learn_from_success(ch, gsn_uppercut);
		ch->melee = true;
		global_retcode = damage(ch, victim, (get_attmod(ch, victim) * number_range(6, 10)), TYPE_HIT);
		ch->melee = false;
	} else {
		act(AT_SKILL, "You launch your fist upwards, but you miss $N.", ch, NULL, victim, TO_CHAR);
		act(AT_SKILL, "$n launchs $s fist upwards, but $e misses you.", ch, NULL, victim, TO_VICT);
		act(AT_SKILL, "$n launchs $s fist upwards, but $e misses $N.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_uppercut);
		ch->melee = true;
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
		ch->melee = false;
	}
}

void
do_evolve(CHAR_DATA * ch, char *argument)
{

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (!IS_NPC(ch)) {
		if (IS_SET(ch->pcdata->flags, PCFLAG_KNOWSMYSTIC)) {
			ch_printf(ch, "You are unable to call upon those powers while you know mystic.\n\r");
			return;
		}
	}
	if (wearing_chip(ch)) {
		ch_printf(ch, "You can't while you have a chip installed.\n\r");
		return;
	}
	if (IS_NPC(ch) || ch->race != 6) {
		send_to_char("Huh?\n\r", ch);
		return;
	}
	if (argument[0] == '\0') {
		send_to_char("How do you want to evolve?\n\r", ch);
		return;
	}
	if (str_prefix(argument, "semi-perfect form")
	    && str_prefix(argument, "perfect form")
	    && str_prefix(argument, "ultra-perfect form")) {
		send_to_char("You can't evolve into that.\n\r", ch);
		return;
	}
	if ((!str_prefix(argument, "semi-perfect form") && ch->pcdata->learned[gsn_semiperfect] <= 0)
	    || (!str_prefix(argument, "perfect form") && ch->pcdata->learned[gsn_perfect] <= 0)
	    || (!str_prefix(argument, "ultra-perfect form") && ch->pcdata->learned[gsn_ultraperfect] <= 0)) {
		send_to_char("You must absorb more energy before you can evolve into that form.\n\r", ch);
		return;
	}
	if (!str_prefix(argument, "semi-perfect form")
	    && ch->pcdata->learned[gsn_semiperfect] > 0) {
		if (ch->mana < skill_table[gsn_semiperfect]->min_mana) {
			send_to_char("You don't have enough energy.\n\r", ch);
			return;
		}
		if (xIS_SET(ch->affected_by, AFF_SEMIPERFECT)) {
			send_to_char("You are already in that form.\n\r", ch);
			return;
		}
		xSET_BIT(ch->affected_by, AFF_SEMIPERFECT);
		xREMOVE_BIT(ch->affected_by, AFF_PERFECT);
		xREMOVE_BIT(ch->affected_by, AFF_ULTRAPERFECT);
		act(AT_PURPLE, "Your horns shift closer together, your features becoming more humanoid as "
		    "you grow in size and complete your evolution to a Semi-Perfect form.", ch, NULL, NULL, TO_CHAR);
		act(AT_PURPLE, "$n's horns shift closer together, $s features becoming more humanoid as "
		    "$e grows in size and completes $s evolution to a Semi-Perfect form.", ch, NULL, NULL, TO_NOTVICT);
		ch->pl = ch->exp * 8;
		transStatApply(ch, 8, 8, 8, 8);
		ch->mana -= skill_table[gsn_semiperfect]->min_mana;
		return;
	}
	if (!str_prefix(argument, "perfect form")
	    && ch->pcdata->learned[gsn_perfect] > 0) {
		if (ch->mana < skill_table[gsn_perfect]->min_mana) {
			send_to_char("You don't have enough energy.\n\r", ch);
			return;
		}
		if (xIS_SET(ch->affected_by, AFF_PERFECT)) {
			send_to_char("You are already in that form.\n\r", ch);
			return;
		}
		xSET_BIT(ch->affected_by, AFF_PERFECT);
		xREMOVE_BIT(ch->affected_by, AFF_SEMIPERFECT);
		xREMOVE_BIT(ch->affected_by, AFF_ULTRAPERFECT);
		act(AT_PURPLE, "You surge with energy as your body becomes more compact, efficient, and almost "
		    "human.  Your horns fuse into a kind of hat, your tail retracts up under your "
		    "wings as you evolve to a Perfect form.", ch, NULL, NULL, TO_CHAR);
		act(AT_PURPLE, "$n surges with energy as $s body becomes more compact, efficient, and almost "
		    "human.  $n's horns fuse into a kind of hat, $s tail retracts up under $s wings "
		    "as $e evolves to a Perfect form.", ch, NULL, NULL, TO_NOTVICT);
		ch->pl = ch->exp * 18;
		transStatApply(ch, 18, 18, 18, 18);
		ch->mana -= skill_table[gsn_perfect]->min_mana;
		return;
	}
	if (!str_prefix(argument, "ultra-perfect form")
	    && ch->pcdata->learned[gsn_ultraperfect] > 0) {
		if (ch->mana < skill_table[gsn_ultraperfect]->min_mana) {
			send_to_char("You don't have enough energy.\n\r", ch);
			return;
		}
		if (xIS_SET(ch->affected_by, AFF_ULTRAPERFECT)) {
			send_to_char("You are already in that form.\n\r", ch);
			return;
		}
		xSET_BIT(ch->affected_by, AFF_ULTRAPERFECT);
		xREMOVE_BIT(ch->affected_by, AFF_PERFECT);
		xREMOVE_BIT(ch->affected_by, AFF_SEMIPERFECT);
		//act(AT_SKILL, "You evolve into your ultra-perfect form.", ch, NULL, NULL, TO_CHAR);
		//act(AT_SKILL, "$n evolves into $s ultra-perfect form.", ch, NULL, NULL, TO_NOTVICT);
		act(AT_PURPLE, "You draw on newfound power, your body moving with perfect grace and "
		    "efficiency, your entire form free from blemish or impurity.  You calmly stand "
		    "in this most human of forms, having evolved to an Ultra-Perfect being.", ch, NULL, NULL, TO_CHAR);
		act(AT_PURPLE, "$n draws on newfound power, $s body moving with perfect grace and efficiency, "
		    "$s entire form free from blemish or impurity.  $n calmly stands in this most "
		    "human of forms, having evolved to an Ultra-Perfect being.", ch, NULL, NULL, TO_NOTVICT);
		ch->pl = ch->exp * 27;
		transStatApply(ch, 27, 27, 27, 27);
		ch->mana -= skill_table[gsn_ultraperfect]->min_mana;
		return;
	}
}

/*
 * Checks to see if the android is able to absorb part (or all)
 * of a Ki attack.  This function must be added to the ki attack
 * code for it to be checked.
 */
int
ki_absorb(CHAR_DATA * ch, CHAR_DATA * victim, int damage, int ki_sn)
{
	int 	newDam = 0;
	int 	reduction = 0;
	int 	kiGain = 0;

	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		return (damage);
	}
	if (!IS_NPC(ch)) {
		if (!IS_SET(ch->pcdata->combatFlags, CMB_NO_DCD)) {
			if (ch->pcdata->learned[gsn_dcd] < 1)
				return (damage);

			if (!can_use_skill(ch, number_percent(), gsn_dcd))
				return (damage);

			if (damage > 1000)
				/* so that instant kills cannot be blocked. */
				return (damage);

			int 	att = ((get_attmod(ch, victim) / 2) * 10);
			int 	revatt = ((get_attmod(victim, ch) / 2) * 5);

			if (att > 100)
				att = 100;
			if (att < 0)
				att = 0;
			if (revatt > 100)
				revatt = 100;
			if (revatt < 0)
				revatt = 0;

			int 	c = 0;
			int 	spd = 0;

			if (get_curr_dex(ch) > get_curr_dex(victim)) {
				if (((float) get_curr_dex(ch) / (float) get_curr_dex(victim)) >= 1.25)
					spd = 10;
				if (((float) get_curr_dex(ch) / (float) get_curr_dex(victim)) >= 1.5)
					spd = 20;
				if (((float) get_curr_dex(ch) / (float) get_curr_dex(victim)) >= 2)
					spd = 30;
				if (((float) get_curr_dex(ch) / (float) get_curr_dex(victim)) >= 3)
					spd = 50;
			} else if (get_curr_dex(ch) < get_curr_dex(victim)) {
				if (((float) get_curr_dex(victim) / (float) get_curr_dex(ch)) >= 1.25)
					spd = -5;
				if (((float) get_curr_dex(victim) / (float) get_curr_dex(ch)) >= 1.5)
					spd = -10;
				if (((float) get_curr_dex(victim) / (float) get_curr_dex(ch)) >= 2)
					spd = -15;
				if (((float) get_curr_dex(victim) / (float) get_curr_dex(ch)) >= 3)
					spd = -20;
			} else
				spd = 0;

			c = ((20 + spd) + (att - revatt));

			if (c < 1)
				c = 1;
			if (c > 100)
				c = 100;

			if (number_range(1, 100) > c) {
				learn_from_failure(ch, gsn_dcd);
				return (damage);
			} else
				learn_from_success(ch, gsn_dcd);

			int 	dcd = number_range(1, 3);

			if (dcd == 1) {
				ch->ki_dodge = true;
				newDam = 0;
				return (newDam);
			} else if (dcd == 2) {
				ch->ki_deflect = true;
				newDam = 0;
				return (newDam);
			} else if (dcd == 3) {
				ch->ki_cancel = true;
				newDam = 0;
				return (newDam);
			}
		}
	}
	if (!is_android(ch)) {
		return (damage);
	}
	if (!IS_NPC(ch)) {
		if (ch->pcdata->learned[gsn_ki_absorb] <= 0)
			return (damage);
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_ki_absorb]->skill_level[ch->class]) {
		return (damage);
	}
	if ((victim = who_fighting(ch)) == NULL) {
		return (damage);
	}
	if (!IS_NPC(ch) && IS_SET(ch->pcdata->combatFlags, CMB_NO_KI_ABSORB)) {
		return (damage);
	}
	int 	chance = 0;

	if (is_android_e(ch))
		chance = 50;
	else if (is_android_fm(ch))
		chance = 35;
	else
		chance = 25;

	if (number_range(1, 100) > chance) {
		return (damage);
	}
	if (can_use_skill(ch, number_percent(), gsn_ki_absorb)) {
		act(AT_SKILL, "$N's Ki attack washes over your outstretched hands as you absorb some of it.", ch, NULL, victim, TO_CHAR);
		act(AT_SKILL, "Your Ki attack washes over $n's outstretched hands as $e absorbs some of it.", ch, NULL, victim, TO_VICT);
		act(AT_SKILL, "$N's Ki attack washes over $n's outstretched hands as $e absorbs some of it.", ch, NULL, victim, TO_NOTVICT);

		learn_from_success(ch, gsn_ki_absorb);
		switch (number_range(0, 4)) {
		case 0:
			reduction = 0;
			break;

		case 1:
			reduction = 25;
			break;

		case 2:
			reduction = 50;
			break;

		case 3:
			reduction = 75;
			break;

		case 4:
			reduction = 100;
			break;
		}
		newDam = damage * reduction / 100;
		if (reduction == 0)
			kiGain = skill_table[ki_sn]->min_mana;
		else
			kiGain = skill_table[ki_sn]->min_mana * reduction / 100;

		ch->mana = UMAX(ch->max_mana, ch->mana + kiGain);
		if (ch->mana > ch->max_mana)
			ch->mana = ch->max_mana;

		if (!IS_NPC(ch)) {
			if (ch->battery < 100 && reduction < 100 &&
			    is_android_e(ch) &&
			    ch->exp >= skill_table[gsn_battery]->skill_level[ch->class]
			    && ch->pcdata->learned[gsn_battery] > 0) {
				if (reduction >= 100) {
					ch_printf(ch, "&BYou fail to absorb any spare energy into your ki battery.\n\r");
				} else {
					int 	battery = 0;

					battery = (damage - newDam);
					if (battery > 10)
						battery = 10;
					ch->battery += battery;
					if (ch->battery > 100)
						ch->battery = 100;

					ch_printf(ch, "&BYou absorb %d points of damage directly into your ki battery.\n\r",
					    battery);
				}
			}
		}
	} else {
		act(AT_SKILL, "You hold your hands forward in a futile attempt to absorb $N's Ki attack.", ch, NULL, victim, TO_CHAR);
		act(AT_SKILL, "$n holds $s hands forward in a futile attempt to absorb your Ki attack.", ch, NULL, victim, TO_VICT);
		act(AT_SKILL, "$n holds $s hands forward in a futile attempt to absorb $N's Ki attack.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_ki_absorb);
		newDam = damage;
	}
	return (newDam);
}

void
do_hells_flash(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_hells_flash]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_hells_flash]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_hells_flash]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_hells_flash]->focus;

	WAIT_STATE(ch, skill_table[gsn_hells_flash]->beats);

	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_hells_flash]->min_mana;

	if (can_use_skill(ch, number_percent(), gsn_hells_flash)) {
		dam = get_attmod(ch, victim) * number_range(35, 39);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);
		act(AT_YELLOW, "You suddenly appear infront of $N, dealing a quick punch to $S gut, then elbowing $M into the ground. You reach down and grab $N with both arms and lift $M over your head. Yelling out, you then throw $N down into the ground with tremendous force.", ch, NULL, victim, TO_CHAR);
		act(AT_YELLOW, "You cross your arms and pull them apart just below the elbow; holding your forearms under your arms, as your arms now display a large array of energy crystals. Your arms start to glow as you charge your energy. Shouting 'HELLS FLASH', you unleash a large blast of energy into the hole $N is laying in, causing considerable damage. After you are done firing, you reattach your arms. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(AT_YELLOW, "$n suddenly appears infront of you, dealing a quick punch to your gut, then elbowing you into the ground. $n reaches down and grabs you with both arms and lifts you over $s head. Yelling out, $n then throws you down into the ground with tremendous force.", ch, NULL, victim, TO_VICT);
		act(AT_YELLOW, "$n crosses $s arms and pulls them apart just below the elbow; holding $s forearms under $s arms, as $s arms now display a large array of energy crystals. $n's arms start to glow as $e charges $s energy. Shouting 'HELLS FLASH', $n unleashes a large blast of energy into the hole you are laying in, causing considerable damage. After $n is done firing, $e reattaches $s arms. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
		act(AT_YELLOW, "$n suddenly appears infront of $N, dealing a quick punch to $S gut, then elbowing $M into the ground. $n reaches down and grabs $N with both arms and lifts $M over $s head. Yelling out, $n then throws $N down into the ground with tremendous force.", ch, NULL, victim, TO_NOTVICT);
		act(AT_YELLOW, "$n crosses $s arms and pulls them apart just below the elbow; holding $s forearms under $s arms, as $s arms now display a large array of energy crystals. $n's arms start to glow as $e charges $s energy. Shouting 'HELLS FLASH', $n unleashes a large blast of energy into the hole $N is laying in, causing considerable damage. After $n is done firing, $e reattaches $s arms. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

		learn_from_success(ch, gsn_hells_flash);
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
	} else {
		act(AT_YELLOW, "You fail to catch $N.", ch, NULL, victim, TO_CHAR);
		act(AT_YELLOW, "$n fails to catch you.", ch, NULL, victim, TO_VICT);
		act(AT_YELLOW, "$n fails to catch $N.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_hells_flash);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}
}

void
do_blast_zone(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_bz]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_bz]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_bz]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_bz]->focus;

	int 	z = get_aura(ch);

	WAIT_STATE(ch, skill_table[gsn_bz]->beats);
	if (can_use_skill(ch, number_percent(), gsn_bz)) {
		dam = get_attmod(ch, victim) * number_range(35, 39);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);

		act(z, "You put one arm up into the air, open palm facing up. There is a deafening sound and a blinding flash of light as you suddenly release an incredible amount of energy in a single blast that damages $N and reduces the area all around to ashes. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(z, "$n puts one arm up into the air, open palm facing up. There is a deafening sound and a blinding flash of light as $n suddenly releases an incredible amount of energy in a single blast that damages you and reduces the area all around to ashes. &W[$t]", ch, num_punct(dam), victim, TO_VICT);
		act(z, "$n puts one arm up into the air, open palm facing up. There is a deafening sound and a blinding flash of light as $n suddenly releases an incredible amount of energy in a single blast that damages $N and reduces the area all around to ashes. &W[$t]", ch, num_punct(dam), victim, TO_NOTVICT);

		learn_from_success(ch, gsn_bz);
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
	} else {
		act(z, "You missed $N with your blast zone.", ch, NULL, victim, TO_CHAR);
		act(z, "$n misses you with $s blast zone.", ch, NULL, victim, TO_VICT);
		act(z, "$n missed $N with a blast zone.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_bz);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}
	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_bz]->min_mana;
}

void
do_enhance(CHAR_DATA * ch, char *argument)
{
	sh_int 	mod = 0;
	bool 	strength = false;
	bool 	speed = false;
	int 	energy = 0;

	if (IS_NPC(ch))
		return;

	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_enhance]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if (argument[0] == '\0') {
		ch_printf(ch, "\n\rSyntax: enhance (stat)\n\r");
		ch_printf(ch, "\n\rValid stats to enhance are:\n\r");
		if (is_android_fm(ch))
			ch_printf(ch, "  strength");
		if (is_android_h(ch))
			ch_printf(ch, "  speed");

		ch_printf(ch, "\n\r");
		return;
	}
	mod = 5;
	energy = 300;

	if (ch->exp > 100000000) {
		mod = 10;
		energy = 1000;
	}
	if (ch->exp > 5000000000ULL) {
		mod = 15;
		energy = 5000;
	}
	if (ch->exp > 100000000000ULL) {
		mod = 20;
		energy = 10000;
	}
	if (is_android_fm(ch))
		strength = true;
	if (is_android_h(ch))
		speed = true;

	if (!str_cmp(argument, "strength")) {
		if (!strength) {
			do_enhance(ch, "");
			return;
		}
		if (ch->add_str > 0) {
			ch->perm_str -= ch->add_str;
			ch->add_str = 0;
			ch_printf(ch, "\n\r&wYour strength returns to normal.&D\n\r");
		} else {
			if (ch->mana < energy) {
				ch_printf(ch, "You don't have energy energy.\n\r");
				return;
			}
			if (can_use_skill(ch, number_percent(), gsn_enhance)) {
				ch->add_str = mod;
				ch->perm_str += mod;
				ch_printf(ch, "\n\r&RYou enhance your strength.\n\r");
			} else {
				ch_printf(ch, "\n\r&gYou fail to enhance your strength.\n\r");
			}
		}
		if (!is_android_h(ch))
			ch->mana -= energy;
		save_char_obj(ch);
		return;
	}
	if (!str_cmp(argument, "speed")) {
		if (!speed) {
			do_enhance(ch, "");
			return;
		}
		if (ch->add_dex > 0) {
			ch->perm_dex -= ch->add_dex;
			ch->add_dex = 0;
			ch_printf(ch, "\n\r&wYour speed returns to normal.&D\n\r");
		} else {
			if (ch->mana < energy) {
				ch_printf(ch, "You don't have energy energy.\n\r");
				return;
			}
			if (can_use_skill(ch, number_percent(), gsn_enhance)) {
				ch->add_dex = mod;
				ch->perm_dex += mod;
				ch_printf(ch, "\n\r&BYou enhance your speed.\n\r");
			} else {
				ch_printf(ch, "\n\r&gYou fail to enhance your speed.\n\r");
			}
		}
		if (!is_android_h(ch))
			ch->mana -= energy;
		save_char_obj(ch);
		return;
	}
	do_enhance(ch, "");
}

void
do_ki_burst(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (IS_NPC(ch) && is_split(ch)) {
		if (!ch->master)
			return;
		if (!can_use_skill(ch->master, number_percent(), gsn_ki_burst))
			return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_ki_burst]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch) && ch->mana < skill_table[gsn_ki_burst]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_ki_burst]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_ki_burst]->focus;

	sh_int 	z = get_aura(ch);

	WAIT_STATE(ch, skill_table[gsn_ki_burst]->beats);
	if (can_use_skill(ch, number_percent(), gsn_ki_burst)) {
		dam = get_attmod(ch, victim) * number_range(50, 67);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);
		act(z, "You clench your fists and gather your energy about you, bringing a black", ch, NULL, victim, TO_CHAR);
		act(z, "and purple aura flaring up around you.  With a thought it explodes outward,", ch, NULL, victim, TO_CHAR);
		act(z, "forming a deadly sphere that sends $N reeling. &W[$t]", ch, num_punct(dam), victim, TO_CHAR);
		act(z, "$n clenches $s fists as a black and purple aura flares up around $m.", ch, NULL, victim, TO_VICT);
		act(z, "The aura explodes outward, forming a deadly sphere that sends you reeling. &W[$t]"
		    ,ch, num_punct(dam), victim, TO_VICT);
		act(z, "$n clenches $s fists as a black and purple aura flares up around $m.", ch, NULL, victim, TO_NOTVICT);
		act(z, "The aura explodes outward, forming a deadly sphere that sends $N reeling. &W[$t]"
		    ,ch, num_punct(dam), victim, TO_NOTVICT);

		learn_from_success(ch, gsn_ki_burst);
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
	} else {
		act(z, "You missed $N with your ki burst.", ch, NULL, victim, TO_CHAR);
		act(z, "$n misses you with $s ki burst.", ch, NULL, victim, TO_VICT);
		act(z, "$n missed $N with a ki burst.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_ki_burst);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}

	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_ki_burst]->min_mana;
}

void
do_ssd_bomber(CHAR_DATA * ch, char *argument)
{
	CHAR_DATA *victim;
	int 	dam = 0;

	if (is_namek(ch)) {
		ch_printf(ch, "You are not allowed.\n\r");
		return;
	}
	if (IS_NPC(ch) && IS_AFFECTED(ch, AFF_CHARM)) {
		send_to_char("You can't concentrate enough for that.\n\r", ch);
		return;
	}
	if (!IS_NPC(ch)
	    && ch->exp < skill_table[gsn_ssd_bomber]->skill_level[ch->class]) {
		send_to_char("You can't do that.\n\r", ch);
		return;
	}
	if ((victim = who_fighting(ch)) == NULL) {
		send_to_char("You aren't fighting anyone.\n\r", ch);
		return;
	}
	if (ch->mana < skill_table[gsn_ssd_bomber]->min_mana) {
		send_to_char("You don't have enough energy.\n\r", ch);
		return;
	}
	if (ch->focus < skill_table[gsn_ssd_bomber]->focus) {
		send_to_char("You need to focus more.\n\r", ch);
		return;
	} else
		ch->focus -= skill_table[gsn_ssd_bomber]->focus;

	WAIT_STATE(ch, skill_table[gsn_ssd_bomber]->beats);
	if (can_use_skill(ch, number_percent(), gsn_ssd_bomber)) {
		dam = get_attmod(ch, victim) * number_range(50, 54);
		if (ch->charge > 0)
			dam = chargeDamMult(ch, dam);

		act(AT_RED, "You clasp your hands forward, as if charging an "
		    "enery ball.  Suddenly, it surges with incredible "
		    "power, entangled in a spider-web-like sphere of "
		    "energy.  You push your hands forward, sending the "
		    "'Deadly Bomb' after $N which eventually causes a "
		    "tremendous explosion, giving its name credit. &W[$t]",
		    ch, num_punct(dam), victim, TO_CHAR);
		act(AT_RED, "$n clasps $s hands forward, as if charging an "
		    "enery ball.  Suddenly, it surges with incredible "
		    "power, entangled in a spider-web-like sphere of "
		    "energy.  $n pushes $s hands forward, sending the "
		    "'Deadly Bomb' after you which eventually causes a "
		    "tremendous explosion, giving its name credit. &W[$t]",
		    ch, num_punct(dam), victim, TO_VICT);
		act(AT_RED, "$n clasps $s hands forward, as if charging an "
		    "enery ball.  Suddenly, it surges with incredible "
		    "power, entangled in a spider-web-like sphere of "
		    "energy.  $n pushes $s hands forward, sending the "
		    "'Deadly Bomb' after $N which eventually causes a "
		    "tremendous explosion, giving its name credit. &W[$t] ",
		    ch, num_punct(dam), victim, TO_NOTVICT);

		learn_from_success(ch, gsn_ssd_bomber);
		global_retcode = damage(ch, victim, dam, TYPE_HIT);
	} else {
		act(AT_RED, "You missed $N with your ssd bomber attack.", ch, NULL, victim, TO_CHAR);
		act(AT_RED, "$n misses you with $s ssd bomber attack.", ch, NULL, victim, TO_VICT);
		act(AT_RED, "$n missed $N with a ssd bomber attack.", ch, NULL, victim, TO_NOTVICT);
		learn_from_failure(ch, gsn_ssd_bomber);
		global_retcode = damage(ch, victim, 0, TYPE_HIT);
	}

	if (!is_android_h(ch))
		ch->mana -= skill_table[gsn_ssd_bomber]->min_mana;
}