Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #library "FACTION"
- #include "zcommon.acs"
- #libdefine MAX_SIGNED_LONG 2147483647
- #libdefine NUM_FACTIONS 50
- global int 51:faction_a[]; /* 0-63 = Player TIDs, 100 onwards = faction indexes and tids */
- int total_faction = (NUM_FACTIONS - 1); /* counts 0 as first faction, so for instance if there are 10 total factions this should be 9 */
- int faction_indexes[NUM_FACTIONS] = { 0 }; /* index locations for global array management */
- int targets[200][2]; /* array of targets to be used for targets in script; map level because compatibility and really no difference */
- str faction_s[50] = { "NULL" }; /* string array to store class names for assigning factions based on class names */
- /* below function from ijon tichy's commonFuncs.h */
- function int magnitudeThree_f(int x, int y, int z)
- {
- int len, ang;
- ang = VectorAngle(x, y);
- if (((ang + 0.125) % 0.5) > 0.25) { len = FixedDiv(y, sin(ang)); }
- else { len = FixedDiv(x, cos(ang)); }
- ang = VectorAngle(len, z);
- if (((ang + 0.125) % 0.5) > 0.25) { len = FixedDiv(z, sin(ang)); }
- else { len = FixedDiv(len, cos(ang)); }
- return len;
- }
- /* below function from ijon tichy's commonFuncs.h */
- function int distance_tid(int tid1, int tid2)
- {
- int x1 = GetActorX(tid1);
- int y1 = GetActorY(tid1);
- int z1 = GetActorZ(tid1);
- int x2 = GetActorX(tid2);
- int y2 = GetActorY(tid2);
- int z2 = GetActorZ(tid2);
- return magnitudeThree_f(x2-x1, y2-y1, z2-z1);
- }
- function int setup_array_index (void) /* function to set up array index before being used */
- {
- if(faction_indexes[0] == 100){ return 0; } /* if faction array is already set up, don't set it up */
- if(GetCVar("faction_debug_msg")){ log(s:"initializing faction index array"); } /* debugging log */
- for(int i = 0; i <= total_faction; i++){ /* for all faction array elements */
- if(GetCVar("faction_debug_msg")){ log(s:"index for faction ", i:i, s:" set to ", i:100 + (i * 5)); } /* debugging log */
- faction_indexes[i] = 100 + (i * 5); } /* create index locations starting at 100, 5 apart */
- return 0;
- }
- function int store_faction_tid (int faction, int tid) /* faction to place tid, tid to place */
- {
- int index, index_loc; /* index for faction global array, location of faction index in faction tid global array */
- index_loc = faction_indexes[faction]; /* grab index location for faction from map index array */
- index = faction_a[index_loc]; /* grab index for faction from map array */
- if(GetCVar("faction_debug_msg")){ log(s:"storing tid ", i: tid, s:" for faction ", i: faction, s:" in location ", i:(index_loc + index)); } /* debugging log */
- faction_a[index_loc + index + 1] = tid; /* store the tid in the proper location in the faction tid array */
- faction_a[index_loc] = index + 1; /* increment the faction index by one to track that we added new tid to faction tid array */
- if(GetCVar("faction_debug_msg")){ log(s:"faction ", i: faction, s:" index updated to ", i: faction_a[index_loc]); } /* debugging log */
- return 0;
- }
- function int get_faction_tid (int faction, int loc) /* faction to get tid from, location in array */
- {
- int index_loc; /* location of faction index in faction tid global array */
- index_loc = faction_indexes[faction]; /* grab index location for faction from map index array */
- return faction_a[index_loc + loc]; /* return the tid stored in the specified location */
- }
- function int get_array_location (int faction, int loc) /* faction, location in faction array */
- {
- return faction_indexes[faction] + loc; /* return the specified location */
- }
- function int manage_faction_array (int faction) /* faction in array to manage */
- {
- /* index for faction global array, location of faction index in faction tid global array, location of index after this one */
- int index, index_loc, index_loc_next;
- /* loop variable, end of faction array, location of last faction index */
- int i, faction_end, last_faction;
- index_loc = faction_indexes[faction]; /* grab index location for faction from map index array */
- index_loc_next = faction_indexes[faction + 1]; /* grab next index location for faction from map index array */
- index = faction_a[index_loc]; /* grab index for faction from map array */
- if(index > /* if the number of tids stored in the specified faction array */
- (index_loc_next - index_loc - 3 )){ /* is within 2 elements of encroaching on next array */
- last_faction = faction_indexes[total_faction]; /* get the location of the index for the last faction */
- if(GetCVar("faction_debug_msg")){ log(s:"faction ", i:faction, s:" is full so factions ", i:faction+1, s:" and onward are moving up 5 spaces in the array."); } /* debugging log */
- faction_end = last_faction + faction_a[last_faction] + 1; /* get the last element locaction in the array */
- for(i = faction_end; i >= index_loc_next; i-- ){ /* working backwards, move everything in array forward by 5 */
- faction_a[i + 5] = faction_a[i];
- faction_a[i] = 0; } /* zero out array element onced moved */
- for(i = (faction + 1); i <= total_faction; i++ ){ /* update all faction indexes, starting with one after the managed faction */
- faction_indexes[i] += 5; }}/* increase faction index at i by 5 to make room for managed faction */
- return 0;
- }
- function int get_faction(int tid)
- {
- if(tid){ /* if the tid is not 0 */
- return (CheckActorInventory(tid,"faction_counter") - 1); } /* return how many faction counters - 1 the actor with tid has (what their faction is) */
- return (CheckInventory("faction_counter") - 1); /* return how many faction counters - 1 the activator has (what their faction is) */
- }
- function int set_faction(int tid, int faction)
- {
- TakeInventory("faction_counter", MAX_SIGNED_LONG); /* remove any faction counters the actor might have, even though they shouldn't */
- GiveInventory("faction_counter", faction + 1); /* give them a number of counters corresponding to their faction + 1, so we can know if they have a faction set even if faction is 0 */
- return (CheckActorInventory(tid,"faction_counter") - 1);
- }
- function int clear_targets (void) /* function for clearing out targets in target array */
- {
- for(int i = 0; i < 200; i++){ /* for all target positions in array */
- targets[i][0] = 0; /* set all tids in array to 0 */
- targets[i][1] = 0;} /* set all distances in array to 0 */
- return 0;
- }
- function int store_target (int tid, int dist) /* function for clearing out targets in target array */
- {
- int index; /* index for the target array */
- index = targets[0][0]; /* get the index */
- targets[0][0] += 1; /* update index to reflect that we added another target to array */
- targets[index + 1][0] = tid; /* store the tid for the target in the array */
- targets[index + 1][1] = dist; /* store the distance for the target in the array */
- return targets[index + 1][0] == tid && targets[index +1][1] == dist; /* return if target is stored in array */
- }
- script "start_fights" OPEN /* script to give every monster an item to get them to have factions */
- {
- int xCount, yCount;
- /* from http://forum.zdoom.org/viewtopic.php?p=845858#p845858 */
- for(xCount=-6; xCount<7; xCount++){
- for(yCount=-6; yCount<7; yCount++){
- SpawnForced("RadiusGiveActorFaction", 335544320*xCount, 335544320*yCount, 0, 0, 0); }}
- Delay(5);
- for(xCount=-6; xCount<7; xCount++){
- for(yCount=-6; yCount<7; yCount++){
- SpawnForced("RadiusGiveActorFactionLook", 335544320*xCount, 335544320*yCount, 0, 0, 0); }}
- Delay(105);
- restart;
- }
- script "player_tid" ENTER /* player tid script */
- {
- int player_num, cur_tid, new_tid; /* player number, current tid, new tid */
- while(true){ /* script will loop continuously */
- player_num = PlayerNumber(); /* get player number */
- cur_tid = ActivatorTID(); /* get player current tid */
- if(!faction_a[player_num] /* IF there's no value for the player tid in the array */
- || !ActivatorTID() /* OR the player currently has no tid or tid is 0 */
- || ThingCount(T_NONE,cur_tid) > 1){ /* OR more than one thing has the same tid as the player */
- new_tid = UniqueTID(); /* get a new unique tid */
- faction_a[player_num] = new_tid; /* put it in the array */
- Thing_ChangeTid(0, new_tid); } /* give the player the new tid */
- delay(1); } /* 1 tic delay for loop, means we can be somewhat sure players tids won't have issues */
- }
- script "get_faction_start" (void) /* script to sort out what faction actor should belong to */
- {
- int faction, i; /* faction to put actor into, loop variable */
- str class; /* actor class */
- class = GetActorClass(0); /* get actor class */
- faction = -1; /* set faction to -1 for loop below */
- for(i = 0; i < 50 && faction < 0; i++){ /* for all strings in array, so long as a match or NULL string hasn't been found */
- if(StrCmp(class, faction_s[i]) == 0){ /* if found a match with class name */
- faction = i; } /* set faction to i */
- else if(StrCmp("NULL", faction_s[i]) == 0){ /* if found a NULL string */
- faction = i; /* set faction to i */
- faction_s[i] = class; }} /* store class name to array so others with same class name will be grouped to faction */
- ACS_NamedExecuteWithResult("faction_tid_start", faction);
- }
- script "faction_tid_start" (int faction) /* script to give actor unique tid and store it in faction array and on actor */
- {
- int new_tid; /* new tid */
- if(CheckInventory("faction_counter")){ terminate; } /* if they have already run this script, stop */
- setup_array_index(); /* make sure the array index has already been set up */
- if(faction < total_faction){ /* if faction isn't last faction, which doesn't need to be managed really */
- manage_faction_array(faction); } /* make sure there's enough room in the faction */
- new_tid = UniqueTID(); /* get a new unique tid */
- store_faction_tid(faction, new_tid); /* put it in the faction array */
- Thing_ChangeTid(0, new_tid); /* give the activator the new tid */
- set_faction(0, faction); /* set the faction on the actor with inventory counter items */
- }
- script "faction_look" (int enemy_faction, int flags, int max_dist, int min_dist_wakeup) /* script for actor to look for members of enemy factions */
- {
- /* activator tid, target tid, location in faction array, faction index location, faction index */
- int act_tid, tar_tid, loc, index_loc, index;
- /* faction of activator, faction currently checking, if found target */
- int faction, check_faction, found_target;
- /* loop variable, distance for loops, flag for player target finding being done */
- int i, dist, play_tar;
- /* player and target flags */
- int play_flag, tar_flag;
- if(flags){ /* if any flag has been set */
- play_flag = flags % 10; /* extract play_flag from flags */
- tar_flag = flags - play_flag; } /* extract tar_flag from flags */
- /*
- --player flags
- 0 won't target players
- 1 process players like other targets
- 2 prioritize player targetsd
- --target processsing flags
- 0 pick first valid target
- 1 pick random target from valid targets
- 2 pick closest target
- */
- clear_targets(); /* clear targets in target array prior to use */
- max_dist = max_dist << 16; /* convert to fixed point */
- min_dist_wakeup = min_dist_wakeup << 16; /* convert to fixed point */
- faction = get_faction(0); /* get faction of activator */
- act_tid = ActivatorTID(); /* get activator tid */
- /* minimum distance to player check */
- if(min_dist_wakeup){ /* if a minimum distance to a player to wake up is set */
- dist = 0; /* set dist to 0 */
- /* for all player tids in array, and while no player close enough has been found */
- for(i = 0; i < 64 && !dist; i++){
- if(faction_a[i]){ /* if there is actually a tid stored in the the noted location */
- if(GetCVar("faction_debug_msg")){ log(s:"player ", i:i, s:" with tid ", i:faction_a[i], s:" is ", f:distance_tid(0, faction_a[i]), s:" map units away "); } /* debugging log */
- dist = distance_tid(0, faction_a[i]) <= min_dist_wakeup; /* check if player is at least as close as min distance, will exit loop if true */
- if(dist){ /* if the player is at least as close to activator as min distance */
- if(GetCVar("faction_debug_msg")){ log(s:"player ", i:i, s:" with tid ", i:faction_a[i], s:" is close enough."); }}}}} /* debugging log */
- if(!dist && min_dist_wakeup){ /* if min distance to player check was unsuccessful */
- terminate; } /* stop looking */
- dist = 0; /* reset dist for next loop */
- if(play_flag){ /* if player flags instruct to look for player targets as well */
- for(i = 0; i < 64 && /* for all player tids stored in the array, and so long as */
- ( (!found_target && !tar_flag) || /* no target has been found and we are going with the first target OR */
- (tar_flag) ) ; i++){ /* we are storing targets to sort through later */
- tar_tid = faction_a[i]; /* grab tid stored in the the noted location */
- if( tar_tid && /* if actually retrieved target tid AND */
- CheckSight(0, tar_tid, 0) ){ /* if activator can see this member of enemy faction */
- dist = distance_tid(0, tar_tid); /* get distance between the activator and the target */
- if(!max_dist || /* there is no check for max distance OR */
- (dist <= max_dist) ){ /* the target is within max distance */
- store_target(tar_tid, dist); /* store the target in the array */
- if(play_flag == 2){ /* if prioritizing player flags */
- play_tar = 1; } /* note that a player target has been found */
- found_target = 1; }}}} /* flag that a target has been found */
- while( (check_faction <= total_faction) && /* while all factions haven't been checked yet AND */
- (!play_tar) && /* players targetting hasn't resulted in final target AND */
- ( (!found_target && !tar_flag) || /* no target has been found and we are going with the first target OR */
- (tar_flag) ) ){ /* we are storing targets to sort through later */
- if( (check_faction != faction) && /* don't look for targets in the monster's own faction AND */
- ( (check_faction == enemy_faction) || /* if the faction being checked is the same as the enemy_faction OR */
- (enemy_faction < 0) ) ){ /* no enemy faction was specified */
- loc = 1; /* set faction location to 1, normally 0 would be first in array but faction index takes up [0] spot */
- index_loc = faction_indexes[check_faction]; /* grab index location for faction from map index array */
- index = faction_a[index_loc]; /* grab index for faction from map array */
- while(loc <= index /* while we haven't checked all entries in faction */
- && ( (!found_target && !tar_flag) || /* no target has been found and we are going with the first target OR */
- (tar_flag) ) ){ /* we are storing targets to sort through later */
- tar_tid = get_faction_tid(check_faction, loc); /* get next faction tid */
- if( tar_tid && /* if actually retrieved target tid AND */
- CheckSight(0, tar_tid, 0) ){ /* if activator can see this member of enemy faction */
- dist = distance_tid(0, tar_tid); /* get distance between the activator and the target */
- if(!max_dist || /* there is no check for max distance OR */
- (dist <= max_dist) ){ /* the target is within max distance */
- store_target(tar_tid, dist); /* store the target in the array */
- found_target = 1; }} /* flag that a target has been found */
- ++loc; }} /* check next location in array */
- ++check_faction; } /* check next faction in array */
- if(found_target){ /* if a target was successfully found */
- if(!tar_flag){ /* if we are going with the first target found */
- tar_tid = targets[1][0]; } /* set the target tid to the first tid in the array */
- else if(tar_flag == 1){ /* if we are picking a random target from available targets */
- tar_tid = targets[random(1, targets[0][0])][0]; } /* randomly select from 1 to the total number of targets in the array */
- else if(tar_flag == 2){ /* if we are picking the closest to attck */
- dist = 0; /* set distance variable to 0 for the folloing loop */
- for(i = 1; i <= targets[0][0]; i++){ /* for all tids stored in target array, up to the last stored */
- if(targets[i][1] < dist || dist == 0){ /* if distance of potential target is smaller than current smallest, or first checked */
- tar_tid = i; /* store current i, using tar_tid as temp */
- dist = targets[i][1]; }} /* store distance for selection as new smallest distance */
- tar_tid = targets[tar_tid][0]; } /* set tid for target with lowest distance to final target */
- if(GetCVar("faction_debug_msg")){ log(s:GetActorClass(0), s:" in faction ", i: faction, s:" found a target:", i:tar_tid, s:" which is a ", s:GetActorClass(tar_tid), s:" in faction " , i: check_faction - 1); } /* debugging log */
- Thing_Hate(0, tar_tid, 0); } /* make activator go after target */
- }
- //script "faction_look_decorate" (void) /* script to check if monster already has target before making it hate new one to */
- //{
- // if(GetActorProperty(0, APROP_TargetTID)){ /* if activator has a target already */
- // ACS_NamedExecuteWithResult("faction_look"); } /* start the faction_look script */
- //}
- script "clear_faction_array" UNLOADING /* script to clear faction array for next map */
- {
- /* loop variable, start of faction array, end of faction array, location of last faction index */
- int i, faction_start, faction_end, last_faction;
- last_faction = faction_indexes[total_faction]; /* get the location of the index for the last faction */
- faction_start = faction_indexes[0]; /* get the location of the index for the first faction, which is also beginning of array */
- faction_end = last_faction + faction_a[last_faction] + 1; /* get the last element locaction in the array */
- for(i = faction_start; i <= faction_end; i++ ){ faction_a[i] = 0; } /* clear all values used for faction in the global array */
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement