Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Archaicvirus

Ok.

I'm sure he's grateful for your wisdom.
464 days ago
Im not sure what I've done I may have deleted something accidentally but long story short I can compile and build the map but then I go to launch it on BO3 it crashed and gives me this error
****1 script error(s):
"D15f3cea" with no parameters in
"Scripts/zm/zm_mapname.gsc" at line 0****
****Unresolved external "D15f3cea" with 0 parameters in
"Scripts/zm/zm_mapname.gsc****

Can anyone tell me which this means

Looks like theres a string of random text in your zm_mapname.gsc "D15f3cea" at the top of the file.
Open that file and delete that text, or post a copy of your zm_mapname.gsc here and I'll take a look.
It may be something else altogether though, because it's saying the error is on line 0, not line 1 or higher. Don't know how 'line 0' exists, but whatever I'll check it out if you're still trying to fix it. Other option is start a new map. Sucks, but at least you can move forward.
471 days ago
I am not confident of the code.
This is part_shader_logic code I touched.

function part_shader_logic(shader, position, size_x, size_y){
hud = position - 1;
self.shader_var[hud] = NewClientHudElem(self);
self.shader_var[hud].alignX = "right";
self.shader_var[hud].alignY = "top";
self.shader_var[hud].horzAlign = "user_right";
self.shader_var[hud].vertAlign = "user_top";
if(self IsSplitScreen())
self.shader_var[hud].y = ((size_y * position) + 10) - 25;
else
self.shader_var[hud].y = ((size_y * position) + 10);
self.shader_var[hud].x = -5;
self.shader_var[hud] setShader(shader, size_x, size_y);
self waittill("power_crafted");
self waittill("pap_crafted");
foreach(shader in self.shader_var){
shader Destroy();
}
}
I don't know what you mean by not confident, but at the bottom you have
self waittill("pap_crafted")
. Why?  Are you also sending a notify "pap_crafted"? Without doing
 player notify("pap_crafted")
the call
self waittill("pap_crafted")
will halt the function and wait forever until that notify is sent. In the function part_shader_logic, 'self' is an alias for the player that the function is being called on.
595 days ago
Post your code, and I'll take a look. Also, tell me what you did in radiant so I can determine if your buildables are set up correctly.
629 days ago
Sounds good, let me know when you do. Ill have to download it
642 days ago
This is the Black ops 3 forum if you didn't notice.

The link you provided shows the function as Destroy() not "destroyelem" and also gives you an example
self.bombstopwatch Destroy();
. Have you included the hud script in your map file?
649 days ago
So, you need to create your custom zombie in APE, there you can setup its life and strength, look about custom zombies in YouTube or some shit like that and hopefully you can setup this boss.

Or you could get the zombie in script, and do
zombie.health = 1000;
651 days ago
In your switch/case code, there's no need to have so much code in each "case" when you're calling the same functions in each, but only changing the variables (perk bottle, hintstring, and weapon). Just use a variable for each string, and then after all the case declarations run the functions once, then insert correct variables. Here's an example.

	switch(entity_num)
{
case 0;
perk = "zombie_perk_bottle_revive";    //The bottle & weapon have the same name, only 1 var needed.
hint = "revive soda";
break;
case 1;
perk = "zombie_perk_bottle_jug";
hint = "Juggernog";
break;
case 2;
perk = "zombie_perk_bottle_doubletap";
hint = "ze Root Beer";
break;
case 3;
perk = "zombie_perk_bottle_sleight";
hint = "Speed Cola";
break;
}

perk_bottle SetModel(perk);
level.w_trigger SetHintString("Press ^3&&1 ^7to get " + hint + "!");
self waittill("trigger", player);
player GiveWeapon(perk);
player SwitchToWeapon(perk);
wait(3);
player TakeWeapon(perk);

Makes code a lot shorter, easier to read, and it looks clean. Just my opinion.
651 days ago
If you need some custom models, let me know. I do all the texturing as well. No charge, just a credit. I also do a lot of scripting, so I could help you out.
652 days ago
If any mappers would like to use this robot, please comment below. I am willing to help you implement this in your map as well as adding features you may want

I've been working on this project for about a year, but off and on as I procrastinate and also have many behind the scenes unfinished projects. My main reason for posting this is I see a lot of potential with this mod, but I'm not that creative when it comes to mapping, so I thought I would see how many people/mappers are interested in using something like this in their map so all my work isn't for nothing. So far I have the state machine coded for the robot's animations, as well as a combat logic that handles enemy targeting and FX. Currently the robot will follow the player and dynamically shift focus on the nearest zombie within 500u of the robot.

Planned features:
  • The drone will pick up a single crawler and hold until killed, similar to leroy from BO2
  • The drone will focus on zombies closest to the owner, and have varied attacks, such as grabbing zombie's heads and pulling them off, grappling zombie's ankles & ragdoll-ing them, swinging them around & slamming
  • Adding in many more animations & creating a pool for each type. For example the default idle animation will have 5 variants that randomly play while in the idle state, so no animation will repeat
  • Scripting a complete buildable system for the robot, including the parts to initially acquire the drone, parts for it's laser-gun, and any parts for future mods/enhancements
  • The ability to revive downed player/teammates + buildable upgrade to keep all perks after robot revives
  • A cooldown system, to balance gameplay difficulty. I want this mod to be fun, not over-powered. Perhaps I could make a fuel system with a HUD for feedback (remaining fuel) Comment ideas on how to acquire fuel or other methods to balance!
  • Ability to grab nearby power-ups and bring them to the owner, similar to the BO2 tomahawk.
  • All ideas are welcome! Please comment below what you think.




Here is a video showing some of the earlier prototype models & animations



And here is the final prototype, fully textured & animation demo.



Here is an in-game demo of the current state of the robot's AI script



There are a few other prototypes that didn't get featured, but these should show the basic idea I had in the beginning and how it evolved as I gained experience with the various programs I used.

I have a decent script made that handles the robot's basic behaviors, and right now I'm re-doing the FX for the laser-fire -for the buildable laser-gun add-on. Everything in this project is custom, no borrowed scripts or models, textures or anything. The programs I used were mainly Blender for the modelling, Maya 2015 for the animations, Substance Painter 2 for the materials and Adobe Photoshop for the robot screen (face). If any mappers would like to use this, let me know below. I'd love to hear feedback, see if this thing is worth putting more time into or just putting on the shelf. Thanks for checking it out!

Here's the script so far if you're interested in how it works

#using scripts\codescripts\struct;
#using scripts\shared\flag_shared;
#using scripts\shared\array_shared;
#using scripts\shared\util_shared;
#using scripts\shared\ai\zombie_utility;
#using scripts\zm\_zm_utility;
#using scripts\zm\_zm_score;
#using scripts\zm\_zm_unitrigger;
#using scripts\shared\math_shared;
#using scripts\zm\_zm_traps;
#using scripts\zm\_zm_weap_gravityspikes;
#using scripts\zm\_zm_spawner;
#using scripts\shared\hud_util_shared;
#using scripts\zm\_zm_powerups;
#using scripts\zm\crate_powerup_logic;
#using scripts\zm\vial_spawn;

#precache("fx", "custom/arch_robot_propulsion");
#precache("fx", "custom/arch_robot_laser");
//#precache("xanim", "arch_robot_anim_test");
//#precache("xanim", "arch_robot_dance");
//#precache("xanim", "arch_robot_hack_loop");
//#precache("xanim", "arch_robot_idle_passive");
//#precache("xanim", "arch_robot_idle");
#precache("xanim", "arch_robot_v7_idle");
#precache("xanim", "arch_robot_v7_combat_idle");
#precache("xanim", "arch_robot_v7_focus_atk");
#precache("xanim", "arch_robot_v7_laser_fire");
#precache("xanim", "arch_robot_v7_laser_aim_idle");
#precache("xmodel", "arch_robot_v7");
#precache("xmodel", "arch_robot_laser_gun");


#using_animtree("arch_drone_anims");

#namespace arch_drone_ai;

function init()
{
level flag::wait_till("all_players_connected");
level flag::init("inRadius", false);
level._effect["robot_propulsion"] = "custom/arch_robot_propulsion";
level._effect["robot_laser"] = "custom/arch_robot_laser";
trig = GetEnt("robot_test", "targetname");
trig SetCursorHint("HINT_NOICON");
trig SetHintString("Press &&1 to test anim");
trig thread follow();
}

function follow()
{
self waittill("trigger", player);
org = positionBot(player);
self.robot = Spawn("script_model", player.origin + org);
self.robot.angles = (0, -90, 0);
self.mover = Spawn("script_model", player.origin + org);
wait(0.2);
self.mover SetModel("tag_origin");
self.robot SetModel("arch_robot_v7");
self.robot EnableLinkTo();
self.robot LinkTo(self.mover, "tag_origin");
PlayFXOnTag(level._effect["robot_propulsion"], self.robot, "tag_origin");
self.robot.animState = "idle";
//self.robot SetScale(2.0);
self.robot UseAnimTree(#animtree);
wait(0.2);
tag = self.robot GetTagOrigin("tag_right_elbow");
self.robot.laser = Spawn("script_model", tag);
self.robot.laser SetModel("arch_robot_laser_gun");
self.robot.laser LinkTo(self.robot, "tag_right_elbow", (15, 0, 1.5), (0, -90, 0));
self.robot.laser Hide();
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_idle);
self thread robot_animState_watcher();
self thread robot_positioning_system(player);
while(1)
{
org = positionBot(player);
self.mover MoveTo(player.origin + org, .2);
wait(.2);
}
}

function positionBot(player)
{
//Forward and to the right of players view
f = AnglesToForward(player.angles) * 125;
org = AnglesToRight(player.angles) * 40 + (f + (0,0,75));
return org;
}

function robot_positioning_system(player)
{
while(1)
{
switch(self.robot.animState)
{
case "combat_idle":
case "focus_atk":
case "laser_atk":

//Decide robot's facing direction
zombies = GetAISpeciesArray("axis", "all");
closestZombie = ArrayGetClosest(self.mover.origin, zombies, 500);

//Target nearest enemy
tag = closestZombie GetTagOrigin("tag_eye");
vectorToFace = self.mover.origin - (tag[0], tag[1], tag[2] + 25);
//vectorToFace = self.mover.origin - (closestZombie.origin[0], closestZombie.origin[1], closestZombie.origin[2] + 120);
angle2Face = VectortoAngles(vectorToFace);
self.mover RotateTo((angle2Face[0], angle2Face[1] + 180, angle2Face[2]), .2);

break;

case "idle":
//If no zombies are in range, robot follows players direction
angles = player GetPlayerAngles();
self.mover RotateTo(angles, .2);
break;
}
wait(0.2);
}
}

function robot_animState_watcher()
{
while(1)
{
zombies = GetAISpeciesArray("axis", "all");
closest = ArrayGetClosest(self.robot.origin, zombies);
dist = Distance2D(self.robot.origin, closest.origin);
if(!isdefined(closest) || dist > 500 && self.robot.animState != "idle")
{
switch(self.robot.animState)
{
//void <entity> AnimScripted(<notify>,<origin>,<angles>,<animation>,[mode],[root],[rate],[blend],[lerp],[animation time],[is_scene_animation],[showPlayerWeaponInFirstPerson])
case "combat_idle":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_idle, "normal", %arch_robot_v7_combat_idle, 1, 1, 1);
break;

case "focus_atk":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_idle, "normal", %arch_robot_v7_laser_aim_idle, 1, .5, .5);
break;

case "laser_atk":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_idle, "normal", %arch_robot_v7_laser_fire, 1, .5, .5);
break;
}
self.robot.animState = "idle";
}

if(isdefined(closest) && dist < 500 && dist > 200 && self.robot.animState != "combat_idle")
{
switch(self.robot.animState)
{
case "idle":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_combat_idle, "normal", %arch_robot_v7_idle, 1, .5, .5);
break;

case "focus_atk":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_combat_idle, "normal", %arch_robot_v7_laser_aim_idle, 1, .5, .5);
break;

case "laser_atk":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_combat_idle, "normal", %arch_robot_v7_laser_fire, 1, .5, .5);
break;
}
self.robot.animState = "combat_idle";
}

if(isdefined(closest) && dist < 200 && dist > 50 && self.robot.animState != "focus_atk")
{
switch(self.robot.animState)
{
case "combat_idle":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_aim_idle, "normal", %arch_robot_v7_combat_idle, 1, .5, .5);
break;

case "idle":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_aim_idle, "normal", %arch_robot_v7_idle, 1, .5, .5);
break;

case "laser_atk":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_aim_idle, "normal", %arch_robot_v7_laser_fire, 1, .5, .5);
break;
}
self.robot.animState = "focus_atk";
self thread projectile_logic();
}
/*
if(isdefined(closest) && dist < 50 && self.robot.animState != "laser_atk")
{
switch(self.robot.animState)
{
case "combat_idle":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_fire, "normal", %arch_robot_v7_combat_idle, 2, .5, .5);
break;

case "idle":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_fire, "normal", %arch_robot_v7_idle, 2, .5, .5);
break;

case "focus_atk":
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_fire, "normal", %arch_robot_v7_laser_aim_idle, 2, .5, .5);
break;
}
self.robot.animState = "laser_atk";
}
*/
wait(.5);
}
}


function projectile_logic()
{
self.robot.laser Show();
while(self.robot.animState == "focus_atk")
{
zombies = GetAIArray("axis", "all");
zombie = ArrayGetClosest(self.mover.origin, zombies);
//laserOrg = Spawn("script_model");
//laserOrg SetModel("tag_origin");
PlayFXOnTag(level._effect["robot_laser"], self.mover, "tag_origin");
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_fire, "normal", %arch_robot_v7_laser_aim_idle, 2, .05, .05);
//self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_fire);
//PlayFXOnTag(level._effect["robot_laser"], self.mover, "tag_origin");

/*traceArray = BulletTrace(self.mover.origin, (zombie.origin[0], zombie.origin[1], zombie.origin[2] + 100), true, self.robot);
foreach(val in traceArray)
{
IPrintLnBold(val);
}
*/
self.robot waittill("anim_done");
wait(0.5);
self.robot AnimScripted("anim_done", self.robot.origin, self.robot.angles, %arch_robot_v7_laser_aim_idle, "normal", %arch_robot_v7_laser_fire, 1, .2, .2);
wait(1);
if(self.robot.animState != "focus_atk")
{
break;
}
}
self.robot.laser Hide();
}

function robot_combat_logic()
{
//void <entity> DoDamage(<health>,<source position>,[attacker],[inflictor],[hitloc],[mod],[dflags],[weapon],[infdestructible_piece_indexlictor],[forcePain])

}


655 days ago
Hey guys,

I want to know if it is possible to attach a light to the players.
I want to put in my map a buildable flashlight or just a simple flashlight. who can be used like a weapons or the sheild.

Thanks for your help.

You need to use an fx light, more info in your root/docsmodtools folder to set up the fx. I highly suggest creating your own fx in radiant. It's basically a bunch of settings you adjust, tutorials are out there. Once you have an fx light, you can link an empty to the player, then do PlayFXOnTag() on the empty. Check out my tutorial on buildables here https://ugx-mods.com/forum/index.php/topic,15031.0.html. You will also need a method for the player to toggle the flashlight. In the docsmodtools folder open the scriptapi html file, hit ctrl + f and search for buttonpressed(). That will give you hooks for keystrokes, so you can write a function to toggle the light. That plus adjusting the spawn position of the empty script_model and adjusting the angle of the light, color, etc.
659 days ago
I know you solved the issue, but I don't think you fully understand how while() loops work. Figured I'd explain a little to help you out.

Everything inside {curly braces} will loop forever until while(true) is evaluated as false - unless you call a break. It will work the way you're doing it (saw the pastebin, lol btw) however it is completely unnecessary if you call a wait() statement.

Basically, loops in general are intended to repeat or iterate a block of code until some condition is met. Logically if you're waiting() for a zone entrance, what code do you need to repeat? None. When you call waittill("zone_enter"), the script halts and does not process the next line until that notification is recieved, thus making a loop irrelevant. Then the next waittill("zone_enter") gets called and halts again until the player enters. So just get rid of the loop altogether, and write your code as normal. Ill give you a few examples for the sake of it. I'm no expert coder, but I can teach what I know.

//This example counts 10 player slide actions, prints the total to the screen, then breaks out of the loop & ends the function.
function example_loop()
{
slides = 0;
max_slides = 10;
players = GetPlayers();
player = players[0];

while(1)
{
if(player isSliding())
{
slides++;
IPrintLnBold("[" + slides + "] Slides have been detected");
if(slides >= max_slides)
{
break;
}
}
wait(1);
}
}

//This ex. uses a for() loop, counts & prints the array of zombies alive. You don't need a break statement as 'i' counts up with zombies.size.
//Once 'i' is greater than zombies.size, then middle statement in the loop becomes false, breaking the loop.
function example_loop2()
{
zombies = GetAISpeciesArray("axis", "all");

for(i = 0; i < zombies.size; i++)
{
IPrintLnBold("[" + i + 1 + "] zombies have been detected");
}

}

//Or you could do
function example_loop3()
{
i = 0;
foreach(zombie in GetAISpeciesArray("axis", "all"))
{
IPrintLnBold("[" + i + 1 + "] zombies have been detected");
i++;
}
}
659 days ago
you can move an FX, but what you will want to do is use the function named
fx = playfxontag(id, ent, tag);
where 'id' is the FX id, ent is the script_model that you want to play the FX on, and tag is the model tag you where you want the FX attached.
example:
fx = PlayFxOnTag(level._effect["bouledefeu"], level.model, "tag_origin");

PS: if you ran it in developer mode you should have gotten an error saying "Type String is not an entity and cannot call EnableLinkTo"


Close, but no cigar. According to the api (root/docsmodtools/bo3_scriptapifunctions.html) search for playfxontag. I use a lot of custom fx in my projects and am familiar with this topic. Im on standby at work right now, but give me an hour and I'll give you (original poster) a proper example once I get home. (On mobile)

Double Post Merge: November 29, 2017, 11:55:48 pm
Is it possible to move an fx, that we spawned or not?

This script spawn the model and the fx but doesn't move the fx:

function move_fx()
{
level flag::wait_till( "initial_blackscreen_passed" );
struct1 = struct::get("struct1","targetname");
level.model = spawn( "script_model", struct1.origin );
level.model SetModel( "p7_skulls_bones_head_02" );
level._effect["bouledefeu"] = "Symbo/test3";
PlayLoopedFX(level._effect["bouledefeu"], 1, struct1.origin);
level.model enablelinkto();
level._effect["bouledefeu"] linkto(level.model);
fx_trigger = GetEnt("fx_trigger", "targetname");
fx_trigger waittill("trigger", player);
level.model moveY(-338,2);

}

This should help you out:

//First, you need to pre-cache your fx file before init(). (Certain fx are pre-cached by default, there is a list in the forums here)
#precache("fx", "Symbo/test3");

function init()
{
level flag::wait_till("initial_blackscreen_passed");
level._effect["bouledefeu"] = "Symbo/test3"; //Defining the fx

temp = struct::get("struct1", "targetname");
//In radiant, put a new struct where the skull moves to - name it "destination"
destination = struct::get("destination", "targetname");
skull = Spawn("script_model", temp.origin);
skull SetModel("p7_skulls_bones_head_02");
skull.destination = destination.origin;

temp Delete(); //If only using as an origin point - no longer needed
destination Delete();

fx_trigger = GetEnt("fx_trigger", "targetname");
fx_trigger waittill("trigger");
skull thread move_fx();
}

//level.model enablelinkto();
//level._effect["bouledefeu"] linkto(level.model);
//***You do not call EnableLinkTo() on the fx ^ or the model here. The fx in gsc is only a string pointing to the fx file,
//PlayFXOnTag() solves that, the fx will move with the model

function move_fx()
{
PlayFXOnTag(level._effect["bouledefeu"], self, "tag_origin");
//If you want to get fancy, you could make the skull look towards the destination point as it moves there
//I wrote an easy function for that at the bottom of the page
self face_target(self.destination);
//Then move it there
self MoveTo(self.destination, 2);

//If feeling extra fancy you could make the skull 'look' at the nearest player
while(1)
{
players = GetPlayers();
searchDist = 500; //500 is the search distance for players - change as needed
nearestPlayer = ArrayGetClosest(self.origin, players, searchDist);

if(!isdefined(nearestPlayer) || Distance2D(self.origin, nearestPlayer.origin) > searchDist)
{
wait(1);
}
else
{
target = nearestPlayer GetTagOrigin("tag_eye");
self face_target(target);
wait(0.2);
}
}
}

//Syntax: <entity> face_target(<vector3>)
function face_target(target)
{
vectorToFace = self.origin - target;
angleToFace = VectortoAngles(vectorToFace);
self RotateTo(angleToFace, 0.25);
}

659 days ago
Awesome man, I hope you got this working, would love to see it in action!
659 days ago
No problemo
791 days ago

Login

or login with an authentication provider below
Sign In with Google
Sign In with Twitter
Sign In with Discord
Sign In with Steam
Sign In with Twitch
Loading ...