/////////////////////////////////////////////////////
// RPG/Adv. Temp 2.0
// Player Module
//
// (C) 2006 by Claus N.
// www.nighthawk.dk
//
// -- UPDATES --
// July 12th 2006:
// -Fixed manabar bug
//
// July 14th 2006:
// -Hold down Shift, and click somewhere, to attack in that direction
//
// July 16th 2006:
// -Fixed bug (now player always looks at his target when attacking)
/////////////////////////////////////////////////////
// We are using the Player "Core"
define USE_CORE_PLAYER;
/////////////////////////////////////////////////////
// We need the Defines "sub-core"
ifndef USE_SUBCORE_DEFINES;
include <NHASC_defines.wdl>;
endif;
/////////////////////////////////////////////////////
// And the animation "sub-core"
ifndef USE_SUBCORE_ANIMATION;
include <NHASC_animation.wdl>;
endif;
/////////////////////////////////////////////////////
// The player event
function playerEvent()
{
if(event_type == event_scan)
{
// If you exist
if(you)
{
// If you're just searching for an enemy, we are not on the same team,
// and you haven't found an enemy yet
if(you.scan_mode == SCAN_SEARCH
&& you.team != my.team
&& you.enemy == 0)
{
// I'm your enemy
you.enemy = handle(my);
}
// Are you attacking me!?
if(you.scan_mode == SCAN_ATTACK
&& you.team != my.team)
{
// Subtract health - also note that defense can usefull ;)
my.health -= max(random(you.damage * 5) - random((my.defense + NHAC_ITM_GET_DFS()) * 5),1);
// If player isn't doing anything, attack the attacker!
if(vec_dist(my.ent_target,nullvector) <= 1 && my.enemy == 0) {my.enemy = handle(you);}
}
}
}
}
/////////////////////////////////////////////////////
// Player melee attack
function NHAC_player_attack()
{
// I'm attacking!
my.isAttacking = true;
// Set animation state
my.anim_state = anim_state_special;
// If I got an enemy
if(my.enemy)
{
// Set the you pointer
you = ptr_for_handle(my.enemy);
}
else
{
// Reset 'you' (not necessary)
you = null;
}
// Animate attack
my.skill46 = 0;
while(my.skill46 < 100)
{
ent_animate(my,"attack",my.skill46,0);
my.skill46 += my.anim_speed_attack * time;
// If 'you' isn't null
if(you)
{
// Turn against you
vec_set(temp,you.x);
vec_sub(temp,my.x);
vec_to_angle(my.pan,temp);
}
// Don't bow
my.tilt = 0;
wait(1);
}
// Tell other entities, that we are attacking
my.scan_mode = SCAN_ATTACK;
// Setup the "area" to scan within
temp.pan = 90;
temp.tilt = 120;
temp.z = 60;
// Scan for enemies
scan_entity(my.x,temp);
// We also use cast rate here
my.cr_cdown = my.cast_rate;
// Handle animation
my.anim_state = anim_state_stand;
// Finished attack
my.isAttacking = false;
}
/////////////////////////////////////////////////////
// The player script
// Title: NHA Core RPG Player
// Desc: NHA RPG/Adv. temp 2.0 Core Player
// Desc: (C) 2006 by Claus N. (www.nighthawk.dk)
// Section: Skills and Flags:
// Use: max_health, health, max_mana, mana, damage, defense, speed, anim_speed_stand
// Use: anim_speed_walk, anim_speed_run, anim_speed_attack, anim_speed_death
// Use: cast_rate, team
// Use: run
action NHAC_player
{
// I'm the player :o)
player = me;
// Animate me, plz...
std_animpack();
// If we should use this function
if(NHAC_ENTS_TO_GROUND)
{
// Then do it :)
// Don't flow
attach_to_ground();
}
// Initialize skills
if(!my.max_health) {my.max_health = 100;}
if(!my.health) {my.health = my.max_health;}
if(!my.max_mana) {my.max_mana = 100;}
if(!my.mana) {my.mana = my.max_mana;}
if(!my.damage) {my.damage = 5;}
if(!my.defense) {my.defense = 5;}
if(!my.speed) {my.speed = 6;}
if(!my.cast_rate) {my.cast_rate = 20;}
if(!my.anim_speed_stand) {my.anim_speed_stand = 2;}
if(!my.anim_speed_walk) {my.anim_speed_walk = 8;}
if(!my.anim_speed_run) {my.anim_speed_run = 12;}
if(!my.anim_speed_attack) {my.anim_speed_attack = 10;}
if(!my.anim_speed_death) {my.anim_speed_death = 5;}
// Enable enemies to attack me
my.isAITarget = true;
// Event and triggers
my.enable_scan = true;
my.event = playerEvent;
// The main player loop
// As long as the player exists, and is alive
while(my && (my.health > 0))
{
// Wait till attack is finished
while(my.isAttacking) {wait(1);}
// Handle cast rate
my.cr_cdown = max(0,my.cr_cdown - 1 * time);
// Compute the health/mana for the HUD panel
pl_HUDC_health = (bmap_width(NHAC_HPBAR) / 2) - my.health / (my.max_health + NHAC_ITM_GET_HLT()) * (bmap_width(NHAC_HPBAR) / 2);
pl_HUDC_mana = (bmap_width(NHAC_MANABAR) / 2) - my.mana / (my.max_mana + NHAC_ITM_GET_MAN()) * (bmap_width(NHAC_MANABAR) / 2);
// Limit health and mana
my.health = min(my.health,(my.max_health + NHAC_ITM_GET_HLT()));
my.mana = min(my.mana,(my.max_mana + NHAC_ITM_GET_MAN()));
// We only use the X and Y position of the target
// Z could cause stupid-looking "errors"
my.ent_target_z = 0;
// If the player got a walkpoint
if(vec_dist(my.ent_target,nullvector) > 1 && !NHAC_PLAYER_STANDSTILL)
{
// If I haven't yet reached my target
if(vec_dist(vector(my.ent_target_x,my.ent_target_y,my.z),my.x) > 10)
{
// Turn against the target
vec_set(temp,my.ent_target);
vec_sub(temp,my.x);
vec_to_angle(my.pan,temp);
// Don't bow
my.tilt = 0;
// Set the player's movement speed
my.curSpeed = (my.speed + NHAC_ITM_GET_SPD()) * (1 + my.run);
// Move the player
c_move(my,vector(my.curSpeed * time,0,0),nullvector,ignore_passable + ignore_you + glide);
// Set the animation to walk or run
my.anim_state = anim_state_walk + my.run;
}
else
{
// If I'm below 10 quants away from my target
// Reset my target
vec_set(my.ent_target,nullvector);
// Use the stand animation
my.anim_state = anim_state_stand;
}
}
// If we have clicked an enemy
if(my.enemy != 0)
{
// Get a pointer to the enemy!
you = ptr_for_handle(my.enemy);
// If the pointer is valid..
if(you)
{
// Are we on the same team..?
if(you.team != my.team && you.health > 0)
{
// If we are too far away
if(vec_dist(my.x,you.x) >= 60)
{
// Set my walkpoint
vec_set(my.ent_target,you.x);
}
// If I'm close enough for a melee attack
if(vec_dist(my.x,you.x) < 60 && my.cr_cdown <= 0)
{
// We are close enough
vec_set(my.ent_target,nullvector);
// Attack!
NHAC_player_attack();
}
}
else
{
// If we are on the same team, reset our enemy skill
my.enemy = 0;
}
}
else
{
// If the pointer isn't valid, reset our enemy skill
my.enemy = 0;
}
}
// Avoid endless loops
wait(1);
}
// Compute the health/mana for the HUD panel
pl_HUDC_health = (bmap_width(NHAC_HPBAR) / 2) - my.health / (my.max_health + NHAC_ITM_GET_HLT()) * (bmap_width(NHAC_HPBAR) / 2);
pl_HUDC_mana = (bmap_width(NHAC_MANABAR) / 2) - my.mana / (my.max_mana + NHAC_ITM_GET_MAN()) * (bmap_width(NHAC_MANABAR) / 2);
// Do not animate me anymore
my.anim_state = anim_stop;
// Show death animation
my.skill46 = 0;
while(my.skill46 < 100)
{
ent_animate(my,"death",my.skill46,0);
my.skill46 += my.anim_speed_death * time;
wait(1);
}
// The player is gone
if(player == my) {player = null;}
}
/////////////////////////////////////////////////////
// Function to set the player's walkpoint, using mouse coordinates
function set_player_walkpoint()
{
// Check whether the player exists
if(!player) {return;}
// If we clicked in the inventory panel, don't set a new walkpoint
if(NHAC_CVAR_USE_CINVENTORY // DO NOT MODIFY THIS VARIABLE!!!
&& mouse_pos.x > NHAC_CINV_POSX
&& mouse_pos.x < NHAC_CINV_POSX + NHAC_CINV_BMAPWIDTH
&& mouse_pos.y > NHAC_CINV_POSY
&& mouse_pos.y < NHAC_CINV_POSY + NHAC_CINV_BMAPHEIGHT
&& NHAC_CINV_VISIBLE == true)
{
return;
}
// Neither set a walkpoint if we clicked the HUD in the bottom
if(NHAC_CVAR_USE_CHUD // DO NOT MODIFY THIS VARIABLE!!!
&& mouse_pos.x > NHAC_CHUD_POSX
&& mouse_pos.x < NHAC_CHUD_POSX + NHAC_CHUD_BMAPWIDTH
&& mouse_pos.y > NHAC_CHUD_POSY
&& mouse_pos.y < NHAC_CHUD_POSY + NHAC_CHUD_BMAPHEIGHT
&& NHAC_CHUD_VISIBLE == true)
{
return;
}
// Or if an item is attached to the mouse
if(NHAC_MOUSEITEM) {return;}
// Will be changed if we cliked an enemy
player.enemy = 0;
// First we get the mouse coordinates (2D)
temp.x = mouse_pos.x;
temp.y = mouse_pos.y;
temp.z = 0;
// Set "target" to the same coordinates
vec_set(target,temp);
// Add some depth/dist. from screen, to "target"
target.z = 10000;
// Convert from 2D screen coordinates, to 3D world coordinates
vec_for_screen(temp,camera);
vec_for_screen(target,camera);
// Trace from temp (mouse pos.) to target
c_trace(temp,target,ignore_passable + ignore_passents + ignore_you);
// If key Shift is pressed
if(key_shift)
{
// If we are ready for attacking
if(player.isAttacking != true && player.cr_cdown <= 0)
{
// Reset player's enemy
player.enemy = 0;
// Remove walkpoint
vec_set(player.ent_target,nullvector);
// Turn against target
vec_sub(target,player.x);
vec_to_angle(player.pan,target);
// Set my to the player
my = player;
// Attack!
NHAC_player_attack();
}
}
else
{
// Set player's walkpoint, to the target from the trace
vec_set(player.ent_target,target);
}
}
// Trigger the function on the left mouse button
//on_mouse_left = set_player_walkpoint;
/////////////////////////////////////////////////////
// Function to toggle player run/walk
function toggle_runwalk()
{
// If the player doesn't exist...
if(!player) {return;}
// Toggle run/walk
player.run = (player.run == off);
}
// Trigger function on key [R]
on_r = toggle_runwalk;
/////////////////////////////////////////////////////