Using Arcane Dimensions code for Armor Shards in my Episode.

darkfader

New member
Nov 15, 2022
19
18
3
I'm currently trying to modify the existing code to incorporate the best things from all the Quake series, one of which is the Armor Shards from Quake 2 and Quake 3.
Touching any armor runs though armor checks which calculates if you can pick it up, or not.

Currently, I'm aware of 4 documents that I will need to consider when doing this ...
1668471995883.png


Most of which will incur changes in items.qc
This is my currently configuration, items.qc
1668472115738.png


Which only lets mew pick my first armor shard, which I'm trying to associate to an armorvalue of 10 or so. (for now)
I've also noticed Arcane Dimensions does have an existing 'Armor Shard' system incorporated into it, but i'm unable to fully understand it due to how technical the coding is. I am inexperienced in writing any code at all.

defsclass.qc
1668472256054.png


I appreciate any help, and thank you for your time.



quakespasm-spiked-win64 2022-11-14 16-32-14.png
 
  • Like
Reactions: sock
Arcane Dimensions does have an armour shard system, but it uses the item backpack system instead. What you got above is very close, you just need to merge a couple more bits in and it should work.

Here is some example code for your new entity "item_armour_shard". Put this function at the end of the items.qc and compile the code to get a new progs.dat file. You will need to create/update your FGD/DEF files with the new entity type "item_armour_shard" otherwise it will not appear in your editor entity list. You can manually add entities types not listed, but its easier if the editor files are updated.

If you want alternative versions of armour shards code, both Alkaline and Progs_dump have small armour shard systems as well.

Code:
//----------------------------------------------------------------------
void() item_armour_shard =
{
    // Replace this next line with unique armour shard model
    self.mdl = MODEL_BACKPACK;
    precache_model (self.mdl);
    
    // Replace this next line with unique armour shard sound
    self.noise = "items/armour_shard.wav";
    precache_sound(self.noise);

    // This is essentially green armour with a value of 10
    // If the player has no armour, a green icon/setup is given
    self.armortype = 0;
    if (self.armorvalue < 1) self.armorvalue = 10;
    
    // This makes the entity work and play like a backpack
    self.flags = FL_ITEM;
    self.classtype = CT_ARMORITEMPACK;
    self.classgroup = CG_AMMOITEM;
    self.bbmins = '-16 -16 -12';
    self.bbmaxs = '16 16 32';
    self.part_active = PARTICLE_STYLE_BACKPACK;
    if (self.respawn_time == 0) self.respawn_time = RESPAWN_BACKPACK;
    self.respawn_ofs = '0 0 12';
    self.touch2 = BackpackTouch;
    
    // Match particle effect to skin colour (default)
    self.respawn_style = PARTICLE_BURST_WHITE;
    self.respawn_style = self.respawn_style | PARTICLE_BURST_CENTER;
    
    // Random start times for variable spawning
    self.think = item_backpack_setup;
    self.nextthink = time + 0.1 + random();
};
 
  • Like
Reactions: darkfader
Thank you so much for your reply, sock.
I highly appreciate you taking the time to help me, this means a lot to me.
Especially since this is my first attempt at coding.

So, I have replaced my existing item_armorshard code with yours, with some adjustments.

Code:
void() item_armorshard =
{
  
    // Replace this next line with unique armour shard model
        self.mdl = MODEL_ASHARD;
        precache_sound (self.noise);

    // This is essentially green armour with a value of 10
        // If the player has no armour, a green icon/setup is given
        self.armortype = 0;
        if (self.armorvalue < 1) self.armorvalue = 10;
  
        // This makes the entity work and play like a backpack
        self.flags = FL_ITEM;
        self.classtype = CT_ARMORITEMPACK;
        self.classgroup = CG_AMMOITEM;
        self.bbmins = '-16 -16 -12';
        self.bbmaxs = '16 16 32';
        self.part_active = PARTICLE_STYLE_BACKPACK;
        if (self.respawn_time == 0) self.respawn_time = RESPAWN_BACKPACK;
        self.respawn_ofs = '0 0 12';
        self.touch2 = BackpackTouch;
  
        // Match particle effect to skin colour (default)
        self.respawn_style = PARTICLE_BURST_WHITE;
        self.respawn_style = self.respawn_style | PARTICLE_BURST_CENTER;
  
        // Random start times for variable spawning
        self.think = item_backpack_setup;
        self.nextthink = time + 0.1 + random();
};



It is not recognizing my self.mdl = MODEL_ASHARD for some reason.

1668520993852.png


My (not pak'd) ashard.mdl is located in ad/progs/
1668521026471.png


Once again, thank you for your help, sock.
You are a legend.
 

Attachments

  • 1668520636866.png
    1668520636866.png
    32.4 KB · Views: 54
  • 1668520580607.png
    1668520580607.png
    48 KB · Views: 48
  • 1668520399958.png
    1668520399958.png
    24 KB · Views: 54
  • 1668520112869.png
    1668520112869.png
    29.7 KB · Views: 51
  • 1668520096178.png
    1668520096178.png
    6.2 KB · Views: 55
Last edited:
  • Like
Reactions: sock
I get (3) errors upon compile.

1. It seems that self.mdl = doesn't recognize my MODEL_ASHARD.
I have ashard.mdl in my progs folder (not pak'd) ad/progs/ashard.mdl
"self.mdl = MODEL_ASHARD;"

The problem is you have defined a variable for self.mdl called MODEL_ASHARD. If you want use a variable, then you need to define it elsewhere like the defsclass.qc file for example. OR just define self.mdl to point directly to the model name instead like ...

self.mdl = "ashard.mdl";
This is assuming you are storing all your new models in the progs directory (the default place for all mdl files)

2. self.touch2 = BackpackTouch
I notice it's pointing to the BackpackTouch section ... but don't understand why it's not recognizing it.

You got to define that function "BackpackTouch" before your current function. You MUST put your *new* function at the bottom of the items.qc file. So the compiler will find BackpackTouch first in the file. The compiler reads the file sequentially.

3. Also referencing the item_backpack_setup ...

This is the same error 2 (above), you are defining your *new* function before the "item_backpack_setup" function. The QC files are sequential lists of functions, if you reference another function before its defined, then the compiler is going to throw up an error. There is ways to get around this by defining function stubs (forward compiler references) but it is much easier just to put the new function "item_armorshard" at the bottom (last function in file) of the items.qc file.

.
.
.

OK this maybe confusing, but you might want your new function to appear in a certain point of the items.qc file, so here is a way to get rid of those compiler function reference errors ...

Code:
//----------------------------------------------------------------------
void() BackpackTouch;
void() item_backpack_setup;
void() item_armorshard =
{
    // Replace this next line with unique armour shard model
    self.mdl = MODEL_BACKPACK;
    precache_model (self.mdl);

Add the two extra void() lines above your *new* armour shard function. This will tell the compiler that these functions are defined elsewhere (forward) and to link them later on once all the QC files have been read. The downside to this is that if the functions change (extra parameters etc) then the forward references need to change as well, which can get messy. Also please be aware, the function names are case sensitive! so the forward references have to be exactly spelt.
 
Last edited:
Thank you for your time and help on this, sock.
I really appreciate it a lot. Especially since I'm new to coding, and I'm sure it takes patience helping others, due to the extent of the details.

I will be working on this Episode for the next 1-2 years, so I'm sure I'll be back.
Thank you, my Friend.



Finished product, for anyone that may need it in the future.
Code:
======================================================================*/
void() item_armorshard =
{
    
    // Replace this next line with unique armour shard model
        self.mdl = "progs/ashard.mdl";
        precache_model (self.mdl);
        self.noise = "items/ashard.wav";
        precache_sound(self.noise);
        

    // This is essentially green armour with a value of 10
        // If the player has no armour, a green icon/setup is given
        self.armortype = 0;
        if (self.armorvalue < 1) self.armorvalue = 10;
    
        // This makes the entity work and play like a backpack
        self.flags = FL_ITEM;
        self.classtype = CT_ARMORITEMPACK;
        self.classgroup = CG_AMMOITEM;
        self.bbmins = '-16 -16 -12';
        self.bbmaxs = '16 16 32';
        self.part_active = PARTICLE_STYLE_BACKPACK;
        if (self.respawn_time == 0) self.respawn_time = RESPAWN_BACKPACK;
        self.respawn_ofs = '0 0 12';
        self.touch2 = BackpackTouch;
    
        // Match particle effect to skin colour (default)
        self.respawn_style = PARTICLE_BURST_WHITE;
        self.respawn_style = self.respawn_style | PARTICLE_BURST_CENTER;
    
        // Random start times for variable spawning
        self.think = item_backpack_setup;
        self.nextthink = time + 0.1 + random();
};
 
  • Like
Reactions: zaratzara and sock
@sock
If i raise the sv_maxvelocity above 2000 (i believe is the default), will it mess with the physics of the game?
I am hoping to raise the speed for some of the projectiles.

Thank, my Friend.

 
  • Like
Reactions: zaratzara
If i raise the sv_maxvelocity above 2000 (i believe is the default), will it mess with the physics of the game?
I am hoping to raise the speed for some of the projectiles.
I don't think that is a good idea, that limit is likely there for a reason. You should ask someone who knows more about the engine on QM discord. If you are trying to make a projectile go faster than 2000, then it should probably be a hitscan attack.
 
@sock
I hope you and your family are well this Holiday, my Friend.

I am porting over the Turret from Quake 2 - Rogue next.
I am designing this guy a little bit different, he will be spawned (on demand at first) to fight alongside the player.

at the bottom of my newly created mon_turret.qc i have input this coding, based on reading a rough tutorial that is likely almost 20 years old.

Code:
// ------------------------------------------------
void() create_tur =
// ------------------------------------------------
{

local entity bot, spawn_spot;

// start entity and place it in world
    bot = spawn();
    spawn_spot = SelectSpawnPoint ();
    bot.origin = spawn_spot.origin + '0 0 1';
    bot.angles = spawn_spot.angles;
    bot.fixangle = TRUE;
    spawn_tfog (bot.origin);
    spawn_tdeath (bot.origin, bot);
    if (self.bboxtype < 1) self.bboxtype = BBOX_TINY;
    bot.solid = SOLID_NOT;
    bot.movetype = MOVETYPE_NONE;
    setmodel(bot, "progs/mon_turret.mdl");
    bot.flags = bot.flags | FL_MONSTER;
    bot.takedamage = DAMAGE_AIM;
 
    if (self.health < 1) self.health = 325;
    self.exactskin = 1;
    if (self.ammo_nails < 0) self.ammo_nails = 1;
    else if (self.ammo_nails == 0) self.ammo_nails = 1;
 
    self.solid = SOLID_NOT;
    self.movetype = MOVETYPE_NONE;
    if (self.bboxtype < 1) self.bboxtype = BBOX_TINY;
    self.gibbed = FALSE;
    self.pain_flinch = 120;                // low pain threshold
    self.pain_longanim = TRUE;            // Long pain animation for axe
    self.steptype = FS_FLYING;        // heavy player
    if (self.deathstring == "")
        self.deathstring = " were annhilated by a Flying Orb\n";

    self.takedamage = DAMAGE_YES;    // Grenades bounce off
    self.bouncegrenade = FALSE;        // Warning to other monsters
    self.th_stand = tur_stand01;
    self.th_walk = tur_walk01;
    self.th_run = tur_run01;
    self.th_missile = tur_active01;
    self.th_pain = tur_pain;
    self.th_die = tur_is_dead;
        self.classtype = CT_MONTURRET;
    self.classgroup = CG_ROBOT;
    self.classmove = MON_MOVEFLY;
     
    monster_start();
};

And to assign Impulse control to spawn bot.

Code:
void() W_WeaponFrame2 =
{
    ImpulseCommands ();
    // Allow for impulse commands before weapon lockout
    if (time < self.attack_finished) return;
        if (self.impulse >= 1 && self.impulse <= 8) CycleWeaponReverseCommand();
        if (self.impulse == 199) create_tur();
};

I am able to compile without errors, and start QSS, but no turret is spawning. Even if i drag the console down and manually type Impulse 199.
I had also addressed Impulse 199 in quake.rc
Also, no errors are popping up in QSS when i try this.

Any help is greatly appreciated.
Thank You.

edit:
Maybe it's possible to spawn a monster from the console?

I've also found a func_spawn function in hipspawn.qc, that maybe i should be referencing?
 
Last edited:
I am not sure why you are creating a duplicate W_WeaponFrame2, one already exists at the bottom (line 1231) of the weapons.qc file. When you run "ImpulseCommands" function (line 382) there is a impulse reset, so once that is run, you cannot check any new impulse inputs. All new impulse commands have to go into the settings.qc file, otherwise they will be ignored by the code.

"I am porting over the Turret from Quake 2 - Rogue next. I am designing this guy a little bit different, he will be spawned (on demand at first) to fight alongside the player."

All AD monsters are setup to be delay spawned, your function is creating your monster without any delay setup. If you want a good example of buddy code, look at the Ritual/Hipnotic Horn of Conjuring item (QC dev kit included) which spawns a buddy/monster to help the player.

"I've also found a func_spawn function in hipspawn.qc, that maybe i should be referencing?"
Yeah, that code is really weird and lacks many edge case safety checks, so it can result is some spectacular crashes.
 

Attachments

  • hipnotic-devkit-all.zip
    559.4 KB · Views: 49
  • Like
Reactions: darkfader