Advertisement
Guest User

ZMR2018 :(

a guest
Oct 20th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 25.26 KB | None | 0 0
  1. #library "ZMRACS"
  2. #include "zcommon.acs"
  3.  
  4. #pragma define raw on
  5. #pragma block_scope on
  6. #pragma fixed off
  7. #define     DISABLE_DEBUG  
  8.  
  9. #ifndef DISABLE_DEBUG
  10. #define     ZMR_DEBUG_LOG       Log
  11.  
  12. #define     ZMR_ASSERT(expr)        if(!(expr)) \
  13.                                         ZMR_DEBUG_LOG(#expr)
  14.  
  15. #else
  16. #define     ZMR_DEBUG_LOG(...) 
  17. #define     ZMR_ASSERT(expr)       
  18. #endif
  19.  
  20. #define     tid_t           int
  21.  
  22. function tid_t zmr_create16KPage(void) {
  23.     tid_t resultTID = UniqueTID();
  24.     Spawn("ZMR_Page16k", 0, 0, 0, resultTID);
  25.     return resultTID;
  26. }
  27.  
  28. function tid_t zmr_createPathfinderMonster(void) {
  29.     tid_t resultTID = UniqueTID();
  30.     Spawn("ZMR_Pathfinder", 0, 0, 0, resultTID);
  31.     return resultTID;
  32. }
  33.  
  34. function tid_t zmr_createPatrolPoint(void) {
  35.     tid_t resultTID = UniqueTID();
  36.     Spawn("PatrolPoint", 0, 0, 0, resultTID);
  37.     return resultTID;
  38. }
  39.  
  40.  
  41.  
  42. #define     ZMR_KILOBYTE            (1024)
  43.  
  44. #define     ZMR_MEGABYTE            (ZMR_KILOBYTE * ZMR_KILOBYTE)
  45.  
  46. #define     ZMR_PAGE_SIZE           (4096*4)
  47. #define     ZMR_PAGE_FOR_PTR(p)     ((p) >> 14)
  48.  
  49. #define     ZMR_PAGE_OFFSET(p)      ((p) & (ZMR_PAGE_SIZE - 1))
  50.  
  51. #define     ZMR_MAX_MEMENTRIES      8192
  52.  
  53. #define     ZMR_MAX_PAGES           4096
  54.  
  55.  
  56. #define     zmr_page_t              int
  57.  
  58.  
  59. #define     ZMR_STARTUP_MEMORY      (ZMR_MEGABYTE * 5)
  60.  
  61. #define     ZMR_PREALLOC_PAGES      ((ZMR_STARTUP_MEMORY / ZMR_PAGE_SIZE) + 1)
  62.  
  63. struct zmr_mementry_t {
  64.     int offset;
  65.     int size;
  66.     bool claimed;
  67.     bool in_use;
  68. };
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75. zmr_mementry_t g_mementries[ZMR_MAX_MEMENTRIES];
  76.  
  77. zmr_page_t g_zmr_pages[ZMR_MAX_PAGES];
  78.  
  79. bool g_zmr_didinit = false;
  80.  
  81.  
  82. int g_zmr_current_free_memory = ZMR_STARTUP_MEMORY;
  83.  
  84.  
  85. function void zmr_init_mman(void) {
  86.     g_mementries[0].size = ZMR_STARTUP_MEMORY;
  87.     g_mementries[0].offset = 8;
  88.     g_mementries[0].in_use = true;
  89.     g_mementries[0].claimed = false;
  90.    
  91.     for(int i = 0; i < ZMR_PREALLOC_PAGES; ++i) {
  92.         g_zmr_pages[i] = zmr_create16KPage();
  93.     }
  94.     g_zmr_didinit = true;
  95. }
  96.  
  97. function void zmr_deinit_mman(void) {
  98.     for(int i = 0; i < ZMR_MAX_PAGES; ++i) {
  99.     g_mementries[i].size = 0;
  100.     g_mementries[i].offset = 0;
  101.     g_mementries[i].in_use = 0;
  102.     g_mementries[i].claimed = 0;
  103.     }
  104.    
  105.     for(int i = 0; i < ZMR_PREALLOC_PAGES; ++i) {
  106.         g_zmr_pages[i] = 0;
  107.     }
  108.     g_zmr_didinit = false;
  109.     g_zmr_current_free_memory = ZMR_STARTUP_MEMORY;
  110.    
  111. }
  112.  
  113.  
  114. function void zmr_ensure_init(void) {
  115.     if(!g_zmr_didinit) {
  116.         zmr_init_mman();
  117.     //  ZMR_DEBUG_LOG( s: "mman init");
  118.     }
  119. }
  120.  
  121. function void zmr_free_relocating(int i) {
  122.     if(i > 0 && g_mementries[i-1].claimed == false && g_mementries[i-1].in_use == true) {
  123.        
  124.         //set current entry to be unused, enlargen previous entry
  125.         g_mementries[i-1].size += g_mementries[i].size;
  126.         g_mementries[i].size = 0;
  127.         g_mementries[i].offset = -1;
  128.         g_mementries[i].in_use = false;
  129.         return;
  130.     }
  131.     else if((i+1) < ZMR_MAX_MEMENTRIES && g_mementries[i+1].in_use == true && g_mementries[i+1].claimed == false) {
  132.         g_mementries[i].size += g_mementries[i+1].size;
  133.         g_mementries[i+1].size = 0;
  134.         g_mementries[i+1].offset = -1;
  135.         g_mementries[i+1].in_use = false;
  136.     }
  137.     else if(i > 0 && g_mementries[i-1].in_use == false) {
  138.         g_mementries[i-1].size = g_mementries[i].size;
  139.         g_mementries[i-1].offset = g_mementries[i].offset;
  140.         g_mementries[i-1].in_use = true;
  141.         g_mementries[i].size = 0;
  142.         g_mementries[i].offset = -1;
  143.         g_mementries[i].in_use = false;
  144.     }
  145. }
  146.  
  147. function void zmr_malloc_relocating(int i, int size) {
  148.     if(g_mementries[i].size == size)
  149.         return;
  150.     int relocate_size = g_mementries[i].size - size;
  151.     if(i > 0 && g_mementries[i-1].claimed == false && g_mementries[i-1].in_use == true) {
  152.        
  153.         /*
  154.             an entry prior to this one is present,
  155.             the prior entry is a record of memory that is free
  156.            
  157.             we need to make the previous entry larger by giving it the bytes in our entry
  158.             that we do not need
  159.            
  160.             prior->size += current->size - size;
  161.             current->offset += current->size - size;
  162.             current->size = size;
  163.            
  164.             we relocate the unused bytes to prior, advance our offset to be after prior, and set our size to the new size
  165.         */
  166.        
  167.         g_mementries[i-1].size += relocate_size;
  168.         g_mementries[i].offset += relocate_size;
  169.         g_mementries[i].size = size;
  170.     }
  171.     else if((i+1) < ZMR_MAX_MEMENTRIES && g_mementries[i+1].in_use == true && g_mementries[i+1].claimed == false) {
  172.    
  173.         /*
  174.             inverse of prior, we relocate bytes to the next entry, moving its offset back
  175.         */
  176.         g_mementries[i+1].size += relocate_size;
  177.         g_mementries[i+1].offset -= relocate_size;
  178.         g_mementries[i].size = size;
  179.  
  180.     }
  181.     else if(i > 0 && g_mementries[i-1].in_use == false) {
  182.        
  183.         g_mementries[i-1].in_use = true;
  184.         g_mementries[i-1].size = relocate_size;
  185.         g_mementries[i-1].offset = g_mementries[i].offset;
  186.         g_mementries[i-1].claimed = false;
  187.         g_mementries[i].offset += relocate_size;
  188.         g_mementries[i].size = size;
  189.     }
  190.     else if((i+1) < ZMR_MAX_MEMENTRIES && g_mementries[i+1].in_use == false) {
  191.        
  192.         g_mementries[i+1].in_use = true;
  193.         g_mementries[i+1].size = relocate_size;
  194.         g_mementries[i+1].offset = g_mementries[i].offset + size;
  195.         g_mementries[i+1].claimed = false;
  196.         g_mementries[i].size = size;
  197.     }
  198. }
  199.  
  200. function int zmr_malloc(int size) {
  201.     ZMR_ASSERT(size < g_zmr_current_free_memory && size > 0);
  202.    
  203.     for(int i = 0; i < ZMR_MAX_MEMENTRIES;++i) {
  204.         if(g_mementries[i].claimed == false && g_mementries[i].in_use == true && g_mementries[i].size >= size) {
  205.             g_mementries[i].claimed = true;
  206.             zmr_malloc_relocating(i, size);
  207.             g_zmr_current_free_memory -= size;
  208.             int result = g_mementries[i].offset;
  209.            
  210.             //ZMR_DEBUG_LOG(s:"Allocated memory, offset is ", d:result, s:".");
  211.             return result;
  212.         }
  213.     }
  214.     return 0;
  215. }
  216.  
  217.  
  218. function bool zmr_free(int offset) {
  219.     for(int i = 0; i < ZMR_MAX_MEMENTRIES;++i) {
  220.         if(g_mementries[i].offset == offset) {
  221.             int sz = g_mementries[i].size;
  222.            
  223.             g_mementries[i].claimed = false;
  224.             zmr_free_relocating(i);
  225.             g_zmr_current_free_memory += sz;
  226.             return true;
  227.         }
  228.     }
  229.     return false;
  230. }
  231.  
  232.  
  233.  
  234. function void zmr_write_i32(int ptr, int value) {
  235.     ZMR_ASSERT(ptr != 0);
  236.     ZMR_ASSERT((ptr & 3) == 0); //must be int aligned
  237.  
  238.     SetUserArray(g_zmr_pages[ZMR_PAGE_FOR_PTR(ptr)], "user_data", (ZMR_PAGE_OFFSET(ptr)) >> 2, value);
  239. }
  240.  
  241. function int zmr_read_i32(int ptr) {
  242.     ZMR_ASSERT(ptr != 0);
  243.     ZMR_ASSERT((ptr & 3) == 0); //must be int aligned
  244.     return GetUserArray(g_zmr_pages[ZMR_PAGE_FOR_PTR(ptr)], "user_data", ZMR_PAGE_OFFSET(ptr) >> 2);
  245. }
  246.  
  247.  
  248. #define N_MONSTER_CLASSES 20
  249. int g_total_monsters = 0;
  250.  
  251. str g_monster_classes[N_MONSTER_CLASSES] = {
  252.     "SpiderMastermind",
  253.     "Cyberdemon",
  254.     "Archvile",
  255.     "Arachnotron",
  256.     "StealthArachnotron",
  257.     "BaronOfHell",
  258.     "Revenant",
  259.     "StealthRevenant",
  260.     "PainElemental",
  261.     "Fatso",
  262.     "HellKnight",
  263.     "Cacodemon",
  264.     "Spectre",
  265.     "ChaingunGuy",
  266.     "Demon",
  267.     "ShotgunGuy",
  268.     "DoomImp",
  269.     "LostSoul",
  270.     "WolfensteinSS",
  271.     "ZombieMan"
  272. };
  273.  
  274. str g_weight_cvar_strings[N_MONSTER_CLASSES] = {
  275.     "SpiderMastermind_weight",
  276.     "Cyberdemon_weight",
  277.     "Archvile_weight",
  278.     "Arachnotron_weight",
  279.     "StealthArachnotron_weight",
  280.     "BaronOfHell_weight",
  281.     "Revenant_weight",
  282.     "StealthRevenant_weight",
  283.     "PainElemental_weight",
  284.     "Fatso_weight",
  285.     "HellKnight_weight",
  286.     "Cacodemon_weight",
  287.     "Spectre_weight",
  288.     "ChaingunGuy_weight",
  289.     "Demon_weight",
  290.     "ShotgunGuy_weight",
  291.     "DoomImp_weight",
  292.     "LostSoul_weight",
  293.     "WolfensteinSS_weight",
  294.     "ZombieMan_weight"
  295.  
  296. };
  297.  
  298. int g_n_monsters_of_class[N_MONSTER_CLASSES] = {0};
  299.  
  300.  
  301. int g_monster_ratios[N_MONSTER_CLASSES] = {0};
  302.  
  303.  
  304. #define     zmr_patherptr_t     int
  305. #define     zmr_pointvec_t      int
  306. enum {
  307.     ZMR_PATHER_FIELD_startx = 0,
  308.     ZMR_PATHER_FIELD_starty = 4,
  309.     ZMR_PATHER_FIELD_startz = 8,
  310.     ZMR_PATHER_FIELD_goalx = 12,
  311.     ZMR_PATHER_FIELD_goaly = 16,
  312.     ZMR_PATHER_FIELD_goalz = 20,
  313.     ZMR_PATHER_FIELD_tid = 24,
  314.     ZMR_PATHER_FIELD_flags = 28,
  315.     ZMR_PATHER_FIELD_points = 32,
  316.     ZMR_PATHER_FIELD_goaltid = 36,
  317.     ZMR_PATHER_FIELD_tickpoll = 40,
  318.     ZMR_PATHER_FIELD_nextpather = 44,
  319.     ZMR_PATHER_FIELD_lasttick = 48,
  320.     ZMR_PATHER_FIELD_speed = 52,
  321.     ZMR_SIZEOF_PATHER = 56
  322. }
  323.  
  324. enum {
  325.     ZMR_PATHER_FLAGS_in_use = 1,
  326.     ZMR_PATHER_FLAGS_allocated = 2,
  327.     ZMR_PATHER_FLAGS_completed = 4,
  328.     ZMR_PATHER_FLAGS_failed = 8
  329. }
  330.  
  331.  
  332. #define     ZMR_PATHER_SET_START(pather, x, y, z) {\
  333.             zmr_patherptr_t _pather = (pather); \
  334.             int _x = (x);\
  335.             int _y = (y);\
  336.             int _z = (z);\
  337.             Warp(zmr_read_i32(_pather + ZMR_PATHER_FIELD_tid), _x, _y, _z, 0, WARPF_ABSOLUTEPOSITION);\
  338.             zmr_write_i32(_pather + ZMR_PATHER_FIELD_startx, _x);\
  339.             zmr_write_i32(_pather + ZMR_PATHER_FIELD_starty, _y);\
  340.             zmr_write_i32(_pather + ZMR_PATHER_FIELD_startx, _z);\
  341.             }
  342.  
  343.  
  344.  
  345. #define     ZMR_PATHER_SET_GOAL(pather, x, y, z) {\
  346.             zmr_patherptr_t _pather = (pather); \
  347.             int _x = (x);\
  348.             int _y = (y);\
  349.             int _z = (z);\
  350.             tid_t goal_tid = zmr_read_i32(_pather + ZMR_PATHER_FIELD_goaltid);\
  351.             Warp(goal_tid, _x, _y, _z, 0, WARPF_ABSOLUTEPOSITION);\
  352.             zmr_write_i32(_pather + ZMR_PATHER_FIELD_goalx, _x);\
  353.             zmr_write_i32(_pather + ZMR_PATHER_FIELD_goaly, _y);\
  354.             zmr_write_i32(_pather + ZMR_PATHER_FIELD_goalx, _z);\
  355.             Thing_SetGoal(zmr_read_i32(_pather + ZMR_PATHER_FIELD_tid), goal_tid, 0, 1);\
  356.             }
  357.  
  358. zmr_patherptr_t g_zmr_first_pather = 0;
  359.  
  360. zmr_patherptr_t g_zmr_previous_pather = 0;
  361.  
  362. function zmr_patherptr_t zmr_create_pathfinder(void) {
  363.     zmr_patherptr_t pather = zmr_malloc(ZMR_SIZEOF_PATHER);
  364.     ZMR_ASSERT(pather != 0);
  365.    
  366.     zmr_write_i32(pather + ZMR_PATHER_FIELD_flags, 0);
  367.     zmr_write_i32(pather + ZMR_PATHER_FIELD_tid, zmr_createPathfinderMonster());
  368.     zmr_write_i32(pather + ZMR_PATHER_FIELD_goaltid, zmr_createPatrolPoint());
  369.     zmr_write_i32(pather + ZMR_PATHER_FIELD_nextpather, 0);
  370.     zmr_write_i32(pather + ZMR_PATHER_FIELD_points, 0);
  371.    
  372.     /*
  373.         save first pather so we can iterate over them
  374.     */
  375.     if(g_zmr_first_pather == 0) {
  376.    
  377.         g_zmr_first_pather = pather;
  378.     }
  379.     else {
  380.     /*
  381.         link new pather into the global list
  382.     */
  383.         zmr_write_i32(g_zmr_previous_pather + ZMR_PATHER_FIELD_nextpather, pather);
  384.        
  385.     }
  386.     g_zmr_previous_pather = pather;
  387.     return pather;
  388. }
  389.  
  390. #define     ZMR_FOREACH_PATHER(indexvar)        for(zmr_patherptr_t indexvar = g_zmr_first_pather; indexvar != 0; indexvar = zmr_read_i32(indexvar + ZMR_PATHER_FIELD_nextpather))
  391.  
  392. /*
  393.     find an unused pathfinder in the global list to reuse
  394.     or allocate a new one
  395. */
  396. function zmr_patherptr_t zmr_allocate_pathfinder(void) {
  397.     ZMR_FOREACH_PATHER(pather) {
  398.         int pather_flags = zmr_read_i32(pather + ZMR_PATHER_FIELD_flags);
  399.         if((pather_flags & ZMR_PATHER_FLAGS_allocated) == 0) {
  400.             zmr_write_i32(pather + ZMR_PATHER_FIELD_flags, pather_flags | ZMR_PATHER_FLAGS_allocated);
  401.             return pather;
  402.         }
  403.     }
  404.    
  405.     zmr_patherptr_t new_pather = zmr_create_pathfinder();
  406.     zmr_write_i32(new_pather + ZMR_PATHER_FIELD_flags, ZMR_PATHER_FLAGS_allocated);
  407.     return new_pather;
  408. }
  409.  
  410. function void zmr_release_pathfinder(zmr_patherptr_t pather) {
  411.     ZMR_ASSERT(pather != 0);
  412.     zmr_pointvec_t point_data = zmr_read_i32(pather + ZMR_PATHER_FIELD_points);
  413.     if(point_data != 0) {
  414.         zmr_free(point_data);
  415.         zmr_write_i32(pather + ZMR_PATHER_FIELD_points, 0);
  416.     }
  417.     zmr_write_i32(pather + ZMR_PATHER_FIELD_flags, zmr_read_i32(pather + ZMR_PATHER_FIELD_flags) & (~ZMR_PATHER_FLAGS_allocated));
  418.    
  419. }
  420.  
  421.  
  422.  
  423. enum {
  424.     ZMR_POINTVEC_FIELD_position = 0,
  425.     ZMR_POINTVEC_FIELD_nalloc = 4,
  426.     ZMR_SIZEOF_POINTVEC = 8
  427. }
  428.  
  429. enum {
  430.     ZMR_POINT_FIELD_x = 0,
  431.     ZMR_POINT_FIELD_y = 4,
  432.     ZMR_POINT_FIELD_z = 8,
  433.     ZMR_SIZEOF_POINT = 12
  434. }
  435.  
  436.  
  437. function zmr_pointvec_t zmr_create_pointvec(int maxpoints) {
  438.     ZMR_ASSERT(maxpoints > 0);
  439.    
  440.     zmr_pointvec_t points = zmr_malloc(ZMR_SIZEOF_POINTVEC + (ZMR_SIZEOF_POINT * maxpoints));
  441.     ZMR_ASSERT(points != 0);
  442.    
  443.     zmr_write_i32(points + ZMR_POINTVEC_FIELD_position, 0);
  444.     zmr_write_i32(points + ZMR_POINTVEC_FIELD_nalloc, maxpoints);
  445.     return points;
  446. }
  447.  
  448. function void zmr_release_pointvec(zmr_pointvec_t points) {
  449.     ZMR_ASSERT(points != 0);
  450.     zmr_free(points);
  451. }
  452.  
  453.  
  454. function void zmr_pointvec_set_at(zmr_pointvec_t points, int x, int y, int z, int index) {
  455.     int start_offs = (points + ZMR_SIZEOF_POINTVEC) + (index * ZMR_SIZEOF_POINT);
  456.    
  457.     zmr_write_i32(start_offs + ZMR_POINT_FIELD_x, x);
  458.     zmr_write_i32(start_offs + ZMR_POINT_FIELD_y, y);
  459.     zmr_write_i32(start_offs + ZMR_POINT_FIELD_z, z);
  460.    
  461. }
  462.  
  463. function zmr_patherptr_t zmr_find_path(
  464. int startx, int starty, int startz,
  465. int goalx, int goaly, int goalz,
  466. int movement_speed, int tick_granularity, int maxpoints) {
  467.     zmr_patherptr_t pather = zmr_allocate_pathfinder();
  468.    
  469.     ZMR_ASSERT(pather != 0);
  470.    
  471.     ZMR_PATHER_SET_START(pather, startx, starty, startz)
  472.     zmr_write_i32(pather + ZMR_PATHER_FIELD_lasttick, Timer());
  473.    
  474.     zmr_write_i32(pather + ZMR_PATHER_FIELD_tickpoll, tick_granularity);
  475.     zmr_write_i32(pather + ZMR_PATHER_FIELD_points, zmr_create_pointvec(maxpoints));
  476.     ZMR_PATHER_SET_GOAL(pather, goalx, goaly, goalz)
  477.     zmr_write_i32(pather + ZMR_PATHER_FIELD_speed, movement_speed);
  478.    
  479.     SetActorProperty( zmr_read_i32(pather + ZMR_PATHER_FIELD_tid), APROP_SPEED, movement_speed);
  480.    
  481.    
  482.     zmr_write_i32(pather + ZMR_PATHER_FIELD_flags, zmr_read_i32(pather + ZMR_PATHER_FIELD_flags) | ZMR_PATHER_FLAGS_in_use);
  483.    
  484.     return pather;
  485.    
  486. }
  487.  
  488.  
  489.  
  490. int
  491. g_current_unique_id = 1;
  492.  
  493.  
  494.  
  495. int g_uid_tid_lut = 0;
  496.  
  497. int g_uid_tid_mod = 0;
  498.  
  499.  
  500. //i swear to god, this value wasnt randomly chosen. i used the m,n formula for collision calculation and this
  501. //was the ideal table scale
  502. #define     ZMR_ZEROCOLLIDE_SCALE       666
  503.  
  504. #define     ZMR_MONSTER_DATA_SIZE       512
  505.  
  506.  
  507.  
  508.  
  509.  
  510. enum {
  511.     ZMR_MONSTER_FIELD_prev = 0,
  512.     ZMR_MONSTER_FIELD_next = 4,
  513.     ZMR_MONSTER_FIELD_thingid = 8,
  514.     ZMR_MONSTER_FIELD_lastx = 12,
  515.     ZMR_MONSTER_FIELD_lasty = 16,
  516.     ZMR_MONSTER_FIELD_lastz = 20,
  517.     ZMR_MONSTER_FIELD_buddy = 24,
  518.     ZMR_MONSTER_FIELD_dead  = 28,
  519.     ZMR_MONSTER_FIELD_initial_health = 32,
  520.     ZMR_MONSTER_FIELD_flee_timepoint = 36,
  521.     ZMR_MONSTER_FIELD_is_fleeing = 40,
  522.     ZMR_MONSTER_FIELD_has_missile = 44
  523. }
  524.  
  525. #define     zmr_monsterptr_t                int
  526.  
  527. #define     ZMR_M0NSTER_READ(monster, field, type)              zmr_read_##type ((monster) + (ZMR_MONSTER_FIELD_##field  ))
  528. #define     ZMR_M0NSTER_WRITE(monster, field, type, val)        zmr_write_##type ((monster) +ZMR_MONSTER_FIELD_##field , (val))
  529. zmr_monsterptr_t g_zmr_last_monster_alloc = 0;
  530. zmr_monsterptr_t g_zmr_first_monster = 0;
  531.  
  532.  
  533. function zmr_monsterptr_t zmr_alloc_monster_data(void) {
  534.  
  535.     zmr_monsterptr_t p = zmr_malloc(ZMR_MONSTER_DATA_SIZE);
  536.    
  537.     ZMR_M0NSTER_WRITE(p, prev, i32, g_zmr_last_monster_alloc);
  538.    
  539.     if(g_zmr_last_monster_alloc != 0)
  540.         ZMR_M0NSTER_WRITE(g_zmr_last_monster_alloc, next, i32, p);
  541.     else
  542.         g_zmr_first_monster = p;
  543.        
  544.     g_zmr_last_monster_alloc = p;
  545.     return p;
  546. }
  547.  
  548. bool g_zmr_monster_globals_initialized = false;
  549.  
  550.  
  551. function void zmr_monster_global_ensure_init(void) {
  552.     if(!g_zmr_monster_globals_initialized) {
  553.    
  554.        
  555.         zmr_ensure_init();
  556.        
  557.         //WASTE MEMORY
  558.         zmr_malloc(32);
  559.         g_total_monsters = GetLevelInfo(LEVELINFO_TOTAL_MONSTERS);
  560.         g_uid_tid_mod = (g_total_monsters) * ZMR_ZEROCOLLIDE_SCALE;
  561.         g_uid_tid_lut = zmr_malloc(((g_total_monsters) * ZMR_ZEROCOLLIDE_SCALE) * sizeof(int));
  562.        
  563.        
  564.         g_zmr_monster_globals_initialized = true;
  565.            
  566.     ACS_NamedExecute("ZMR_UpdateBuddies", 0);
  567.     ACS_NamedExecute("ZMR_UpdatePaths", 0);
  568.     }
  569. }
  570.  
  571.  
  572.  
  573. /*
  574.     zero is not a valid uid
  575. */
  576. function bool zmr_monster_has_uid(int tid) {
  577.     return GetUserVariable(tid, "user_ZMR_enemy_uid") != 0;
  578. }
  579.  
  580. function int zmr_monster_get_uid(int tid) {
  581.     return GetUserVariable(tid, "user_ZMR_enemy_uid");
  582. }
  583.  
  584. function void zmr_assign_uid_impl(void) {
  585.     zmr_monster_global_ensure_init();
  586.     g_current_unique_id = g_current_unique_id + 1;
  587.     SetUserVariable(0, "user_ZMR_enemy_uid", g_current_unique_id);
  588.     zmr_monsterptr_t myptr = zmr_alloc_monster_data();
  589.     if(ActivatorTID() ==0)
  590.         Thing_ChangeTID(0, UniqueTID());
  591.     int _tid = ActivatorTID();
  592.     if(_tid == 0) {
  593.         //ZMR_DEBUG_LOG(s:"Got a zero tid in ZMR_AssignUID!");
  594.     }
  595.     ZMR_M0NSTER_WRITE(myptr, thingid, i32, _tid);
  596.     zmr_write_i32(myptr + ZMR_MONSTER_FIELD_initial_health, GetActorProperty(_tid, APROP_HEALTH));
  597.     zmr_set_monster_dataptr(g_current_unique_id, myptr);
  598.    
  599. }
  600.  
  601.  
  602. function zmr_monsterptr_t zmr_get_monster_dataptr(int uid) {
  603. zmr_monster_global_ensure_init();
  604.     if(uid == 0) {
  605.    
  606.         zmr_assign_uid_impl();
  607.        
  608.         return 0;
  609.     }
  610.     zmr_monsterptr_t result = zmr_read_i32( g_uid_tid_lut + ((uid % g_uid_tid_mod) << 2));
  611.     ZMR_ASSERT(result != 0);
  612.     return result;
  613. }
  614. function void zmr_set_monster_dataptr(int uid, zmr_monsterptr_t dataptr) {
  615.     ZMR_ASSERT(dataptr != 0);
  616.    
  617.     zmr_write_i32( g_uid_tid_lut + ((uid % g_uid_tid_mod)  << 2), dataptr);
  618. }
  619.  
  620.  
  621.  
  622. #define     ZMR_FOREACH_MONSTER(indexname)      for(zmr_monsterptr_t indexname = g_zmr_first_monster; indexname != 0; indexname = zmr_read_i32(indexname + ZMR_MONSTER_FIELD_next))
  623.  
  624. #define     ZMR_MONSTER_IS_DEAD(monster)        (GetActorProperty(zmr_read_i32((monster) + ZMR_MONSTER_FIELD_thingid), APROP_Health) <= 0)
  625.  
  626. //(zmr_read_i32((monster) + ZMR_MONSTER_FIELD_dead) != 0
  627.  
  628. function zmr_monsterptr_t find_closest_monster(zmr_monsterptr_t self) {
  629.    
  630.     if(self == 0)
  631.         return 0;
  632.     int mytid = zmr_read_i32(self+ZMR_MONSTER_FIELD_thingid);
  633.    
  634.     int selfx = GetActorX(mytid),//zmr_read_i32(self + ZMR_MONSTER_FIELD_lastx),
  635.         selfy = GetActorY(mytid),//zmr_read_i32(self + ZMR_MONSTER_FIELD_lasty),
  636.         selfz = GetActorZ(mytid);//zmr_read_i32(self + ZMR_MONSTER_FIELD_lastz);
  637.        
  638.    
  639.     int smallest_absdistance = 0x7fffffff;
  640.    
  641.     zmr_monsterptr_t closest_found = 0;
  642.    
  643.     ZMR_FOREACH_MONSTER(i) {
  644.         if(i == self || ZMR_MONSTER_IS_DEAD(i) )
  645.             continue;
  646.         int theirtid = zmr_read_i32(i+ZMR_MONSTER_FIELD_thingid);
  647.        
  648.     int x = GetActorX(theirtid);//zmr_read_i32(i + ZMR_MONSTER_FIELD_lastx);
  649.     int y = GetActorY(theirtid);//zmr_read_i32(i + ZMR_MONSTER_FIELD_lasty);
  650.     //int z = zmr_read_i32(i + ZMR_MONSTER_FIELD_lastz);
  651.    
  652.    
  653.     int len = VectorLength(selfx - x, selfy - y);
  654.     //len = VectorLength(selfz - z, len);
  655.    
  656.    
  657.     if(len < smallest_absdistance) {
  658.         smallest_absdistance = len;
  659.         closest_found = i;
  660.     }
  661.        
  662.     }
  663.     //ZMR_DEBUG_LOG(s:"Closest found is ", d: smallest_absdistance);
  664.    
  665.     return closest_found;
  666. }
  667.  
  668. Script "ZMR_UpdateBuddies" (void) NET {
  669. zmr_monster_global_ensure_init();
  670.     while(true) {
  671.         Delay(1);
  672.         int counter = 0;
  673.         ZMR_FOREACH_MONSTER(i) {
  674.             if(ZMR_MONSTER_IS_DEAD(i))
  675.                 continue;
  676.                
  677.             zmr_write_i32(i + ZMR_MONSTER_FIELD_buddy, find_closest_monster(i));
  678.             ++counter;
  679.            
  680.             if((counter & 0xF) == 0)
  681.                 Delay(1);
  682.         }
  683.     }
  684. }
  685. Script "ZMR_UpdatePaths" (void) NET  {
  686. zmr_monster_global_ensure_init();
  687.     while(true) {
  688.         Delay(10);
  689.         int current_tick = Timer();
  690.         ZMR_FOREACH_PATHER(path) {
  691.             int flags = zmr_read_i32(path + ZMR_PATHER_FIELD_flags);
  692.             if( (flags & (ZMR_PATHER_FLAGS_completed | ZMR_PATHER_FLAGS_failed)) != 0
  693.                 ||
  694.                 (flags & ZMR_PATHER_FLAGS_in_use) == 0)
  695.                 continue;
  696.            
  697.             int last_tick = zmr_read_i32(path + ZMR_PATHER_FIELD_lasttick);
  698.             int tickpoll = zmr_read_i32(path + ZMR_PATHER_FIELD_tickpoll);
  699.            
  700.             if( (last_tick + tickpoll) < current_tick) {
  701.                 continue;
  702.             }
  703.            
  704.             zmr_write_i32(path + ZMR_PATHER_FIELD_lasttick, current_tick);
  705.            
  706.            
  707.             zmr_pointvec_t points = zmr_read_i32(path + ZMR_PATHER_FIELD_points);
  708.             ZMR_ASSERT(points != 0);
  709.            
  710.             int current_pointvec_index = zmr_read_i32(points + ZMR_POINTVEC_FIELD_position);
  711.            
  712.             int pointvec_nalloc = zmr_read_i32(points + ZMR_POINTVEC_FIELD_nalloc);
  713.            
  714.             int pather_tid = zmr_read_i32(path + ZMR_PATHER_FIELD_tid);
  715.            
  716.             int currentx = GetActorX(pather_tid),
  717.                 currenty = GetActorY(pather_tid),
  718.                 currentz = GetActorZ(pather_tid);
  719.            
  720.             int goalx = zmr_read_i32(path + ZMR_PATHER_FIELD_goalx),
  721.                 goaly = zmr_read_i32(path + ZMR_PATHER_FIELD_goaly),
  722.                 goalz = zmr_read_i32(path + ZMR_PATHER_FIELD_goalz);
  723.                
  724.            
  725.            
  726.             int len = VectorLength(goalx - currentx, goaly - currenty);
  727.             len = VectorLength(goalz - currentz, len);
  728.            
  729.            
  730.             int movement_speed = zmr_read_i32(path + ZMR_PATHER_FIELD_speed);
  731.            
  732.             if( len < movement_speed) {
  733.                 zmr_write_i32(path + ZMR_PATHER_FIELD_flags, flags | ZMR_PATHER_FLAGS_completed);
  734.                 SetActorProperty( pather_tid, APROP_SPEED, 0);
  735.             }
  736.            
  737.             else if((current_pointvec_index + 1) >= pointvec_nalloc) {
  738.                 zmr_write_i32(path + ZMR_PATHER_FIELD_flags, flags | ZMR_PATHER_FLAGS_failed);
  739.                 SetActorProperty( pather_tid, APROP_SPEED, 0);
  740.                 continue;
  741.             }
  742.            
  743.            
  744.             zmr_pointvec_set_at(points, currentx, currenty, currentz, current_pointvec_index);
  745.            
  746.             zmr_write_i32(points + ZMR_POINTVEC_FIELD_position, current_pointvec_index + 1);
  747.            
  748.         }
  749.     }
  750. }
  751. Script 32766 OPEN NET
  752. {
  753.     zmr_monster_global_ensure_init();
  754.    
  755.     for( int i = 0; i < N_MONSTER_CLASSES; ++i) {
  756.         g_n_monsters_of_class[i] = ThingCountName(g_monster_classes[i], 0);
  757.         if(g_n_monsters_of_class[i] != 0)
  758.             g_monster_ratios[i] = (g_total_monsters/ g_n_monsters_of_class[i]);
  759.  
  760.                     int x = ((N_MONSTER_CLASSES+1) - i) * g_monster_ratios[i];
  761.             SetCVar(g_weight_cvar_strings[i], x);
  762.     }
  763.    
  764.     ACS_NamedExecute("ZMR_UpdateBuddies", 0);
  765.     ACS_NamedExecute("ZMR_UpdatePaths", 0);
  766.    
  767. }
  768.  
  769.  
  770.  
  771. #define     ZMR_thunk_prologue  \
  772.             zmr_monster_global_ensure_init();\
  773.             if(zmr_monster_has_uid(0) == false)\
  774.                 terminate;\
  775.             zmr_monsterptr_t self = zmr_get_monster_dataptr(zmr_monster_get_uid(ActivatorTID()) );\
  776.             if(self == 0) \
  777.                 terminate;\
  778.             zmr_write_i32(self + ZMR_MONSTER_FIELD_lastx, GetActorX(0));\
  779.             zmr_write_i32(self + ZMR_MONSTER_FIELD_lasty, GetActorY(0));\
  780.             zmr_write_i32(self + ZMR_MONSTER_FIELD_lastz, GetActorZ(0));
  781.            
  782.            
  783.  
  784. Script "ZMR_OnDeath" KILL NET {
  785.     ZMR_thunk_prologue
  786.    
  787.    
  788.  
  789.  
  790.     ZMR_DEBUG_LOG(s:"Dead monster had tid ", d: ZMR_M0NSTER_READ( self, thingid, i32), s:".");
  791.     ZMR_DEBUG_LOG(s:"Dead monster had buddy with tid ", d: ZMR_M0NSTER_READ( zmr_read_i32(self + ZMR_MONSTER_FIELD_buddy), thingid, i32), s:".");
  792.  
  793.  
  794.     zmr_write_i32(self + ZMR_MONSTER_FIELD_dead, 1);
  795.     SetActivatorToTarget(0);
  796.    
  797.     int target = ActivatorTID();
  798.    
  799.    
  800.     zmr_monsterptr_t buddy = zmr_read_i32(self + ZMR_MONSTER_FIELD_buddy);
  801.    
  802.     if(buddy == 0 )//|| ZMR_MONSTER_IS_DEAD(buddy))
  803.         terminate;
  804.        
  805.     //SetActivator(zmr_read_i32(buddy + ZMR_MONSTER_FIELD_thingid));
  806.    
  807.     //SetPointer(AAPTR_TARGET, target);
  808.     //SetActorState(0, "See");
  809.    
  810.     int i = 0;
  811.     zmr_monsterptr_t otherbuddy;
  812.     for( otherbuddy = zmr_read_i32(buddy + ZMR_MONSTER_FIELD_buddy); otherbuddy != 0 && otherbuddy != buddy;
  813.        
  814.        
  815.         otherbuddy = zmr_read_i32(otherbuddy + ZMR_MONSTER_FIELD_buddy),++i) {
  816.        
  817.        
  818.         if(i > 4)
  819.             break;
  820.         if (!ZMR_MONSTER_IS_DEAD(otherbuddy)){
  821.  
  822.         SetActivator(zmr_read_i32(otherbuddy + ZMR_MONSTER_FIELD_thingid));
  823.        
  824.         SetPointer(AAPTR_TARGET, target);
  825.         SetActorState(0, "See");
  826.         buddy = otherbuddy;
  827.         }
  828.     }
  829.    
  830.    
  831.    
  832.     if(i != 0) {
  833.         ZMR_DEBUG_LOG(s:"They're coming for you! ", d:i );
  834.     }
  835.     else
  836.         ZMR_DEBUG_LOG(s:"He's coming for you!");
  837. }
  838.  
  839.  
  840.            
  841.  
  842.  
  843. Script "ZMR_Hierophant_GravManip" (void) {
  844. }
  845.  
  846.  
  847.  
  848.  
  849. Script "ZMR_monster_OnIdle" (void) {
  850. }
  851.  
  852. script "ZMR_monster_OnSee" (void) NET {
  853. ZMR_thunk_prologue
  854.  
  855.  
  856. }
  857.  
  858. script "ZMR_monster_OnMelee" (void) {
  859.  
  860. }
  861.  
  862. script "ZMR_monster_OnMissile" (void) NET {
  863. ZMR_thunk_prologue
  864.     zmr_write_i32(self + ZMR_MONSTER_FIELD_has_missile, 1);
  865.    
  866. }
  867.  
  868. script "ZMR_monster_OnPain" (void) NET {
  869.     ZMR_thunk_prologue
  870.     int curr_tick = Timer();
  871.     if(zmr_read_i32(self + ZMR_MONSTER_FIELD_is_fleeing) == 1) {
  872.        
  873.         if( curr_tick - zmr_read_i32(self + ZMR_MONSTER_FIELD_flee_timepoint) >= 50) {
  874.            
  875.             zmr_write_i32(self + ZMR_MONSTER_FIELD_is_fleeing, 0);
  876.             SetActorProperty(0, APROP_Frightened, 0);
  877.             int original_speed = GetActorProperty(0, APROP_Speed);
  878.             original_speed = (original_speed >> 2) * 3;
  879.             SetActorProperty(0, APROP_Speed, original_speed);
  880.             ZMR_DEBUG_LOG(s:"Nah, fuck you.");
  881.             /*
  882.                 We put some distance between us and them, so if we have
  883.                 a missile attack use it
  884.             */
  885.             if(zmr_read_i32(self + ZMR_MONSTER_FIELD_has_missile) == 1)
  886.                 SetActorState(0, "Missile");
  887.             else {
  888.                 SetActorState(0, "See");
  889.             }
  890.         }
  891.         else
  892.             terminate;
  893.     }
  894.     int myhealth = GetActorProperty(0, APROP_Health);
  895.     int initial_health = zmr_read_i32(self + ZMR_MONSTER_FIELD_initial_health);
  896.    
  897.     /*
  898.         panic mode - 50% health - 25%
  899.     */
  900.     if(myhealth < (initial_health >> 1) && myhealth >= (initial_health >> 2) ) {
  901.         SetActorProperty(0, APROP_Frightened, 1);
  902.         int original_speed = GetActorProperty(0, APROP_Speed);
  903.         original_speed += original_speed >> 1;
  904.         SetActorProperty(0, APROP_Speed, original_speed);
  905.         zmr_write_i32(self + ZMR_MONSTER_FIELD_flee_timepoint, curr_tick);
  906.         zmr_write_i32(self + ZMR_MONSTER_FIELD_is_fleeing, 1);
  907.         ZMR_DEBUG_LOG(s:"I'm scared!");
  908.     }
  909.     /*
  910.         desperation - other monsters attacking this monster should leave them alone
  911.        
  912.         monster attacks slightly faster in a sort of frenzied way
  913.     */
  914.     else if (myhealth < (initial_health >> 2)) {
  915.         int reaction_time = GetActorProperty(0, APROP_ReactionTime);
  916.         SetActorProperty(0, APROP_ReactionTime, reaction_time + (reaction_time >> 3));
  917.         SetActorProperty(0, APROP_NOTARGET, 1);
  918.         ZMR_DEBUG_LOG(s:"I'm desperate");
  919.     }
  920.    
  921.    
  922.    
  923. }
  924.    
  925.  
  926. script "ZMR_monster_OnResurrected" (void) NET {
  927.             zmr_monster_global_ensure_init();
  928.  
  929. }
  930.  
  931.  
  932.  
  933. script "ZMR_monster_OnSpawn" (void) NET {
  934.  zmr_monster_global_ensure_init();
  935.     zmr_assign_uid_impl();
  936. }
  937. Script "ZMR_AssignUID" (void) {
  938. zmr_monster_global_ensure_init();
  939.     //zmr_monster_global_ensure_init();
  940. zmr_assign_uid_impl();
  941. }
  942.  
  943.  
  944. script "ZMR_OnUnload" UNLOADING NET {
  945. zmr_monster_global_ensure_init();
  946.     ACS_NamedTerminate("ZMR_UpdateBuddies", 0);
  947.    
  948.     zmr_deinit_mman();
  949.     g_zmr_monster_globals_initialized = false;
  950.     g_current_unique_id = 1;
  951.     g_zmr_last_monster_alloc = 0;
  952. }
  953.  
  954. script 32767 (void) NET
  955. {
  956. zmr_monster_global_ensure_init();
  957.     //zmr_monster_global_ensure_init();
  958.     SetActorState(0,"Demonic",true);
  959.  
  960.    
  961. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement