Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Author: cvet
- #include "_macros.fos"
- #include "_msgstr.fos"
- #include "_teams.fos"
- #include "_npc_pids.fos"
- #include "_animation.fos"
- #include "teams_table.fos"
- // Imports
- import void InitializeGame() from "config";
- import bool OnUseExplode( Critter& cr, Item& explode, Critter@ targetCr, Item@ targetItem, Scenery@ targetScen, uint timer ) from "explode";
- import bool UseItemOnCar( Critter& cr, Item& car, Item& item ) from "car";
- import bool UseSkillOnCar( Critter& cr, Item& car, int skill ) from "car";
- import void WorldmapInit() from "worldmap";
- import void SetStartLocation( Critter& cr ) from "replication";
- import void SetReplicationTime( Critter& cr ) from "replication";
- import void ReplicateCritter( Critter& cr ) from "replication";
- import void CombatAttack( Critter& cr, Critter& target, ProtoItem& weapon, uint8 weaponMode, ProtoItem@ ammo ) from "combat";
- import bool TryRepairItem( Critter& cr, Item& item ) from "repair";
- import bool WantedSignSet( Item& wantedSign, string& name, uint cost ) from "wanted";
- import bool IsReadableBook( uint16 pid ) from "books";
- import void TryReadBook( Critter& cr, Item& book ) from "books";
- import void UseDrug( Critter& cr, Item& drug ) from "drugs";
- import void UseDrugOn( Critter& cr, Critter& onCr, Item& drug ) from "drugs";
- import bool UseGeiger( Critter& cr, Item& geiger ) from "geiger";
- import bool UseItemOnGeiger( Critter& cr, Item& geiger, Item& item ) from "geiger";
- import bool UseSkillOnGeiger( Critter& cr, Item& geiger, int skill ) from "geiger";
- import void CallTownSupply( Critter& victim, Critter& hostile ) from "town_supply";
- import bool AddAttackPlane( Critter& npc, uint priority, Critter& target ) from "npc_planes";
- import bool AddAttackPlane( Critter& npc, uint priority, Critter& target, int minHp ) from "npc_planes";
- import bool UseSkillOnLocker( Critter& cr, Item& locker, int skill ) from "lockers";
- import bool PerkCheck( Critter& cr, uint perk ) from "perks";
- import void CritterGenerate( Critter& cr ) from "parameters";
- import void CaravansInit() from "caravan";
- import int GetDeteriorationProcent( Item& item ) from "repair";
- import void SetDeterioration( Item& item, int deteriorationProcent ) from "repair";
- import void NpcProcessLevel( Critter& npc ) from "parameters";
- import bool IsPermanentDeath( uint id ) from "replication";
- import bool SetPlayerStoryLineLocation( Critter& player ) from "q_main_intro";
- import void EditRadioSettings( Critter& player, Item& radio ) from "radio";
- import void SetNoPvp() from "nopvp_maps";
- import void OnCritterMapOut( Critter& cr, Map& map ) from "nopvp_maps";
- import void OnCitterMapIn( Critter& cr, Map& map ) from "nopvp_maps";
- import void DeclareEvents() from "game_event";
- import void CheckAllGameEvents() from "game_event";
- import void PlaceLoot2Container( Map& map, Critter& cr ) from "game_event_caches";
- import void StartMessenger() from "bulletin_board";
- import void SaveMessengerData() from "bulletin_board";
- import void CountEmpRocketTests( Critter& player, Critter& target ) from "navarro";
- import void OnCritterKilled( Critter& cr, Critter@ killer ) from "q_hunter";
- import bool BarterAllowed( int crId, Item@[]& buyItems, Item@[]& saleItems ) from "limited_barter";
- import uint CheckPlayerName( const string& name ) from "parameters";
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Called before world generation.
- void init()
- {
- InitializeGame();
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on start server.
- bool start()
- {
- // Send info about others critters
- // Remember:
- // - all this info can be hacked in client;
- // - more parameters - more traffic.
- SetSendParameter( ST_GENDER, true );
- SetSendParameter( ST_AGE, true );
- SetSendParameter( ST_FOLLOW_CRIT, true );
- SetSendParameter( ST_PLAYER_KARMA, true );
- // Armor class, uses Agility
- SetSendParameter( ST_ARMOR_CLASS, true );
- SetSendParameter( ST_TURN_BASED_AC, true );
- // Agility
- SetSendParameter( ST_AGILITY, true );
- // Hit points, uses Strenght and Endurance
- SetSendParameter( ST_MAX_LIFE, true );
- SetSendParameter( ST_CURRENT_HP, true );
- // Strenght, uses battle timeout
- SetSendParameter( ST_STRENGTH, true );
- SetSendParameter( PE_ADRENALINE_RUSH, true );
- // Battle timeout
- SetSendParameter( TO_BATTLE, true );
- // Endurance
- SetSendParameter( ST_ENDURANCE, true );
- // Injures
- SetSendParameter( DAMAGE_EYE, true );
- SetSendParameter( DAMAGE_RIGHT_ARM, true );
- SetSendParameter( DAMAGE_LEFT_ARM, true );
- SetSendParameter( DAMAGE_RIGHT_LEG, true );
- SetSendParameter( DAMAGE_LEFT_LEG, true );
- // Item slots, passed with -
- SetSendParameter( -SLOT_HAND1, true, "fonline_tla.dll@allowSlot_Hand1" );
- SetSendParameter( -SLOT_ARMOR, true );
- // Some flags for correct client working
- SetSendParameter( MODE_NO_BARTER, true );
- SetSendParameter( MODE_NO_STEAL, true );
- SetSendParameter( MODE_NO_LOOT, true );
- SetSendParameter( MODE_NO_FLATTEN, true );
- SetSendParameter( MODE_NO_TALK, true );
- // 3d animation layers
- #ifdef PLAYERS_3D
- // Enable sending 3d layers, from Skin to Backpack
- uint fromLayer = ST_ANIM3D_LAYERS + ANIM3D_LAYER_SKIN;
- uint toLayer = ST_ANIM3D_LAYERS + ANIM3D_LAYER_BACKPACK;
- for( uint i = fromLayer; i <= toLayer; i++ )
- SetSendParameter( i, true );
- #endif
- // Npc talk distance
- SetSendParameter( ST_TALK_DISTANCE, true );
- // Dialog id
- SetSendParameter( ST_DIALOG_ID, true );
- // To see pid of unarmed attack
- SetSendParameter( ST_HANDS_ITEM_AND_MODE, true );
- // Scale factor
- SetSendParameter( ST_SCALE_FACTOR, true );
- // Walk / Run speed
- SetSendParameter( ST_WALK_TIME, true );
- SetSendParameter( ST_RUN_TIME, true );
- // Send item data masks
- // Look fields in fonline.h 'struct Item::ItemData'
- // SortValue Info Indicator PicMapHash PicInvHash AnimWaitBase AStay[2] AShow[2] AHide[2] Flags Rate LightDist Inten Flags LightColor ScriptId TrapValue Count Cost ScriptValues[10] Other 36 bytes
- // ITEM_DATA_MASK_CHOSEN ITEM_DATA_MASK_CHOSEN ITEM_DATA_MASK_CHOSEN
- int8[] mask0 = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0 };
- // ITEM_DATA_MASK_CRITTER ITEM_DATA_MASK_CRITTER ITEM_DATA_MASK_CRITTER
- int8[] mask1 = { 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- // ITEM_DATA_MASK_CRITTER_EXT ITEM_DATA_MASK_CRITTER_EXT ITEM_DATA_MASK_CRITTER_EXT
- int8[] mask2 = { 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0 };
- // ITEM_DATA_MASK_CONTAINER ITEM_DATA_MASK_CONTAINER ITEM_DATA_MASK_CONTAINER
- int8[] mask3 = { -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0 };
- // ITEM_DATA_MASK_MAP ITEM_DATA_MASK_MAP ITEM_DATA_MASK_MAP
- int8[] mask4 = { -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0 };
- SetItemDataMask( ITEM_DATA_MASK_CHOSEN, mask0 );
- SetItemDataMask( ITEM_DATA_MASK_CRITTER, mask1 );
- SetItemDataMask( ITEM_DATA_MASK_CRITTER_EXT, mask2 );
- SetItemDataMask( ITEM_DATA_MASK_CONTAINER, mask3 );
- SetItemDataMask( ITEM_DATA_MASK_MAP, mask4 );
- // Global map initialization
- WorldmapInit();
- // Caravans initialization
- CaravansInit();
- // NoPvP initialization
- SetNoPvp();
- // Game Events initialization
- DeclareEvents();
- CheckAllGameEvents();
- // Bulletin boards
- StartMessenger();
- return true;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on world initialization.
- // Parameter Min Max
- // multiplier 1 50000
- // year 1700 30000
- // month 1 12
- // day 1 31
- // hour 0 23
- // minute 0 59
- void get_start_time( uint16& multiplier, uint16& year, uint16& month, uint16& day, uint16& hour, uint16& minute )
- {
- multiplier = 20;
- year = 2246;
- month = 10;
- day = 30;
- hour = 1;
- minute = 0;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on finish server.
- void finish()
- {}
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call every returned value, in milliseconds.
- // Return next call in milliseconds or zero to disable loop.
- uint loop()
- {
- return 0; // Disable
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter attack another.
- void critter_attack( Critter& cr, Critter& target, ProtoItem& weapon, uint8 weaponMode, ProtoItem@ ammo )
- {
- if( cr.IsPlayer() && valid( ammo ) && ammo.ProtoId == PID_EMP_ROCKET && target.Stat[ ST_BODY_TYPE ] == BT_ROBOT )
- CountEmpRocketTests( cr, target );
- cr.TimeoutBase[ TO_AGGRESSOR ] = __FullSecond + REAL_MINUTE( 1 );
- CombatAttack( cr, target, weapon, weaponMode, ammo );
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter attack another.
- void critter_attacked( Critter& cr, Critter& attacker )
- {
- if( cr.IsPlayer() )
- return; // Diable player helping
- else
- AddAttackPlane( cr, 0, attacker ); // Answer on attack
- // if(cr.Timeout[TO_AGGRESSOR]>0) return;
- uint helpers = 0;
- uint maxHelpers = 10 - attacker.Stat[ ST_CHARISMA ];
- maxHelpers = CLAMP( maxHelpers, 2, 8 );
- Critter@[] critters;
- cr.GetCritters( true, FIND_LIFE_AND_KO | FIND_ONLY_NPC, critters );
- for( uint i = 0, j = critters.length(); i < j; i++ )
- {
- NpcPlane@ plane = critters[ i ].GetCurPlane();
- if( valid( plane ) && plane.Type == AI_PLANE_ATTACK && plane.Attack_TargId == attacker.Id )
- {
- helpers++;
- if( helpers >= maxHelpers )
- return; // No help needed
- @critters[ i ] = null; // Exclude this critter
- }
- }
- int crHpProc = cr.Stat[ ST_CURRENT_HP ] * 100 / cr.Stat[ ST_MAX_LIFE ];
- uint teamId = cr.Stat[ ST_TEAM_ID ];
- uint attackerTeamId = attacker.Stat[ ST_TEAM_ID ];
- for( uint i = 0, j = critters.length(); i < j; i++ )
- {
- Critter@ someCr = critters[ i ];
- if( not valid( someCr ) )
- continue; // Skip excluded
- uint someCrTeamId = someCr.Stat[ ST_TEAM_ID ];
- if( attackerTeamId == someCrTeamId )
- continue; // No attack temmate
- int teamParity = TEAM_PARITY( someCrTeamId, teamId ); // From -> To
- switch( teamParity )
- {
- case Ignore:
- continue;
- case Anyway:
- break;
- case NotBusy:
- if( someCr.IsCurPlane( AI_PLANE_ATTACK ) )
- continue;
- break;
- case HpLess10:
- if( crHpProc >= 10 )
- continue;
- break;
- case HpLess30:
- if( crHpProc >= 30 )
- continue;
- break;
- case HpLess50:
- if( crHpProc >= 50 )
- continue;
- break;
- case IfDead:
- if( not cr.IsDead() )
- continue;
- break;
- case GoodPerson:
- if( attacker.IsNpc() || cr.Stat[ ST_CHARISMA ] < 5 || cr.Stat[ ST_KARMA ] < 0 )
- continue;
- break;
- default:
- continue;
- }
- AddAttackPlane( someCr, 0, attacker );
- helpers++;
- if( helpers >= maxHelpers )
- break; // Enough
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter steal another.
- bool critter_stealing( Critter& cr, Critter& thief, Item& item, uint count )
- {
- thief.TimeoutBase[ TO_AGGRESSOR ] = __FullSecond + REAL_MINUTE( 1 );
- if( cr.IsDead() || cr.Timeout[ TO_BATTLE ] > 0 || thief.Timeout[ TO_BATTLE ] > 0 )
- {
- thief.StatBase[ ST_LAST_STEAL_CR_ID ] = 0;
- thief.StatBase[ ST_STEAL_COUNT ] = 0;
- return false;
- }
- if( cr.Mode[ MODE_NO_PVP ] != 0 || thief.Mode[ MODE_NO_PVP ] != 0 )
- {
- thief.Say( SAY_NETMSG, "No PvP." );
- return false;
- }
- int dir1 = cr.Dir;
- int dir2 = thief.Dir;
- int kDir = MAX( dir1, dir2 ) - MIN( dir1, dir2 );
- if( kDir > 3 )
- kDir = 6 - kDir;
- int steal = thief.Skill[ SK_STEAL ];
- if( steal <= 0 )
- steal = 1;
- int size = item.Proto.Volume;
- if( size <= 0 )
- size = 1;
- // Perk pickpocket, ignore size and facing
- if( thief.Perk[ PE_PICKPOCKET ] != 0 )
- {
- kDir = 0;
- size = 1;
- }
- // Count modifier
- int kCount = count / steal;
- if( kCount <= 0 )
- kCount = 1;
- // Check time of stealing
- uint lastStealCrId = thief.Stat[ ST_LAST_STEAL_CR_ID ];
- uint stealCount = thief.Stat[ ST_STEAL_COUNT ];
- if( lastStealCrId == cr.Id && thief.Timeout[ TO_STEALING ] > 0 )
- steal -= steal * stealCount * 9 / 100;
- // Calc
- int k = ( steal - kDir * 10 ) / ( size * kCount );
- k = CLAMP( k, 5, 95 );
- bool success = !( Random( 1, 100 ) > k );
- if( success )
- {
- // Add experience 10,30,60,100,150,210,280,360,450,550,660,780
- const int[] stealExp = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 };
- if( lastStealCrId == cr.Id && thief.Timeout[ TO_STEALING ] > 0 )
- {
- stealCount++;
- if( stealCount > 11 )
- stealCount = 11;
- thief.StatBase[ ST_STEAL_COUNT ] = stealCount;
- }
- else
- {
- thief.StatBase[ ST_LAST_STEAL_CR_ID ] = cr.Id;
- thief.StatBase[ ST_STEAL_COUNT ] = 0;
- }
- thief.TimeoutBase[ TO_STEALING ] = STEAL_TIMEOUT( thief );
- if( cr.IsNpc() )
- {
- GameVar@ stealExpCount = ::GetUnicumVar( UVAR_steal_exp_count, cr.Id, thief.Id );
- if( stealExpCount < 12 )
- {
- thief.StatBase[ ST_EXPERIENCE ] += stealExp[ stealCount ];
- thief.AddScore( SCORE_THIEF, 1 );
- }
- stealExpCount = stealExpCount + 1;
- }
- }
- else
- {
- thief.StatBase[ ST_LAST_STEAL_CR_ID ] = 0;
- thief.StatBase[ ST_STEAL_COUNT ] = 0;
- if( cr.IsNpc() )
- {
- int thiefHp = thief.Stat[ ST_CURRENT_HP ];
- AddAttackPlane( cr, 0, thief, thiefHp< 10 || Random( 1, 10 ) > cr.Stat[ ST_LUCK ] + 4 || cr.Stat[ ST_CHARISMA ] < 3 ? __DeadHitPoints : Random( thiefHp / 4, thiefHp / 2 ) );
- }
- }
- return success;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter use item.
- bool critter_use_item( Critter& cr, Item& item, Critter@ targetCr, Item@ targetItem, Scenery@ targetScen, uint param )
- {
- bool isPlayer = cr.IsPlayer();
- uint16 pid = item.GetProtoId();
- bool useOnSelf = ( not valid( targetCr ) && not valid( targetItem ) && not valid( targetScen ) );
- // Radio
- if( FLAG( item.Flags, ITEM_RADIO ) && useOnSelf )
- {
- if( isPlayer )
- EditRadioSettings( cr, item );
- return true;
- }
- // Book reading
- if( useOnSelf && IsReadableBook( pid ) )
- {
- TryReadBook( cr, item );
- return true;
- }
- // Explosion
- if( OnUseExplode( cr, item, targetCr, targetItem, targetScen, param ) )
- return true;
- // Cars
- if( valid( targetItem ) && targetItem.GetType() == ITEM_TYPE_CAR && UseItemOnCar( cr, targetItem, item ) )
- return true;
- // Drugs
- if( item.GetType() == ITEM_TYPE_DRUG )
- {
- if( useOnSelf )
- UseDrug( cr, item );
- else if( valid( targetCr ) )
- UseDrugOn( cr, targetCr, item );
- else
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- return true;
- }
- // Play dice
- if( pid == PID_DICE )
- {
- cr.SayMsg( SAY_EMOTE_ON_HEAD, TEXTMSG_TEXT, STR_DICE_THROW, "$result" + Random( 1, 6 ) );
- return true;
- }
- if( pid == PID_LOADED_DICE )
- {
- cr.SayMsg( SAY_EMOTE_ON_HEAD, TEXTMSG_TEXT, STR_DICE_THROW, "$result" + uint( ( item.Id % 6 ) + 1 ) );
- return true;
- }
- // Magic ball
- if( pid == PID_MAGIC_8_BALL )
- {
- // cr.SayMsg(SAY_EMOTE_ON_HEAD,TEXTMSG_TEXT,Random(1,2)==1?STR_MAGIC_BALL_YES:STR_MAGIC_BALL_NO);
- return true;
- }
- // Cosmetic
- if( pid == PID_COSMETIC_CASE && cr.Stat[ ST_GENDER ] == GENDER_FEMALE )
- {
- cr.SayMsg( SAY_EMOTE_ON_HEAD, TEXTMSG_TEXT, STR_COSMETIC_USE );
- return true;
- }
- // Cigarettes smoking
- if( pid == PID_CIGARETTES && _CritCountItem( cr, PID_LIGHTER ) > 0 )
- {
- cr.SayMsg( SAY_EMOTE_ON_HEAD, TEXTMSG_TEXT, STR_CIGARETTES_SMOKE );
- return true;
- }
- // Geiger counter
- if( pid == PID_GEIGER_COUNTER && useOnSelf && UseGeiger( cr, item ) )
- return true;
- if( valid( targetItem ) && targetItem.GetProtoId() == PID_GEIGER_COUNTER && UseItemOnGeiger( cr, targetItem, item ) )
- return true;
- // Take process to engine
- return false;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter use skill.
- bool critter_use_skill( Critter& cr, int skill, Critter@ targetCr, Item@ targetItem, Scenery@ targetScen )
- {
- bool isPlayer = cr.IsPlayer();
- // Cars
- if( valid( targetItem ) && targetItem.GetType() == ITEM_TYPE_CAR && UseSkillOnCar( cr, targetItem, skill ) )
- return true;
- // Geiger counter
- if( valid( targetItem ) && targetItem.GetProtoId() == PID_GEIGER_COUNTER && UseSkillOnGeiger( cr, targetItem, skill ) )
- return true;
- // Doors or containers
- if( valid( targetItem ) && ( targetItem.GetType() == ITEM_TYPE_DOOR || targetItem.GetType() == ITEM_TYPE_CONTAINER ) && UseSkillOnLocker( cr, targetItem, skill ) )
- return true;
- switch( skill )
- {
- case SKILL_PICK_ON_GROUND: // Pick item or scenery on ground
- {
- // Scenery
- if( valid( targetScen ) )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- return true;
- }
- // Wanted
- if( valid( targetItem ) && targetItem.GetProtoId() == PID_WANTED_SIGN && WantedSignSet( targetItem, cr.Name, Random( 1000, 2000 ) ) )
- return true;
- // Explosion
- if( valid( targetItem ) && targetItem.GetProtoId() == PID_ACTIVE_MINE && OnUseExplode( cr, targetItem, null, null, null, 0 ) )
- return true;
- // Pick some item
- if( valid( targetItem ) )
- {
- Item@ item = targetItem;
- if( not FLAG( item.Flags, ITEM_CAN_PICKUP ) )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- break;
- }
- int freeWeight = cr.Stat[ ST_CARRY_WEIGHT ] - cr.ItemsWeight();
- if( freeWeight >= int( item.Proto.Weight * item.GetCount() ) )
- {
- // Pick full
- MoveItem( item, 0, cr );
- }
- else
- {
- // Pick half
- if( item.IsStackable() && freeWeight >= int(item.Proto.Weight) )
- MoveItem( item, freeWeight / item.Proto.Weight, cr );
- // Overweight
- else
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_OVERWEIGHT );
- }
- }
- }
- break;
- case SKILL_PUT_CONT: // Put item in container, only targetItem is valid
- case SKILL_TAKE_CONT: // Take item from container, only targetItem is valid
- case SKILL_TAKE_ALL_CONT: // Take all items from critter or item container
- return false; // Allow transactions
- case SKILL_LOOT_CRITTER: // Loot critter, only targetCr is valid
- cr.Action( ACTION_PICK_CRITTER, 0, null );
- cr.ShowContainer( targetCr, null, TRANSFER_CRIT_LOOT );
- return true;
- case SKILL_PUSH_CRITTER: // Push critter, only targetCr is valid
- cr.Action( ACTION_PICK_CRITTER, 2, null );
- if( ( cr.Timeout[ TO_BATTLE ] == 0 && targetCr.Timeout[ TO_BATTLE ] == 0 ) &&
- ( targetCr.IsPlayer() || ( targetCr.IsNoPlanes() && targetCr.GetTalkedPlayers( null ) == 0 ) ) )
- targetCr.MoveRandom();
- return true;
- case SK_SCIENCE:
- {
- // Radio
- if( valid( targetItem ) && FLAG( targetItem.Flags, ITEM_RADIO ) && targetItem.Accessory == ACCESSORY_CRITTER && targetItem.CritId == cr.Id )
- {
- if( isPlayer )
- EditRadioSettings( cr, targetItem );
- return true;
- }
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING ); // Todo: "You fail to learn anything."
- }
- break;
- case SK_REPAIR:
- {
- // Generic repair
- if( valid( targetItem ) && targetItem.Accessory == ACCESSORY_CRITTER && targetItem.IsDeteriorable() && TryRepairItem( cr, targetItem ) )
- return true;
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- }
- break;
- case SK_SNEAK:
- {
- if( cr.Mode[ MODE_HIDE ] != 0 )
- cr.ModeBase[ MODE_HIDE ] = 0;
- else if( not isPlayer )
- cr.ModeBase[ MODE_HIDE ] = 1;
- else
- {
- if( cr.Timeout[ TO_SNEAK ] > 0 )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_TIMEOUT_SNEAK_WAIT );
- else if( IS_TURN_BASED_TIMEOUT( cr ) )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_TIMEOUT_BATTLE_WAIT );
- // else if(cr.GetCritters(true,FIND_LIFE,null)>0)
- // {
- // cr.TimeoutBase[TO_SNEAK]=SNEAK_TIMEOUT(cr);
- // cr.SayMsg(SAY_NETMSG,TEXTMSG_GAME,STR_SKILL_SNEAK_VISIBLE);
- // }
- else
- cr.ModeBase[ MODE_HIDE ] = 1;
- }
- }
- break;
- case SK_STEAL:
- {
- if( valid( targetItem ) )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- }
- else if( valid( targetCr ) )
- {
- // Loot
- if( targetCr.IsDead() )
- {
- cr.Action( ACTION_PICK_CRITTER, 0, null );
- cr.ShowContainer( targetCr, null, TRANSFER_CRIT_LOOT );
- }
- // Steal
- else
- {
- if( isPlayer && cr.Timeout[ TO_SK_STEAL ] > 0 )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_WEARINESS );
- else
- {
- cr.Action( ACTION_PICK_CRITTER, 1, null );
- cr.ShowContainer( targetCr, null, TRANSFER_CRIT_STEAL );
- cr.TimeoutBase[ TO_SK_STEAL ] = STEAL_TIMEOUT( cr );
- cr.StatBase[ ST_LAST_STEAL_CR_ID ] = 0;
- cr.StatBase[ ST_STEAL_COUNT ] = 0;
- }
- }
- }
- else
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- }
- }
- break;
- case SK_FIRST_AID:
- {
- if( valid( targetItem ) || valid( targetScen ) )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- break;
- }
- if( not valid( targetCr ) )
- @targetCr = cr;
- bool is_self = ( targetCr.Id == cr.Id );
- if( targetCr.IsDead() )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NORESSURECT );
- break;
- }
- if( targetCr.Stat[ ST_CURRENT_HP ] >= targetCr.Stat[ ST_MAX_LIFE ] )
- {
- if( _CritIsInjured( targetCr ) )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NOFIRSTAID_NEEDDOCTOR );
- else if( is_self )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NONEED_FIRSTAID );
- break;
- }
- if( isPlayer && cr.Timeout[ TO_SK_FIRST_AID ] > 0 )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_WEARINESS );
- break;
- }
- int sk = cr.Skill[ SK_FIRST_AID ];
- uint8 mode = 0;
- uint16 activePid = cr.GetSlotProto( SLOT_HAND1, mode ).ProtoId;
- if( activePid == PID_FIRST_AID_KIT )
- {
- sk += 25;
- if( Random( 0, 30 ) == 0 )
- cr.DeleteItem( PID_FIRST_AID_KIT, 1 );
- }
- else if( activePid == PID_FIELD_MEDIC_KIT )
- {
- sk += 50;
- if( Random( 0, 30 ) == 0 )
- cr.DeleteItem( PID_FIELD_MEDIC_KIT, 1 );
- }
- int mod = 11 - cr.Stat[ ST_LUCK ];
- mod = CLAMP( mod, 1, 10 );
- int heal = Random( sk / mod, sk );
- if( heal < 1 )
- heal = 1;
- if( cr.Perk[ PE_VAMPIRE_REGENERATION ] > 0 )
- heal += 5;
- int curHp = targetCr.Stat[ ST_CURRENT_HP ];
- int maxHp = targetCr.Stat[ ST_MAX_LIFE ];
- if( curHp + heal > maxHp )
- heal = maxHp - curHp;
- targetCr.StatBase[ ST_CURRENT_HP ] += heal;
- cr.Say( SAY_NETMSG, "+" + heal );
- if( not is_self )
- targetCr.Say( SAY_NETMSG, "+" + heal );
- if( isPlayer )
- {
- GameVar@ firstAidCount = ::GetUnicumVar( UVAR_first_aid_count, cr.Id, targetCr.Id );
- if( firstAidCount < 10 )
- cr.StatBase[ ST_EXPERIENCE ] += heal * 3;
- firstAidCount += 1;
- cr.TimeoutBase[ TO_SK_FIRST_AID ] = FIRST_AID_TIMEOUT( cr );
- cr.AddScore( SCORE_DOCTOR, 1 );
- }
- }
- break;
- case SK_DOCTOR:
- {
- if( valid( targetItem ) || valid( targetScen ) )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- break;
- }
- if( not valid( targetCr ) )
- @targetCr = cr;
- bool is_self = ( targetCr.Id == cr.Id );
- if( targetCr.IsDead() )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NORESSURECT );
- break;
- }
- if( not _CritIsInjured( targetCr ) )
- {
- if( targetCr.Stat[ ST_CURRENT_HP ] < targetCr.Stat[ ST_MAX_LIFE ] )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NODOCTOR_NEEDFIRSTAID );
- else if( is_self )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NONEED_DOCTOR );
- break;
- }
- if( isPlayer && cr.Timeout[ TO_SK_DOCTOR ] > 0 )
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_WEARINESS );
- break;
- }
- int uninjured = 0;
- int sk = cr.Skill[ SK_DOCTOR ];
- uint8 mode = 0;
- uint16 activePid = cr.GetSlotProto( SLOT_HAND1, mode ).ProtoId;
- if( activePid == PID_DOCTORS_BAG )
- {
- sk += 25;
- if( Random( 0, 30 ) == 0 )
- cr.DeleteItem( PID_DOCTORS_BAG, 1 );
- }
- else if( activePid == PID_PARAMEDICS_BAG )
- {
- sk += 50;
- if( Random( 0, 30 ) == 0 )
- cr.DeleteItem( PID_PARAMEDICS_BAG, 1 );
- }
- for( int i = DAMAGE_EYE; i <= DAMAGE_LEFT_LEG; ++i )
- {
- if( targetCr.Damage[ i ] != 0 )
- {
- if( sk > Random( 5, 95 ) )
- {
- targetCr.DamageBase[ i ] = 0;
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_HEAL_DMG( i - DAMAGE_POISONED ) );
- uninjured++;
- }
- else
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SKILL_NOHEAL_DMG( i - DAMAGE_POISONED ) );
- }
- sk /= 2;
- }
- }
- if( isPlayer )
- {
- if( uninjured > 0 )
- cr.StatBase[ ST_EXPERIENCE ] += uninjured * 50;
- cr.TimeoutBase[ TO_SK_DOCTOR ] = DOCTOR_TIMEOUT( cr );
- cr.AddScore( SCORE_DOCTOR, uninjured );
- }
- }
- break;
- case SK_LOCKPICK:
- {
- // Lockers processed in lockers.fos
- }
- break;
- case SK_TRAPS:
- {
- // Explosion
- if( valid( targetItem ) )
- {
- uint16 pid = targetItem.GetProtoId();
- if( ( pid == PID_ACTIVE_DYNAMITE || pid == PID_ACTIVE_PLASTIC_EXPLOSIVE || pid == PID_ACTIVE_MINE ) &&
- OnUseExplode( cr, targetItem, null, null, null, 0 ) )
- return true;
- }
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- }
- break;
- default:
- {
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_USE_NOTHING );
- }
- break;
- }
- return true;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter reload weapon.
- // If ammo is not valid than only unload.
- void critter_reload_weapon( Critter& cr, Item& weapon, Item@ ammo )
- {
- // Special weapons
- if( weapon.Proto.Weapon_Caliber == 0 )
- {
- if( weapon.GetProtoId() == PID_SOLAR_SCORCHER )
- {
- if( IS_NIGHT( __Hour ) )
- cr.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_SOLAR_SCORCHER_NO_LIGHT );
- else
- {
- weapon.AmmoCount = weapon.Proto.Weapon_MaxAmmoCount;
- weapon.Update();
- }
- }
- return;
- }
- // Other weapons
- // Unload
- if( not valid( ammo ) || ( weapon.AmmoCount > 0 && weapon.AmmoPid != ammo.GetProtoId() ) )
- {
- if( weapon.AmmoPid != 0 )
- {
- Item@ existAmmo = cr.GetItem( weapon.AmmoPid, -1 );
- if( not valid( existAmmo ) )
- cr.AddItem( weapon.AmmoPid, weapon.AmmoCount );
- else
- _IncItem( existAmmo, weapon.AmmoCount );
- }
- weapon.AmmoCount = 0;
- }
- // Load
- if( valid( ammo ) )
- {
- uint count = MIN( ammo.GetCount(), weapon.Proto.Weapon_MaxAmmoCount - weapon.AmmoCount );
- weapon.AmmoCount += count;
- weapon.AmmoPid = ammo.GetProtoId();
- _SubItem( ammo, count );
- }
- weapon.Update();
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on player register/login in game or npc created/loaded.
- // Default start position for players is center of global map.
- void critter_init( Critter& cr, bool firstTime )
- {
- if( firstTime )
- {
- if( cr.IsPlayer() )
- {
- // Input: 7 special, 3 tag skills, 2 traits, age, gender
- uint traits = 0;
- for( uint i = TRAIT_BEGIN; i <= TRAIT_END; i++ )
- {
- if( cr.TraitBase[ i ] != 0 && traits < 2 )
- {
- cr.TraitBase[ i ] = 1;
- traits++;
- }
- else
- cr.TraitBase[ i ] = 0;
- }
- if( cr.StatBase[ ST_GENDER ] < 0 || cr.StatBase[ ST_GENDER ] > 1 )
- cr.StatBase[ ST_GENDER ] = 0;
- if( cr.StatBase[ ST_AGE ] < 14 || cr.StatBase[ ST_AGE ] > 80 )
- cr.StatBase[ ST_AGE ] = 25;
- for( uint i = ST_STRENGTH; i <= ST_LUCK; i++ )
- cr.StatBase[ i ] = CLAMP( cr.StatBase[ i ], 1, 10 );
- if( ( cr.StatBase[ ST_STRENGTH ] + cr.StatBase[ ST_PERCEPTION ] + cr.StatBase[ ST_ENDURANCE ] +
- cr.StatBase[ ST_CHARISMA ] + cr.StatBase[ ST_INTELLECT ] + cr.StatBase[ ST_AGILITY ] + cr.StatBase[ ST_LUCK ] ) != __StartSpecialPoints )
- {
- for( uint i = ST_STRENGTH; i <= ST_LUCK; i++ )
- cr.StatBase[ i ] = 5;
- }
- cr.StatBase[ ST_EMP_RESIST ] = 500;
- cr.AddHolodiskInfo( 42 ); // Journalist's research
- // Default skin
- #ifdef PLAYERS_3D
- if( cr.StatBase[ ST_GENDER ] == GENDER_MALE )
- {
- cr.StatBase[ ST_BASE_CRTYPE ] = CLAMP( cr.StatBase[ ST_BASE_CRTYPE ], CRTYPE_3D_MALE_NORMAL, CRTYPE_3D_MALE_FAT );
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_HAIR ] = CLAMP( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_HAIR ], 0, ATTRIBUTE_Hair_Male_Shoulder + ATTRIBUTE_COLOR_RedGrey );
- if( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_MUSTACHE ] != ATTRIBUTE_Mustache_MadMax )
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_MUSTACHE ] = CLAMP( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_MUSTACHE ], 0, ATTRIBUTE_Mustache_Male_Stubble + ATTRIBUTE_COLOR_RedGrey );
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_BEARD ] = CLAMP( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_BEARD ], 0, ATTRIBUTE_Beard_Male_Stubble + ATTRIBUTE_COLOR_RedGrey );
- }
- else
- {
- cr.StatBase[ ST_BASE_CRTYPE ] = CLAMP( cr.StatBase[ ST_BASE_CRTYPE ], CRTYPE_3D_FEMALE_NORMAL, CRTYPE_3D_FEMALE_FAT );
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_HAIR ] = CLAMP( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_HAIR ], 0, ATTRIBUTE_Hair_Female_Short + ATTRIBUTE_COLOR_RedGrey );
- if( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_MUSTACHE ] != ATTRIBUTE_Mustache_MadMax )
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_MUSTACHE ] = 0;
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_BEARD ] = 0;
- }
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_SKIN ] = CLAMP( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_SKIN ], ATTRIBUTE_Skin_Human_White01, ATTRIBUTE_Skin_Human_Yellow03 );
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_PONYTAIL ] = CLAMP( cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_PONYTAIL ], 0, ATTRIBUTE_Ponytail_Ponytail2 + ATTRIBUTE_COLOR_RedGrey );
- cr.StatBase[ ST_ANIM3D_LAYERS + ANIM3D_LAYER_ARMLET ] = ATTRIBUTE_Armlet_PipBoyClosed;
- cr.ChangeCrType( cr.StatBase[ ST_BASE_CRTYPE ] );
- #endif
- #ifndef PLAYERS_3D
- cr.ChangeCrType( cr.Stat[ ST_GENDER ] == GENDER_MALE ? CRTYPE_DEFAULT_M : CRTYPE_DEFAULT_F );
- #endif
- }
- if( cr.TagSkill[ TAG_SKILL1 ] < int(SKILL_BEGIN) || cr.TagSkill[ TAG_SKILL1 ] > int(SKILL_END) )
- cr.TagSkillBase[ TAG_SKILL1 ] = 0;
- if( cr.TagSkill[ TAG_SKILL2 ] < int(SKILL_BEGIN) || cr.TagSkill[ TAG_SKILL2 ] > int(SKILL_END) )
- cr.TagSkillBase[ TAG_SKILL2 ] = 0;
- if( cr.TagSkill[ TAG_SKILL3 ] < int(SKILL_BEGIN) || cr.TagSkill[ TAG_SKILL3 ] > int(SKILL_END) )
- cr.TagSkillBase[ TAG_SKILL3 ] = 0;
- if( cr.TagSkill[ TAG_SKILL1 ] == cr.TagSkill[ TAG_SKILL2 ] )
- cr.TagSkillBase[ TAG_SKILL1 ] = 0;
- if( cr.TagSkill[ TAG_SKILL2 ] == cr.TagSkill[ TAG_SKILL3 ] )
- cr.TagSkillBase[ TAG_SKILL2 ] = 0;
- if( cr.TagSkill[ TAG_SKILL3 ] == cr.TagSkill[ TAG_SKILL1 ] )
- cr.TagSkillBase[ TAG_SKILL3 ] = 0;
- CritterGenerate( cr );
- cr.StatBase[ ST_CURRENT_HP ] = cr.Stat[ ST_MAX_LIFE ];
- cr.StatBase[ ST_CURRENT_AP ] = cr.Stat[ ST_ACTION_POINTS ] * 100;
- // for(int i=REPUTATION_BEGIN;i<=599;i++) cr.ParamBase[i]=int(0x80000000); // 599 is last number processed in client
- if( cr.IsPlayer() )
- {
- for( uint i = ST_STRENGTH; i <= ST_LUCK; i++ )
- cr.StatBase[ i ] = CLAMP( cr.StatBase[ i ], 1, 10 );
- cr.StatBase[ ST_REPLICATION_COST ] = 100;
- cr.StatBase[ ST_REPLICATION_MONEY ] = 0;
- cr.StatBase[ ST_REPLICATION_COUNT ] = 0;
- cr.StatBase[ ST_TEAM_ID ] = 1;
- cr.StatBase[ ST_DAMAGE_TYPE ] = DAMAGE_NORMAL;
- SetStartLocation( cr );
- // Main quest
- if( __MainStoryLineActive )
- SetPlayerStoryLineLocation( cr );
- }
- else
- {
- cr.ChangeCrType( cr.StatBase[ ST_BASE_CRTYPE ] );
- if( cr.Stat[ ST_LEVEL ] != 0 )
- NpcProcessLevel( cr );
- }
- }
- else
- {
- // Main quest
- if( cr.IsPlayer() && __MainStoryLineActive )
- SetPlayerStoryLineLocation( cr );
- // Current skin validation
- Item@ armor = cr.GetItem( 0, SLOT_ARMOR );
- if( not valid( armor ) )
- {
- uint crType = cr.Stat[ ST_BASE_CRTYPE ];
- if( crType == 0 )
- crType = ( cr.Stat[ ST_GENDER ] == GENDER_MALE ? CRTYPE_DEFAULT_M : CRTYPE_DEFAULT_F );
- if( cr.CrType != crType )
- cr.ChangeCrType( crType );
- }
- // Armor perk validation
- if( not valid( armor ) && cr.Stat[ ST_CURRENT_ARMOR_PERK ] != 0 )
- {
- switch( cr.Stat[ ST_CURRENT_ARMOR_PERK ] )
- {
- case ARMOR_PERK_POWERED:
- cr.StatBase[ ST_STRENGTH_EXT ] -= 3;
- cr.StatBase[ ST_RADIATION_RESISTANCE_EXT ] -= 30;
- break;
- case ARMOR_PERK_COMBAT:
- cr.StatBase[ ST_RADIATION_RESISTANCE_EXT ] -= 20;
- break;
- case ARMOR_PERK_ADVANCED_I:
- cr.StatBase[ ST_STRENGTH_EXT ] -= 4;
- cr.StatBase[ ST_RADIATION_RESISTANCE_EXT ] -= 60;
- break;
- case ARMOR_PERK_ADVANCED_II:
- cr.StatBase[ ST_STRENGTH_EXT ] -= 4;
- cr.StatBase[ ST_RADIATION_RESISTANCE_EXT ] -= 75;
- break;
- case ARMOR_PERK_CHARISMA:
- cr.StatBase[ ST_CHARISMA_EXT ] -= 1;
- break;
- default:
- break;
- }
- cr.StatBase[ ST_CURRENT_ARMOR_PERK ] = 0;
- }
- // Clear timeouts if too long (happens when saves got removed)
- for( uint i = TIMEOUT_BEGIN; i <= TIMEOUT_END; i++ )
- if( i != TO_BATTLE && cr.Timeout[ i ] > int(MAXIMUM_TIMEOUT) )
- cr.TimeoutBase[ i ] = __FullSecond;
- // Erase zero time events
- cr.EraseTimeEvents( 0 );
- // TRAIT_FAST_SHOT migration, delete in future
- if( cr.Trait[ TRAIT_FAST_SHOT ] != 0 )
- cr.ModeBase[ MODE_NO_AIM ] = 1;
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on critter exit from game.
- void critter_finish( Critter& cr, bool toDelete )
- {
- if( toDelete && cr.Stat[ ST_DEAD_BLOCKER_ID ] != 0 )
- {
- Item@ block = ::GetItem( cr.Stat[ ST_DEAD_BLOCKER_ID ] );
- if( valid( block ) )
- DeleteItem( block );
- cr.StatBase[ ST_DEAD_BLOCKER_ID ] = 0;
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call every __CritterIdleTick time.
- void critter_idle( Critter& cr )
- {
- if( cr.IsDead() && cr.Stat[ ST_REPLICATION_TIME ] >= 0 && cr.Timeout[ TO_REPLICATION ] == 0 )
- ReplicateCritter( cr );
- // Healing
- if( cr.Timeout[ TO_HEALING ] == 0 )
- {
- if( !cr.IsDead() && cr.Mode[ MODE_NO_HEAL ] == 0 && cr.Timeout[ TO_BATTLE ] == 0 && cr.StatBase[ ST_CURRENT_HP ] < cr.Stat[ ST_MAX_LIFE ] )
- {
- cr.StatBase[ ST_CURRENT_HP ] += cr.Stat[ ST_HEALING_RATE ] * ( cr.Perk[ PE_VAMPIRE_REGENERATION ] > 0 ? 2 : 1 );
- if( cr.StatBase[ ST_CURRENT_HP ] > cr.Stat[ ST_MAX_LIFE ] )
- cr.StatBase[ ST_CURRENT_HP ] = cr.Stat[ ST_MAX_LIFE ];
- }
- cr.TimeoutBase[ TO_HEALING ] = HEALING_TIMEOUT( cr );
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter dies.
- // Killer can be null.
- void critter_dead( Critter& cr, Critter@ killer )
- {
- Map@ map = cr.GetMap();
- // Move inventory items to ground
- if( ( cr.Anim2Dead == ANIM2_DEAD_PULSE_DUST || cr.Anim2Dead == ANIM2_DEAD_EXPLODE ) && _CritCanDropItemsOnDead( cr ) )
- {
- // Drop all, exclude armor
- Item@[] items;
- cr.GetItems( SLOT_INV, items );
- cr.GetItems( SLOT_HAND1, items );
- cr.GetItems( SLOT_HAND2, items );
- if( valid( map ) )
- {
- // Disable drop of hidden items
- for( uint i = 0, j = items.length(); i < j; i++ )
- {
- if( FLAG( items[ i ].Flags, ITEM_GAG ) )
- {
- Item@ item = items[ i ];
- if( valid( item ) )
- DeleteItem( item );
- @items[ i ] = null;
- }
- else if( FLAG( items[ i ].Flags, ITEM_HIDDEN ) )
- @items[ i ] = null;
- }
- MoveItems( items, map, cr.HexX, cr.HexY );
- }
- else
- DeleteItems( items );
- }
- // Mob drops
- uint16 npcPid = cr.GetProtoId();
- uint16 dropPid = 0;
- switch( npcPid )
- {
- case NPC_PID_GoldenGecko:
- case NPC_PID_ToughGoldenGecko:
- if( valid( killer ) && killer.Perk[ PE_GECKO_SKINNING ] != 0 )
- dropPid = PID_GOLDEN_GECKO_PELT;
- break;
- case NPC_PID_SmallSilverGecko:
- case NPC_PID_ToughSilverGecko:
- if( valid( killer ) && killer.Perk[ PE_GECKO_SKINNING ] != 0 )
- dropPid = PID_GECKO_PELT;
- break;
- case NPC_PID_SmallRadscorpion:
- case NPC_PID_SmallRadscorpion2:
- case NPC_PID_LargeRadscorpion:
- case NPC_PID_LargeRadscorpion2:
- case NPC_PID_LargeRadscorpion3:
- dropPid = PID_SCORPION_TAIL;
- break;
- case NPC_PID_Brahmin:
- case NPC_PID_Brahmin2:
- case NPC_PID_Brahmin3:
- case NPC_PID_WeakBrahmin:
- case NPC_PID_WildBrahmin:
- if( valid( killer ) && killer.Perk[ PE_GECKO_SKINNING ] != 0 )
- dropPid = PID_BRAHMIN_SKIN;
- break;
- case NPC_PID_GiantBeetle:
- case NPC_PID_GiantBeetle_2:
- if( Random( 1, 3 ) == 3 )
- dropPid = PID_RADSCORPION_PARTS;
- break;
- }
- if( dropPid != 0 && _CritCountItem( cr, dropPid ) == 0 )
- _CritAddItem( cr, dropPid, 1 );
- // Karma, temporary
- if( valid( killer ) && killer.IsPlayer() )
- {
- int karmaBefore = killer.StatBase[ ST_KARMA ];
- uint team = cr.Stat[ ST_TEAM_ID ];
- // if(team==TEAM_Player) killer.StatBase[ST_KARMA]-=10;
- if( team == TEAM_Poorman )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_Narcoman )
- killer.StatBase[ ST_KARMA ] += 10;
- else if( team == TEAM_Citizen )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_Guard )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_PrivateGuard )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_Trader )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_Bandit )
- killer.StatBase[ ST_KARMA ] += 10;
- else if( team == TEAM_CasinoPlayer )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_CityElite )
- killer.StatBase[ ST_KARMA ] -= 30;
- else if( team == TEAM_QuestNpc )
- killer.StatBase[ ST_KARMA ] -= 30;
- else if( team == TEAM_Police )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_Slaver )
- killer.StatBase[ ST_KARMA ] += 10;
- else if( team == TEAM_Slave )
- killer.StatBase[ ST_KARMA ] -= 10;
- else if( team == TEAM_Trapper )
- killer.StatBase[ ST_KARMA ] -= 10;
- if( cr.Stat[ ST_BODY_TYPE ] == BT_CHILDREN )
- killer.KarmaBase[ KARMA_CHILDKILLER ]++;
- CallTownSupply( cr, killer ); // Town supply call
- }
- SetReplicationTime( cr );
- if( cr.IsNpc() )
- cr.DropPlanes(); // Delete all planes
- if( valid( map ) && cr.Mode[ MODE_NO_FLATTEN ] != 0 )
- {
- Item@ blocker = map.AddItem( cr.HexX, cr.HexY, PID_UNVISIBLE_BLOCK, 1 );
- if( valid( blocker ) )
- cr.StatBase[ ST_DEAD_BLOCKER_ID ] = blocker.Id;
- }
- OnCritterKilled( cr, killer );
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter reswapned.
- void critter_respawn( Critter& cr )
- {
- if( cr.Stat[ ST_DEAD_BLOCKER_ID ] != 0 )
- {
- Item@ block = ::GetItem( cr.Stat[ ST_DEAD_BLOCKER_ID ] );
- if( valid( block ) )
- DeleteItem( block );
- cr.StatBase[ ST_DEAD_BLOCKER_ID ] = 0;
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter in to map.
- void map_critter_in( Map& map, Critter& cr )
- {
- OnCitterMapIn( cr, map );
- if( cr.IsPlayer() )
- {
- uint16 locPid = map.GetLocation().GetProtoId();
- if( LOCATION_IS_CITY( locPid ) )
- {
- GameVar@ lastCityVar = GetLocalVar( LVAR_last_city, cr.Id );
- if( lastCityVar is null )
- return;
- lastCityVar = locPid;
- }
- PlaceLoot2Container( map, cr );
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something critter out from map.
- void map_critter_out( Map& map, Critter& cr )
- {
- OnCritterMapOut( cr, map );
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something player votes for another.
- // Already checked valid positions and timeout.
- void karma_voting( Critter& crFrom, Critter& crTo, bool valUp )
- {
- // Players karma system (not used)
- crTo.StatBase[ ST_PLAYER_KARMA ] += ( valUp ? int(5) : -10 );
- crFrom.TimeoutBase[ TO_KARMA_VOTING ] = __FullSecond + REAL_HOUR( 4 ); // 4 hours
- /* // Good / Evil system (not used)
- crFrom.TimeoutBase[TO_KARMA_VOTING]=__FullSecond+60; // Some small time to prevent bruteforce
- int crId=int(crTo.Id);
- // Find alredy added
- for(uint i=GOOD_EVIL_LIST_BEGIN;i<=GOOD_EVIL_LIST_END;i++)
- {
- int id=crFrom.GoodEvilList[i];
- if(id!=0)
- {
- bool isEvil=FLAG(id,0x80000000);
- if(isEvil) id^=0x80000000;
- if(id==crId)
- {
- if((valUp && not isEvil) || (not valUp && isEvil)) return; // Already added
- crFrom.GoodEvilListBase[i]=0; // Erase from list
- return;
- }
- }
- }
- // Add new record
- if(not valUp) crId|=0x80000000;
- for(uint i=GOOD_EVIL_LIST_BEGIN;i<=GOOD_EVIL_LIST_END;i++)
- {
- int id=crFrom.GoodEvilList[i];
- if(id==0)
- {
- crFrom.GoodEvilListBase[i]=crId;
- return;
- }
- }
- // All places busy, erase first 10
- for(uint i=GOOD_EVIL_LIST_BEGIN;i<=GOOD_EVIL_LIST_END-10;i++) crFrom.GoodEvilListBase[i]=crFrom.GoodEvilListBase[i+10];
- for(uint i=GOOD_EVIL_LIST_END-9;i<=GOOD_EVIL_LIST_END;i++) crFrom.GoodEvilListBase[i]=0;
- crFrom.GoodEvilListBase[GOOD_EVIL_LIST_END-10]=crId;*/
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call to determine visibility of critters.
- // To start working set flag LOOK_CHECK_SCRIPT to __LookChecks global var.
- // Return true to allow see one critter another, false to disallow.
- // Note: CRITTER_EVENT_SHOW_CRITTER_X, CRITTER_EVENT_HIDE_CRITTER_X is not processed.
- bool check_look( Map& map, Critter& cr, Critter& opponent )
- {
- return true;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call to determine visibility of items with ITEM_TRAP flag.
- // To start working set flag LOOK_CHECK_SCRIPT to __LookChecks global var.
- bool check_trap_look( Map& map, Critter& cr, Item& trap )
- {
- return true;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call to determine cost of single item.
- // To allow function set __CustomItemCost to true.
- // Don't forgot specify this function in client script.
- uint item_cost( Item& item, Critter& cr, Critter& npc, bool sell )
- {
- return sell ? 1 : 2;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on barter transaction.
- // Return false to cancel transaction.
- bool items_barter( Item@[]& saleItems, uint[]& saleItemsCount, Item@[]& buyItems, uint[]& buyItemsCount, Critter& player, Critter& npc )
- {
- if( npc.Mode[ MODE_BARTER_ONLY_CASH ] > 0 )
- {
- for( uint i = 0, j = saleItems.length(); i < j; i++ )
- {
- Item@ item = saleItems[ i ];
- if( valid( item ) && item.GetProtoId() != PID_BOTTLE_CAPS )
- {
- npc.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_BARTER_ONLY_CASH );
- npc.SayMsg( SAY_DIALOG, TEXTMSG_GAME, STR_BARTER_ONLY_CASH );
- return false;
- }
- }
- }
- if( !BarterAllowed( npc.Id, buyItems, saleItems ) )
- {
- npc.SayMsg( SAY_NETMSG, TEXTMSG_GAME, STR_BARTER_ITEM_NOT_ALLOWED );
- return false;
- }
- return true;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Call on something player craft some items.
- // Resources have None accessory and will be deleted after this function if no will be added to some place.
- void items_crafted( Item@[]& items, uint[]& itemsCount, Item@[]& resources, Critter& crafter )
- {
- // Find max deterioration value
- int maxDeterioration = 0;
- for( uint i = 0, j = resources.length(); i < j; i++ )
- {
- Item@ item = resources[ i ];
- int deterioration = GetDeteriorationProcent( item );
- if( deterioration > maxDeterioration )
- maxDeterioration = deterioration;
- }
- for( uint i = 0, j = items.length(); i < j; i++ )
- {
- // Unload weapons
- Item@ item = items[ i ];
- if( item.GetType() == ITEM_TYPE_WEAPON && item.Proto.Weapon_MaxAmmoCount > 0 )
- {
- item.AmmoCount = 0;
- item.Update();
- }
- // Set max deterioration value
- SetDeterioration( item, maxDeterioration );
- }
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Levelup callback.
- void player_levelup( Critter& player, uint skillIndex, uint skillUp, uint perkIndex )
- {
- if( skillIndex >= SKILL_BEGIN && skillIndex <= SKILL_END )
- {
- for( ; skillUp != 0; skillUp-- )
- {
- int skillVal = player.SkillBase[ skillIndex ];
- if( skillVal >= MAX_SKILL_VAL )
- break;
- int needPoints = 1;
- if( skillVal > __SkillModAdd6 )
- needPoints = 6;
- else if( skillVal > __SkillModAdd5 )
- needPoints = 5;
- else if( skillVal > __SkillModAdd4 )
- needPoints = 4;
- else if( skillVal > __SkillModAdd3 )
- needPoints = 3;
- else if( skillVal > __SkillModAdd2 )
- needPoints = 2;
- if( player.StatBase[ ST_UNSPENT_SKILL_POINTS ] < needPoints )
- break;
- skillVal++;
- if( _CritIsTagSkill( player, skillIndex ) && skillVal < MAX_SKILL_VAL )
- skillVal++;
- player.SkillBase[ skillIndex ] = skillVal;
- player.StatBase[ ST_UNSPENT_SKILL_POINTS ] -= needPoints;
- }
- }
- else if( perkIndex >= PERK_BEGIN && perkIndex <= PERK_END )
- {
- if( PerkCheck( player, perkIndex ) )
- {
- player.PerkBase[ perkIndex ]++;
- player.StatBase[ ST_UNSPENT_PERKS ]--;
- }
- }
- player.StatBase[ ST_REPLICATION_COST ] = player.Stat[ ST_LEVEL ] * 100;
- }
- // //////////////////////////////////////////////////////////////////////////////////////////////////
- // Turn based callbacks.
- // Called on every round begin, return false to disable turn-based
- void turn_based_begin( Map& map )
- {
- // Try end battle
- if( map.TurnBasedRound > 0 )
- {
- uint[] crittersIds;
- map.GetTurnBasedSequence( crittersIds );
- bool continueBattle = false;
- if( crittersIds.length() >= 2 )
- {
- for( uint i = 0, j = crittersIds.length(); i < j; i++ )
- {
- Critter@ cr = ::GetCritter( crittersIds[ i ] );
- if( !( not valid( cr ) || cr.IsDead() ||
- ( cr.IsNpc() && cr.GetPlanes( AI_PLANE_ATTACK, null ) == 0 ) ||
- ( cr.IsPlayer() && ( cr.Mode[ MODE_END_COMBAT ] != 0 || cr.Stat[ ST_CURRENT_HP ] < 1 ) ) ) )
- {
- continueBattle = true;
- break;
- }
- }
- }
- if( not continueBattle )
- map.EndTurnBased();
- }
- }
- // Call on end turn-based battle
- void turn_based_end( Map& map )
- {
- //
- }
- // Call on every begin and end turn
- void turn_based_process( Map& map, Critter& cr, bool beginTurn )
- {
- if( beginTurn )
- {
- cr.StatBase[ ST_MOVE_AP ] = cr.Stat[ ST_MAX_MOVE_AP ];
- cr.StatBase[ ST_TURN_BASED_AC ] = 0;
- }
- else
- {
- bool hthEvade = false;
- if( cr.Perk[ PE_HTH_EVADE ] != 0 )
- {
- // In hands only HtH weapons
- Item@ hand1 = cr.GetItem( 0, SLOT_HAND1 );
- Item@ hand2 = cr.GetItem( 0, SLOT_HAND2 );
- if( ( not valid( hand1 ) || hand1.GetType() != ITEM_TYPE_WEAPON || not hand1.Weapon_IsHtHAttack( 0 ) ) &&
- ( not valid( hand1 ) || hand1.GetType() != ITEM_TYPE_WEAPON || not hand1.Weapon_IsHtHAttack( 0 ) ) )
- {
- hthEvade = true;
- }
- }
- cr.StatBase[ ST_TURN_BASED_AC ] = cr.Stat[ ST_CURRENT_AP ] * ( hthEvade ? 2 : 1 );
- if( cr.Stat[ ST_TURN_BASED_AC ] < 0 )
- cr.StatBase[ ST_TURN_BASED_AC ] = 0;
- if( hthEvade && cr.Skill[ SK_UNARMED ] > 0 )
- cr.StatBase[ ST_TURN_BASED_AC ] += cr.Skill[ SK_UNARMED ] / 12;
- cr.StatBase[ ST_MOVE_AP ] = 0;
- }
- }
- // Call when need generate turns sequence
- void turn_based_sequence( Map& map, Critter@[]& critters, Critter@ firstTurnCrit )
- {
- // Check first turn critter
- if( valid( firstTurnCrit ) && ( firstTurnCrit.IsDead() || firstTurnCrit.Stat[ ST_CURRENT_AP ] <= 0 ) )
- @firstTurnCrit = null;
- // Collect critters
- SequenceCritter[] sequenceCritters;
- for( uint i = 0, j = critters.length(); i < j; i++ )
- {
- Critter@ cr = critters[ i ];
- if( valid( firstTurnCrit ) && firstTurnCrit.Id == cr.Id )
- continue;
- if( cr.IsDead() )
- continue;
- sequenceCritters.resize( sequenceCritters.length() + 1 );
- @sequenceCritters.last().critter = cr;
- }
- // Sort sequence, see SequenceCritter::opCmp below
- SequenceCritterRandom = Random( 0, 1 );
- sequenceCritters.sortDesc();
- // Fill result
- critters.resize( 0 );
- if( valid( firstTurnCrit ) )
- critters.insertLast( firstTurnCrit );
- for( uint i = 0, j = sequenceCritters.length(); i < j; i++ )
- critters.insertLast( sequenceCritters[ i ].critter );
- }
- // Sequence sorter for turn_based_sequence
- int SequenceCritterRandom = 0;
- class SequenceCritter
- {
- Critter@ critter;
- int opCmp( SequenceCritter& in other )
- {
- bool result;
- Critter@ cr1 = critter;
- Critter@ cr2 = other.critter;
- int seq1 = cr1.Stat[ ST_SEQUENCE ];
- int seq2 = cr2.Stat[ ST_SEQUENCE ];
- if( seq1 == seq2 )
- {
- int ag1 = cr1.Stat[ ST_AGILITY ];
- int ag2 = cr2.Stat[ ST_AGILITY ];
- if( ag1 == ag2 )
- {
- int lk1 = cr1.Stat[ ST_LUCK ];
- int lk2 = cr2.Stat[ ST_LUCK ];
- if( lk1 == lk2 )
- {
- if( SequenceCritterRandom == 0 )
- result = cr1.Id > cr2.Id;
- else
- result = cr1.Id < cr2.Id;
- }
- else
- result = lk1 > lk2;
- }
- else
- result = ag1 > ag2;
- }
- else
- result = seq1 > seq2;
- return result ? int(1) : int(-1);
- }
- }
- // Call on world saving
- // Range of currentIndex: 1..9999
- void world_save( uint currentIndex, uint[]& deleteIndexes )
- {
- // Keep only current and four last saves
- if( currentIndex == 1 )
- {
- deleteIndexes.resize( 5 );
- for( uint i = 0; i < 5; i++ )
- deleteIndexes[ i ] = 9999 - i;
- }
- else if( currentIndex > 4 )
- {
- deleteIndexes.resize( 1 );
- deleteIndexes[ 0 ] = currentIndex - 5;
- }
- // bboards
- SaveMessengerData();
- }
- // Call on player try register
- // Return true to allow, false to disallow
- bool player_registration( uint ip, string& name, uint& textMsg, uint& strNum )
- {
- uint nameError = CheckPlayerName( name );
- if( nameError != 0 )
- {
- textMsg = TEXTMSG_GAME;
- strNum = nameError;
- return false;
- }
- return true;
- }
- // Call on player try login
- // Return true to allow, false to disallow
- bool player_login( uint ip, string& name, uint id, uint& textMsg, uint& strNum )
- {
- if( __PermanentDeath > 0 && IsPermanentDeath( id ) )
- {
- textMsg = TEXTMSG_GAME;
- strNum = STR_NET_PERMANENT_DEATH;
- return false;
- }
- return true;
- }
- // Call on player try change access
- // Return true to allow, false to disallow
- bool player_getaccess( Critter& player, int access, string& password )
- {
- Log( "Access changed for player " + player.Name + ", from " + player.GetAccess() + " to " + access + "." );
- return true;
- }
- bool player_allowcommand( Critter@ player, string@ adminPanel, uint8 command )
- {
- if( valid( adminPanel ) )
- return true;
- switch( command )
- {
- // ACCESS_CLIENT
- case COMMAND_CHANGE_PASSWORD:
- case COMMAND_DELETE_ACCOUNT:
- case COMMAND_EXIT:
- case COMMAND_GETACCESS:
- case COMMAND_MYINFO:
- return true;
- // ACCESS_TESTER
- case COMMAND_DROP_UID:
- case COMMAND_PARAM:
- case COMMAND_TOGLOBAL:
- if( player.GetAccess() >= ACCESS_TESTER )
- return true;
- break;
- // ACCESS_MODER
- case COMMAND_ADDITEM:
- case COMMAND_ADDITEM_SELF:
- case COMMAND_ADDLOCATION:
- case COMMAND_ADDNPC:
- case COMMAND_BAN:
- case COMMAND_CHECKVAR:
- case COMMAND_CRITID:
- case COMMAND_DISCONCRIT:
- case COMMAND_GAMEINFO:
- case COMMAND_KILLCRIT:
- case COMMAND_MOVECRIT:
- case COMMAND_RESPAWN:
- case COMMAND_SETVAR:
- if( player.GetAccess() >= ACCESS_MODER )
- return true;
- break;
- // ACCESS_ADMIN
- case COMMAND_LOADDIALOG:
- case COMMAND_LOADLOCATION:
- case COMMAND_LOADMAP:
- case COMMAND_LOADSCRIPT:
- case COMMAND_LOG:
- case COMMAND_RELOAD_CLIENT_SCRIPTS:
- case COMMAND_RELOADAI:
- case COMMAND_RELOADDIALOGS:
- case COMMAND_RELOADLOCATIONS:
- case COMMAND_RELOADMAPS:
- case COMMAND_RELOADSCRIPTS:
- case COMMAND_RELOADTEXTS:
- case COMMAND_REGENMAP:
- case COMMAND_RUNSCRIPT:
- case COMMAND_SETTIME:
- if( player.GetAccess() == ACCESS_ADMIN )
- return true;
- break;
- // Unknown command
- default:
- player.Say( SAY_NETMSG, "Unknown command." );
- return false;
- }
- player.Say( SAY_NETMSG, "Access denied." );
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement