What are you working on?
Moderator: InsideQC Admins
Re: What are you working on?
Cool frag.machine!! Will it support altitude difference(hills, valleys,etc)? Will it be open sourced?
Great work tough, I never saw a functional procedurally generated world in quake. Is it made in C or quakec?
Great work tough, I never saw a functional procedurally generated world in quake. Is it made in C or quakec?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: What are you working on?
toneddu2000 wrote:Cool frag.machine!! Will it support altitude difference(hills, valleys,etc)?
It could, although not right now.
toneddu2000 wrote:Will it be open sourced?
If I ever finish and release it, sure, after all is based on GPL'd work. Even if I end up not finishing it, I may donate the code to anyone willing to use it. I have no problem with sharing my work with the community, after all I got tons of free stuff and knowledge thru the years, the least I can do to retribute is to share my ideas and experiments.
toneddu2000 wrote:Great work tough, I never saw a functional procedurally generated world in quake. Is it made in C or quakec?
It requires a bunch of DP specific extensions, but otherwise is 100% QuakeC.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: What are you working on?
It requires a bunch of DP specific extensions, but otherwise is 100% QuakeC.
Umm...So, what about the fps? Is it high with an high amount of details (High poly meshes) generated at runtime?
I always tought that, for this kind of work, Engine programming was the only choice, but I could be wrong!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: What are you working on?
toneddu2000 wrote:It requires a bunch of DP specific extensions, but otherwise is 100% QuakeC.
Umm...So, what about the fps? Is it high with an high amount of details (High poly meshes) generated at runtime?
I always tought that, for this kind of work, Engine programming was the only choice, but I could be wrong!
The fps are between 180 to 220, mostly due the camera angles and position that allows the engine to cull a good number of entities from the PVS. I probably wouldn't be able to get decent framerates in1st person view, but for top down or isometric games it works well enough it seems.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: What are you working on?
I can't make out anything on my phone :/
-

ceriux - Posts: 2223
- Joined: Sat Sep 06, 2008 3:30 pm
- Location: Indiana, USA
Re: What are you working on?
This natural canyon environment looks well-suited for map generation. Easy to imagine expanding the types of pieces- a variety of rock, vegetation, maybe a creek.frag.machine wrote:Procedurally generated world + split model + top down camera + misc stuff:
http://youtu.be/tA-mS-inKAg
-
qbism - Posts: 1236
- Joined: Thu Nov 04, 2004 5:51 am
Re: What are you working on?
frag.machine wrote:The fps are between 180 to 220, mostly due the camera angles and position that allows the engine to cull a good number of entities from the PVS. I probably wouldn't be able to get decent framerates in1st person view, but for top down or isometric games it works well enough it seems.
Yeah, you'd probably lose 30,35% of fps but it's a good goal afterall
Meadow Fun!! - my first commercial game, made with FTEQW game engine
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: What are you working on?
I also like the rocks, they look almost natural with their shape.
Maybe one thing: You could try to raise the rocks higher that their top is no more visible,
that will give the impression of beeing inside a dungeon. Seeing that you can "enter" into rocks in your clip.
The rocks outside of a dungeon should stay as they are right now.
Really great work frag.machine !
Maybe one thing: You could try to raise the rocks higher that their top is no more visible,
that will give the impression of beeing inside a dungeon. Seeing that you can "enter" into rocks in your clip.
The rocks outside of a dungeon should stay as they are right now.
Really great work frag.machine !
- Seven
- Posts: 301
- Joined: Sat Oct 06, 2007 8:49 pm
- Location: Germany
Re: What are you working on?
Seven wrote:I also like the rocks, they look almost natural with their shape.
Maybe one thing: You could try to raise the rocks higher that their top is no more visible,
that will give the impression of beeing inside a dungeon. Seeing that you can "enter" into rocks in your clip.
The rocks outside of a dungeon should stay as they are right now.
Really great work frag.machine !
Thanks! The intended ambience on this demo is not of a dungeon, but an outdoor area actually. I suppose the lack of scene elements and the low light level didn't help to show this. I'm working in a second type of ambience (caves) where I'm using the higher than camera trick to give this idea of clausthrophobic environment. And yeah, chase camera clips thru the BSP models and breaks the immersion
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: What are you working on?
it kind of already seems like a dungeon/cave because of the textures used and how when you go to a new area it seems to always point down, like you're going down a level. maybe you could use portals of some kind rather than what you already have for out door areas?
-

ceriux - Posts: 2223
- Joined: Sat Sep 06, 2008 3:30 pm
- Location: Indiana, USA
Re: What are you working on?
ceriux wrote:it kind of already seems like a dungeon/cave because of the textures used and how when you go to a new area it seems to always point down, like you're going down a level. maybe you could use portals of some kind rather than what you already have for out door areas?
Heh, already doing this.
You may find it confusing because the actual gameplay (maybe it's too early too call it "gameplay", but oh well) changed since I uploaded the video, and I must apologize for this. Now there are distinct "portal" models that visually give the cue to where you are going if you select it - the ground hole portal is used only for cave access from the outdoor badlands, and the stone wall door is meant to be used when travelling from one outdoor area to another).
I also added some grass and dead trees to help to compound the outdoor environment, and raised the light level a bit (I am avoiding to turn it in a shiny day though - the general mood I want to pass is of a desolated area). You can notice the light difference from the cave shots. Still a WIP, more adjusts are required.
The biggest problem is to generate the right artwork to every tiny part. Just for illustration, I may have created like 10 or 12 versions of those stone walls since my first attempt of creating a "minecraft-like" world, a long long time ago. And TBH I am not happy with what I got so far, but is good enough to work as a placeholder while I am coding at least. Not only you need to create something that looks right in different angles, but the light must blend correctly and every BSP model must blend with the rest in a convincent, natural looking way. And the textures... Well, let's just say they are the hardest part. Most of them are low res, not exactly nice and hardly adequate, but if I also had to create my own custom textures I probably would have gave up the whole idea a long time ago. Better have something not that pretty but functional than a bunch of original textures and no mod I say. I can always find/create some better textures later.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC
(LordHavoc)
-

frag.machine - Posts: 2090
- Joined: Sat Nov 25, 2006 1:49 pm
Re: What are you working on?
Q2 software-renderer mash-up:
3.24 unofficial Q2 from Knightmare
Colored light from Lei Q2
Use GDI driver for full screen modes (avoid Win7 ddraw palette derp)
Increase engine limits for largish maps
Engine can do Lazarus mod?
...because I want to play SMD in software mode. http://musashi.backshooters.com/smd.html
Besides the 3.24 patch and FTEQW-SW, any other software Q2 code bases with stealing from?
3.24 unofficial Q2 from Knightmare
Colored light from Lei Q2
Use GDI driver for full screen modes (avoid Win7 ddraw palette derp)
Increase engine limits for largish maps
Engine can do Lazarus mod?
...because I want to play SMD in software mode. http://musashi.backshooters.com/smd.html
Besides the 3.24 patch and FTEQW-SW, any other software Q2 code bases with stealing from?
-
qbism - Posts: 1236
- Joined: Thu Nov 04, 2004 5:51 am
Re: What are you working on?
Nope. The majority of Q2 ports are "cool particle system's for GL" and there's only like one port that even fixes NPO2 and overbrights. DirectQII is the closest Fitzish thing, but the site is now defunct and mh has been corporately absorbed for quite the while. I still have all the files and source releases though
I'd also like to toy with the idea of a simple GL wrapper that artificially limits extensions and does a few GLSL postprocess effects, as a 3dfxgl.dll replacement - because for a while after it came out, Quake2's appearance was mostly representated by 3dfx and their high gamma and filtering. While glide wrappers are one thing, experiencing Voodoo vision is another, and that's not an area Glide wrappers explore in.
I'd also like to toy with the idea of a simple GL wrapper that artificially limits extensions and does a few GLSL postprocess effects, as a 3dfxgl.dll replacement - because for a while after it came out, Quake2's appearance was mostly representated by 3dfx and their high gamma and filtering. While glide wrappers are one thing, experiencing Voodoo vision is another, and that's not an area Glide wrappers explore in.
i should not be here
- leileilol
- Posts: 2783
- Joined: Fri Oct 15, 2004 3:23 am
Re: What are you working on?
Seems many of the older q2 source ports are endangered of disappearing, but surprising to hear about directq2. While surfing I've noticed that deaconstomb and jimw sites are recently gone.
-
qbism - Posts: 1236
- Joined: Thu Nov 04, 2004 5:51 am
Re: What are you working on?
https://github.com/OldTimes-Software/ProjectKatana/commit/7a3a68da086298ed002f7cbce99c27f0caa76440
Added some of the game-code to the repository. This is excluding all code for OpenKatana, since I got told off when I accidentally put that up last time
As you can see above it's not too different from the original QC code, but right now some of it is still a little messy since most of it is still actively being worked on. Updates to the game-code won't be as frequent on the repository than the changes I make to the engine, purely because this would be somewhat being kept in-line and modified from the code we're writing out for OpenKatana which obviously takes a little while.
Added some of the game-code to the repository. This is excluding all code for OpenKatana, since I got told off when I accidentally put that up last time
- Code: Select all
#include "server_weapon.h"
/*
Base code for the weapon system.
*/
#include "server_item.h"
#include "server_player.h"
#include "server_monster.h"
Weapon_t Weapons[] =
{
#ifdef OPENKATANA
{
WEAPON_KATANA,
DAIKATANA_MODEL_VIEW,
Daikatana_Deploy,
// Primary
AM_MELEE,
Daikatana_PrimaryAttack
},
{
WEAPON_DAIKATANA,
DAIKATANA_MODEL_VIEW,
Daikatana_Deploy,
// Primary
AM_MELEE,
Daikatana_PrimaryAttack
},
{
WEAPON_IONBLASTER,
"models/weapons/v_ionblaster.md2",
IonBlaster_Deploy,
// Primary
AM_IONS,
IonBlaster_PrimaryAttack,
},
{
WEAPON_C4VIZATERGO,
"models/weapons/v_c4.md2",
C4Vizatergo_Deploy,
// Primary
AM_C4BOMB,
C4Vizatergo_PrimaryAttack,
// Secondary
AM_NONE,
C4Vizatergo_SecondaryAttack
},
{
WEAPON_SHOTCYCLER,
"models/weapons/v_shotcycler.md2",
Shotcycler_Deploy,
// Primary
AM_SHELL,
Shotcycler_PrimaryAttack
},
{
WEAPON_SIDEWINDER,
"models/weapons/v_sidewinder.md2",
SideWinder_Deploy,
// Primary
AM_ROCKET,
SideWinder_PrimaryAttack
},
{
WEAPON_SHOCKWAVE,
"models/weapons/v_shockwave.md2",
Shockwave_Deploy,
// Primary
AM_LASER,
Shockwave_PrimaryAttack
},
// Secret Weapons
{
WEAPON_IONRIFLE,
"models/weapons/v_ionrifle.md2", // TEMP
IonRifle_Deploy,
// Primary
AM_IONS,
IonRifle_PrimaryAttack,
// Secondary
AM_NONE,
IonRifle_SecondaryAttack
},
// Monster Weapons
{
WEAPON_LASERS,
NULL,
NULL,
// Primary
AM_LASER,
IonBlaster_PrimaryAttack // [31/3/2013] Temporary ~hogsy
},
// Unused Weapons
{
WEAPON_GLOCK,
"models/weapons/v_glock.md2",
Glock_Deploy,
// Primary
AM_BULLET,
Glock_PrimaryAttack
},
#elif ICTUS
#endif
{ 0, NULL, NULL, AM_NONE, NULL, AM_NONE, NULL }
};
/* Returns the entities current active weapon.
*/
Weapon_t *Weapon_GetCurrentWeapon(edict_t *eEntity)
{
Weapon_t *wCurrentWeapon;
for(wCurrentWeapon = Weapons; wCurrentWeapon->iItem; wCurrentWeapon++)
if(eEntity->v.iActiveWeapon == wCurrentWeapon->iItem)
return wCurrentWeapon;
// [20/5/2013] Changed to WEAPON_NONE ~hogsy
return Weapon_GetWeapon(0);
}
Weapon_t *Weapon_GetWeapon(int iWeaponID)
{
Weapon_t *wWeapon;
for(wWeapon = Weapons; wWeapon->iItem; wWeapon++)
if(iWeaponID == wWeapon->iItem)
return wWeapon;
return NULL;
}
void Weapon_Precache(void)
{
#ifdef GAME_OPENKATANA
// [11/5/2013] Model precaches ~eukos
Engine.Server_PrecacheResource(RESOURCE_MODEL,DAIKATANA_MODEL_VIEW);
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/weapons/v_ionblaster.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/weapons/v_c4.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/weapons/v_shotcycler.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/weapons/v_sidewinder.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/weapons/v_shockwave.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/slaser.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/c4ammo.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/ionball.md2");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/sidewinder_missile.md2");
// Ion Rifle
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/weapons/v_ionrifle.md2");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/laser.wav");
// C4
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/c4/c4beep.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/c4/c4cock.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/c4/c4fire.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/c4/c4stick.wav");
// Ion Blaster
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/ionblaster/ionexplode3.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/ionblaster/ionfire.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/ionblaster/ionflyby.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/ionblaster/ionready.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/ionblaster/ionwallbounce.wav");
Engine.Server_PrecacheResource(RESOURCE_MODEL,"models/ionball.md2");
// Shockwave
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shockwave/fade.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shockwave/fire.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shockwave/ready.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shockwave/warmup.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire1.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire2.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire3.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire4.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire5.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire6.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire7.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire8.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerfire9.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/barrelspin.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerready.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotcyclerclick.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotclick.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotpull.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/shotcycler6/shotslap.wav");
// Sidewinder
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/sidewinder/sidewinderfire.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/sidewinder/sidewinderflyby.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/sidewinder/sidewindersplash.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/sidewinder/sidewinderunderwaterfire.wav");
Engine.Server_PrecacheResource(RESOURCE_SOUND,"weapons/sidewinder/sidewinderunderwaterflyby.wav");
#endif
}
void Weapon_BulletProjectile(edict_t *eEntity,float fSpread,int iDamage,vec_t *vDirection)
{
int i;
vec3_t vSource,vTarg;
trace_t tTrace;
Math_VectorCopy(eEntity->v.origin,vSource);
vSource[2] += eEntity->v.view_ofs[2];
for(i = 0; i < 3; i++)
vTarg[i] = vSource[i]+(vDirection[i]*2048.0f)+(fSpread*Math_CRandom()*20.0f);
tTrace = Traceline(eEntity,vSource,vTarg,0);
if((tTrace.fraction == 1.0f) || (Engine.Server_PointContents(tTrace.endpos) == CONTENT_SKY))
return;
else
{
if(tTrace.ent && tTrace.ent->v.bTakeDamage)
MONSTER_Damage(tTrace.ent,eEntity,iDamage);
else
{
edict_t *eSmoke = Spawn();
if(eSmoke)
{
char cSound[32];
eSmoke->v.think = Entity_Remove;
eSmoke->v.dNextThink = Server.dTime+0.5;
Entity_SetOrigin(eSmoke,tTrace.endpos);
PHYSICS_SOUND_RICOCHET(cSound);
Sound(eSmoke,CHAN_BODY,cSound,255,ATTN_NORM);
}
Engine.Particle(tTrace.endpos,vec3_origin,10,"smoke",12);
}
}
}
/* Sets an active weapon for the specified entity.
*/
void Weapon_SetActive(Weapon_t *wWeapon,edict_t *eEntity)
{
bool bPrimaryAmmo,bSecondaryAmmo;
// [11/5/2013] Clear everything out ~hogsy
eEntity->v.cViewModel = "";
eEntity->v.iSecondaryAmmo =
eEntity->v.iPrimaryAmmo =
eEntity->v.iWeaponFrame = 0;
bPrimaryAmmo = Weapon_CheckPrimaryAmmo(wWeapon,eEntity);
bSecondaryAmmo = Weapon_CheckSecondaryAmmo(wWeapon,eEntity);
if(!bPrimaryAmmo && !bSecondaryAmmo)
return;
if(bPrimaryAmmo)
{
// [4/7/2012] Set ammo by type ~hogsy
switch(wWeapon->iPrimaryType)
{
#ifdef OPENKATANA
// [12/8/2012] Added in AM_IONS ~hogsy
case AM_IONS:
eEntity->v.iPrimaryAmmo = eEntity->local.ionblaster_ammo;
break;
case AM_ROCKET:
eEntity->v.iPrimaryAmmo = eEntity->local.sidewinder_ammo;
break;
case AM_DISCUS:
eEntity->v.iPrimaryAmmo = eEntity->local.discus_ammo;
break;
case AM_BULLET:
eEntity->v.iPrimaryAmmo = eEntity->local.glock_ammo;
break;
case AM_SHELL:
eEntity->v.iPrimaryAmmo = eEntity->local.shotcycler_ammo;
break;
case AM_LASER:
eEntity->v.iPrimaryAmmo = eEntity->local.shockwave_ammo;
break;
case AM_C4BOMB:
eEntity->v.iPrimaryAmmo = eEntity->local.iC4Ammo;
break;
#endif
case AM_MELEE:
case AM_SWITCH:
case AM_NONE:
eEntity->v.iPrimaryAmmo = 1;
break;
default:
Engine.Con_Warning("Failed to set primary ammo! (%i)\n",wWeapon->iPrimaryType);
eEntity->v.iPrimaryAmmo = 0;
}
}
if(bSecondaryAmmo)
{
// [4/7/2012] Set ammo by type ~hogsy
switch(wWeapon->iSecondaryType)
{
case AM_MELEE:
case AM_SWITCH:
case AM_NONE:
eEntity->v.iSecondaryAmmo = 1;
break;
default:
Engine.Con_Warning("Failed to set secondary ammo! (%i)\n",wWeapon->iSecondaryType);
eEntity->v.iSecondaryAmmo = 0;
}
}
eEntity->v.iActiveWeapon = wWeapon->iItem;
eEntity->v.cViewModel = wWeapon->model;
eEntity->local.iFireMode =
eEntity->local.iWeaponIdleFrame = 0;
if(wWeapon->Deploy)
wWeapon->Deploy(eEntity);
}
/* Checks for primary ammo.
*/
bool Weapon_CheckPrimaryAmmo(Weapon_t *wWeapon,edict_t *eEntity)
{
switch(wWeapon->iPrimaryType)
{
#ifdef OPENKATANA
// [12/8/2012] Added in AM_IONS ~hogsy
case AM_IONS:
if(eEntity->local.ionblaster_ammo)
return true;
break;
case AM_ROCKET:
if(eEntity->local.sidewinder_ammo)
return true;
break;
case AM_DISCUS:
if(eEntity->local.discus_ammo)
return true;
break;
case AM_BULLET:
if(eEntity->local.glock_ammo)
return true;
break;
case AM_SHELL:
if(eEntity->local.shotcycler_ammo)
return true;
break;
case AM_LASER:
if(eEntity->local.shockwave_ammo)
return true;
break;
case AM_C4BOMB:
if(eEntity->local.iC4Ammo)
return true;
break;
#endif
case AM_MELEE:
case AM_SWITCH:
case AM_NONE:
return true;
}
return false;
}
/* Check for secondary ammo.
*/
bool Weapon_CheckSecondaryAmmo(Weapon_t *wWeapon,edict_t *eEntity)
{
switch(wWeapon->iSecondaryType)
{
case AM_MELEE:
case AM_SWITCH:
case AM_NONE:
return true;
// [12/8/2013] Added to get rid of a silly warning in GCC ~hogsy
default:
return false;
}
}
/*
Animation Code
*/
// 06/02/2013 - Animation system = redone! ~eukos
void Weapon_ResetAnimation(edict_t *ent)
{
// [3/2/2014] Allow for custom idle frames after animation ~hogsy
if(ent->local.iWeaponIdleFrame)
ent->v.iWeaponFrame =
ent->local.iWeaponAnimationCurrent = ent->local.iWeaponIdleFrame;
else
ent->v.iWeaponFrame =
ent->local.iWeaponAnimationCurrent = 0;
ent->local.iWeaponAnimationEnd = 0;
ent->local.fWeaponAnimationTime = 0;
}
void WEAPON_CheckFrames(edict_t *ent)
{
if(!ent->local.iWeaponAnimationEnd || Server.dTime < ent->local.fWeaponAnimationTime) // If something isn't active and Animationtime is over
return;
// [2/10/2013] Reset the animation in-case we die! ~hogsy
else if((ent->local.iWeaponAnimationCurrent > ent->local.iWeaponAnimationEnd) || (ent->v.iHealth <= 0))
{
Weapon_ResetAnimation(ent);
return;
}
ent->v.iWeaponFrame = ent->local.iWeaponFrames[ent->local.iWeaponAnimationCurrent].iFrame;
#ifdef GAME_OPENKATANA
if(ent->local.attackb_finished > Server.dTime)
ent->local.fWeaponAnimationTime = ((float)Server.dTime)+ent->local.iWeaponFrames[ent->local.iWeaponAnimationCurrent].fSpeed * 0.2f;
else
#endif
ent->local.fWeaponAnimationTime = ((float)Server.dTime)+ent->local.iWeaponFrames[ent->local.iWeaponAnimationCurrent].fSpeed;
if(ent->local.iWeaponFrames[ent->local.iWeaponAnimationCurrent].Function)
ent->local.iWeaponFrames[ent->local.iWeaponAnimationCurrent].Function(ent);
ent->local.iWeaponAnimationCurrent++;
}
void WEAPON_Animate(edict_t *ent,EntityFrame_t *eFrames)
{
int i;
Weapon_ResetAnimation(ent);
ent->local.iWeaponAnimationCurrent = 0;
ent->v.iWeaponFrame = eFrames[0].iFrame;
for(i = 0;; i++)
if(eFrames[i].bIsEnd)
{
ent->local.iWeaponAnimationEnd = i;
break;
}
ent->local.iWeaponFrames = eFrames;
#ifdef GAME_OPENKATANA
if(ent->local.attackb_finished > Server.dTime)
ent->local.fWeaponAnimationTime = ((float)Server.dTime)+eFrames[0].fSpeed*0.5f;
else
#endif
ent->local.fWeaponAnimationTime = ((float)Server.dTime)+eFrames[0].fSpeed;
}
/**/
// [19/8/2012] TODO: Finish ~hogsy
/* Cycle through currently avaliable weapons.
*/
void Weapon_Cycle(edict_t *eEntity,bool bForward)
{
Weapon_t *wCurrentWeapon,*wNext;
if(eEntity->local.dAttackFinished > Server.dTime || !eEntity->v.iActiveWeapon)
return;
eEntity->v.impulse = 0;
wCurrentWeapon = Weapon_GetCurrentWeapon(eEntity);
if(!wCurrentWeapon)
return;
if(bForward)
{
NEXTWEAPON:
// [19/8/2012] Move up to our next slot... ~hogsy
for(wNext = Weapons; wNext->iItem; wNext++)
if(wNext > wCurrentWeapon)
{
eEntity->v.iActiveWeapon = wNext->iItem;
break;
}
if(eEntity->v.items & eEntity->v.iActiveWeapon)
{
if(!Weapon_CheckPrimaryAmmo(wNext,eEntity) && !Weapon_CheckSecondaryAmmo(wNext,eEntity))
goto NEXTWEAPON;
Weapon_SetActive(wNext,eEntity);
eEntity->local.dAttackFinished = Server.dTime+0.3;
}
}
else
{} // [1/1/2013] Previous etc blah fa fakf ~hogsy
}
void Weapon_PrimaryAttack(edict_t *eEntity)
{
Weapon_t *wCurrentWeapon = Weapon_GetCurrentWeapon(eEntity);
if(!wCurrentWeapon || !Weapon_CheckPrimaryAmmo(wCurrentWeapon,eEntity) || eEntity->local.dAttackFinished > Server.dTime)
return;
if(wCurrentWeapon->Primary)
{
Engine.MakeVectors(eEntity->v.v_angle);
#ifdef GAME_OPENKATANA
// [15/8/2013] Why write this out again and again for every weapon? Just do it here! ~hogsy
if((eEntity->monster.iType == MONSTER_PLAYER) && ((eEntity->v.velocity[0] == 0) && (eEntity->v.velocity[1] == 0)))
// [15/8/2013] But let's not forget that the Daikatana is a special case :) ~hogsy
if(wCurrentWeapon->iItem != WEAPON_DAIKATANA)
Entity_Animate(eEntity,PlayerAnimation_Fire);
#endif
wCurrentWeapon->Primary(eEntity);
}
}
void Weapon_SecondaryAttack(edict_t *eEntity)
{
Weapon_t *wCurrentWeapon = Weapon_GetCurrentWeapon(eEntity);
if(!wCurrentWeapon || !Weapon_CheckSecondaryAmmo(wCurrentWeapon,eEntity) || eEntity->local.dAttackFinished > Server.dTime)
return;
if(wCurrentWeapon->Secondary)
{
Engine.MakeVectors(eEntity->v.v_angle);
wCurrentWeapon->Secondary(eEntity);
}
}
void Weapon_CheatCommand(edict_t *eEntity)
{
#ifdef GAME_OPENKATANA
Weapon_t *wWeapon;
eEntity->local.shotcycler_ammo =
eEntity->local.ionblaster_ammo =
eEntity->local.sidewinder_ammo =
eEntity->local.shockwave_ammo =
eEntity->local.iC4Ammo = 300;
Item_AddInventory(Item_GetItem(WEAPON_DAIKATANA),eEntity);
Item_AddInventory(Item_GetItem(WEAPON_IONBLASTER),eEntity);
Item_AddInventory(Item_GetItem(WEAPON_C4VIZATERGO),eEntity);
Item_AddInventory(Item_GetItem(WEAPON_SHOTCYCLER),eEntity);
Item_AddInventory(Item_GetItem(WEAPON_SIDEWINDER),eEntity);
Item_AddInventory(Item_GetItem(WEAPON_SHOCKWAVE),eEntity);
Item_AddInventory(Item_GetItem(WEAPON_IONRIFLE),eEntity);
#if 0
Item_AddInventory(Item_GetItem(WEAPON_GLOCK),eEntity);
#endif
wWeapon = Weapon_GetWeapon(WEAPON_DAIKATANA);
if(wWeapon)
Weapon_SetActive(wWeapon,eEntity);
#elif ICTUS
#endif
eEntity->v.impulse = 0;
}
void Weapon_CheckInput(edict_t *eEntity)
{
if(eEntity->v.impulse >= 1 && eEntity->v.impulse <= 7)
{
int iNewWeapon = 0;
Item_t *iItem;
Weapon_t *wWeapon;
if(eEntity->local.dAttackFinished > Server.dTime)
return;
switch((int)eEntity->v.impulse)
{
#ifdef GAME_OPENKATANA
case 1:
iNewWeapon = WEAPON_IONBLASTER;
break;
case 2:
iNewWeapon = WEAPON_C4VIZATERGO;
break;
case 3:
iNewWeapon = WEAPON_SHOTCYCLER;
break;
case 4:
iNewWeapon = WEAPON_SIDEWINDER;
break;
case 5:
iNewWeapon = WEAPON_SHOCKWAVE;
break;
case 6:
iNewWeapon = WEAPON_DAIKATANA;
break;
case 7:
iNewWeapon = WEAPON_IONRIFLE;
#endif
}
// [29/7/2013] Check our actual inventory! ~hogsy
iItem = Item_GetInventory(iNewWeapon,eEntity);
if(iItem)
{
// [11/5/2013] Check our new weapon against our active one ~hogsy
if(iItem->iNumber != eEntity->v.iActiveWeapon)
{
wWeapon = Weapon_GetWeapon(iItem->iNumber);
if(!wWeapon)
Engine.Con_Warning("Failed to get new weapon! (%i)\n",iItem->iNumber);
else if(!Weapon_CheckPrimaryAmmo(wWeapon,eEntity) && !Weapon_CheckSecondaryAmmo(wWeapon,eEntity))
{
Engine.Server_SinglePrint(eEntity,"Not enough ammo.\n");
// [27/1/2013] TODO: Change to client-specific sound function ~hogsy
Engine.Sound(eEntity,CHAN_AUTO,"misc/deny.wav",255,ATTN_NORM);
}
else
Weapon_SetActive(wWeapon,eEntity);
}
}
}
else if(eEntity->v.impulse == 65)
Weapon_CheatCommand(eEntity);
else if(eEntity->v.impulse == 10)
Weapon_Cycle(eEntity,true); // Forwards cycling
else if(eEntity->v.impulse == 12)
Weapon_Cycle(eEntity,false); // Backwards cycling
else if(eEntity->v.impulse == 66)
Player_Use(eEntity);
if(eEntity->v.button[0])
Weapon_PrimaryAttack(eEntity);
// [28/7/2012] Added secondary attack ~hogsy
else if(eEntity->v.impulse == 150)
Weapon_SecondaryAttack(eEntity);
eEntity->v.impulse = 0;
}
As you can see above it's not too different from the original QC code, but right now some of it is still a little messy since most of it is still actively being worked on. Updates to the game-code won't be as frequent on the repository than the changes I make to the engine, purely because this would be somewhat being kept in-line and modified from the code we're writing out for OpenKatana which obviously takes a little while.
-

hogsy - Posts: 198
- Joined: Wed Aug 03, 2011 3:44 pm
- Location: UK
Who is online
Users browsing this forum: No registered users and 1 guest