home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #7 / amigamamagazinepolishissue1998.iso / rozrywka / rpg / amigamud / src / combat / monsters.m < prev   
Text File  |  1997-06-22  |  15KB  |  492 lines

  1. /*
  2.  * Amiga MUD
  3.  *
  4.  * Copyright (c) 1997 by Chris Gray
  5.  */
  6.  
  7. /*
  8.  * monsters.m - define some monster classes and monsters.
  9.  */
  10.  
  11. private tp_monsters CreateTable()$
  12. use tp_monsters
  13.  
  14. /* a move routine for a simple random moving monster */
  15.  
  16. /*
  17.  * RandomMove - used for dumb monsters which just wander around.
  18.  */
  19.  
  20. define t_monsters proc public RandomMove()void:
  21.     thing theMonster;
  22.     int n;
  23.     action a;
  24.  
  25.     theMonster := Me();
  26.     if MonsterStillMoving(theMonster, nil) then
  27.     a := theMonster@p_mSpecialAction;
  28.     if a ~= nil then
  29.         if not call(a, bool)() then
  30.         /* something special - give it a new lease on life */
  31.         if theMonster@p_mMovesUntilVanish ~= FOREVER_LIFE then
  32.             theMonster@p_mMovesUntilVanish := RANDOM_MONSTER_LIFE;
  33.         fi;
  34.         MonsterReschedule(theMonster);
  35.         fi;
  36.     else
  37.         DoMonsterMove(theMonster);
  38.         MonsterReschedule(theMonster);
  39.     fi;
  40.     fi;
  41. corp;
  42.  
  43. /* set up trackers */
  44.  
  45. /*
  46.  * TrackerDieNotify - called when a player with trackers dies. Return 'true'
  47.  *    to indicate that we want to be removed from the notify list.
  48.  */
  49.  
  50. define t_monsters proc TrackerDieNotify(thing thePlayer)bool:
  51.     list thing trackers;
  52.     int count;
  53.     list int path;
  54.  
  55.     trackers := thePlayer@p_pTrackerList;
  56.     count := Count(trackers);
  57.     while count ~= 0 do
  58.     count := count - 1;
  59.     trackers[count] -- p_mTrackerPath;
  60.     RemTail(trackers);
  61.     od;
  62.     true
  63. corp
  64.  
  65. /*
  66.  * TrackerChecker - a player leave checker that records the direction on all
  67.  *    following trackers
  68.  */
  69.  
  70. define t_monsters proc TrackerChecker(int dir)status:
  71.     list thing lt;
  72.     int count, n, dirCount;
  73.     thing thePlayer, theTracker;
  74.     list int li;
  75.  
  76.     thePlayer := Me();
  77.     lt := thePlayer@p_pTrackerList;
  78.     if lt = nil then
  79.     DelPlayerLeaveChecker(thePlayer, TrackerChecker);
  80.     DelElement(thePlayer@p_pDieNotifyList, TrackerDieNotify);
  81.     else
  82.     count := Count(lt);
  83.     if count ~= 0 then
  84.         n := 0;
  85.         while n ~= count do
  86.         theTracker := lt[n];
  87.         if theTracker@p_mExpired then
  88.             DelElement(lt, theTracker);
  89.             DestroyMachine(theTracker);
  90.             count := count - 1;
  91.         else
  92.             li := theTracker@p_mTrackerPath;
  93.             if li = nil then
  94.             li := CreateIntList();
  95.             theTracker@p_mTrackerPath := li;
  96.             dirCount := 0;
  97.             else
  98.             dirCount := Count(li);
  99.             fi;
  100.             if dirCount ~= 0 and li[dirCount - 1] = DirBack(dir) then
  101.             /* two directions cancel out */
  102.             RemTail(li);
  103.             else
  104.             AddTail(li, dir);
  105.             fi;
  106.             n := n + 1;
  107.         fi;
  108.         od;
  109.     fi;
  110.     if count = 0 then
  111.         thePlayer -- p_pTrackerList;
  112.         DelPlayerLeaveChecker(thePlayer, TrackerChecker);
  113.         DelElement(thePlayer@p_pDieNotifyList, TrackerDieNotify);
  114.     fi;
  115.     fi;
  116.     continue
  117. corp;
  118.  
  119. /*
  120.  * TrackerDie - a die action for trackers, as called by MonsterStillMoving
  121.  */
  122.  
  123. define t_monsters proc TrackerDie(thing theTracker)void:
  124.     list thing lt;
  125.     thing theTarget;
  126.  
  127.     theTarget := theTracker@p_pCurrentTarget;
  128.     if theTarget ~= nil then
  129.     lt := theTarget@p_pTrackerList;
  130.     if lt ~= nil and FindElement(lt, theTracker) ~= -1 then
  131.         DelElement(lt, theTracker);
  132.         if Count(lt) = 0 then
  133.         theTarget -- p_pTrackerList;
  134.         DelPlayerLeaveChecker(theTarget, TrackerChecker);
  135.         DelElement(theTarget@p_pDieNotifyList, TrackerDieNotify);
  136.         fi;
  137.     fi;
  138.     fi;
  139. corp;
  140.  
  141. /*
  142.  * TrackerKill - routine to do extra stuff when a tracker is killed.
  143.  *    NOTE: this should be attached to each model of a tracker.
  144.  */
  145.  
  146. define t_monsters proc TrackerKill(thing thePlayer, theMonster)bool:
  147.     int hitsLeft;
  148.  
  149.     hitsLeft := theMonster@p_pHitNow;
  150.     TrackerDie(theMonster);
  151.     KillMonster(theMonster);
  152.     DestroyMachine(theMonster);
  153.     AddExperience(thePlayer, hitsLeft);
  154.     false
  155. corp;
  156.  
  157. /*
  158.  * TrackerInit - extra init stuff for a tracker.
  159.  */
  160.  
  161. define t_monsters proc TrackerInit()void:
  162.     thing theMonster, thePlayer;
  163.     list thing trackers;
  164.  
  165.     theMonster := Me();
  166.     if theMonster@p_mKillAction = nil then
  167.     /* should be on the model, but if not... */
  168.     theMonster@p_mKillAction := TrackerKill;
  169.     fi;
  170.     MonsterInit();
  171.     thePlayer := theMonster@p_pCurrentTarget;
  172.     trackers := thePlayer@p_pTrackerList;
  173.     if trackers = nil then
  174.     trackers := CreateThingList();
  175.     thePlayer@p_pTrackerList := trackers;
  176.     AddPlayerLeaveChecker(thePlayer, TrackerChecker, false);
  177.     AddTail(thePlayer@p_pDieNotifyList, TrackerDieNotify);
  178.     fi;
  179.     AddTail(trackers, theMonster);
  180. corp;
  181.  
  182. /*
  183.  * TrackerMove - a tracker moves a single step, hopefully on the path
  184.  *    following the target.
  185.  */
  186.  
  187. define t_monsters proc TrackerMove()void:
  188.     thing theMonster, theTarget, here;
  189.     list int li;
  190.     int dir, count;
  191.     bool followed;
  192.  
  193.     theMonster := Me();
  194.     here := Here();
  195.     li := theMonster@p_mTrackerPath;
  196.     if li = nil then
  197.     count := 0;
  198.     else
  199.     count := Count(li);
  200.     fi;
  201.     theTarget := theMonster@p_pCurrentTarget;
  202.     if AgentLocation(theTarget) = here then
  203.     ignore MonsterHitPlayer(theMonster, theTarget, here);
  204.     theMonster@p_mTrackerPath := CreateIntList();
  205.     MonsterReschedule(theMonster);
  206.     else
  207.     followed := false;
  208.     if count ~= 0 then
  209.         dir := li[0];
  210.         RemHead(li);
  211.         if MonsterMove(theMonster, dir) then
  212.         followed := true;
  213.         else
  214.         /* rats! can't follow */
  215.         theMonster -- p_mTrackerPath;
  216.         fi;
  217.     fi;
  218.     if not followed then
  219.         /* where did he go, where did he go? */
  220.         if not MonsterMove(theMonster, Random(12)) then
  221.         if MonsterStillMoving(theMonster, TrackerDie) then
  222.             MonsterAction(theMonster);
  223.             MonsterReschedule(theMonster);
  224.         fi;
  225.         else
  226.         MonsterReschedule(theMonster);
  227.         fi;
  228.     else
  229.         MonsterReschedule(theMonster);
  230.     fi;
  231.     fi;
  232. corp;
  233.  
  234. /* define some "standard" monsters.
  235.    Note: numerics: hitpoints, speed, protection, accuracy, damage, gold */
  236.  
  237. define t_monsters m_rat CreateMonsterModel("rat",
  238.     "The rat is of average size, and, like most rats, is quite filthy.",
  239.     MonsterInit, RandomMove,
  240.     2, 6, 9, 5, 2, 0)$
  241. AddModelAction(m_rat, "runs around")$
  242. AddModelAction(m_rat, "chitters")$
  243. AddModelAction(m_rat, "squeals")$
  244. m_rat@p_Image := "Characters/rat"$
  245. m_rat@p_mSound := "rat"$
  246. GNewIcon(m_rat, makeRatIcon())$
  247.  
  248. define t_monsters m_snake CreateMonsterModel("snake,snak,sna",
  249.     "The snake isn't poisonous, but bites pretty well. It has no "
  250.     "distinguishing markings.",
  251.     MonsterInit, RandomMove,
  252.     4, 8, 9, 5, 2, 0)$
  253. AddModelAction(m_snake, "slithers around")$
  254. AddModelAction(m_snake, "hisses")$
  255. AddModelAction(m_snake, "coils and uncoils")$
  256. m_snake@p_Image := "Characters/snake"$
  257. m_snake@p_mSound := "snake-hiss"$
  258. GNewIcon(m_snake, makeSnakeIcon())$
  259.  
  260. define t_monsters m_dog CreateMonsterModel("dog;wild", "",
  261.     MonsterInit, RandomMove,
  262.     6, 5, 9, 5, 4, 0)$
  263. m_dog@p_mBlocker := true$
  264. AddModelAction(m_dog, "runs around")$
  265. AddModelAction(m_dog, "barks")$
  266. AddModelAction(m_dog, "growls")$
  267. AddModelAction(m_dog, "snarls")$
  268. m_dog@p_Image := "Characters/dog"$
  269. m_dog@p_mSound := "dog-growl"$
  270. GNewIcon(m_dog, makeDogIcon())$
  271.  
  272. define t_monsters m_gremlin CreateMonsterModel("gremlin,gre,grem;nasty",
  273.     "The gremlin, like all of its kind, is quite dirty. It also comes "
  274.     "equipped with sharp teeth and claws.",
  275.     MonsterInit, RandomMove,
  276.     5, 5, 9, 5, 4, 15)$
  277. AddModelAction(m_gremlin, "runs in circles around you")$
  278. AddModelAction(m_gremlin, "shrieks loudly")$
  279. AddModelAction(m_gremlin, "curses")$
  280. AddModelAction(m_gremlin, "picks its nose")$
  281. AddModelAction(m_gremlin, "thumbs its nose")$
  282. AddModelAction(m_gremlin, "spits at you")$
  283. MakeMonsterSmart(m_gremlin)$
  284. m_gremlin@p_Image := "Characters/gremlin"$
  285. m_gremlin@p_mSound := "gremlin"$
  286. GNewIcon(m_gremlin, makeGremlinIcon())$
  287.  
  288. /* and now some bigger stuff for forests, etc. */
  289.  
  290. define t_monsters m_wolf CreateMonsterModel("wolf,wol,wuf,wolve", "",
  291.     MonsterInit, RandomMove,
  292.     10, 5, 9, 7, 6, 0)$
  293. m_wolf@p_mBlocker := true$
  294. AddModelAction(m_wolf, "runs around")$
  295. AddModelAction(m_wolf, "snarls")$
  296. AddModelAction(m_wolf, "howls")$
  297. m_wolf@p_Image := "Characters/wolf"$
  298. m_wolf@p_mSound := "wolf"$
  299. GNewIcon(m_wolf, makeWolfIcon())$
  300.  
  301. define t_monsters m_troll CreateMonsterModel("troll,tro", "",
  302.     MonsterInit, RandomMove,
  303.     13, 4, 8, 6, 7, 40)$
  304. m_troll@p_mBlocker := true$
  305. AddModelAction(m_troll, "lumbers around")$
  306. AddModelAction(m_troll, "bellows")$
  307. AddModelAction(m_troll, "raises its fists and roars")$
  308. m_troll@p_Image := "Characters/troll"$
  309. m_troll@p_mSound := "troll"$
  310. GNewIcon(m_troll, makeTrollIcon())$
  311.  
  312. define t_monsters m_blackBear CreateMonsterModel("bear,bea,beer;black", "",
  313.     MonsterInit, RandomMove,
  314.     15, 5, 8, 6, 7, 0)$
  315. m_blackBear@p_mBlocker := true$
  316. AddModelAction(m_blackBear, "lumbers around")$
  317. AddModelAction(m_blackBear, "roars")$
  318. AddModelAction(m_blackBear, "stands upright and waves its paws")$
  319. m_blackBear@p_Image := "Characters/blackBear"$
  320. m_blackBear@p_mSound := "blackBear"$
  321. GNewIcon(m_blackBear, makeBearIcon())$
  322.  
  323. define t_monsters m_deer CreateMonsterModel("deer,dee,dear;mule", "",
  324.     MonsterInit, RandomMove,
  325.     8, 7, 9, 0, 0, 0)$
  326. AddModelAction(m_deer, "leaps around")$
  327. AddModelAction(m_deer, "screams silently")$
  328. AddModelAction(m_deer, "snorts")$
  329. define tp_monsters proc deerArrivalCheck(thing theDeer, theArrival)void:
  330.  
  331.     if IsAncestor(theArrival, m_wolf) or IsAncestor(theArrival, m_troll) then
  332.     RunAway(theDeer);
  333.     fi;
  334. corp;
  335. m_deer@p_mArriveAction := deerArrivalCheck$
  336. define tp_monsters proc deerCreationCheck(thing theDeer, theNew)void:
  337.  
  338.     if IsAncestor(theNew, m_wolf) or IsAncestor(theNew, m_troll) then
  339.     RunAway(theDeer);
  340.     fi;
  341. corp;
  342. m_deer@p_mCreateAction := deerCreationCheck$
  343. define tp_monsters proc deerArrivedCheck()void:
  344.     thing here;
  345.  
  346.     here := Here();
  347.     if FindAgentAsDescendant(here, m_wolf) ~= nil or
  348.     FindAgentAsDescendant(here, m_troll) ~= nil
  349.     then
  350.     ignore RunAwaySoon();
  351.     fi;
  352. corp;
  353. m_deer@p_mArrivedAction := deerArrivedCheck$
  354. m_deer@p_Image := "Characters/deer"$
  355. m_deer@p_mSound := "deer"$
  356. GNewIcon(m_deer, makeDeerIcon())$
  357.  
  358. define t_monsters m_moose CreateMonsterModel("moose,moo", "",
  359.     MonsterInit, RandomMove,
  360.     18, 4, 7, 6, 7, 0)$
  361. m_moose@p_mBlocker := true$
  362. AddModelAction(m_moose, "wades around")$
  363. AddModelAction(m_moose, "snorts")$
  364. AddModelAction(m_moose, "bellows")$
  365. m_moose@p_Image := "Characters/moose"$
  366. m_moose@p_mSound := "moose"$
  367. GNewIcon(m_moose, makeMooseIcon())$
  368.  
  369. /* larger stuff for the sewers */
  370.  
  371. define t_monsters m_largeRat CreateMonsterModel("rat;large",
  372.     "The rat is of above average size and is quite filthy.",
  373.     MonsterInit, RandomMove,
  374.     4, 6, 9, 5, 4, 0)$
  375. AddModelAction(m_largeRat, "runs around")$
  376. AddModelAction(m_largeRat, "chitters loudly")$
  377. AddModelAction(m_largeRat, "squeals loudly")$
  378. m_largeRat@p_Image := "Characters/largeRat"$
  379. m_largeRat@p_mSound := "largeRat"$
  380. GNewIcon(m_largeRat, makeRatIcon())$
  381.  
  382. define t_monsters m_largeSnake CreateMonsterModel("snake,snak,sna;large",
  383.     "The snake isn't poisonous, but bites pretty well. It has pretty "
  384.     "red and yellow stripes running down its length.",
  385.     MonsterInit, RandomMove,
  386.     8, 8, 9, 5, 4, 0)$
  387. AddModelAction(m_largeSnake, "slithers around")$
  388. AddModelAction(m_largeSnake, "hisses")$
  389. AddModelAction(m_largeSnake, "coils and uncoils")$
  390. m_largeSnake@p_Image := "Characters/largeSnake"$
  391. m_largeSnake@p_mSound := "largeSnake"$
  392. GNewIcon(m_largeSnake, makeSnakeIcon())$
  393.  
  394. define t_monsters m_goblin CreateMonsterModel("goblin,gob",
  395.     "The goblin is a small, humanoid creature with pale skin, large eyes, "
  396.     "protruding ears, and sharp teeth. It walks in a perpetual crouch but "
  397.     "is nonetheless quite fast on its feet.",
  398.     MonsterInit, RandomMove,
  399.     10, 8, 9, 6, 5, 30)$
  400. m_goblin@p_mBlocker := true$
  401. AddModelAction(m_goblin, "slouches around")$
  402. AddModelAction(m_goblin, "gibbers")$
  403. AddModelAction(m_goblin, "drools")$
  404. AddModelAction(m_goblin, "howls")$
  405. MakeMonsterSmart(m_goblin)$
  406. m_goblin@p_Image := "Characters/goblin"$
  407. m_goblin@p_mSound := "goblin"$
  408. GNewIcon(m_goblin, makeGoblinIcon())$
  409.  
  410. define t_monsters m_hugeRat CreateMonsterModel("rat;huge",
  411.     "The rat is quite large, but not totally filthy.",
  412.     MonsterInit, RandomMove,
  413.     8, 6, 10, 5, 8, 0)$
  414. m_hugeRat@p_mBlocker := true$
  415. AddModelAction(m_hugeRat, "runs around")$
  416. AddModelAction(m_hugeRat, "chitters loudly")$
  417. AddModelAction(m_hugeRat, "squeals loudly")$
  418. m_hugeRat@p_Image := "Characters/hugeRat"$
  419. m_hugeRat@p_mSound := "hugeRat"$
  420. GNewIcon(m_hugeRat, makeRatIcon())$
  421.  
  422. define t_monsters m_hugeSnake CreateMonsterModel("snake,snak,sna;huge",
  423.     "The snake isn't poisonous, but bites pretty well. It has a very striking "
  424.     "checkerboard pattern.",
  425.     MonsterInit, RandomMove,
  426.     16, 8, 10, 5, 8, 0)$
  427. m_hugeSnake@p_mBlocker := true$
  428. AddModelAction(m_hugeSnake, "slithers around")$
  429. AddModelAction(m_hugeSnake, "hisses")$
  430. AddModelAction(m_hugeSnake, "coils and uncoils")$
  431. m_hugeSnake@p_Image := "Characters/hugeSnake"$
  432. m_hugeSnake@p_mSound := "hugeSnake"$
  433. GNewIcon(m_hugeSnake, makeSnakeIcon())$
  434.  
  435. define t_monsters m_fighterGoblin CreateMonsterModel("goblin,gob;fighter",
  436.     "The goblin is a small, humanoid creature with pale skin, large eyes, "
  437.     "protruding ears, and sharp teeth. It walks in a perpetual crouch but "
  438.     "is nonetheless quite fast on its feet.",
  439.     MonsterInit, RandomMove,
  440.     20, 8, 10, 6, 10, 50)$
  441. m_fighterGoblin@p_mBlocker := true$
  442. AddModelAction(m_fighterGoblin, "slouches around")$
  443. AddModelAction(m_fighterGoblin, "gibbers")$
  444. AddModelAction(m_fighterGoblin, "drools")$
  445. AddModelAction(m_fighterGoblin, "howls")$
  446. MakeMonsterSmart(m_fighterGoblin)$
  447. m_fighterGoblin@p_Image := "Characters/fighterGoblin"$
  448. m_fighterGoblin@p_mSound := "fighterGoblin"$
  449. GNewIcon(m_fighterGoblin, makeGoblinIcon())$
  450.  
  451. define t_monsters m_hugeSpider CreateMonsterModel("spider,spi;huge",
  452.     "The spider's body is almost as large as yours, and it's long legs give "
  453.     "it good mobility and a long reach.",
  454.     MonsterInit, RandomMove,
  455.     16, 12, 15, 8, 12, 0)$
  456. m_hugeSpider@p_mBlocker := true$
  457. AddModelAction(m_hugeSpider, "dances around")$
  458. AddModelAction(m_hugeSpider, "clashes its fangs")$
  459. AddModelAction(m_hugeSpider, "drips saliva")$
  460. AddModelAction(m_hugeSpider, "waves its front legs menacingly")$
  461. m_hugeSpider@p_Image := "Characters/hugeSpider"$
  462. m_hugeSpider@p_mSound := "hugeSpider"$
  463. GNewIcon(m_hugeSpider, makeSpiderIcon())$
  464.  
  465. define t_monsters m_trackerSpider CreateMonsterModel("spider,spi;tracker",
  466.     "The spider's body is almost as large as yours, and it's long legs give "
  467.     "it good mobility and a long reach.",
  468.     TrackerInit, TrackerMove,
  469.     16, 12, 15, 8, 12, 0)$
  470. m_trackerSpider@p_mBlocker := true$
  471. m_trackerSpider@p_mKillAction := TrackerKill$
  472. AddModelAction(m_trackerSpider, "dances around")$
  473. AddModelAction(m_trackerSpider, "clashes its fangs")$
  474. AddModelAction(m_trackerSpider, "drips saliva")$
  475. AddModelAction(m_trackerSpider, "waves its front legs menacingly")$
  476. m_trackerSpider@p_Image := "Characters/trackerSpider"$
  477. m_trackerSpider@p_mSound := "trackerSpider"$
  478. GNewIcon(m_trackerSpider, makeTSpiderIcon())$
  479.  
  480. define t_monsters m_largeTroll CreateMonsterModel("troll,tro;large", "",
  481.     MonsterInit, RandomMove,
  482.     35, 4, 7, 6, 18, 80)$
  483. m_largeTroll@p_mBlocker := true$
  484. AddModelAction(m_largeTroll, "lumbers around")$
  485. AddModelAction(m_largeTroll, "bellows")$
  486. AddModelAction(m_largeTroll, "raises its fists and roars")$
  487. m_largeTroll@p_Image := "Characters/largeTroll"$
  488. m_largeTroll@p_mSound := "largeTroll"$
  489. GNewIcon(m_largeTroll, makeTrollIcon())$
  490.  
  491. unuse tp_monsters
  492.