diff --git a/SQL/Migrations/add_otaku.sql b/SQL/Migrations/add_otaku.sql new file mode 100644 index 000000000..afa797eed --- /dev/null +++ b/SQL/Migrations/add_otaku.sql @@ -0,0 +1,2 @@ +ALTER TABLE `pfiles` + ADD `Otaku_Path` tinyint(2) DEFAULT 0; \ No newline at end of file diff --git a/lib/world/mob/605.mob b/lib/world/mob/605.mob index 62a6f0560..151f43f23 100644 --- a/lib/world/mob/605.mob +++ b/lib/world/mob/605.mob @@ -30,7 +30,6 @@ DefaultPos: Standing Weight: 200 Ballistic: 15 Impact: 15 -[SKILLS] BREAK #60501 Keywords: cassandra teacher mage magician @@ -64,7 +63,6 @@ DefaultPos: Standing Weight: 50 Ballistic: 15 Impact: 15 -[SKILLS] BREAK #60502 Keywords: dante teacher trainer man @@ -97,7 +95,6 @@ DefaultPos: Standing Weight: 80 Ballistic: 15 Impact: 15 -[SKILLS] BREAK #60503 Keywords: Von Richter linguistics teacher @@ -128,7 +125,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60504 Keywords: gears teacher practice rigger dwarf @@ -160,7 +156,6 @@ DefaultPos: Standing [POINTS] Height: 116 Weight: 114 -[SKILLS] BREAK #60505 Keywords: jet adept trainer agile oriental man @@ -196,7 +191,6 @@ DefaultPos: Standing Cash: 1000 Bank: 5000 [SKILLS] - : 10 Armed Combat: 10 Stealth: 10 Leadership: 10 @@ -236,7 +230,6 @@ DefaultPos: Standing Cash: 1000 Bank: 5000 [SKILLS] - : 10 Firearms: 10 Leadership: 10 Armed Combat: 10 @@ -274,7 +267,6 @@ DefaultPos: Standing Ballistic: 15 Impact: 15 [SKILLS] - : 10 Leadership: 10 Stealth: 10 Athletics: 10 @@ -317,8 +309,6 @@ DefaultPos: Standing Bank: 6000 [SKILLS] Sorcery: 10 - : 10 - : 10 Conjuring: 10 Stealth: 10 BREAK @@ -357,10 +347,8 @@ DefaultPos: Standing Cash: 2000 Bank: 6000 [SKILLS] - : 10 Sorcery: 10 Conjuring: 10 - : 10 Throwing Weapons: 10 BREAK #60510 @@ -393,7 +381,6 @@ DefaultPos: Standing [POINTS] Height: 175 Weight: 70 -[SKILLS] BREAK #60511 Keywords: toby firearms specialist @@ -424,7 +411,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 80 -[SKILLS] BREAK #60512 Keywords: erik smithy danish @@ -455,7 +441,6 @@ DefaultPos: Standing [POINTS] Height: 170 Weight: 90 -[SKILLS] BREAK #60513 Keywords: ave neophyte tailor @@ -486,7 +471,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 60 -[SKILLS] BREAK #60514 Keywords: gremlin sword short stubby @@ -517,7 +501,6 @@ DefaultPos: Standing [POINTS] Height: 120 Weight: 40 -[SKILLS] BREAK #60515 Keywords: dave bowie clerk @@ -548,7 +531,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 90 -[SKILLS] BREAK #60516 Keywords: benjgy firearm accessory clerk @@ -579,7 +561,6 @@ DefaultPos: Standing [POINTS] Height: 200 Weight: 100 -[SKILLS] BREAK #60517 Keywords: padded melee training robot @@ -610,7 +591,6 @@ DefaultPos: Standing [POINTS] Height: 150 Weight: 20 -[SKILLS] BREAK #60518 Keywords: perforated target dummy @@ -640,7 +620,6 @@ DefaultPos: Sitting [POINTS] Height: 150 Weight: 20 -[SKILLS] BREAK #60519 Keywords: joe johnson neophyte scuzzy man @@ -672,7 +651,6 @@ DefaultPos: Standing [POINTS] Height: 170 Weight: 100 -[SKILLS] BREAK #60520 Keywords: mob unfinished @@ -705,7 +683,6 @@ DefaultPos: Standing [POINTS] Height: 190 Weight: 130 -[SKILLS] BREAK #60521 Keywords: vicious rabid rat @@ -737,7 +714,6 @@ AttackType: Bite [POINTS] Height: 10 Weight: 1 -[SKILLS] BREAK #60522 Keywords: entrancing young clerk female neophyte @@ -770,7 +746,6 @@ DefaultPos: Standing [POINTS] Height: 150 Weight: 40 -[SKILLS] BREAK #60523 Keywords: angela receptionist blonde @@ -803,7 +778,6 @@ DefaultPos: Standing [POINTS] Height: 165 Weight: 50 -[SKILLS] BREAK #60524 Keywords: helen waitress ricky neophyte @@ -835,7 +809,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 50 -[SKILLS] BREAK #60525 Keywords: dwarf dynamite jim mechanic @@ -866,7 +839,6 @@ DefaultPos: Standing [POINTS] Height: 120 Weight: 80 -[SKILLS] BREAK #60526 Keywords: postman stanley dorky @@ -897,7 +869,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 180 -[SKILLS] BREAK #60527 Keywords: howie decker store keeper @@ -929,7 +900,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 50 -[SKILLS] BREAK #60528 Keywords: bored geek decker @@ -961,7 +931,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60529 Keywords: cracked decker crazy hacker @@ -992,7 +961,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60530 Keywords: otaku child decker weird bald @@ -1025,7 +993,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60531 Keywords: jarmine dirty unkept @@ -1057,7 +1024,6 @@ DefaultPos: Sitting [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60532 Keywords: deadlock otaku burnt out man @@ -1089,7 +1055,6 @@ DefaultPos: Standing [POINTS] Height: 182 Weight: 66 -[SKILLS] BREAK #60533 Keywords: lucy mature lady @@ -1122,7 +1087,6 @@ DefaultPos: Sitting [POINTS] Height: 160 Weight: 42 -[SKILLS] BREAK #60534 Keywords: steve bored middle aged @@ -1154,7 +1118,6 @@ DefaultPos: Standing [POINTS] Height: 179 Weight: 80 -[SKILLS] BREAK #60535 Keywords: doc greenwood cyberdoc @@ -1186,7 +1149,6 @@ DefaultPos: Standing [POINTS] Height: 160 Weight: 48 -[SKILLS] BREAK #60536 Keywords: winchester doc @@ -1218,7 +1180,6 @@ DefaultPos: Standing [POINTS] Height: 169 Weight: 57 -[SKILLS] BREAK #60537 Keywords: doc tanaki @@ -1250,7 +1211,6 @@ DefaultPos: Standing [POINTS] Height: 149 Weight: 43 -[SKILLS] BREAK #60538 Keywords: Doc Bell @@ -1283,7 +1243,6 @@ DefaultPos: Standing [POINTS] Height: 143 Weight: 95 -[SKILLS] BREAK #60539 Keywords: kyle mall ninja mall-ninja fellow trainer man @@ -1320,7 +1279,6 @@ DefaultPos: Standing Cash: 1000 Bank: 5000 [SKILLS] - : 10 Armed Combat: 10 Stealth: 10 Leadership: 10 @@ -1361,7 +1319,6 @@ DefaultPos: Standing Cash: 1000 Bank: 5000 [SKILLS] - : 10 Armed Combat: 10 Stealth: 10 Leadership: 10 @@ -1401,7 +1358,6 @@ DefaultPos: Standing Cash: 1000 Bank: 5000 [SKILLS] - : 10 Armed Combat: 10 Stealth: 10 Leadership: 10 @@ -1438,7 +1394,6 @@ DefaultPos: Standing [POINTS] Height: 190 Weight: 55 -[SKILLS] BREAK #60601 Keywords: shianra young svelte elf @@ -1472,7 +1427,6 @@ DefaultPos: Sitting [POINTS] Height: 158 Weight: 40 -[SKILLS] BREAK #60602 Keywords: old man lone star oswald @@ -1507,7 +1461,6 @@ DefaultPos: Sitting [POINTS] Height: 182 Weight: 74 -[SKILLS] BREAK #60603 Keywords: peter mayes dwarf male @@ -1540,7 +1493,6 @@ DefaultPos: Sitting [POINTS] Height: 110 Weight: 120 -[SKILLS] BREAK #60604 Keywords: buxom brunette @@ -1573,7 +1525,6 @@ DefaultPos: Standing [POINTS] Height: 139 Weight: 38 -[SKILLS] BREAK #60605 Keywords: yoshitaka old japanese @@ -1605,7 +1556,6 @@ DefaultPos: Standing [POINTS] Height: 167 Weight: 46 -[SKILLS] BREAK #60606 Keywords: beatrix fotar short round @@ -1639,7 +1589,6 @@ DefaultPos: Standing [POINTS] Height: 143 Weight: 98 -[SKILLS] BREAK #60607 Keywords: young clean cut markus martin @@ -1672,7 +1621,6 @@ DefaultPos: Standing [POINTS] Height: 175 Weight: 92 -[SKILLS] BREAK #60608 Keywords: dashing elf duto @@ -1707,7 +1655,6 @@ DefaultPos: Standing [POINTS] Height: 184 Weight: 49 -[SKILLS] BREAK #60622 Keywords: james human male thing @@ -1740,7 +1687,6 @@ DefaultPos: Standing [POINTS] Height: 174 Weight: 45 -[SKILLS] BREAK #60623 Keywords: brody dark brooding @@ -1771,7 +1717,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 82 -[SKILLS] BREAK #60624 Keywords: sandy female human @@ -1803,7 +1748,6 @@ DefaultPos: Sitting [POINTS] Height: 164 Weight: 52 -[SKILLS] BREAK #60625 Keywords: godfrey aristocratic elf @@ -1835,7 +1779,6 @@ DefaultPos: Standing [POINTS] Height: 169 Weight: 64 -[SKILLS] BREAK #60626 Keywords: grant trog ork @@ -1867,7 +1810,6 @@ DefaultPos: Standing [POINTS] Height: 172 Weight: 98 -[SKILLS] BREAK #60627 Keywords: vending machine ammunition @@ -1899,7 +1841,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60628 Keywords: vending machine ammunition @@ -1931,7 +1872,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60629 Keywords: vending machine ammunition @@ -1963,7 +1903,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60630 Keywords: vending machine ammunition @@ -1995,7 +1934,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60631 Keywords: hank dwarf @@ -2029,7 +1967,6 @@ DefaultPos: Sitting [POINTS] Height: 120 Weight: 80 -[SKILLS] BREAK #60632 Keywords: vending machine ammunition @@ -2061,7 +1998,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60634 Keywords: mana young female satyr @@ -2092,7 +2028,6 @@ DefaultPos: Standing [POINTS] Height: 0 Weight: 0 -[SKILLS] BREAK #60635 Keywords: grey human male @@ -2124,7 +2059,6 @@ DefaultPos: Standing [POINTS] Height: 165 Weight: 48 -[SKILLS] BREAK #60636 Keywords: dwarf gruff stereotypical @@ -2156,7 +2090,6 @@ DefaultPos: Standing [POINTS] Height: 125 Weight: 98 -[SKILLS] BREAK #60637 Keywords: chris semi-bald bald old man @@ -2188,7 +2121,6 @@ DefaultPos: Standing [POINTS] Height: 168 Weight: 52 -[SKILLS] BREAK #60638 Keywords: male oni kenji @@ -2219,7 +2151,6 @@ DefaultPos: Standing [POINTS] Height: 183 Weight: 93 -[SKILLS] BREAK #60639 Keywords: Doc Chew cybertechnician doctor @@ -2250,7 +2181,6 @@ DefaultPos: Standing [POINTS] Height: 170 Weight: 70 -[SKILLS] BREAK #60640 Keywords: Doc Croke cybertechnician doctor @@ -2282,7 +2212,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 90 -[SKILLS] BREAK #60641 Keywords: Doc Killie cybertechnician doctor @@ -2314,7 +2243,6 @@ DefaultPos: Standing [POINTS] Height: 190 Weight: 80 -[SKILLS] BREAK #60642 Keywords: Doc Julius cybertechnician doctor @@ -2347,7 +2275,6 @@ DefaultPos: Standing [POINTS] Height: 180 Weight: 95 -[SKILLS] BREAK #60643 Keywords: Doc Malik cybertechnician doctor @@ -2378,6 +2305,43 @@ DefaultPos: Standing [POINTS] Height: 190 Weight: 80 +BREAK +#60692 +Keywords: max maxine teacher trainer woman +Name: Maxine +RoomDesc:$ +A teacher stands here: her LCD nametag reads: "Maxine". + +~ +LookDesc:$ +A young, energetic woman named Maxine, able to teach you the skills necessary +to be an otaku. +~ +ArriveMsg: arrives from +LeaveMsg: leaves +MobFlags: 10000000011010 +AffFlags: 0 +Race: Human +Gender: Female +DefaultPos: Standing +[ATTRIBUTES] + Bod: 40 + Qui: 40 + Str: 40 + Cha: 40 + Int: 40 + Wil: 40 + Mag: 0 +[POINTS] + Height: 0 + Weight: 0 + Ballistic: 15 + Impact: 15 [SKILLS] + Channel Access: 6 + Channel Control: 6 + Channel Index: 6 + Channel Files: 6 + Channel Slave: 6 BREAK END diff --git a/lib/world/obj/0.obj b/lib/world/obj/0.obj index b0a8dfbc9..2bfc8be70 100644 --- a/lib/world/obj/0.obj +++ b/lib/world/obj/0.obj @@ -1341,6 +1341,19 @@ Material: metal [VALUES] Val1: 22 BREAK +#128 +Keywords: blank complex form +Name: a blank complex form +RoomDesc:$ +A blank complex form has been dropped here.~ +LookDesc:$ +A complex form that's yet to be designed by an otaku's mind.~ +Type: Complex Form +WearFlags: 1 +Material: metal +[POINTS] + Barrier: 1 +BREAK #140 Keywords: customized cc10 ares sniper rifle Name: a Customized Ares CC-10 Sniper Rifle diff --git a/lib/world/wld/605.wld b/lib/world/wld/605.wld index 30bea1e55..7bdc96f5c 100644 --- a/lib/world/wld/605.wld +++ b/lib/world/wld/605.wld @@ -13,25 +13,9 @@ good luck. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60501 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60501 @@ -52,25 +36,9 @@ to clear your path. Feel free to try this with the door to the east! ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60502 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] Keywords: door @@ -85,9 +53,6 @@ EAST^n to enter here." KeyVnum: 0 [EXIT south] ToVnum: 60500 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60502 @@ -108,31 +73,12 @@ to the north. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60503 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60501 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60503 @@ -146,31 +92,12 @@ continue. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60502 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60504 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60504 @@ -188,31 +115,12 @@ newly-rediscovered practice of magic. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60505 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60503 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60505 @@ -229,31 +137,12 @@ directions to allocate attribute points. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60504 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60506 @@ -273,79 +162,36 @@ survival. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60505 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northeast] ToVnum: 60507 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60508 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southeast] ToVnum: 60509 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60513 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southwest] ToVnum: 60512 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60511 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northwest] ToVnum: 60510 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60628 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60593 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60507 @@ -362,31 +208,12 @@ to fight with cybernetically-installed weapons such as hand razors and spurs. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southwest] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60626 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60508 @@ -402,31 +229,12 @@ is best to keep firearms concealed unless you actually need to use them. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60627 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60509 @@ -441,25 +249,9 @@ operation of vehicles and drones. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northwest] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60510 @@ -477,25 +269,9 @@ items aura. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southeast] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60511 @@ -510,31 +286,15 @@ Skills to help with Programming are to the WEST. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 + KeyVnum: 0 +[EXIT south] + ToVnum: 60692 KeyVnum: 0 [EXIT west] ToVnum: 60591 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60512 @@ -550,31 +310,12 @@ failed dice roll based on your language skill. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northeast] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southwest] ToVnum: 60592 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60513 @@ -590,31 +331,12 @@ system. Proceed SOUTH to continue. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60514 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60514 @@ -630,43 +352,18 @@ head SOUTH to learn more about their profession. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60513 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60520 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60518 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60515 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60515 @@ -686,31 +383,12 @@ are great. Continue WEST to learn more. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60514 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60516 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60516 @@ -731,31 +409,12 @@ formidable with a legion of machines backing them up. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60515 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60517 @@ -772,75 +431,41 @@ makes it hard for beneficial spells to bind with your body. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60611 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60516 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60610 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southwest] ToVnum: 60614 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60613 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northwest] ToVnum: 60612 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60615 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXTRADESC 0] - Keywords: datajack~~~~~~~~~~~~~~~~~~ + Keywords: wired reflexes~~~~~~~~~~~~~~~~~~ Desc:$ -A DATAJACK is necessary for a decker or a rigger to interface their mind with -a machine. +Wired Reflexes, while costly to the user's essence, enhance their REACTION and +INITIATIVE, allowing them to attack more often than an un-augmented person. +Wired Reflexes are known to cause some people to be extra jumpy. ~ [EXTRADESC 1] - Keywords: smartlink system~~~~~~~~~~~~~~~~~~ + Keywords: Vehicle control rig~~~~~~~~~~~~~~~~~~ Desc:$ -The SMARTLINK system allows the user to use a smartlink accessorized firearm, -granting them greater accuracy in ranged combat. If the weapon is outfitted -with a SMARTLINK accessory and the user has a SMARTLINK system installed, the -feature is automatically used. +The VEHICLE CONTROL RIG and a DATAJACK is necessary for someone who wants to +be able to mentally control a vehicle. An explanation of RIGGING is provided +later in the guild. ~ [EXTRADESC 2] Keywords: spurs razors retractable~~~~~~~~~~~~~~~~~~ @@ -851,18 +476,18 @@ automatically used when the character enters unarmed combat, and success is based on the CYBERIMPLANT COMBAT skill. ~ [EXTRADESC 3] - Keywords: Vehicle control rig~~~~~~~~~~~~~~~~~~ + Keywords: smartlink system~~~~~~~~~~~~~~~~~~ Desc:$ -The VEHICLE CONTROL RIG and a DATAJACK is necessary for someone who wants to -be able to mentally control a vehicle. An explanation of RIGGING is provided -later in the guild. +The SMARTLINK system allows the user to use a smartlink accessorized firearm, +granting them greater accuracy in ranged combat. If the weapon is outfitted +with a SMARTLINK accessory and the user has a SMARTLINK system installed, the +feature is automatically used. ~ [EXTRADESC 4] - Keywords: wired reflexes~~~~~~~~~~~~~~~~~~ + Keywords: datajack~~~~~~~~~~~~~~~~~~ Desc:$ -Wired Reflexes, while costly to the user's essence, enhance their REACTION and -INITIATIVE, allowing them to attack more often than an un-augmented person. -Wired Reflexes are known to cause some people to be extra jumpy. +A DATAJACK is necessary for a decker or a rigger to interface their mind with +a machine. ~ BREAK #60518 @@ -877,31 +502,12 @@ bioware, which should be avoided as they cause random ability loss. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60514 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60607 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60519 @@ -916,31 +522,12 @@ learn to advance that ability another level. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60606 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60525 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60520 @@ -957,31 +544,12 @@ astral projection, which will be explained later in the tutorial. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60523 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60514 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60521 @@ -998,31 +566,12 @@ perception. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60524 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60623 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60522 @@ -1043,31 +592,12 @@ gain you whatever services remained to the elemental's summoner. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60594 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60524 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60523 @@ -1086,31 +616,12 @@ result in the loss of magic abilities by the Shaman. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60624 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60520 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60524 @@ -1131,31 +642,12 @@ have a harder time doing things that require concentration. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60522 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60521 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60525 @@ -1169,31 +661,12 @@ the archetypes. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60526 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60514 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60526 @@ -1219,31 +692,12 @@ CREDSTICK". ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60527 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60525 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60527 @@ -1267,31 +721,12 @@ be accomplished with RADIO OFF. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60528 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60526 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60528 @@ -1306,31 +741,12 @@ NORTH to learn about channels. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60540 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60527 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60529 @@ -1357,31 +773,12 @@ initiated, this is explained later. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60608 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60540 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60530 @@ -1396,20 +793,7 @@ open. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] Keywords: doors shaft Desc:$ @@ -1417,15 +801,12 @@ A pair of elevator doors allows access to the liftway. ~ ToVnum: 60621 Flags: 1 - Material: brick - Barrier: 4 + Material: metal + Barrier: 8 KeyVnum: 998 LockRating: 8 [EXIT south] ToVnum: 60608 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60531 @@ -1439,20 +820,7 @@ elevator. ~ Flags: 11000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] Keywords: doors shaft Desc:$ @@ -1485,20 +853,7 @@ Awake has to offer. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] Keywords: doors shaft Desc:$ @@ -1506,15 +861,12 @@ A pair of elevator doors allows access to the liftway. ~ ToVnum: 60622 Flags: 1 - Material: brick - Barrier: 4 + Material: metal + Barrier: 8 KeyVnum: 998 LockRating: 8 [EXIT south] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60533 @@ -1529,55 +881,24 @@ worlds, and will tell you the important commands that are necessary. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60532 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60535 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60538 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60534 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60537 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60536 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60534 @@ -1598,31 +919,12 @@ be undertaken while in the astral plane, these are explained to the WEST. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60609 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60535 @@ -1643,25 +945,9 @@ LOGON, ANALYZE, DOWNLOAD, SOFTWARE and RUN for more information. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60536 @@ -1688,25 +974,9 @@ UPGRADE, UNINSTALL, ATTACH, TARGET, and REPAIR. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT up] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60537 @@ -1732,25 +1002,9 @@ HAIL when you're out on the street to flag down a cab. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60538 @@ -1762,31 +1016,12 @@ equipment. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60539 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60539 @@ -1803,31 +1038,12 @@ NORTH to learn about the types of equipment in 2060. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60538 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60540 @@ -1845,31 +1061,12 @@ side of a closed door. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60529 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60528 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60541 @@ -1893,73 +1090,33 @@ listed is MUD time. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60549 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northeast] ToVnum: 60545 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60546 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southeast] ToVnum: 60547 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60539 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southwest] ToVnum: 60544 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60543 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northwest] ToVnum: 60542 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60590 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60542 @@ -1984,31 +1141,12 @@ Peacemaker ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southeast] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60548 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60543 @@ -2023,25 +1161,9 @@ Sword ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60544 @@ -2053,25 +1175,9 @@ where you wear it. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northeast] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60545 @@ -2082,25 +1188,9 @@ metroplex might need. Type LIST to see what's available. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southwest] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60546 @@ -2113,37 +1203,15 @@ various electronic devices are stored in storage lockers. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60587 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60588 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60547 @@ -2155,25 +1223,9 @@ environment. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northwest] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60548 @@ -2192,25 +1244,9 @@ for firing in burst fire mode. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60542 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60549 @@ -2226,31 +1262,12 @@ character generation only. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60550 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60550 @@ -2269,31 +1286,12 @@ be able to hurt you. Continue SOUTH to learn more about combat. ~ Flags: 1000000000000000000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60551 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60549 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60551 @@ -2319,31 +1317,12 @@ to cast it. ~ Flags: 1000000000000000000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60550 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60552 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60552 @@ -2364,37 +1343,15 @@ combat. ~ Flags: 1000000000000000000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60551 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60554 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60553 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60553 @@ -2405,25 +1362,9 @@ Go back east before you get shot! ~ Flags: 1000000000000000000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60552 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60554 @@ -2453,31 +1394,12 @@ only as good as its user. ~ Flags: 1000000000000000000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60552 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60555 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60555 @@ -2490,31 +1412,12 @@ Shadowrun Universe. Head DOWN to start. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60554 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60556 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60556 @@ -2530,31 +1433,12 @@ and we are dead serious about this. Continue NORTH. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60557 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60555 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60557 @@ -2565,31 +1449,12 @@ continue north. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60558 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60556 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60558 @@ -2602,31 +1467,12 @@ an arse. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60559 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60557 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60559 @@ -2641,31 +1487,12 @@ Deckers. For more detail, type HELP CUSTOMIZE and HELP DESCRIPTION. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60560 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60558 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60560 @@ -2677,31 +1504,12 @@ trigger if you attack police officers or try and raid corporate installations ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60561 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60559 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60561 @@ -2712,31 +1520,12 @@ Once you're done reading, head SOUTH. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60560 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60562 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60562 @@ -2753,25 +1542,9 @@ by them during my stay here.^n" ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60561 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60563 @@ -2783,61 +1556,27 @@ Maybe you should talk to them. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60585 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northeast] ToVnum: 60566 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60573 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60569 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southwest] ToVnum: 60570 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60564 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northwest] ToVnum: 60565 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60564 @@ -2852,31 +1591,12 @@ all when you go through the guild for the second time. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60500 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60565 @@ -2889,25 +1609,9 @@ exit the game, you must RENT. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southeast] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60566 @@ -2918,31 +1622,12 @@ connection in the Matrix that serves at a database for all Shadowrunners. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60567 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southwest] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60567 @@ -2955,31 +1640,12 @@ assistance. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60568 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60566 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60568 @@ -2991,25 +1657,9 @@ day. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60567 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60569 @@ -3020,25 +1670,9 @@ flashlights, and rations. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60570 @@ -3052,37 +1686,15 @@ various things of all types, donated by the community for the less fortunate. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northeast] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60572 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60571 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60571 @@ -3096,25 +1708,9 @@ various things of all types, donated by the community for the less fortunate. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60570 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60572 @@ -3128,25 +1724,9 @@ various things of all types, donated by the community for the less fortunate. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60570 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60573 @@ -3166,37 +1746,15 @@ MOBS respond and interact with you. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60575 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60574 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60574 @@ -3209,25 +1767,9 @@ booth, maybe you should ask him for work. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60573 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60575 @@ -3247,32 +1789,15 @@ means there are plenty of job opportunities for characters. ~ Flags: 11100 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60573 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] Keywords: door trapdoor hatch ToVnum: 60576 Flags: 1 Material: wood - Barrier: 4 KeyVnum: 0 BREAK #60576 @@ -3285,38 +1810,18 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60577 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60583 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] Keywords: door trapdoor hatch ToVnum: 60575 Flags: 1 Material: wood - Barrier: 4 KeyVnum: 0 BREAK #60577 @@ -3329,31 +1834,12 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60578 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60576 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60578 @@ -3366,31 +1852,12 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60579 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60577 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60579 @@ -3403,31 +1870,12 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60580 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60578 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60580 @@ -3440,37 +1888,15 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60579 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60581 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60584 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60581 @@ -3483,31 +1909,12 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60580 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60582 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60582 @@ -3520,31 +1927,12 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60581 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60583 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60583 @@ -3557,31 +1945,12 @@ illuminated, and incredibly large, vicious rats scamper throughout the area. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60576 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60582 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60584 @@ -3602,24 +1971,10 @@ Trace: 0 RTG: 1100 JackID: 2064897 Address: The basement of Ricky's Eatery -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 +[POINTS] Light: 4 - Smoke: 0 - Background: 0 - BackgroundType: 0 [EXIT east] ToVnum: 60580 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60585 @@ -3636,37 +1991,15 @@ HAIL a cab outside, get inside, and tell the driver where you want to go. ~ Flags: 11100 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 32679 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60586 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60563 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60586 @@ -3681,31 +2014,12 @@ GUILD, THEY ARE ON THE OUTSIDE FOR GOOD. YOU HAVE BEEN WARNED.^N ~ Flags: 110000000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 32680 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60585 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60587 @@ -3718,25 +2032,9 @@ authenticity seals are missing.... ~ Flags: 1000000000000001000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60546 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60588 @@ -3752,31 +2050,12 @@ more professional man, perhaps the higher-quality chips can be had over there. ~ Flags: 1000000000000001000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60589 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60546 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60589 @@ -3789,25 +2068,9 @@ SOFTWARE for your CYBERDECK as well as some high-end PERSONA chips. ~ Flags: 1000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60588 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60590 @@ -3820,25 +2083,9 @@ otherwise it will cost you karma depending on the type, and force of the FOCI. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT up] ToVnum: 60541 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60591 @@ -3851,25 +2098,9 @@ phase of program creation. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60511 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60592 @@ -3883,25 +2114,9 @@ you with better prices in shops, and better rewards from johnsons. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northeast] ToVnum: 60512 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60593 @@ -3913,25 +2128,9 @@ at least a couple of ranks in. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT up] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60594 @@ -3949,31 +2148,12 @@ magic loss. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60595 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60522 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60595 @@ -3994,31 +2174,12 @@ elemental. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60596 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60594 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60596 @@ -4039,31 +2200,12 @@ astral plane. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60597 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60595 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60597 @@ -4080,31 +2222,12 @@ previous owner and makes it usable by you. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60598 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60596 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60598 @@ -4119,61 +2242,27 @@ categories. Go DOWN to continue with the tutorial. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60600 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT northeast] ToVnum: 60601 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60602 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT southeast] ToVnum: 60603 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60604 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60597 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60525 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60599 @@ -4184,25 +2273,9 @@ head down the stairs below. ~ Flags: 10011100 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60565 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60600 @@ -4216,25 +2289,9 @@ targets. Combat spells are represented by the Fire element. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60598 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60601 @@ -4247,25 +2304,9 @@ and increasing stats. Health spells have no elemental representative. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southwest] ToVnum: 60598 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60602 @@ -4279,25 +2320,9 @@ Air Element. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60598 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60603 @@ -4312,25 +2337,9 @@ represented by the Water Elemental. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northwest] ToVnum: 60598 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60604 @@ -4344,25 +2353,9 @@ amounts of mana. Manipulation spells are represented by the Earth Element. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60598 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60605 @@ -4372,20 +2365,7 @@ You are in an unfinished room. ~ Flags: 11000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] BREAK #60606 Name: Purchasing Power Points @@ -4399,31 +2379,12 @@ awakened characters. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60607 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60519 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60607 @@ -4443,31 +2404,12 @@ using the PERCEIVE command. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60518 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60606 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60608 @@ -4489,31 +2431,12 @@ however. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60530 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60529 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60609 @@ -4538,31 +2461,12 @@ stay projected due to essence loss you will have to resume again later. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60534 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60533 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60610 @@ -4574,31 +2478,12 @@ explanatory cyberware listed here. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60633 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60611 @@ -4615,31 +2500,12 @@ sight without projecting or perceiving. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60629 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60612 @@ -4652,31 +2518,12 @@ enforcement and corporate guards, so watch out. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT southeast] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60630 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60613 @@ -4689,31 +2536,12 @@ found on most items here. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60631 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60614 @@ -4726,31 +2554,12 @@ people don't like dealing with someone packed full of machines. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT northeast] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60632 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60615 @@ -4769,55 +2578,24 @@ kick in. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60618 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT east] ToVnum: 60617 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT south] ToVnum: 60619 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60616 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT up] ToVnum: 60517 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT down] ToVnum: 60525 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60616 @@ -4831,25 +2609,9 @@ greater freedom of movement. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60615 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60617 @@ -4865,25 +2627,9 @@ receive the normal cultured bonuses as they are already factored in. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] ToVnum: 60615 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60618 @@ -4899,25 +2645,9 @@ stay healthy. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT south] ToVnum: 60615 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60619 @@ -4929,25 +2659,9 @@ accomplish. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT north] ToVnum: 60615 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60620 @@ -4962,20 +2676,7 @@ remember to ^WOPEN DOOR WEST^n first. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT west] Keywords: door Desc:$ @@ -4997,25 +2698,15 @@ Alternatively, if you're here in person: hop out before the car hits you! ~ Flags: 10000000001010000000000000011100 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 0 -Y: 0 -Z: 0.00 -RoomType: 0 +X: 2 +Y: 2 +Z: 5.00 [POINTS] - SpecIdx: 0 Rating: 6 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 [EXIT down] - ToVnum: 60622 - Flags: 0 - Material: brick - Barrier: 4 + ToVnum: 0 + Material: paper + Barrier: 0 KeyVnum: 0 BREAK #60622 @@ -5027,20 +2718,11 @@ Alternatively, if you're here in person: hop out before the car hits you! ~ Flags: 10000000001010000000000000011100 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 0 -Y: 0 -Z: 0.00 -RoomType: 0 +X: 2 +Y: 2 +Z: 5.00 [POINTS] - SpecIdx: 0 Rating: 6 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 [EXIT south] Keywords: doors shaft Desc:$ @@ -5048,15 +2730,14 @@ A pair of elevator doors allows access to the liftway. ~ ToVnum: 60532 Flags: 1 - Material: brick - Barrier: 4 + Material: metal + Barrier: 8 KeyVnum: 998 LockRating: 8 [EXIT up] - ToVnum: 60621 - Flags: 0 - Material: brick - Barrier: 4 + ToVnum: 0 + Material: paper + Barrier: 0 KeyVnum: 0 BREAK #60623 @@ -5073,31 +2754,12 @@ astral projection, which will be explained later in the tutorial. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60521 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60514 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60624 @@ -5118,31 +2780,12 @@ have a harder time doing things that require concentration. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60625 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60523 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60625 @@ -5163,31 +2806,12 @@ services remained to the spirit's summoner. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT east] ToVnum: 60594 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 [EXIT west] ToVnum: 60624 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60626 @@ -5204,25 +2828,12 @@ able to use throwing knives or shuriken. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 X: 0 Y: 0 Z: 5.00 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60507 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60627 @@ -5237,25 +2848,9 @@ types of ammunition and the process for creating it. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60508 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60628 @@ -5268,25 +2863,9 @@ useful in roleplay scenarios and have no in-game coded effects.^n ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60506 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60629 @@ -5303,25 +2882,9 @@ treated as natural vision. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60611 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60630 @@ -5336,25 +2899,9 @@ mind when running the shadows. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60612 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60631 @@ -5366,25 +2913,9 @@ be found for each type of ware accordingly. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60613 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60632 @@ -5398,25 +2929,9 @@ made out of chrome tends to make people flighty. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60614 - Flags: 0 - Material: brick - Barrier: 4 KeyVnum: 0 BREAK #60633 @@ -5430,25 +2945,24 @@ listed here. ~ Flags: 1000000000000011000 SecType: Inside -MatrixExit: 0 -Crowd: 0 -Cover: 0 -X: 20 -Y: 20 -Z: 2.50 -RoomType: 0 -[POINTS] - SpecIdx: 0 - Rating: 0 - Light: 0 - Smoke: 0 - Background: 0 - BackgroundType: 0 +[POINTS] [EXIT down] ToVnum: 60610 - Flags: 0 - Material: brick - Barrier: 4 + KeyVnum: 0 +BREAK +#60692 +Name: Otaku Channels Training +Desc:$ +You are in an unfinished room. +~ +Flags: 1000000000000011000 +SecType: Inside +X: 0 +Y: 0 +Z: 0.00 +[POINTS] +[EXIT north] + ToVnum: 60511 KeyVnum: 0 BREAK END diff --git a/lib/world/zon/605.zon b/lib/world/zon/605.zon index 4b1d92241..2943d0485 100644 --- a/lib/world/zon/605.zon +++ b/lib/world/zon/605.zon @@ -1,71 +1,72 @@ #605 New Neophyte Guild~ -60699 20 2 0 1 0 +60699 20 2 0 1 0 0 0 0 0 1 0 0 0 0 -M 0 60500 1 60505 -M 0 60501 1 60510 -M 0 60502 1 60511 -M 0 60503 1 60512 -M 0 60504 1 60509 -M 0 60505 1 60507 -M 0 60506 1 60508 -M 0 60507 1 60519 -M 0 60511 1 60542 -M 0 60512 1 60543 -M 0 60514 1 60545 -M 0 60515 1 60547 -M 0 60516 1 60548 -M 0 60517 4 60551 -M 0 60517 4 60551 -M 0 60517 4 60551 -M 0 60517 4 60551 -M 0 60518 4 60553 -M 0 60518 4 60553 -M 0 60518 4 60553 -M 0 60518 4 60553 -M 0 60519 1 60574 -M 0 60520 1 60575 -M 0 60521 4 60581 -M 0 60521 4 60579 +M 0 60500 1 60505 1 +M 0 60501 1 60510 1 +M 0 60502 1 60511 1 +M 0 60503 1 60512 1 +M 0 60504 1 60509 1 +M 0 60505 1 60507 1 +M 0 60506 1 60508 1 +M 0 60507 1 60519 1 +M 0 60511 1 60542 1 +M 0 60512 1 60543 1 +M 0 60514 1 60545 1 +M 0 60515 1 60547 1 +M 0 60516 1 60548 1 +M 0 60517 4 60551 1 +M 0 60517 4 60551 1 +M 0 60517 4 60551 1 +M 0 60517 4 60551 1 +M 0 60518 4 60553 1 +M 0 60518 4 60553 1 +M 0 60518 4 60553 1 +M 0 60518 4 60553 1 +M 0 60519 1 60574 1 +M 0 60520 1 60575 1 +M 0 60521 4 60581 1 +M 0 60521 4 60579 1 D 0 60576 8 1 -M 0 60522 1 60569 -M 0 60523 1 60565 -M 0 60524 1 60573 -M 0 60525 1 60537 -M 0 60526 1 60568 -M 0 60527 1 60546 -M 0 60529 1 60588 -M 0 60530 1 60589 -M 0 60528 1 60587 +M 0 60522 1 60569 1 +M 0 60523 1 60565 1 +M 0 60524 1 60573 1 +M 0 60525 1 60537 1 +M 0 60526 1 60568 1 +M 0 60527 1 60546 1 +M 0 60529 1 60588 1 +M 0 60530 1 60589 1 +M 0 60528 1 60587 1 O 0 26 0 60566 -M 0 60531 0 60590 -M 0 60532 0 60591 -M 0 60533 0 60592 -M 0 60534 0 60593 -M 0 60600 0 60600 -M 0 60601 0 60601 -M 0 60602 0 60602 -M 0 60603 0 60603 -M 0 60604 0 60604 -M 0 60510 0 60613 -M 0 60535 0 60612 -M 0 60536 0 60614 -M 0 60537 0 60610 -M 0 60538 0 60611 -M 0 60605 0 60618 -M 0 60606 0 60616 -M 0 60607 0 60617 -M 0 60608 0 60619 -M 0 60513 1 60544 +M 0 60531 0 60590 1 +M 0 60532 0 60591 1 +M 0 60533 0 60592 1 +M 0 60534 0 60593 1 +M 0 60600 0 60600 1 +M 0 60601 0 60601 1 +M 0 60602 0 60602 1 +M 0 60603 0 60603 1 +M 0 60604 0 60604 1 +M 0 60510 0 60613 1 +M 0 60535 0 60612 1 +M 0 60536 0 60614 1 +M 0 60537 0 60610 1 +M 0 60538 0 60611 1 +M 0 60605 0 60618 1 +M 0 60606 0 60616 1 +M 0 60607 0 60617 1 +M 0 60608 0 60619 1 +M 0 60513 1 60544 1 D 0 60501 2 1 O 0 60500 0 60502 O 0 60502 0 60501 -M 0 60539 0 60626 -M 0 60540 0 60627 -M 0 60541 0 60628 -M 0 60639 1 60629 -M 0 60640 1 60630 -M 0 60641 1 60631 -M 0 60642 1 60632 -M 0 60643 1 60633 +M 0 60539 0 60626 1 +M 0 60540 0 60627 1 +M 0 60541 0 60628 1 +M 0 60639 1 60629 1 +M 0 60640 1 60630 1 +M 0 60641 1 60631 1 +M 0 60642 1 60632 1 +M 0 60643 1 60633 1 +M 0 60692 0 60692 0 $ diff --git a/src/act.informative.cpp b/src/act.informative.cpp index 526aa5f9c..bcc5e2fda 100644 --- a/src/act.informative.cpp +++ b/src/act.informative.cpp @@ -1649,6 +1649,8 @@ void list_one_char(struct char_data * i, struct char_data * ch) strlcat(buf, " is here, working on a cyberdeck.", sizeof(buf)); else if (AFF_FLAGGED(i, AFF_SPELLDESIGN)) strlcat(buf, " is here, working on a spell design.", sizeof(buf)); + else if (AFF_FLAGGED(i, AFF_COMPLEX_FORM_PROGRAM)) + strlcat(buf, " is here, meditating on a complex form.", sizeof(buf)); else if (AFF_FLAGGED(i, AFF_CONJURE)) strlcat(buf, " is here, performing a conjuring ritual.", sizeof(buf)); else if (AFF_FLAGGED(i, AFF_LODGE)) @@ -5149,7 +5151,8 @@ ACMD(do_score) strlcat(mage_string, "Physical Adept", sizeof(mage_string)); break; default: - strlcat(mage_string, "Mundane", sizeof(mage_string)); + if (IS_OTAKU(ch)) strlcat(mage_string, "Otaku", sizeof(mage_string)); + else strlcat(mage_string, "Mundane", sizeof(mage_string)); break; } diff --git a/src/awake.hpp b/src/awake.hpp index c16acc23b..582d06cd9 100644 --- a/src/awake.hpp +++ b/src/awake.hpp @@ -86,6 +86,12 @@ /* char and mob related defines */ +/* otaku paths */ + +#define OTAKU_PATH_NORMIE 0 +#define OTAKU_PATH_CYBERADEPT 1 +#define OTAKU_PATH_TECHNOSHAM 2 + /* magical traditions */ #define TRAD_HERMETIC 0 @@ -355,7 +361,8 @@ enum { #define PLR_IS_TEMPORARILY_LOADED 52 #define PLR_COMPLETED_EXPERT_DRIVER_OVERHAUL 53 #define PLR_OLD_MAN_YELLS_AT_CLOUDS 54 -#define PLR_MAX 55 +#define PLR_SUBMERSION 55 +#define PLR_MAX 56 // Adding something here? Add it to constants.cpp's player_bits too. @@ -584,7 +591,8 @@ enum { #define AFF_VOICE_MODULATOR 54 #define AFF_WEARING_ACTIVE_DOCWAGON_RECEIVER 55 #define AFF_CHEATLOG_MARK 56 -#define AFF_MAX 57 +#define AFF_COMPLEX_FORM_PROGRAM 57 +#define AFF_MAX 58 // TODO: If you add another long-state action like building, designing, etc: // - Add it to the BR_TASK_AFF_FLAGS section below, which affects bioware_check and the B/R flag in the wholist // - Add it to the IS_WORKING and STOP_WORKING macros in utils.h @@ -807,6 +815,20 @@ enum { #define MASK_DUAL (1 << 2) #define MASK_COMPLETE (1 << 3) +#define ECHO_UNDEFINED 0 +#define ECHO_IMPROVED_IO 1 +#define ECHO_IMPROVED_HARD 2 +#define ECHO_IMPROVED_MPCP 3 +#define ECHO_PERSONA_BOD 4 +#define ECHO_PERSONA_EVAS 5 +#define ECHO_PERSONA_MASK 6 +#define ECHO_PERSONA_SENS 7 +#define ECHO_IMPROVED_REA 8 +#define ECHO_GHOSTING 9 +#define ECHO_NEUROFILTER 10 +#define ECHO_OVERCLOCK 11 +#define ECHO_MAX 12 + #define AURA_VIOLENCE 0 #define AURA_TORTURE 1 #define AURA_HATRED 2 @@ -1048,8 +1070,14 @@ enum { #define SKILL_PILOT_WALKER 151 #define SKILL_MANDARIN 152 #define SKILL_HAITIAN_CREOLE 153 - -#define MAX_SKILLS 154 +// otaku-specific skills +#define SKILL_CHANNEL_ACCESS 154 +#define SKILL_CHANNEL_CONTROL 155 +#define SKILL_CHANNEL_INDEX 156 +#define SKILL_CHANNEL_FILES 157 +#define SKILL_CHANNEL_SLAVE 158 + +#define MAX_SKILLS 159 // Adding a pilot skill? Update utils.cpp's pilot_skills[]. // Skill type definitions. @@ -1312,7 +1340,8 @@ enum { #define ITEM_DESTROYABLE 47 #define ITEM_LOADED_DECORATION 48 #define ITEM_CREATIVE_EFFORT 49 -#define NUM_ITEMS 50 +#define ITEM_COMPLEX_FORM 50 /* otaku complex form */ +#define NUM_ITEMS 51 // Adding something? Add convenience definees to utils.hpp and put the type's name in constants.cpp. #define PATCH_ANTIDOTE 0 @@ -1397,7 +1426,8 @@ enum { #define ITEM_EXTRA_CHEATLOG_MARK 33 #define ITEM_EXTRA_CONCEALED_IN_EQ 34 // Doesn't show up when someone looks at you. #define ITEM_EXTRA_TRODE_NET 35 -#define MAX_ITEM_EXTRA 36 +#define ITEM_EXTRA_OTAKU_BS 36 // This is related to Otaku nonsense +#define MAX_ITEM_EXTRA 37 /* Ammo types */ #define AMMO_NORMAL 0 @@ -2050,6 +2080,7 @@ enum { #define SCMD_AUTHORIZE 10 #define SCMD_SQUELCHTELLS 11 #define SCMD_MUTE_NEWBIE 12 +#define SCMD_SUBMERSE 13 /* do_say */ #define SCMD_SAY 0 @@ -2275,7 +2306,9 @@ enum { #define CON_ART_CREATE 52 #define CON_ACCOUNT_PARSE 53 #define CON_FACTION_EDIT 54 -#define CON_MAX 54 +#define CON_CF_CREATE 55 +#define CON_SUBMERSION 56 +#define CON_MAX 56 #define IS_VALID_STATE_TO_RECEIVE_COMMS(s) ((s) == CON_PLAYING || ((s) >= CON_PRO_CREATE && (s) <= CON_AMMO_CREATE) || (s) == CON_PGEDIT || ((s) >= CON_DECORATE_VEH && (s) <= CON_ART_CREATE)) // If you add another state, you need to touch comm.cpp's close_socket and make sure it's reflected there! // Also add it to constants's connected_types. @@ -2808,7 +2841,8 @@ enum { #define OBJ_CUSTOM_ART 125 #define OBJ_HOLIDAY_GIFT 126 #define OBJ_BLANK_MAGAZINE 127 -#define TOP_OF_TEMPLATE_ITEMS 127 +#define OBJ_BLANK_COMPLEX_FORM 128 +#define TOP_OF_TEMPLATE_ITEMS 128 #define OBJ_DOCWAGON_PAPER_GOWN 16201 #define OBJ_ANTI_DRUG_CHEMS 44 @@ -3087,7 +3121,8 @@ enum { #define DIRTY_BIT_MEMORY 5 #define DIRTY_BIT_DRUG 6 #define DIRTY_BIT_ALIAS 7 -#define NUM_DIRTY_BITS 8 +#define DIRTY_BIT_ECHOES 8 +#define NUM_DIRTY_BITS 9 #define SMARTLINK_II_MODIFIER 3 @@ -3226,6 +3261,8 @@ enum { #define OBJ_LOAD_REASON_BULLETPANTS_MAKE_BOX 56 #define OBJ_LOAD_REASON_FIND_OBJ_SHOP 57 #define OBJ_LOAD_REASON_SHOP_RECEIVE 58 +#define OBJ_LOAD_REASON_OTAKU_BS 59 +#define OBJ_LOAD_REASON_CREATE_COMPLEX_FORM 60 #define IDNUM_FOR_MOB_ALERT_STATE -1 diff --git a/src/cf_create.cpp b/src/cf_create.cpp new file mode 100644 index 000000000..989c8391f --- /dev/null +++ b/src/cf_create.cpp @@ -0,0 +1,272 @@ +#include "structs.hpp" +#include "awake.hpp" +#include "db.hpp" +#include "comm.hpp" +#include "interpreter.hpp" +#include "handler.hpp" +#include "utils.hpp" +#include "screen.hpp" +#include "constants.hpp" +#include "olc.hpp" +#include "newmagic.hpp" + +#define CH d->character +#define FORM d->edit_obj + +#define CFEDIT_MENU 0 +#define CFEDIT_TYPE 1 +#define CFEDIT_NAME 2 +#define CFEDIT_RATING 3 +#define CFEDIT_WOUND 4 + +extern int get_program_skill(char_data *ch, obj_data *prog, int target); + +#define COMPLEX_FORM_TYPES 23 + +int complex_form_programs[COMPLEX_FORM_TYPES] = { + 6, // Attack + 7, // Slow + 8, // Medic + 11, // Compressor + 13, // Decrypt + 15, // Relocate + 16, // Sleaze + 20, // Track + 21, // Armor + 22, // Camo + 23, // Crash + 24, // Defuse + 25, // Evaluate + 26, // Validate + 27, // Swerve + 30, // Cloak + 31, // Lock-On +}; + +void cfedit_disp_menu(struct descriptor_data *d) +{ + CLS(CH); + send_to_char(CH, "1) Name: ^c%s^n\r\n", FORM->restring); + send_to_char(CH, "2) Type: ^c%s^n\r\n", programs[GET_DESIGN_PROGRAM(FORM)].name); + send_to_char(CH, "3) Rating: ^c%d^n\r\n", GET_DESIGN_RATING(FORM)); + + // Minimum program size is rating^2. + int program_size = GET_DESIGN_RATING(FORM) * GET_DESIGN_RATING(FORM); + if (GET_DESIGN_PROGRAM(FORM) == SOFT_ATTACK) { + // Attack programs multiply size by a factor determined by wound level. + program_size *= attack_multiplier[GET_DESIGN_PROGRAM_WOUND_LEVEL(FORM)]; + send_to_char(CH, "4) Damage: ^c%s^n\r\n", GET_WOUND_NAME(GET_DESIGN_PROGRAM_WOUND_LEVEL(FORM))); + } else { + // Others multiply by a set multiplier based on software type. + program_size *= programs[GET_DESIGN_PROGRAM(FORM)].multiplier; + } + send_to_char(CH, "Effective Size: ^c%d^n\r\n\r\n", program_size); + send_to_char(CH, "q) Quit and save\r\nEnter your choice: "); + d->edit_mode = CFEDIT_MENU; +} + +void cfedit_disp_program_menu(struct descriptor_data *d) +{ + CLS(CH); + + strncpy(buf, "", sizeof(buf) - 1); + + bool screenreader_mode = PRF_FLAGGED(d->character, PRF_SCREENREADER); + for (int counter = 1; counter < COMPLEX_FORM_TYPES; counter++) + { + if (screenreader_mode) + send_to_char(d->character, "%d) %s\r\n", counter, programs[complex_form_programs[counter]].name); + else { + snprintf(ENDOF(buf), sizeof(buf) - strlen(buf), "%s%2d) %-22s%s", + counter % 3 == 1 ? " " : "", + counter, + programs[complex_form_programs[counter]].name, + counter % 3 == 0 ? "\r\n" : ""); + } + } + if (!screenreader_mode) + send_to_char(d->character, "%s\r\nSelect program type: ", buf); + d->edit_mode = CFEDIT_TYPE; +} + +void cfedit_parse(struct descriptor_data *d, const char *arg) +{ + int number = atoi(arg); + switch(d->edit_mode) + { + case CFEDIT_MENU: + switch (*arg) { + case '1': + send_to_char(CH, "What do you want to call this complex form: "); + d->edit_mode = CFEDIT_NAME; + break; + case '2': + cfedit_disp_program_menu(d); + break; + case '3': + if (!GET_DESIGN_PROGRAM(d->edit_obj)) + send_to_char("Choose a program type first!\r\n", CH); + else { + send_to_char("Enter Rating: ", CH); + d->edit_mode = CFEDIT_RATING; + } + break; + case '4': + if (GET_DESIGN_PROGRAM(d->edit_obj) != SOFT_ATTACK) + send_to_char(CH, "Invalid option!\r\n"); + else { + CLS(CH); + send_to_char(CH, "1) Light\r\n2) Moderate\r\n3) Serious\r\n4) Deadly\r\nEnter your choice: "); + d->edit_mode = CFEDIT_WOUND; + } + break; + case 'q': + case 'Q': + if (!GET_DESIGN_PROGRAM(d->edit_obj) || !GET_DESIGN_RATING(d->edit_obj)) { + send_to_char("You must specify a program type and/or rating first.\r\n", CH); + cfedit_disp_menu(d); + return; + } + + send_to_char(CH, "Design saved!\r\n"); + if (GET_DESIGN_PROGRAM(d->edit_obj) == SOFT_ATTACK) { + GET_DESIGN_DESIGNING_TICKS_LEFT(d->edit_obj) = GET_DESIGN_RATING(d->edit_obj) * attack_multiplier[GET_DESIGN_PROGRAM_WOUND_LEVEL(d->edit_obj)]; + } else if (GET_DESIGN_PROGRAM(d->edit_obj) == SOFT_RESPONSE) { + GET_DESIGN_DESIGNING_TICKS_LEFT(d->edit_obj) = GET_DESIGN_RATING(d->edit_obj) * (GET_DESIGN_RATING(d->edit_obj) * GET_DESIGN_RATING(d->edit_obj)); + } else { + GET_DESIGN_DESIGNING_TICKS_LEFT(d->edit_obj) = GET_DESIGN_RATING(d->edit_obj) * programs[GET_DESIGN_PROGRAM(d->edit_obj)].multiplier; + } + GET_DESIGN_SIZE(d->edit_obj) = GET_DESIGN_RATING(d->edit_obj) * GET_DESIGN_DESIGNING_TICKS_LEFT(d->edit_obj); + GET_DESIGN_DESIGNING_TICKS_LEFT(d->edit_obj) *= 20; + GET_DESIGN_ORIGINAL_TICKS_LEFT(d->edit_obj) = GET_DESIGN_DESIGNING_TICKS_LEFT(d->edit_obj); + GET_DESIGN_CREATOR_IDNUM(d->edit_obj) = GET_IDNUM(CH); + obj_to_char(d->edit_obj, CH); + STATE(d) = CON_PLAYING; + d->edit_obj = NULL; + break; + default: + send_to_char(CH, "Invalid option!\r\n"); + break; + } + break; + case CFEDIT_RATING: + if (number > GET_SKILL(CH, SKILL_COMPUTER)) { + send_to_char(CH, "You can't create a program of a higher rating than your computer skill.\r\n" + "Enter Rating: "); + } else { + GET_DESIGN_RATING(d->edit_obj) = number; + cfedit_disp_menu(d); + } + break; + case CFEDIT_NAME: + { + int length_with_no_color = get_string_length_after_color_code_removal(arg, CH); + + // Silent failure: We already sent the error message in get_string_length_after_color_code_removal(). + if (length_with_no_color == -1) { + cfedit_disp_menu(d); + return; + } + if (length_with_no_color >= LINE_LENGTH) { + send_to_char(CH, "That name is too long, please shorten it. The maximum length after color code removal is %d characters.\r\n", LINE_LENGTH - 1); + cfedit_disp_menu(d); + return; + } + + if (strlen(arg) >= MAX_RESTRING_LENGTH) { + send_to_char(CH, "That restring is too long, please shorten it. The maximum length with color codes included is %d characters.\r\n", MAX_RESTRING_LENGTH - 1); + cfedit_disp_menu(d); + return; + } + + DELETE_ARRAY_IF_EXTANT(d->edit_obj->restring); + d->edit_obj->restring = str_dup(arg); + cfedit_disp_menu(d); + break; + } + case CFEDIT_WOUND: + if (number < LIGHT || number > DEADLY) + send_to_char(CH, "Not a valid option!\r\nEnter your choice: "); + else { + GET_DESIGN_PROGRAM_WOUND_LEVEL(d->edit_obj) = number; + cfedit_disp_menu(d); + } + break; + case CFEDIT_TYPE: + if (number < 1 || number >= COMPLEX_FORM_TYPES) + send_to_char(CH, "Not a valid option!\r\nEnter your choice: "); + else { + GET_DESIGN_PROGRAM(d->edit_obj) = complex_form_programs[number]; + GET_DESIGN_RATING(d->edit_obj) = 1; + + if (GET_DESIGN_PROGRAM(d->edit_obj) == SOFT_ATTACK) { + // Default to Deadly damage. + GET_DESIGN_PROGRAM_WOUND_LEVEL(d->edit_obj) = DEADLY; + } + + cfedit_disp_menu(d); + } + break; + } +} + +void create_complex_form(struct char_data *ch) +{ + struct obj_data *design = read_object(OBJ_BLANK_COMPLEX_FORM, VIRTUAL, OBJ_LOAD_REASON_CREATE_COMPLEX_FORM); + STATE(ch->desc) = CON_CF_CREATE; + design->restring = str_dup("a blank complex form"); + ch->desc->edit_obj = design; + cfedit_disp_menu(ch->desc); +} + +ACMD(do_meditate) +{ + struct obj_data *comp, *prog; + if (!*argument) { + if (AFF_FLAGGED(ch, AFF_COMPLEX_FORM_PROGRAM)) { + AFF_FLAGS(ch).RemoveBit(AFF_COMPLEX_FORM_PROGRAM); + send_to_char(ch, "You stop working on %s.\r\n", ch->char_specials.programming->restring); + ch->char_specials.programming = NULL; + } else + send_to_char(ch, "Meditate On What?\r\n"); + return; + } + + if (GET_POS(ch) > POS_SITTING) { + GET_POS(ch) = POS_SITTING; + send_to_char(ch, "You find a place to sit and focus.\r\n"); + } + + if (IS_WORKING(ch)) { + send_to_char(TOOBUSY, ch); + return; + } + else if (ch->in_veh && (ch->vfront || !ch->in_veh->flags.IsSet(VFLAG_WORKSHOP))) { + send_to_char("You can't do that in here.\r\n", ch); + } + + if (!GET_DESIGN_PROGRAMMING_TICKS_LEFT(prog)) { + if (access_level(ch, LVL_ADMIN)) { + send_to_char(ch, "You use your admin powers to greatly accelerate the development time for %s.\r\n", prog->restring); + GET_DESIGN_PROGRAMMING_TICKS_LEFT(prog) = 1; + GET_OBJ_TIMER(prog) = GET_DESIGN_PROGRAMMING_TICKS_LEFT(prog); + } else { + send_to_char(ch, "You begin to meditate on %s.\r\n", prog->restring); + int target = GET_DESIGN_RATING(prog); + int skill = get_skill(ch, SKILL_COMPUTER, target); + int success = success_test(skill, target); + + if (success > 0) { + GET_DESIGN_PROGRAMMING_TICKS_LEFT(prog) = 60 * (GET_DESIGN_SIZE(prog) / success); + GET_DESIGN_ORIGINAL_TICKS_LEFT(prog) = GET_DESIGN_PROGRAMMING_TICKS_LEFT(prog); + } else { + GET_DESIGN_PROGRAMMING_TICKS_LEFT(prog) = number(1, 6) + number(1, 6); + GET_DESIGN_ORIGINAL_TICKS_LEFT(prog) = (GET_DESIGN_SIZE(prog) * 60) / number(1, 3); + GET_DESIGN_PROGRAMMING_FAILED(prog) = 1; + } + } + } else + send_to_char(ch, "You continue to work on %s.\r\n", prog->restring); + AFF_FLAGS(ch).SetBit(AFF_COMPLEX_FORM_PROGRAM); + GET_BUILDING(ch) = prog; +} \ No newline at end of file diff --git a/src/chargen.cpp b/src/chargen.cpp index 01673faec..68fda2d5f 100644 --- a/src/chargen.cpp +++ b/src/chargen.cpp @@ -76,7 +76,7 @@ void ccr_pronoun_menu(struct descriptor_data *d) { void display_prestige_race_menu(struct descriptor_data *d) { char msg_buf[10000]; snprintf(msg_buf, sizeof(msg_buf), - "\r\nPrestige races cost system points, which you will draw from an existing character." + "\r\nPrestige races and classes cost system points, which you will draw from an existing character." "\r\n" "\r\nThe following races are available:" "\r\n" @@ -109,8 +109,14 @@ void display_prestige_race_menu(struct descriptor_data *d) { "\r\n^c--- Dragons can't use 'ware, but have high stat caps. ---^n" "\r\n B) Western Dragon (%4d sysp, 30 build points / slot B)" "\r\n C) Eastern Dragon (%4d sysp, 30 build points / slot B)" - "\r\n D) Feathered Serpent (%4d sysp, 30 build points / slot B)", - PRESTIGE_RACE_DRAGON_COST, PRESTIGE_RACE_DRAGON_COST, PRESTIGE_RACE_DRAGON_COST); + "\r\n D) Feathered Serpent (%4d sysp, 30 build points / slot B)" + "\r\n" + "\r\nThe following classes are available (Toggle only one):" + "\r\n" + "\r\n--- Otaku are a magic variant of Deckers. ---" + "\r\n O) Otaku [%s] (%4d sys, 30 build points / slot A)", + PRESTIGE_RACE_DRAGON_COST, PRESTIGE_RACE_DRAGON_COST, PRESTIGE_RACE_DRAGON_COST, + d->ccr.is_otaku ? "^g ON^n" : "^rOFF^n", PRESTIGE_CLASS_OTAKU_COST); strlcat(msg_buf, "\r\n" @@ -625,6 +631,14 @@ int magic_cost[4] = { 0, 30, 25, 25 }; const char *magic_table[4] = { "None", "Full Magician", "Aspected Magician", "Adept" }; const char *gnome_magic_table[4] = { "None", "Full Shaman", "Aspected Shaman", "ERROR" }; +int cg_nuyen(struct descriptor_data *d, int x) +{ + int starting_nuyen = resource_table[0][x]; + if (d->ccr.is_otaku) + return MIN(5000, starting_nuyen); + return starting_nuyen; +} + void set_attributes(struct char_data *ch, int magic) { // Everyone starts with 0 bioware index and max natural essence. @@ -825,6 +839,11 @@ int parse_prestige_race(struct descriptor_data *d, const char *arg) case 'd': case 'D': return RACE_FEATHERED_SERPENT; + case 'o': + case 'O': + d->ccr.is_otaku = !d->ccr.is_otaku; + ccr_race_menu(d); + return RETURN_HELP; case 'X': case 'x': case 'Q': @@ -916,6 +935,13 @@ int parse_assign(struct descriptor_data *d, const char *arg) if (d->ccr.pr[lowest_kosher_magic_slot] == PR_RACE) lowest_kosher_magic_slot--; + // Except for otaku who are always mundane lol + if (*arg == 2 && d->ccr.is_otaku && d->ccr.temp <= 1) { + snprintf(buf2, sizeof(buf2), "Magic cannot be assigned on Otaku characters, they are always mundane."); + SEND_TO_Q(buf2, d); + return 0; + } + if (*arg == '2' && (d->ccr.temp > 1 && d->ccr.temp != lowest_kosher_magic_slot)) { char kosher_slot = 'A' + lowest_kosher_magic_slot; snprintf(buf2, sizeof(buf2), "Magic can only fit in slots A, B, or %c for %s characters.", @@ -957,7 +983,7 @@ int parse_assign(struct descriptor_data *d, const char *arg) case PR_MAGIC: break; case PR_RESOURCE: - GET_NUYEN_RAW(d->character) = nuyen_vals[d->ccr.temp]; + GET_NUYEN_RAW(d->character) = MIN(nuyen_vals[d->ccr.temp], d->ccr.is_otaku ? 5000 : nuyen_vals[0]); d->ccr.force_points = force_vals[d->ccr.temp]; break; case PR_SKILL: @@ -993,6 +1019,9 @@ void priority_menu(struct descriptor_data *d) case PR_RACE: snprintf(ENDOF(buf2), sizeof(buf2) - strlen(buf2), "%-11s - - -\r\n", pc_race_types[(int) GET_RACE(d->character)]); break; + case PR_OTAKU: + strlcat(buf2, "Otaku - - -\r\n", sizeof(buf2)); + break; case PR_MAGIC: if ( i == 0 ) { if (GET_RACE(CH) == RACE_GNOME || GET_RACE(CH) == RACE_DRYAD) { @@ -1024,7 +1053,7 @@ void priority_menu(struct descriptor_data *d) case PR_RESOURCE: snprintf(buf3, sizeof(buf3), "%sResources - - %d nuyen / %d\r\n", buf2, - nuyen_vals[i], + MIN(nuyen_vals[i], d->ccr.is_otaku ? 5000 : nuyen_vals[0]), force_vals[i]); strlcpy(buf2, buf3, sizeof(buf2)); break; @@ -1040,11 +1069,11 @@ void init_char_sql(struct char_data *ch, const char *call_origin) char buf2[MAX_STRING_LENGTH]; snprintf(buf, sizeof(buf), "INSERT INTO pfiles (`idnum`, `name`, `password`, `race`, `gender`, `Rank`, `Voice`,"\ "`Physical_Keywords`, `Physical_Name`, `Whotitle`, `Height`, `Weight`, `Host`,"\ - "`Tradition`, `Born`, `Background`, `Physical_LookDesc`, `Matrix_LookDesc`, `Astral_LookDesc`, `LastD`, `multiplier`) VALUES ('%ld', '%s', '%s', %d, '%d',"\ - "'%d', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%d', '%ld', '%s', '%s', '%s', '%s', %ld, 100);", GET_IDNUM(ch), + "`Tradition`, `Otaku_Path`, `Born`, `Background`, `Physical_LookDesc`, `Matrix_LookDesc`, `Astral_LookDesc`, `LastD`, `multiplier`) VALUES ('%ld', '%s', '%s', %d, '%d',"\ + "'%d', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%d', '%d', '%ld', '%s', '%s', '%s', '%s', %ld, 100);", GET_IDNUM(ch), GET_CHAR_NAME(ch), GET_PASSWD(ch), GET_RACE(ch), GET_PRONOUNS(ch), MAX(1, GET_LEVEL(ch)), prepare_quotes(buf2, ch->player.physical_text.room_desc, sizeof(buf2) / sizeof(buf2[0])), GET_KEYWORDS(ch), GET_NAME(ch), GET_WHOTITLE(ch), - GET_HEIGHT(ch), GET_WEIGHT(ch), ch->player.host, GET_TRADITION(ch), ch->player.time.birth, "A blank slate.", + GET_HEIGHT(ch), GET_WEIGHT(ch), ch->player.host, GET_TRADITION(ch), GET_OTAKU_PATH(ch), ch->player.time.birth, "A blank slate.", "A nondescript person.\r\n", "A nondescript entity.\r\n", "A nondescript entity.\r\n", time(0)); mysql_wrapper(mysql, buf); if (PLR_FLAGGED(ch, PLR_NOT_YET_AUTHED)) { @@ -1084,6 +1113,24 @@ static void start_game(descriptor_data *d, const char *origin) GET_LOADROOM(d->character) = RM_CHARGEN_START_ROOM; } + // Otaku get some starting gear, so assign that here + if (d->ccr.is_otaku) { + // add asist + obj_data *temp_obj = read_object(CYB_ASIST, VIRTUAL, OBJ_LOAD_REASON_ARCHETYPE); + int esscost = GET_CYBERWARE_ESSENCE_COST(temp_obj); + if (IS_GHOUL(CH) || IS_DRAKE(CH)) + esscost *= 2; + GET_REAL_ESS(CH) -= esscost; + obj_to_cyberware(temp_obj, d->character); + // add jack + temp_obj = read_object(CYB_DATAJACK, VIRTUAL, OBJ_LOAD_REASON_ARCHETYPE); + esscost = GET_CYBERWARE_ESSENCE_COST(temp_obj); + if (IS_GHOUL(CH) || IS_DRAKE(CH)) + esscost *= 2; + GET_REAL_ESS(CH) -= esscost; + obj_to_cyberware(temp_obj, d->character); + } + init_char_sql(d->character, "start_game()"); GET_CHAR_MULTIPLIER(d->character) = 100; if(PLR_FLAGGED(d->character,PLR_NOT_YET_AUTHED)) { @@ -1234,11 +1281,13 @@ void points_menu(struct descriptor_data *d) " 3) Resources : ^c%15d^n (^c%3d^n Points)\r\n" " 4) Magic : ^c%15s^n (^c%3d^n Points)\r\n" " Race : ^c%15s^n (^c%3d^n Points)\r\n" + " Class : ^c%15s^n (^c%3d^n Points)\r\n" " Points Remaining: ^c%d^n\r\n" "Choose an area to change points on(p to continue): ", d->ccr.pr[PO_ATTR]/2, d->ccr.pr[PO_ATTR], - d->ccr.pr[PO_SKILL], d->ccr.pr[PO_SKILL], resource_table[0][d->ccr.pr[PO_RESOURCES]], + d->ccr.pr[PO_SKILL], d->ccr.pr[PO_SKILL], cg_nuyen(d, d->ccr.pr[PO_RESOURCES]), resource_table[1][d->ccr.pr[PO_RESOURCES]], magic_table_ptr[d->ccr.pr[PO_MAGIC]], - magic_cost[d->ccr.pr[PO_MAGIC]], pc_race_types[(int)GET_RACE(d->character)], d->ccr.pr[PO_RACE], d->ccr.points); + magic_cost[d->ccr.pr[PO_MAGIC]], pc_race_types[(int)GET_RACE(d->character)], d->ccr.pr[PO_RACE], + d->ccr.is_otaku ? "Otaku" : "None", d->ccr.is_otaku ? 30 : 0, d->ccr.points); SEND_TO_Q(buf, d); } @@ -1362,12 +1411,18 @@ void create_parse(struct descriptor_data *d, const char *arg) d->ccr.points += resource_table[1][d->ccr.pr[PO_RESOURCES]]; snprintf(buf, sizeof(buf), " "); for (int x = 0; x < 8; x++) - snprintf(ENDOF(buf), sizeof(buf) - strlen(buf), " %d) %8d nuyen (%2d points)\r\n ", x+1, resource_table[0][x], resource_table[1][x]); + snprintf(ENDOF(buf), sizeof(buf) - strlen(buf), " %d) %8d nuyen (%2d points)\r\n ", x+1, cg_nuyen(d, x), resource_table[1][x]); + if (d->ccr.is_otaku) + send_to_char(CH, "^wNOTE:^n Otaku are always limited to 5000 nuyen on start.\r\n "); SEND_TO_Q(buf, d); send_to_char(CH, "Enter desired amount of nuyen points (^c%d^n available): ", d->ccr.points); d->ccr.mode = CCR_PO_RESOURCES; break; case '4': + if (d->ccr.is_otaku) { + send_to_char(CH, "Otaku are always considered mundane.\r\n"); + break; + } d->ccr.points += magic_cost[d->ccr.pr[PO_MAGIC]]; snprintf(buf, sizeof(buf), " "); if (GET_RACE(CH) == RACE_GNOME || GET_RACE(CH) == RACE_DRYAD) { @@ -1399,10 +1454,14 @@ void create_parse(struct descriptor_data *d, const char *arg) break; } - GET_NUYEN_RAW(CH) = resource_table[0][d->ccr.pr[PO_RESOURCES]]; + GET_NUYEN_RAW(CH) = cg_nuyen(d, d->ccr.pr[PO_RESOURCES]); GET_SKILL_POINTS(CH) = d->ccr.pr[PO_SKILL]; GET_ATT_POINTS(CH) = d->ccr.pr[PO_ATTR]/2; - if (d->ccr.pr[PO_MAGIC] > CCR_MAGIC_NONE) { + + if (d->ccr.is_otaku) { + d->ccr.mode = CCR_OTAKU_PATH; + SEND_TO_Q("\r\nFollow the [c]yberadept, or [t]echnoshaman path? Enter '?' for help. ", d); + } else if (d->ccr.pr[PO_MAGIC] > CCR_MAGIC_NONE) { set_attributes(CH, 1); if (GET_RACE(CH) == RACE_GNOME || GET_RACE(CH) == RACE_DRYAD) { GET_TRADITION(CH) = TRAD_SHAMANIC; @@ -1452,6 +1511,9 @@ void create_parse(struct descriptor_data *d, const char *arg) d->ccr.points -= d->ccr.pr[PO_RACE]; d->ccr.pr[5] = -1; + // Otaku hardcode removing points + if (d->ccr.is_otaku) d->ccr.points -= 30; + points_menu(d); break; default: @@ -1526,6 +1588,9 @@ void create_parse(struct descriptor_data *d, const char *arg) return; } + // TODO: disabled for testing + // if (d->ccr.is_otaku) d->ccr.prestige_cost += PRESTIGE_CLASS_OTAKU_COST; + SEND_TO_Q("Enter the name of the character to deduct syspoints from: ", d); d->ccr.mode = CCR_PRESTIGE_PAYMENT_GET_NAME; break; @@ -1589,7 +1654,7 @@ void create_parse(struct descriptor_data *d, const char *arg) GET_SYSTEM_POINTS(victim) -= d->ccr.prestige_cost; if (victim->desc) - send_to_char(victim, "^RYou've just spent %d system points on a prestige race. If this is not correct, change your password and notify staff immediately.^n\r\n", d->ccr.prestige_cost); + send_to_char(victim, "^RYou've just spent %d system points on a prestige race/class. If this is not correct, change your password and notify staff immediately.^n\r\n", d->ccr.prestige_cost); mudlog_vfprintf(d->character, LOG_CHEATLOG, "%s/%s spent %d of %s's syspoints to become a %s.", d->host, @@ -1620,6 +1685,7 @@ void create_parse(struct descriptor_data *d, const char *arg) // fall through case CCR_PRESTIGE_RACE_PAID_FOR: { + if (d->ccr.is_otaku) d->ccr.pr[0] = PR_OTAKU; switch (GET_RACE(CH)) { case RACE_HUMAN: d->ccr.pr[4] = PR_RACE; @@ -1973,6 +2039,11 @@ void create_parse(struct descriptor_data *d, const char *arg) case CCR_PRIORITY: switch (LOWER(*arg)) { case 'a': + if (d->ccr.is_otaku) { + send_to_char(CH, "Sorry, you cannot change this due to code limitations. If you need to change it, please reconnect and restart creation.\r\n"); + priority_menu(d); + break; + } case 'b': case 'c': case 'd': @@ -1996,6 +2067,11 @@ void create_parse(struct descriptor_data *d, const char *arg) set_attributes(d->character, 1); else set_attributes(d->character, 0); + if (d->ccr.is_otaku) { + d->ccr.mode = CCR_OTAKU_PATH; + SEND_TO_Q("\r\nFollow the [c]yberadept, or [t]echnoshaman path? Enter '?' for help. ", d); + return; + } if (d->ccr.pr[0] == PR_MAGIC || d->ccr.pr[1] == PR_MAGIC) { if (GET_RACE(d->character) == RACE_GNOME || GET_RACE(CH) == RACE_DRYAD) { GET_TRADITION(d->character) = TRAD_SHAMANIC; @@ -2010,7 +2086,7 @@ void create_parse(struct descriptor_data *d, const char *arg) d->ccr.mode = CCR_TRADITION; SEND_TO_Q("\r\nFollow [h]ermetic, [s]hamanic or som[a]tic (Adept) magical tradition? Enter '?' for help. ", d); } - return; + return; } else GET_TRADITION(d->character) = TRAD_MUNDANE; start_game(d, "create_parse 'p'"); @@ -2037,6 +2113,33 @@ void create_parse(struct descriptor_data *d, const char *arg) priority_menu(d); break; + case CCR_OTAKU_PATH: + #define PATH_HELP_STRING "\r\nCyberadepts express their connection to the matrix in a formulaic and rational way. Their complex forms are more potent." \ + "\r\n" \ + "\r\nTechnoshamans commune with the matrix in a more magical way. The natural way in which they interact with the matrix makes it easier to channel and command." \ + "\r\n" \ + "\r\nEnter C to select Cyberadept, or T to select Technoshaman: " + if (isalpha(*arg) && isalpha(*(arg+1))) { + snprintf(buf, sizeof(buf), "\r\nARG: '%s'\r\n", arg); + SEND_TO_Q(buf, d); + SEND_TO_Q(PATH_HELP_STRING, d); + } else { + switch (LOWER(*arg)) { + case 'c': + GET_OTAKU_PATH(d->character) = OTAKU_PATH_CYBERADEPT; + start_game(d, "create_parse otaku_path 'c'"); + break; + case 't': + GET_OTAKU_PATH(d->character) = OTAKU_PATH_TECHNOSHAM; + start_game(d, "create_parse otaku_path 't'"); + break; + default: + SEND_TO_Q(PATH_HELP_STRING, d); + break; + } + } + break; + case CCR_TRADITION: #define TRADITION_HELP_STRING "\r\nHermetic mages focus on magic as a science. Their conjured elementals are powerful, but expensive to bring forth." \ "\r\n" \ @@ -2164,6 +2267,8 @@ void refund_chargen_prestige_syspoints_if_needed(struct char_data *ch) { refund_amount = PRESTIGE_RACE_DRAGON_COST; } else if (GET_RACE(ch) == RACE_DRYAD) { refund_amount = PRESTIGE_RACE_DRYAD_COST; + } else if (IS_OTAKU(ch)) { + refund_amount = PRESTIGE_CLASS_OTAKU_COST; } if (!refund_amount) diff --git a/src/chargen.hpp b/src/chargen.hpp index ff4ed8b25..4f2aded0c 100644 --- a/src/chargen.hpp +++ b/src/chargen.hpp @@ -24,6 +24,7 @@ #define CCR_PRESTIGE_PAYMENT_GET_NAME 18 #define CCR_PRESTIGE_PAYMENT_GET_PASS 19 #define CCR_PRESTIGE_RACE_PAID_FOR 20 +#define CCR_OTAKU_PATH 21 #define PO_RACE 0 #define PO_ATTR 1 @@ -41,5 +42,8 @@ #define NUM_CCR_PR_POINTS 6 +/* Special value for Otaku assignment */ +#define PR_OTAKU 6 + void refund_chargen_prestige_syspoints_if_needed(struct char_data *ch); #endif diff --git a/src/config.hpp b/src/config.hpp index 872d39cdd..ff14b50a1 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -210,6 +210,7 @@ extern const char *CHARACTER_DELETED_NAME_FOR_SQL; #define FAILED_SPELL_LEARNING_WAIT_STATE (0.25 RL_SEC) #define INITIATION_CAP 50 +#define SUBMERSION_CAP 50 #define RITUAL_SPELL_BASE_TIME 3 #define RITUAL_SPELL_COMPONENT_COST 500 @@ -302,9 +303,10 @@ extern const char *CHARACTER_DELETED_NAME_FOR_SQL; #define COST_TO_DECORATE_APT 5000 #define COST_TO_DECORATE_VEH 1500 -// Prestige race costs. +// Prestige race/class costs. #define MIN_PRESTIGE_RACE_COST 25 #define PRESTIGE_RACE_GHOUL_COST 25 +#define PRESTIGE_CLASS_OTAKU_COST 30 #define PRESTIGE_RACE_DRYAD_COST 50 #define PRESTIGE_RACE_DRAKE_COST 500 #define PRESTIGE_RACE_DRAGON_COST 1000 diff --git a/src/constants.cpp b/src/constants.cpp index f8e2f5415..acb66a7b0 100644 --- a/src/constants.cpp +++ b/src/constants.cpp @@ -2,6 +2,7 @@ #include "awake.hpp" #include "newmagic.hpp" #include "networth.hpp" +#include "otaku.hpp" const char *awakemud_version[] = { @@ -615,6 +616,7 @@ const char *player_bits[] = "TEMPORARILY_LOADED", "CDEX_DONE", "CLOUD_HATER", + "SUBMERSION", "\n" }; @@ -881,6 +883,7 @@ const char *affected_bits[] = "Voice Modulator", "Wearing DocWagon Receiver", "Cheatlog Mark", + "Complex Form Design", MAX_FLAG_MARKER }; @@ -942,6 +945,8 @@ const char *connected_types[] = "Creating Art", "Account Editing", "Faction Editing", + "Creating Complex Form", + "Increasing Submersion", "\n" }; @@ -1107,6 +1112,7 @@ const char *item_types[] = "Destroyable", "Loaded Decoration", "Art", + "Complex Form", "\n" }; @@ -1183,6 +1189,7 @@ const char *extra_bits[] = "CHEATLOG_MARK", "CONCEALED_IN_EQ", "TRODE_NET", + "OTAKU_BS", MAX_FLAG_MARKER }; @@ -1224,6 +1231,7 @@ const char *pc_readable_extra_bits[] = "Doesn't Save", // Deliberate -- concealing cheatlog mark "Concealed in Equipment", "Is Electrode Net", + "Is Virtual Otaku Item", MAX_FLAG_MARKER }; @@ -1658,161 +1666,166 @@ const char *adept_powers[] = struct skill_data skills[] = { - // name, linked attribute, active/knowledge, magic, group, reflex, nodflt - {"OMGWTFBBQ", BOD, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Athletics", BOD, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Armed Combat", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Edged Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, 2, TRUE , FALSE }, - {"Pole Arms", STR, SKILL_TYPE_ACTIVE, FALSE, 2, TRUE , FALSE }, - {"Whips and Flails", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Clubs", STR, SKILL_TYPE_ACTIVE, FALSE, 2, TRUE , FALSE }, - {"Brawling", STR, SKILL_TYPE_ACTIVE, FALSE, 4, TRUE , FALSE }, - {"Centering", WIL, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, FALSE }, - {"Cyber Implants", STR, SKILL_TYPE_ACTIVE, FALSE, 4, TRUE , FALSE }, - {"Firearms", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Pistols", QUI, SKILL_TYPE_ACTIVE, FALSE, 5, TRUE , FALSE }, - {"Rifles", QUI, SKILL_TYPE_ACTIVE, FALSE, 5, TRUE , FALSE }, - {"Shotguns", QUI, SKILL_TYPE_ACTIVE, FALSE, 5, TRUE , FALSE }, - {"Assault Rifles", QUI, SKILL_TYPE_ACTIVE, FALSE, 5, TRUE , FALSE }, - {"Submachine Guns", QUI, SKILL_TYPE_ACTIVE, FALSE, 5, TRUE , FALSE }, - {"Grenade Launchers", INT, SKILL_TYPE_ACTIVE, FALSE, 6, FALSE, FALSE }, - {"Tasers", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Mounted Gunnery", INT, SKILL_TYPE_ACTIVE, FALSE, 6, FALSE, FALSE }, - {"Machine Guns", STR, SKILL_TYPE_ACTIVE, FALSE, 1, TRUE , FALSE }, - {"Missile Launchers", INT, SKILL_TYPE_ACTIVE, FALSE, 6, FALSE, FALSE }, - {"Assault Cannons", STR, SKILL_TYPE_ACTIVE, FALSE, 1, TRUE , FALSE }, - {"Artillery", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Projectile Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Oral Strike", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Spell Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Throwing Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Enchanting", WIL, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, FALSE }, - {"Cyberterminal Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Demolitions", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Computers", INT, SKILL_TYPE_ACTIVE, FALSE, 7, FALSE, FALSE }, - {"Electronics", INT, SKILL_TYPE_ACTIVE, FALSE, 7, TRUE , FALSE }, - {"Computer Building and Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Biotech", INT, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Electronics Building and Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Talismongering", INT, SKILL_TYPE_KNOWLEDGE, TRUE , 99, FALSE, FALSE }, - {"Police Procedures", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Leadership", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Interrogation", CHA, SKILL_TYPE_ACTIVE, FALSE, 8, FALSE, FALSE }, - {"Negotiation", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Chanting", CHA, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, FALSE }, - {"Conjuring", WIL, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, TRUE }, - {"Sorcery", WIL, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, TRUE }, - {"Legerdemain", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Corporate Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Media Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Street Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Tribal Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Elf Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Combat Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Defensive Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Operational Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Special Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Cyberterminal Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Data Brokerage", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Aura Reading", INT, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, TRUE }, - {"Stealth", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Steal", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Track", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Climbing", BOD, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Driving Motorcycles", REA, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"zzzzzzzzzzzzzz", REA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, // unused skill - {"Driving Cars", REA, SKILL_TYPE_ACTIVE, FALSE, 10, TRUE , FALSE }, - {"Driving Trucks", REA, SKILL_TYPE_ACTIVE, FALSE, 99, TRUE , FALSE }, - {"Repairing Motorcycles", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Cars", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Drones", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Trucks", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Dancing", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Singing", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Instrument", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Arcane Language", INT, SKILL_TYPE_KNOWLEDGE, TRUE , 99, FALSE, FALSE }, - {"Meditation", WIL, SKILL_TYPE_ACTIVE, TRUE , 99, FALSE, FALSE }, - {"English", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Sperethiel", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Spanish", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Japanese", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Cantonese", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Korean", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Italian", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Russian", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Sioux", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Makaw", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Crow", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Salish", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Ute", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Navajo", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"German", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Or'zet", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Arabic", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Latin", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Gaelic", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"French", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Animal Handling", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Animal Taming", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Edged Weapon Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Polearm Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Club Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Throwing Weapon Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Whips/Flail Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Projectile Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Pistol Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, 13, FALSE, FALSE }, - {"Shotgun Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, 13, FALSE, FALSE }, - {"Rifle Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, 13, FALSE, FALSE }, - {"Heavy Weapon Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Submachine Gun Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, 13, FALSE, FALSE }, - {"Armor Repair", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Off-hand Edged Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Off-hand Clubs", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Off-hand Cyber Implants", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Off-hand Whips/Flails", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Survival", WIL, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Land Navigation", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Water Navigation", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Air Navigation", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Small Unit Tactics", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Chemistry", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Diving", BOD, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Parachuting", BOD, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Underwater Combat", STR, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Piloting Rotorcraft", REA, SKILL_TYPE_ACTIVE, FALSE, 9, FALSE, FALSE }, - {"Piloting Fixed Wing Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, 9, FALSE, FALSE }, - {"Piloting Vector Thrust Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, 9, FALSE, FALSE }, - {"Acting", CHA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Disguise", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Lock Picking", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Riding", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Spray Weapons", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Intimidation", CHA, SKILL_TYPE_ACTIVE, FALSE, 8, FALSE, FALSE }, - {"Gun Cane", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Bracer Gun", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Blowgun", QUI, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Pharmaceuticals", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Hebrew", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Iroquois", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Medicine", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Repairing Fixed Wing Aircraft", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Rotorcraft", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Vector Thrust Aircraft", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Hovercraft", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Motorboats", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Ships", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Repairing Lighter-than-Air Aircraft", INT, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Piloting Hovercraft", REA, SKILL_TYPE_ACTIVE, FALSE, 99, FALSE, FALSE }, - {"Piloting Motorboats", REA, SKILL_TYPE_ACTIVE, FALSE, 12, FALSE, FALSE }, - {"Piloting Ships", REA, SKILL_TYPE_ACTIVE, FALSE, 12, FALSE, FALSE }, - {"Piloting Lighter-than-Air Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, 9, FALSE, FALSE }, - {"Mechanical Arm Operation", REA, SKILL_TYPE_ACTIVE, FALSE, 11, FALSE, FALSE }, - {"Piloting Semiballistic Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, 9, FALSE, FALSE }, - {"Piloting Suborbital Craft", REA, SKILL_TYPE_ACTIVE, FALSE, 9, FALSE, FALSE }, - {"Piloting Tracked Vehicles", REA, SKILL_TYPE_ACTIVE, FALSE, 10, FALSE, FALSE }, - {"Piloting Walkers", REA, SKILL_TYPE_ACTIVE, FALSE, 11, FALSE, FALSE }, - {"Mandarin", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, - {"Haitian Creole", INT, SKILL_TYPE_KNOWLEDGE, FALSE, 99, FALSE, FALSE }, + // name, linked attribute, active/knowledge, magic, resonance, group, reflex, nodflt + {"OMGWTFBBQ", BOD, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Athletics", BOD, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Armed Combat", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Edged Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 2, TRUE , FALSE }, + {"Pole Arms", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 2, TRUE , FALSE }, + {"Whips and Flails", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Clubs", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 2, TRUE , FALSE }, + {"Brawling", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 4, TRUE , FALSE }, + {"Centering", WIL, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, FALSE }, + {"Cyber Implants", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 4, TRUE , FALSE }, + {"Firearms", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Pistols", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 5, TRUE , FALSE }, + {"Rifles", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 5, TRUE , FALSE }, + {"Shotguns", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 5, TRUE , FALSE }, + {"Assault Rifles", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 5, TRUE , FALSE }, + {"Submachine Guns", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 5, TRUE , FALSE }, + {"Grenade Launchers", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 6, FALSE, FALSE }, + {"Tasers", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Mounted Gunnery", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 6, FALSE, FALSE }, + {"Machine Guns", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 1, TRUE , FALSE }, + {"Missile Launchers", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 6, FALSE, FALSE }, + {"Assault Cannons", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 1, TRUE , FALSE }, + {"Artillery", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Projectile Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Oral Strike", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Spell Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Throwing Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Enchanting", WIL, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, FALSE }, + {"Cyberterminal Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Demolitions", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Computers", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 7, FALSE, FALSE }, + {"Electronics", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 7, TRUE , FALSE }, + {"Computer Building and Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Biotech", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Electronics Building and Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Talismongering", INT, SKILL_TYPE_KNOWLEDGE, TRUE , FALSE, 99, FALSE, FALSE }, + {"Police Procedures", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Leadership", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Interrogation", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 8, FALSE, FALSE }, + {"Negotiation", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Chanting", CHA, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, FALSE }, + {"Conjuring", WIL, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, TRUE }, + {"Sorcery", WIL, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, TRUE }, + {"Legerdemain", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Corporate Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Media Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Street Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Tribal Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Elf Etiquette", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Combat Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Defensive Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Operational Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Special Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Cyberterminal Program Design", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Data Brokerage", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Aura Reading", INT, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, TRUE }, + {"Stealth", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Steal", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Track", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Climbing", BOD, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Driving Motorcycles", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"zzzzzzzzzzzzzz", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, // unused skill + {"Driving Cars", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 10, TRUE , FALSE }, + {"Driving Trucks", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, TRUE , FALSE }, + {"Repairing Motorcycles", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Cars", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Drones", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Trucks", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Dancing", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Singing", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Instrument", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Arcane Language", INT, SKILL_TYPE_KNOWLEDGE, TRUE , FALSE, 99, FALSE, FALSE }, + {"Meditation", WIL, SKILL_TYPE_ACTIVE, TRUE , FALSE, 99, FALSE, FALSE }, + {"English", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Sperethiel", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Spanish", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Japanese", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Cantonese", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Korean", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Italian", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Russian", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Sioux", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Makaw", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Crow", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Salish", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Ute", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Navajo", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"German", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Or'zet", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Arabic", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Latin", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Gaelic", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"French", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Animal Handling", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Animal Taming", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Edged Weapon Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Polearm Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Club Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Throwing Weapon Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Whips/Flail Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Projectile Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Pistol Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 13, FALSE, FALSE }, + {"Shotgun Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 13, FALSE, FALSE }, + {"Rifle Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 13, FALSE, FALSE }, + {"Heavy Weapon Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Submachine Gun Repair and Ammo Crafting", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 13, FALSE, FALSE }, + {"Armor Repair", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Off-hand Edged Weapons", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Off-hand Clubs", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Off-hand Cyber Implants", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Off-hand Whips/Flails", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Survival", WIL, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Land Navigation", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Water Navigation", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Air Navigation", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Small Unit Tactics", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Chemistry", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Diving", BOD, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Parachuting", BOD, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Underwater Combat", STR, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Piloting Rotorcraft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 9, FALSE, FALSE }, + {"Piloting Fixed Wing Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 9, FALSE, FALSE }, + {"Piloting Vector Thrust Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 9, FALSE, FALSE }, + {"Acting", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Disguise", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Lock Picking", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Riding", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Spray Weapons", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Intimidation", CHA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 8, FALSE, FALSE }, + {"Gun Cane", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Bracer Gun", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Blowgun", QUI, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Pharmaceuticals", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Hebrew", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Iroquois", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Medicine", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Fixed Wing Aircraft", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Rotorcraft", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Vector Thrust Aircraft", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Hovercraft", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Motorboats", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Ships", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Repairing Lighter-than-Air Aircraft", INT, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Piloting Hovercraft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Piloting Motorboats", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 12, FALSE, FALSE }, + {"Piloting Ships", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 12, FALSE, FALSE }, + {"Piloting Lighter-than-Air Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 9, FALSE, FALSE }, + {"Mechanical Arm Operation", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 11, FALSE, FALSE }, + {"Piloting Semiballistic Aircraft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 9, FALSE, FALSE }, + {"Piloting Suborbital Craft", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 9, FALSE, FALSE }, + {"Piloting Tracked Vehicles", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 10, FALSE, FALSE }, + {"Piloting Walkers", REA, SKILL_TYPE_ACTIVE, FALSE, FALSE, 11, FALSE, FALSE }, + {"Mandarin", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Haitian Creole", INT, SKILL_TYPE_KNOWLEDGE, FALSE, FALSE, 99, FALSE, FALSE }, + {"Channel Access", WIL, SKILL_TYPE_ACTIVE, FALSE, TRUE , 99, FALSE, FALSE }, + {"Channel Control", WIL, SKILL_TYPE_ACTIVE, FALSE, TRUE , 99, FALSE, FALSE }, + {"Channel Index", WIL, SKILL_TYPE_ACTIVE, FALSE, TRUE , 99, FALSE, FALSE }, + {"Channel Files", WIL, SKILL_TYPE_ACTIVE, FALSE, TRUE , 99, FALSE, FALSE }, + {"Channel Slave", WIL, SKILL_TYPE_ACTIVE, FALSE, TRUE , 99, FALSE, FALSE }, }; int rev_dir[] = @@ -2813,6 +2826,21 @@ const char *metamagic[] = { "Anchoring" }; +struct otaku_echo echoes[] = { + {"UNDEF", FALSE}, + {"Improved I/O Speed", TRUE}, + {"Improved Hardening", TRUE}, + {"Improved MPCP", TRUE}, + {"Improved Persona Bod", TRUE}, + {"Improved Persona Evasion", TRUE}, + {"Improved Persona Masking", TRUE}, + {"Improved Persona Sensor", TRUE}, + {"Improved Reaction", TRUE}, + {"Ghosting", FALSE}, + {"Neurofilter", FALSE}, + {"Overclock", FALSE} +}; + const char *legality_codes[][2] = { { "*", "Nothing" }, { "A", "Small Blade" }, diff --git a/src/deck_build.cpp b/src/deck_build.cpp index 3984a709f..f661c386f 100644 --- a/src/deck_build.cpp +++ b/src/deck_build.cpp @@ -1146,6 +1146,14 @@ ACMD(do_progress) return; } + if (AFF_FLAGS(ch).IsSet(AFF_COMPLEX_FORM_PROGRAM)) { + int timeleft = GET_OBJ_VAL(GET_BUILDING(ch), 5); + int amount_needed = GET_OBJ_TIMER(GET_BUILDING(ch)); + send_to_char(ch, "You are about %2.2f%% of the way through learning %s.\r\n", + (((float)(amount_needed - amount_left) * 100) / amount_needed), GET_OBJ_NAME(GET_BUILDING(ch))); + return; + } + if (AFF_FLAGS(ch).IsSet(AFF_SPELLDESIGN)) { int timeleft = GET_SPELLFORMULA_TIME_LEFT(ch->char_specials.programming); if (GET_OBJ_TIMER(ch->char_specials.programming) == SPELL_DESIGN_FAILED_CODE) diff --git a/src/interpreter.cpp b/src/interpreter.cpp index 6c9819875..315a17b59 100644 --- a/src/interpreter.cpp +++ b/src/interpreter.cpp @@ -77,6 +77,7 @@ void zedit_parse(struct descriptor_data *d, const char *arg); void hedit_parse(struct descriptor_data *d, const char *arg); void icedit_parse(struct descriptor_data *d, const char *arg); void pedit_parse(struct descriptor_data *d, const char *arg); +void cfedit_parse(struct descriptor_data *d, const char *arg); void dbuild_parse(struct descriptor_data *d, const char *arg); void pbuild_parse(struct descriptor_data *d, const char *arg); void spedit_parse(struct descriptor_data *d, const char *arg); @@ -246,6 +247,7 @@ ACMD_DECLARE(do_iload); ACMD_DECLARE(do_imagelink); ACMD_DECLARE(do_info); ACMD_DECLARE(do_initiate); +ACMD_DECLARE(do_submerse); ACMD_DECLARE(do_insult); ACMD_DECLARE(do_inventory); ACMD_DECLARE(do_invis); @@ -2726,6 +2728,9 @@ void nanny(struct descriptor_data * d, char *arg) case CON_PRO_CREATE: pedit_parse(d, arg); break; + case CON_CF_CREATE: + cfedit_parse(d, arg); + break; case CON_PART_CREATE: pbuild_parse(d, arg); break; diff --git a/src/newdb.cpp b/src/newdb.cpp index 28147bc1c..b6f98db73 100644 --- a/src/newdb.cpp +++ b/src/newdb.cpp @@ -480,6 +480,7 @@ bool load_char(const char *name, char_data *ch, bool logon, int pc_load_origin) SETTABLE_EMAIL(ch) = str_dup(row[80]); GET_CHAR_MULTIPLIER(ch) = atoi(row[81]); const char *lifestyle_string = str_dup(row[82]); + GET_OTAKU_PATH(ch) = atoi(row[83]); mysql_free_result(res); // Update lifestyle information. diff --git a/src/newmatrix.cpp b/src/newmatrix.cpp index e75c04436..7b267b7e0 100644 --- a/src/newmatrix.cpp +++ b/src/newmatrix.cpp @@ -29,6 +29,7 @@ extern void create_deck(struct char_data *ch); extern void create_spell(struct char_data *ch); extern void create_ammo(struct char_data *ch); extern void create_art(struct char_data *ch); +extern void create_complex_form(struct char_data *ch); ACMD_DECLARE(do_look); @@ -205,6 +206,10 @@ void roll_matrix_init(struct matrix_icon *icon) // Matrix pg 18 & 24, available bonuses are response increase, reality filter, and hot asist init_dice += GET_INIT_DICE(icon->decker->ch) + icon->decker->response + (icon->decker->reality ? 1 : 0) + (icon->decker->asist[0] ? 1 : 0); + if (icon->type == ICON_LIVING_PERSONA) { + init_dice = MIN(5, init_dice + GET_ECHO(icon->decker->ch, ECHO_OVERCLOCK)); + } + // Apply Matrix 'trode net cap (max init dice 2d6) if (GET_EQ(icon->decker->ch, WEAR_HEAD) && IS_OBJ_STAT(GET_EQ(icon->decker->ch, WEAR_HEAD), ITEM_EXTRA_TRODE_NET)) { init_dice = MIN(init_dice, 2); @@ -358,6 +363,28 @@ int system_test(rnum_t host, struct char_data *ch, int type, int software, int m } int target = HOST.stats[type][MTX_STAT_RATING]; + if (PERSONA->type == ICON_LIVING_PERSONA) { + // We lower the TN by the channel rating + int channel_rating = GET_OTAKU_PATH(ch) == OTAKU_PATH_TECHNOSHAM ? 1 : 0; + switch(type) { + case ACIFS_ACCESS: + channel_rating += GET_SKILL(ch, SKILL_CHANNEL_ACCESS); + break; + case ACIFS_CONTROL: + channel_rating += GET_SKILL(ch, SKILL_CHANNEL_CONTROL); + break; + case ACIFS_FILES: + channel_rating += GET_SKILL(ch, SKILL_CHANNEL_FILES); + break; + case ACIFS_INDEX: + channel_rating += GET_SKILL(ch, SKILL_CHANNEL_INDEX); + break; + case ACIFS_SLAVE: + channel_rating += GET_SKILL(ch, SKILL_CHANNEL_SLAVE); + break; + } + target = MAX(2, target - channel_rating); + } snprintf(rollbuf, sizeof(rollbuf), "System test against %s with software %s: Starting TN %d", acifs_strings[type], programs[software].name, target); int skill = get_skill(ch, SKILL_COMPUTER, target) + MIN(GET_MAX_HACKING(ch), GET_REM_HACKING(ch)); @@ -391,6 +418,9 @@ int system_test(rnum_t host, struct char_data *ch, int type, int software, int m detect += DECKER->masking + 1; // +1 because we round up detect = detect / 2; detect -= DECKER->res_det; + if (PERSONA->type == ICON_LIVING_PERSONA) { + detect -= 1 + GET_ECHO(ch, ECHO_GHOSTING); // Otaku always get +1 DF + } int tally = MAX(0, success_test(HOST.security, detect)); target = MAX(target, 2); @@ -1797,6 +1827,10 @@ ACMD(do_logoff) send_to_char("Your hitcher has disconnected.\r\n", ch); temp->persona->decker->hitcher = NULL; } + // Clear the deck if this is an otaku + if (PERSONA->decker && PERSONA->decker->deck && PERSONA->decker->deck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS)) { + extract_obj(PERSONA->decker->deck); + } return; } if (subcmd) { @@ -1829,11 +1863,15 @@ ACMD(do_logoff) send_to_host(PERSONA->in_host, buf, PERSONA, FALSE); // Cleanup of uploads, downloads, etc is handled in icon_from_host, which is called in extract_icon. - extract_icon(PERSONA); PERSONA = NULL; PLR_FLAGS(ch).RemoveBit(PLR_MATRIX); + // Clear the deck if this is an otaku + if (PERSONA->decker && PERSONA->decker->deck && PERSONA->decker->deck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS)) { + extract_obj(PERSONA->decker->deck); + } + // Make 'em look if they're not screenreaders. if (!PRF_FLAGGED(ch, PRF_SCREENREADER)) { char emptybuf[10] = { '\0' }; @@ -1903,6 +1941,9 @@ ACMD(do_connect) cyberdeck = make_staff_deck_target_mpcp(12); obj_to_char(cyberdeck, ch); send_to_char(ch, "You pull a deck out of thin air to connect with.\r\n"); + } else if (IS_OTAKU(ch)) { + extern struct obj_data *make_otaku_deck(struct char_data *ch); + cyberdeck = make_otaku_deck(ch); } else { send_to_char(ch, "I don't recommend trying to do that without a cyberdeck.\r\n"); return; @@ -1943,7 +1984,8 @@ ACMD(do_connect) if (GET_POS(ch) != POS_SITTING) { GET_POS(ch) = POS_SITTING; - send_to_char(ch, "You find a place to sit and work with your deck.\r\n"); + if (IS_OTAKU(ch)) send_to_char(ch, "You find a place to sit down and commune with the matrix.\r\n"); + else send_to_char(ch, "You find a place to sit and work with your deck.\r\n"); } icon = Mem->GetIcon(); @@ -1960,6 +2002,10 @@ ACMD(do_connect) icon->long_desc = str_dup(ch->player.matrix_text.look_desc); else icon->long_desc = str_dup("A nondescript persona stands idly here.\r\n"); + // If this is an Otaku GhostDeck, then this is a living persona + if (cyberdeck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS)) { + icon->type = ICON_LIVING_PERSONA; + } if (GET_OBJ_TYPE(cyberdeck) == ITEM_CUSTOM_DECK && GET_CYBERDECK_IS_INCOMPLETE(cyberdeck)) { send_to_char(ch, "That deck is missing some components.\r\n"); @@ -2025,7 +2071,8 @@ ACMD(do_connect) // IO is then divided by 10. I've set it to be a minimum of 1 here. DECKER->io = MAX(1, (int)(DECKER->io / 10)); - if (GET_OBJ_VNUM(cyberdeck) != OBJ_CUSTOM_CYBERDECK_SHELL) { + if (GET_OBJ_VNUM(cyberdeck) != OBJ_CUSTOM_CYBERDECK_SHELL + && !cyberdeck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS)) { DECKER->asist[1] = 0; DECKER->asist[0] = 0; GET_MAX_HACKING(ch) = 0; @@ -2051,7 +2098,7 @@ ACMD(do_connect) } } if (GET_OBJ_VAL(soft, 4)) { - if (GET_OBJ_VAL(soft, 2) > DECKER->active) { + if (GET_OBJ_VAL(soft, 2) > DECKER->active && !soft->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS)) { send_to_char(ch, "%s^n would exceed your deck's active memory, so it failed to load.\r\n", GET_OBJ_NAME(soft)); continue; } @@ -2074,15 +2121,19 @@ ACMD(do_connect) switch (GET_OBJ_VAL(soft, 0)) { case PART_BOD: DECKER->bod = GET_OBJ_VAL(soft, 1); + if (PERSONA->type == ICON_LIVING_PERSONA) DECKER->bod = MIN(DECKER->mpcp*1.5, DECKER->bod + GET_ECHO(ch, ECHO_PERSONA_BOD)); break; case PART_SENSOR: DECKER->sensor = GET_OBJ_VAL(soft, 1); + if (PERSONA->type == ICON_LIVING_PERSONA) DECKER->sensor = MIN(DECKER->mpcp*1.5, DECKER->sensor + GET_ECHO(ch, ECHO_PERSONA_SENS)); break; case PART_MASKING: DECKER->masking = GET_OBJ_VAL(soft, 1); + if (PERSONA->type == ICON_LIVING_PERSONA) DECKER->masking = MIN(DECKER->mpcp*1.5, DECKER->masking + GET_ECHO(ch, ECHO_PERSONA_MASK)); break; case PART_EVASION: DECKER->evasion = GET_OBJ_VAL(soft, 1); + if (PERSONA->type == ICON_LIVING_PERSONA) DECKER->evasion = MIN(DECKER->mpcp*1.5, DECKER->evasion + GET_ECHO(ch, ECHO_PERSONA_EVAS)); break; case PART_ASIST_HOT: DECKER->asist[1] = 1; @@ -2111,7 +2162,7 @@ ACMD(do_connect) PERSONA->next = icon_list; icon_list = PERSONA; icon_to_host(PERSONA, host); - if (DECKER->bod + DECKER->sensor + DECKER->evasion + DECKER->masking > DECKER->mpcp * 3) { + if (PERSONA->type != ICON_LIVING_PERSONA && (DECKER->bod + DECKER->sensor + DECKER->evasion + DECKER->masking > DECKER->mpcp * 3)) { send_to_char(ch, "Your deck overloads on persona programs and crashes. You'll have to keep the combined bod, sensor, evasion, and masking rating less than or equal to %d.\r\n", DECKER->mpcp * 3); extract_icon(PERSONA); PERSONA = NULL; @@ -2139,12 +2190,15 @@ ACMD(do_connect) if (GET_OBJ_TYPE(jack) == ITEM_CYBERWARE) { if (GET_CYBERWARE_TYPE(jack) == CYB_DATAJACK) { if (GET_CYBERWARE_FLAGS(jack) == DATA_INDUCTION) { - snprintf(buf, sizeof(buf), "$n places $s hand over $s induction pad as $e connects to $s cyberdeck."); + snprintf(buf, sizeof(buf), "$n places $s hand over $s induction pad as $e connects to %s.", + cyberdeck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS) ? "the jackpoint" : "$s cyberdeck"); } else { - snprintf(buf, sizeof(buf), "$n slides one end of the cable into $s datajack and the other into $s cyberdeck."); + snprintf(buf, sizeof(buf), "$n slides one end of the cable into $s datajack and the other into %s.", + cyberdeck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS) ? "the jackpoint" : "$s cyberdeck"); } } else { - snprintf(buf, sizeof(buf), "$n's eye opens up as $e slides $s cyberdeck cable into $s eye datajack."); + snprintf(buf, sizeof(buf), "$n's eye opens up as $e slides %s cable into $s eye datajack.", + cyberdeck->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS) ? "the jackpoint" : "$s cyberdeck"); } } else { snprintf(buf, sizeof(buf), "$n plugs the leads of $s 'trode net into $s cyberdeck."); @@ -2171,6 +2225,10 @@ ACMD(do_load) } skip_spaces(&argument); if (subcmd == SCMD_UNLOAD) { + if (PERSONA->type == ICON_LIVING_PERSONA) { + send_to_icon(PERSONA, "You don't have active memory to erase things from.\r\n"); + return; + } struct obj_data *temp = NULL; for (struct obj_data *soft = DECKER->software; soft; soft = soft->next_content) { if (keyword_appears_in_obj(argument, soft)) { @@ -2197,7 +2255,8 @@ ACMD(do_load) continue; if (subcmd == SCMD_UPLOAD) { - if (GET_OBJ_TYPE(soft) == ITEM_PROGRAM && (GET_PROGRAM_TYPE(soft) <= SOFT_SENSOR || GET_PROGRAM_TYPE(soft) == SOFT_EVALUATE)) { + if (GET_OBJ_TYPE(soft) == ITEM_PROGRAM && (GET_PROGRAM_TYPE(soft) <= SOFT_SENSOR || GET_PROGRAM_TYPE(soft) == SOFT_EVALUATE + || soft->obj_flags.extra_flags.IsSet(ITEM_EXTRA_OTAKU_BS))) { send_to_icon(PERSONA, "You can't upload %s^n.\r\n", GET_OBJ_NAME(soft)); return; } @@ -3722,7 +3781,16 @@ ACMD(do_create) } argument = any_one_arg(argument, buf1); - if (is_abbrev(buf1, "program")) { + if (is_abbrev(buf1, "complex form")) + { + if (!IS_OTAKU(ch)) { + send_to_char("Everyone knows that otaku aren't real, chummer.\r\n", ch); + return; + } + create_complex_form(ch); + } + + else if (is_abbrev(buf1, "program")) { if (!GET_SKILL(ch, SKILL_COMPUTER)) { send_to_char("You must learn computer skills to create programs.\r\n", ch); return; @@ -3771,7 +3839,7 @@ ACMD(do_create) } else { - send_to_char("You can only create programs, parts, decks, ammunition, spells, and art.\r\n", ch); + send_to_char("You can only create programs, parts, decks, ammunition, spells, complex forms, and art.\r\n", ch); return; } } @@ -3801,6 +3869,8 @@ ACMD(do_asist) { if (!PERSONA) send_to_char("You can't do that while hitching.\r\n", ch); + else if (PERSONA->type == ICON_LIVING_PERSONA) + send_to_char("You can't switch ASIST modes while using a living persona.\r\n", ch); else if (!DECKER->asist[1]) send_to_char("You can't switch ASIST modes with a cold ASIST interface.\r\n", ch); else if (DECKER->asist[0]) { diff --git a/src/newmatrix.hpp b/src/newmatrix.hpp index 6b90b8a0c..9afca6682 100644 --- a/src/newmatrix.hpp +++ b/src/newmatrix.hpp @@ -14,6 +14,9 @@ #define FILE_PROTECTION_SCRAMBLED 1 +#define ICON_MATRIX 0 // This is just a normal persona or icon +#define ICON_LIVING_PERSONA 1 // Weird otaku BS living persona + #define IC_CRIPPLER 0 // Destroys programs. #define IC_KILLER 1 // NERP #define IC_PROBE 2 // NERP @@ -229,6 +232,7 @@ struct matrix_icon { char *long_desc; char *look_desc; + byte type; int idnum; rnum_t rnum; vnum_t vnum; @@ -250,8 +254,8 @@ struct matrix_icon { #endif matrix_icon(): - name(NULL), long_desc(NULL), look_desc(NULL), idnum(0), rnum(0), vnum(0), - condition(10), initiative(0), parry(0), evasion(0), position(0), + name(NULL), long_desc(NULL), look_desc(NULL), type(ICON_MATRIX), idnum(0), rnum(0), + vnum(0), condition(10), initiative(0), parry(0), evasion(0), position(0), decker(NULL), fighting(NULL), next(NULL), next_in_host(NULL), next_fighting(NULL) { #ifdef USE_DEBUG_CANARIES diff --git a/src/otaku.cpp b/src/otaku.cpp new file mode 100644 index 000000000..b1ef9f95d --- /dev/null +++ b/src/otaku.cpp @@ -0,0 +1,197 @@ +#include +#include + +#include "otaku.hpp" +#include "structs.hpp" +#include "awake.hpp" +#include "db.hpp" +#include "comm.hpp" +#include "interpreter.hpp" +#include "handler.hpp" +#include "utils.hpp" +#include "screen.hpp" +#include "constants.hpp" +#include "olc.hpp" +#include "config.hpp" +#include "ignore_system.hpp" +#include "newdb.hpp" +#include "playerdoc.hpp" +#include "newhouse.hpp" +#include "quest.hpp" + +extern struct otaku_echo echoes[]; + +long calculate_sub_nuyen_cost(int desired_grade) { + if (desired_grade >= 6) + return 825000; + else + return 25000 + (25000 * (1 << (desired_grade - 1))); +} + +bool submersion_cost(struct char_data *ch, bool spend) +{ + int desired_grade = GET_GRADE(ch) + 1; + long karmacost = (desired_grade + 5) * 300; + long nuyencost = calculate_sub_nuyen_cost(desired_grade); + + if (karmacost < 0) { + send_to_char("Congratulations, you've hit the ceiling! You can't increase submersion until the code is fixed to allow someone at your rank to do so.\r\n", ch); + mudlog_vfprintf(ch, LOG_SYSLOG, "lol init capped at %d for %s, karma overflowed... this game was not designed for that init level", GET_GRADE(ch), GET_CHAR_NAME(ch)); + return FALSE; + } + + long tke = 0; + if (karmacost > GET_KARMA(ch) || (GET_KARMA(ch) - karmacost) > GET_KARMA(ch)) { + send_to_char(ch, "You do not have enough karma to increase submersion. It will cost you %.2f karma.\r\n", ((float) karmacost / 100)); + return FALSE; + } + if (nuyencost > GET_NUYEN(ch) || (GET_NUYEN(ch) - nuyencost) > GET_NUYEN(ch)) { + send_to_char(ch, "You do not have enough nuyen to increase submersion. It will cost you %ld nuyen.\r\n", nuyencost); + return FALSE; + } + + switch (desired_grade) { + case 1: + tke = 0; + break; + case 2: + tke = 100; + break; + case 3: + tke = 200; + break; + default: + tke = 200 + ((GET_GRADE(ch)-2)*200); + break; + } + if (tke > GET_TKE(ch)) { + send_to_char(ch, "You do not have high enough TKE to initiate. You need %ld TKE.\r\n", tke); + return FALSE; + } + if (spend) { + lose_nuyen(ch, nuyencost, NUYEN_OUTFLOW_INITIATION); + GET_KARMA(ch) -= karmacost; + } + return TRUE; +} + +void disp_submersion_menu(struct descriptor_data *d) +{ + CLS(CH); + send_to_char("1) Increase submersion grade\r\n" + "2) Learn a new echo\r\n" + "3) Return to game\r\n" + "Enter initiation option: ", CH); + d->edit_mode = SUBMERSION_MAIN; +} + +ACMD(do_submerse) +{ + FAILURE_CASE(!IS_OTAKU(ch), "Sorry, submersions are for otaku characters only."); + + skip_spaces(&argument); + + if (subcmd == SCMD_SUBMERSE && submersion_cost(ch, FALSE)) { + // Enforce grade restrictions. We can't do this init_cost since it's used elsewhere. + if ((GET_GRADE(ch) + 1) > SUBMERSION_CAP) { + send_to_char("Congratulations, you've reached the submersion cap! You're not able to advance further.\r\n", ch); + return; + } + + // Check to see that they can afford it. This sends its own message. + if (!submersion_cost(ch, FALSE)) { + return; + } + STATE(ch->desc) = CON_SUBMERSION; + PLR_FLAGS(ch).SetBit(PLR_SUBMERSION); + disp_submersion_menu(ch->desc); + return; + } +} + +bool can_select_echo(struct char_data *ch, int i) +{ + // Count our grades vs selected echos so we can't learn more than we have grades + int available_echoes = GET_GRADE(ch); + for (int i = 1; i < ECHO_MAX; i++) { + available_echoes -= GET_ECHO(ch, i); + } + if (available_echoes <= 0) + return FALSE; + // incremental echoes can be selected an arbitrary number of times + if (echoes[i].incremental) + return TRUE; + // otherwise static echoes only once + if (GET_ECHO(ch, i)) + return FALSE; + return TRUE; +} + +void disp_echo_menu(struct descriptor_data *d) +{ + CLS(CH); + for (int i = 1; i < ECHO_MAX; i++) { + if (PRF_FLAGGED(CH, PRF_SCREENREADER)) { + send_to_char(CH, "%d) %s%s^n\r\n", i, echoes[i], can_select_echo(CH, i) ? " (can learn)" : " (cannot learn)"); + } else { + send_to_char(CH, "%d) %s%s^n\r\n", i, can_select_echo(CH, i) ? "" : "^r", echoes[i]); + } + } + + send_to_char("q) Quit \r\nSelect echo to learn: ", CH); + d->edit_mode = SUBMERSION_ECHO; +} + +void submersion_parse(struct descriptor_data *d, char *arg) +{ + struct obj_data *obj = NULL; + int number, i; + switch (d->edit_mode) + { + case SUBMERSION_MAIN: + switch (*arg) + { + case '1': + submersion_cost(CH, FALSE); + send_to_char("Are you sure you want to increase your submersion? Type 'y' to continue, anything else to abort.\r\n", CH); + d->edit_mode = SUBMERSION_CONFIRM; + break; + case '2': + disp_echo_menu(d); + break; + case '3': + STATE(d) = CON_PLAYING; + PLR_FLAGS(CH).RemoveBit(PLR_INITIATE); + send_to_char("Submersion cancelled.\r\n", CH); + break; + default: + disp_submersion_menu(d); + break; + } + break; + case SUBMERSION_CONFIRM: + if (*arg == 'y') { + GET_GRADE(CH)++; + send_to_char(CH, "You feel yourself grow closer to the resonance, opening new echoes for you to learn.\r\n"); + STATE(d) = CON_PLAYING; + PLR_FLAGS(CH).RemoveBit(PLR_SUBMERSION); + } else { + disp_submersion_menu(d); + } + break; + case SUBMERSION_ECHO: + // learning a new echo here + number = atoi(arg); + if (number >= ECHO_MAX) + send_to_char("Invalid Response. Select another echo to unlock: ", CH); + else if (!can_select_echo(CH, number)) + send_to_char("You aren't able to learn that echo at this time. Select another echo to learn: ", CH); + else { + SET_ECHO(CH, number, GET_ECHO(CH, number) + 1); + send_to_char(CH, "New ways to manipulate the resonance open up before you as you learn %s.\r\n", echoes[number].name); + STATE(d) = CON_PLAYING; + PLR_FLAGS(CH).RemoveBit(PLR_SUBMERSION); + } + break; + } +} \ No newline at end of file diff --git a/src/otaku.hpp b/src/otaku.hpp new file mode 100644 index 000000000..7569f1211 --- /dev/null +++ b/src/otaku.hpp @@ -0,0 +1,13 @@ +#ifndef __otaku_h__ +#define __otaku_h__ + +struct otaku_echo { + const char *name; + bool incremental; +}; + +#define SUBMERSION_MAIN 0 +#define SUBMERSION_ECHO 1 +#define SUBMERSION_CONFIRM 2 + +#endif diff --git a/src/pro_create.cpp b/src/pro_create.cpp index cab364094..933884fff 100644 --- a/src/pro_create.cpp +++ b/src/pro_create.cpp @@ -28,6 +28,7 @@ extern void part_design(struct char_data *ch, struct obj_data *design); extern void spell_design(struct char_data *ch, struct obj_data *design); +extern void complex_form_design(struct char_data *ch, struct obj_data *design); extern void ammo_test(struct char_data *ch, struct obj_data *obj); extern void weight_change_object(struct obj_data * obj, float weight); extern bool focus_is_usable_by_ch(struct obj_data *focus, struct char_data *ch); @@ -246,6 +247,66 @@ struct obj_data *can_program(struct char_data *ch) return NULL; } +int get_program_skill(char_data *ch, obj_data *prog, int target) +{ + int skill = 0; + switch (GET_DESIGN_PROGRAM(prog)) { + case SOFT_BOD: + case SOFT_EVASION: + case SOFT_MASKING: + case SOFT_SENSOR: + case SOFT_ASIST_COLD: + case SOFT_ASIST_HOT: + case SOFT_HARDENING: + case SOFT_ICCM: + case SOFT_ICON: + case SOFT_MPCP: + case SOFT_REALITY: + case SOFT_RESPONSE: + skill = get_skill(ch, SKILL_PROGRAM_CYBERTERM, target); + break; + case SOFT_ATTACK: + case SOFT_SLOW: + skill = get_skill(ch, SKILL_PROGRAM_COMBAT, target); + break; + case SOFT_CLOAK: + case SOFT_LOCKON: + case SOFT_MEDIC: + case SOFT_ARMOR: + skill = get_skill(ch, SKILL_PROGRAM_DEFENSIVE, target); + break; + case SOFT_BATTLETEC: + case SOFT_COMPRESSOR: + case SOFT_SLEAZE: + case SOFT_TRACK: + case SOFT_SUITE: + skill = get_skill(ch, SKILL_PROGRAM_SPECIAL, target); + break; + case SOFT_CAMO: + case SOFT_CRASH: + case SOFT_DEFUSE: + case SOFT_EVALUATE: + case SOFT_VALIDATE: + case SOFT_SWERVE: + case SOFT_SNOOPER: + case SOFT_ANALYZE: + case SOFT_DECRYPT: + case SOFT_DECEPTION: + case SOFT_RELOCATE: + case SOFT_SCANNER: + case SOFT_BROWSE: + case SOFT_READ: + case SOFT_COMMLINK: + skill = get_skill(ch, SKILL_PROGRAM_OPERATIONAL, target); + break; + default: + mudlog_vfprintf(ch, LOG_SYSLOG, "SYSERR: Unknown SOFT_X %d to do_design's switch statement!", GET_DESIGN_PROGRAM(prog)); + skill = 0; + break; + } + return skill; +} + ACMD(do_design) { ACMD_DECLARE(do_program); @@ -308,60 +369,7 @@ ACMD(do_design) target--; else if (GET_DESIGN_RATING(prog) > 9) target++; - switch (GET_DESIGN_PROGRAM(prog)) { - case SOFT_BOD: - case SOFT_EVASION: - case SOFT_MASKING: - case SOFT_SENSOR: - case SOFT_ASIST_COLD: - case SOFT_ASIST_HOT: - case SOFT_HARDENING: - case SOFT_ICCM: - case SOFT_ICON: - case SOFT_MPCP: - case SOFT_REALITY: - case SOFT_RESPONSE: - skill = get_skill(ch, SKILL_PROGRAM_CYBERTERM, target); - break; - case SOFT_ATTACK: - case SOFT_SLOW: - skill = get_skill(ch, SKILL_PROGRAM_COMBAT, target); - break; - case SOFT_CLOAK: - case SOFT_LOCKON: - case SOFT_MEDIC: - case SOFT_ARMOR: - skill = get_skill(ch, SKILL_PROGRAM_DEFENSIVE, target); - break; - case SOFT_BATTLETEC: - case SOFT_COMPRESSOR: - case SOFT_SLEAZE: - case SOFT_TRACK: - case SOFT_SUITE: - skill = get_skill(ch, SKILL_PROGRAM_SPECIAL, target); - break; - case SOFT_CAMO: - case SOFT_CRASH: - case SOFT_DEFUSE: - case SOFT_EVALUATE: - case SOFT_VALIDATE: - case SOFT_SWERVE: - case SOFT_SNOOPER: - case SOFT_ANALYZE: - case SOFT_DECRYPT: - case SOFT_DECEPTION: - case SOFT_RELOCATE: - case SOFT_SCANNER: - case SOFT_BROWSE: - case SOFT_READ: - case SOFT_COMMLINK: - skill = get_skill(ch, SKILL_PROGRAM_OPERATIONAL, target); - break; - default: - mudlog_vfprintf(ch, LOG_SYSLOG, "SYSERR: Unknown SOFT_X %d to do_design's switch statement!", GET_DESIGN_PROGRAM(prog)); - skill = 0; - break; - } + skill = get_program_skill(ch, prog, target); if (!skill) { send_to_char(ch, "You have no idea how to go about creating a program design for that.\r\n"); return; @@ -674,6 +682,49 @@ void update_buildrepair(void) AFF_FLAGS(desc->character).RemoveBit(AFF_PROGRAM); CH->char_specials.timer = 0; } + } else if (AFF_FLAGGED(CH, AFF_COMPLEX_FORM_PROGRAM)) { + if (--GET_DESIGN_PROGRAMMING_TICKS_LEFT(PROG) < 1) { + if (GET_DESIGN_PROGRAMMING_FAILED(PROG)) { + switch(number(1,10)) { + case 1: + send_to_char(desc->character, "You have finished a spell formula for Stunbolt... wait, what the hell?! You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 2: + send_to_char(desc->character, "There was a series of articles related to what you were doing, but you somehow ended up on a page about crabs. Why always crabs?!? You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 3: + send_to_char(desc->character, "You became distracted and lost hours of your life to a Penumbrawalk mud. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 4: + send_to_char(desc->character, "You try to shape the resonance but somehow end up ordering takeout from a Stuffer Shack in Neo-Tokyo. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 5: + send_to_char(desc->character, "The deep resonance speaks to you! Unfortunately, it's just complaining about matrix lag. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 6: + send_to_char(desc->character, "You reach for the threads of resonance but accidentally subscribe to 47 different spam newsletters. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 7: + send_to_char(desc->character, "You achieve deep matrix meditation, only to discover you've been watching cat videos for the last four hours. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 8: + send_to_char(desc->character, "Success! You've mastered... wait, no, that's just static cling. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + case 9: + send_to_char(desc->character, "Your attempt to weave the resonance somehow results in all nearby devices playing 'Never Gonna Give You Up'. You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + break; + default: + send_to_char(desc->character, "You realise learning %s is a lost cause.\r\n", GET_OBJ_NAME(PROG)); + } + extract_obj(PROG); + } else { + send_to_char(desc->character, "You successfully learn %s.\r\n", GET_OBJ_NAME(PROG)); + GET_OBJ_TIMER(PROG) = 0; + } + } + PROG = NULL; + AFF_FLAGS(desc->character).RemoveBit(AFF_COMPLEX_FORM_PROGRAM); + CH->char_specials.timer = 0; } else if (AFF_FLAGGED(CH, AFF_RITUALCAST)) { if (handle_ritualcast_tick(CH, PROG)) { // Successful completion means the prog was extracted in the function. diff --git a/src/spec_assign.cpp b/src/spec_assign.cpp index 9f8575005..6fc3747c2 100644 --- a/src/spec_assign.cpp +++ b/src/spec_assign.cpp @@ -152,6 +152,11 @@ struct teach_data teachers[] = { { 60501, { SKILL_CONJURING, SKILL_SORCERY, SKILL_SPELLDESIGN, SKILL_AURA_READING, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, "After hours of study and practice, you feel like you've learned something.\r\n", NEWBIE }, + + // Newbie otaku teacher + { 60692, { SKILL_CHANNEL_ACCESS, SKILL_CHANNEL_CONTROL, SKILL_CHANNEL_INDEX, SKILL_CHANNEL_FILES, SKILL_CHANNEL_SLAVE, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + "After hours of study and practice, you feel like you've learned something.\r\n", NEWBIE }, { 60502, { SKILL_COMPUTER, SKILL_BR_COMPUTER, SKILL_DATA_BROKERAGE, SKILL_CYBERTERM_DESIGN, SKILL_ELECTRONICS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, diff --git a/src/spec_procs.cpp b/src/spec_procs.cpp index c81f12360..c21ca21a9 100644 --- a/src/spec_procs.cpp +++ b/src/spec_procs.cpp @@ -785,8 +785,10 @@ int get_max_skill_for_char(struct char_data *ch, int skill, int type) { } // Scope maximums based on teacher type. - if (type == NEWBIE) + if (type == NEWBIE) { max = NEWBIE_SKILL; + if (skill == SKILL_COMPUTER && IS_OTAKU(ch)) max = 8; // Otakus can start with computers 8 + } else if (type == AMATEUR) max = NORMAL_MAX_SKILL; else if (type == ADVANCED) @@ -856,7 +858,7 @@ int get_max_skill_for_char(struct char_data *ch, int skill, int type) { SPECIAL(teacher) { struct char_data *master = (struct char_data *) me; - int i, ind, max, skill_num; + int i, ind, max, skill_num, channel_points; if (!(CMD_IS("practice"))) return FALSE; @@ -907,8 +909,16 @@ SPECIAL(teacher) return TRUE; } + if (IS_OTAKU(ch)) { + // Otaku get free skill points to spend on JUST channels based on the avg of these stats, round up + channel_points = (GET_REAL_INT(ch) + GET_REAL_WIL(ch) + GET_REAL_CHA(ch) + 2) / 3; + channel_points -= GET_SKILL(ch, SKILL_CHANNEL_ACCESS) + GET_SKILL(ch, SKILL_CHANNEL_CONTROL) + + GET_SKILL(ch, SKILL_CHANNEL_FILES) + GET_SKILL(ch, SKILL_CHANNEL_INDEX) + GET_SKILL(ch, SKILL_CHANNEL_SLAVE); + } + if (!*argument) { bool found_a_skill_already = FALSE; + bool channel_skills_found = FALSE; for (int i = 0; i < NUM_TEACHER_SKILLS; i++) { if (teachers[ind].s[i] > 0) { // Mundanes can't learn magic skills, with the exception of dragons/ghouls who can learn aura reading. @@ -918,6 +928,10 @@ SPECIAL(teacher) continue; } + // Non-otaku cannot learn otaku channel skills. + if (skills[teachers[ind].s[i]].requires_resonance && !IS_OTAKU(ch)) + continue; + // Adepts can't learn externally-focused skills. if (GET_TRADITION(ch) == TRAD_ADEPT && (teachers[ind].s[i] == SKILL_CONJURING || teachers[ind].s[i] == SKILL_SORCERY)) @@ -934,7 +948,16 @@ SPECIAL(teacher) if ((max = get_max_skill_for_char(ch, teachers[ind].s[i], teachers[ind].type)) < 0) return FALSE; - if (GET_SKILL_POINTS(ch) > 0) { + if (skills[teachers[ind].s[i]].requires_resonance && channel_points > 0 && PLR_FLAGGED(ch, PLR_NEWBIE)) { + // Channel skills are a bit unique for otaku + if (!found_a_skill_already) { + found_a_skill_already = TRUE; + snprintf(buf, sizeof(buf), "%s can teach you the following:\r\n", GET_NAME(master)); + } + snprintf(ENDOF(buf), sizeof(buf) - strlen(buf), " %-24s (1 channel point)\r\n", + skills[teachers[ind].s[i]].name); + channel_skills_found = TRUE; + } else if (GET_SKILL_POINTS(ch) > 0) { // Add conditional messaging. if (!found_a_skill_already) { found_a_skill_already = TRUE; @@ -962,7 +985,11 @@ SPECIAL(teacher) return TRUE; } - if (GET_SKILL_POINTS(ch) > 0) + if (channel_skills_found && channel_points > 0) + snprintf(ENDOF(buf), sizeof(buf) - strlen(buf), "\r\nYou have %d channel point%s to use specifically for otaku skills, and %d skill point%s.\r\n", + channel_points, channel_points > 1 ? "s" : "", + GET_SKILL_POINTS(ch), GET_SKILL_POINTS(ch) > 1 ? "s" : ""); + else if (GET_SKILL_POINTS(ch) > 0) snprintf(ENDOF(buf), sizeof(buf) - strlen(buf), "\r\nYou have %d point%s to use for skills.\r\n", GET_SKILL_POINTS(ch), GET_SKILL_POINTS(ch) > 1 ? "s" : ""); else @@ -1052,7 +1079,21 @@ SPECIAL(teacher) } lose_nuyen(ch, skill_nuyen_cost, NUYEN_OUTFLOW_SKILL_TRAINING); } - if (GET_SKILL_POINTS(ch) > 0) + if (PLR_FLAGGED(ch, PLR_NEWBIE) && skills[skill_num].requires_resonance && channel_points > 0) { + // Check this wouldn't put us above our newbie limits. + if (REAL_SKILL(ch, skill_num) + 1 > 3) { + // Check we don't have any other channel skills at the same value. + for (int ci=154; i < 159;i++) { + if (REAL_SKILL(ch, ci) == REAL_SKILL(ch, skill_num) + 1) { + // Break. + send_to_char(ch, "When buying channel skills with freebies you can only have one channel skill at %d, and %s is already at that value.", + REAL_SKILL(ch, skill_num) + 1, skills[ci].name); + return FALSE; + } + } + } + // No points to detect; it's all calculated on the fly. Leave blank. + } else if (GET_SKILL_POINTS(ch) > 0) GET_SKILL_POINTS(ch)--; else GET_KARMA(ch) -= get_skill_price(ch, skill_num) * 100; diff --git a/src/structs.hpp b/src/structs.hpp index 965bacbb9..c8b8de786 100644 --- a/src/structs.hpp +++ b/src/structs.hpp @@ -467,6 +467,7 @@ struct char_player_data ush_int weight; /* PC / NPC's weight */ ush_int height; /* PC / NPC's height */ byte race; /* PC / NPC's race */ + byte otaku_path; /* PC / NPC's otaku status */ byte tradition; /* PC / NPC's tradition */ ubyte aspect; char *host; /* player host */ @@ -475,7 +476,7 @@ struct char_player_data char_name(NULL), background(NULL), title(NULL), pretitle(NULL), whotitle(NULL), prompt(NULL), matrixprompt(NULL), poofin(NULL), poofout(NULL), email(NULL), multiplier(0), salvation_ticks(5), pronouns(PRONOUNS_NEUTRAL), level(0), last_room(NOWHERE), - weight(0), height(0), race(0), tradition(TRAD_MUNDANE), aspect(0), host(NULL) + weight(0), height(0), race(0), otaku_path(OTAKU_PATH_NORMIE), tradition(TRAD_MUNDANE), aspect(0), host(NULL) { memset(passwd, 0, sizeof(passwd)); } @@ -586,6 +587,7 @@ struct char_special_data_saved byte skills[MAX_SKILLS+1][3]; /* array of skills plus skill 0. Slot 0 is unaltered, */ byte powers[ADEPT_NUMPOWER+1][2]; unsigned char metamagic[META_MAX+1]; + unsigned char echoes[ECHO_MAX+1]; ush_int centeringskill; ush_int boosted[3][2]; /* str/qui/bod timeleft/amount */ ubyte masking; @@ -603,6 +605,7 @@ struct char_special_data_saved } ZERO_OUT_ARRAY(metamagic, META_MAX + 1); + ZERO_OUT_ARRAY(echoes, ECHO_MAX + 1); for (int i = 0; i < 3; i++) { ZERO_OUT_ARRAY(boosted[i], 2); @@ -1058,6 +1061,7 @@ struct ccreate_t sh_int prestige_race; idnum_t prestige_bagholder; int prestige_cost; + bool is_otaku; }; struct descriptor_data @@ -1264,6 +1268,7 @@ struct skill_data { sh_int attribute; bool is_knowledge_skill; bool requires_magic; + bool requires_resonance; sh_int group; bool reflex_recorder_compatible; bool no_defaulting_allowed; diff --git a/src/utils.cpp b/src/utils.cpp index 6836f9564..09653e8ae 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -5809,6 +5809,61 @@ struct obj_data *make_new_finished_program(int part_type, int mpcp, int rating=0 return prog; } +struct obj_data *make_otaku_deck(struct char_data *ch) { + struct obj_data *new_deck = read_object(OBJ_CUSTOM_CYBERDECK_SHELL, VIRTUAL, OBJ_LOAD_REASON_OTAKU_BS); + + // Add parts. + int mpcp = (GET_REAL_INT(ch) + GET_REAL_WIL(ch) + GET_REAL_CHA(ch) + 2) / 3; // adding 2 always ensures a round up + if (GET_ECHO(ch, ECHO_IMPROVED_MPCP)) { + mpcp = MIN(GET_REAL_INT(ch) * 2, mpcp + GET_ECHO(ch, ECHO_IMPROVED_MPCP)); + } + obj_to_obj(make_new_finished_part(PART_MPCP, mpcp, mpcp), new_deck); + obj_to_obj(make_new_finished_part(PART_BOD, mpcp, GET_REAL_WIL(ch)), new_deck); + obj_to_obj(make_new_finished_part(PART_EVASION, mpcp, GET_REAL_INT(ch)), new_deck); + obj_to_obj(make_new_finished_part(PART_SENSOR, mpcp, GET_REAL_INT(ch)), new_deck); + obj_to_obj(make_new_finished_part(PART_MASKING, mpcp, (GET_REAL_WIL(ch) + GET_REAL_CHA(ch) + 1) / 2), new_deck); + obj_to_obj(make_new_finished_part(PART_ASIST_HOT, mpcp), new_deck); + obj_to_obj(make_new_finished_part(PART_RAS_OVERRIDE, mpcp), new_deck); + + GET_CYBERDECK_MPCP(new_deck) = mpcp; + GET_CYBERDECK_HARDENING(new_deck) = MIN(GET_REAL_WIL(ch), GET_REAL_WIL(ch) / 2 + GET_ECHO(ch, ECHO_IMPROVED_HARD)); + GET_CYBERDECK_ACTIVE_MEMORY(new_deck) = 999999; + GET_CYBERDECK_TOTAL_STORAGE(new_deck) = 0; + GET_CYBERDECK_RESPONSE_INCREASE(new_deck) = MIN(mpcp * 1.5, GET_REAL_REA(ch) + GET_ECHO(ch, ECHO_IMPROVED_REA)); + GET_CYBERDECK_IO_RATING(new_deck) = MIN(GET_REAL_INT(ch) * 200, (GET_REAL_INT(ch) * 100) + (GET_ECHO(ch, ECHO_IMPROVED_IO) * 100)); + GET_CYBERDECK_IS_INCOMPLETE(new_deck) = FALSE; + + new_deck->obj_flags.extra_flags.SetBit(ITEM_EXTRA_NOSELL); + new_deck->obj_flags.extra_flags.SetBit(ITEM_EXTRA_CONCEALED_IN_EQ); + new_deck->obj_flags.extra_flags.SetBit(ITEM_EXTRA_OTAKU_BS); + + for (struct obj_data *form = ch->carrying; form; form = form->next_content) { + if (GET_OBJ_TYPE(form) != ITEM_COMPLEX_FORM) continue; + struct obj_data *active = read_object(OBJ_BLANK_PROGRAM, VIRTUAL, OBJ_LOAD_REASON_OTAKU_BS); + GET_PROGRAM_TYPE(active) = GET_PROGRAM_TYPE(form); + GET_PROGRAM_SIZE(active) = 1; + GET_PROGRAM_ATTACK_DAMAGE(active) = GET_PROGRAM_ATTACK_DAMAGE(form); + GET_PROGRAM_IS_DEFAULTED(active) = TRUE; + GET_OBJ_TIMER(active) = 1; + + GET_PROGRAM_RATING(active) = GET_PROGRAM_RATING(form); + + active->obj_flags.extra_flags.SetBit(ITEM_EXTRA_OTAKU_BS); + active->obj_flags.extra_flags.SetBit(ITEM_EXTRA_NOSELL); + + char restring[500]; + snprintf(restring, sizeof(restring), "a rating-%d %s complex form", GET_PROGRAM_RATING(form), programs[GET_PROGRAM_TYPE(form)].name); + active->restring = str_dup(restring); + obj_to_obj(active, new_deck); + } + + char restring[500]; + snprintf(restring, sizeof(restring), "a living persona cyberdeck"); + new_deck->restring = str_dup(restring); + + return new_deck; +} + struct obj_data *make_staff_deck_target_mpcp(int mpcp) { struct obj_data *new_deck = read_object(OBJ_CUSTOM_CYBERDECK_SHELL, VIRTUAL, OBJ_LOAD_REASON_STAFF_DECK); diff --git a/src/utils.hpp b/src/utils.hpp index 291116578..a360a5a6b 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -426,6 +426,8 @@ bool update_pos(struct char_data *victim, bool protect_spells_from_purge=0); #define IS_PRESTIGE_RACE(race) (RACE_IS_DRAGON(race) || RACE_IS_DRAKE(race) || RACE_IS_GHOUL(race) || race == RACE_DRYAD) #define IS_PRESTIGE_CH(ch) (IS_PRESTIGE_RACE(GET_RACE(ch))) +#define IS_OTAKU(ch) (GET_OTAKU_PATH(ch) > 0) + #define GET_RACIAL_STARTING_ESSENCE_FOR_RACE(race) (RACE_IS_GHOUL(race) ? 500 : (RACE_IS_DRAGON(race) ? 700 : 600)) // ONLY for use on non-Bitfield bitvectors: @@ -544,12 +546,13 @@ extern bool PLR_TOG_CHK(char_data *ch, dword offset); #define GET_DESC_LEVEL(d) ((d)->original ? GET_LEVEL((d)->original) : ((d)->character ? GET_LEVEL((d)->character) : 0)) #define GET_RACE(ch) ((ch)->player.race) -#define GET_TRADITION(ch) ((ch)->player.tradition) -#define GET_ASPECT(ch) ((ch)->player.aspect) -#define GET_LASTROOM(ch) ((ch)->player.last_room) +#define GET_OTAKU_PATH(ch) ((ch)->player.otaku_path) +#define GET_TRADITION(ch) ((ch)->player.tradition) +#define GET_ASPECT(ch) ((ch)->player.aspect) +#define GET_LASTROOM(ch) ((ch)->player.last_room) #define GET_HEIGHT(ch) ((ch)->player.height) #define GET_WEIGHT(ch) ((ch)->player.weight) -#define GET_PRONOUNS(ch) ((ch)->player.pronouns) +#define GET_PRONOUNS(ch) ((ch)->player.pronouns) #define GET_ATT(ch, i) ((ch)->aff_abils.attributes[(i)]) #define GET_REAL_ATT(ch, i) ((ch)->real_abils.attributes[(i)]) @@ -736,6 +739,9 @@ int get_armor_penalty_grade(struct char_data *ch); #define GET_METAMAGIC(ch, i) ((ch)->char_specials.saved.metamagic[i] != 0 ? (ch)->char_specials.saved.metamagic[i] : 0) #define SET_METAMAGIC(ch, i, amt) {(ch)->char_specials.saved.metamagic[i] = amt; GET_METAMAGIC_DIRTY_BIT(ch) = TRUE;} +#define GET_ECHO(ch, i) ((ch)->char_specials.saved.echoes[i] != 0 ? (ch)->char_specials.saved.echoes[i] : 0) +#define SET_ECHO(ch, i, amt) {(ch)->char_specials.saved.echoes[i] = amt; GET_ECHOES_DIRTY_BIT(ch) = TRUE;} + #define GET_MASKING(ch) ((ch)->char_specials.saved.masking) #define GET_CENTERINGSKILL(ch) ((ch)->char_specials.saved.centeringskill) #define GET_PP(ch) ((ch)->char_specials.saved.powerpoints) @@ -749,6 +755,7 @@ int get_armor_penalty_grade(struct char_data *ch); #define GET_SPELLS_DIRTY_BIT(ch) ((ch)->char_specials.dirty_bits[DIRTY_BIT_SPELLS]) #define GET_METAMAGIC_DIRTY_BIT(ch) ((ch)->char_specials.dirty_bits[DIRTY_BIT_METAMAGIC]) #define GET_ELEMENTALS_DIRTY_BIT(ch) ((ch)->char_specials.dirty_bits[DIRTY_BIT_ELEMENTALS]) +#define GET_ECHOES_DIRTY_BIT(ch) ((ch)->char_specials.dirty_bits[DIRTY_BIT_ECHOES]) #define GET_MEMORY_DIRTY_BIT(ch) ((ch)->char_specials.dirty_bits[DIRTY_BIT_MEMORY]) #define GET_ALIAS_DIRTY_BIT(ch) ((ch)->char_specials.dirty_bits[DIRTY_BIT_ALIAS]) @@ -797,8 +804,8 @@ bool _mob_is_alert(struct char_data *npc); #define IS_JACKED_IN(ch) (IS_RIGGING(ch) || PLR_FLAGGED(ch, PLR_MATRIX) || PLR_FLAGGED(ch, PLR_REMOTE)) #define CAN_SEE_IN_DARK(ch) (SEES_ASTRAL(ch) || CURRENT_VISION(ch) == THERMOGRAPHIC || PRF_FLAGGED((ch), PRF_HOLYLIGHT)) #define GET_BUILDING(ch) ((ch)->char_specials.programming) -#define IS_WORKING(ch) ((AFF_FLAGS(ch).AreAnySet(BR_TASK_AFF_FLAGS, AFF_PILOT, AFF_RIG, AFF_BONDING, AFF_CONJURE, AFF_PACKING, ENDBIT))) -#define STOP_WORKING(ch) {AFF_FLAGS((ch)).RemoveBits(BR_TASK_AFF_FLAGS, AFF_BONDING, AFF_CONJURE, AFF_PACKING, ENDBIT); \ +#define IS_WORKING(ch) ((AFF_FLAGS(ch).AreAnySet(BR_TASK_AFF_FLAGS, AFF_PILOT, AFF_RIG, AFF_BONDING, AFF_CONJURE, AFF_PACKING, AFF_COMPLEX_FORM_PROGRAM, ENDBIT))) +#define STOP_WORKING(ch) {AFF_FLAGS((ch)).RemoveBits(BR_TASK_AFF_FLAGS, AFF_BONDING, AFF_CONJURE, AFF_PACKING, AFF_COMPLEX_FORM_PROGRAM, ENDBIT); \ GET_BUILDING((ch)) = NULL;} #define STOP_DRIVING(ch) {AFF_FLAGS((ch)).RemoveBits(AFF_PILOT, AFF_RIG, ENDBIT);}